diff --git a/src/endWeek/economics/arcmgmt.js b/src/endWeek/economics/arcmgmt.js
index b93d8335e9908a25b6fdc71fd3aa928e4b77ec18..e644672a6b664a5b629174d87652a6048d449897 100644
--- a/src/endWeek/economics/arcmgmt.js
+++ b/src/endWeek/economics/arcmgmt.js
@@ -3,16 +3,6 @@ App.EndWeek.arcManagement = function() {
 	const secExpImmigrationBonus = App.SecExp.propagandaEffects("immigration");
 	let r;
 	let enslaved;
-	let crime;
-	let terrain;
-	let transportHub;
-	let honeymoon;
-	let LCD;
-	let SCD;
-	let LSCD;
-	let MCD;
-	let UCD;
-	let TCD;
 	let rentMultiplier;
 	let AWeekGrowth;
 	let econMult;
@@ -78,7 +68,6 @@ App.EndWeek.arcManagement = function() {
 	r = [];
 	r.push(slaveRetirement());
 	r.push(expiration());
-	r.push(denseApartments());
 	App.Events.addParagraph(el, r);
 
 	citizenToSlave();
@@ -92,32 +81,25 @@ App.EndWeek.arcManagement = function() {
 		econMult = (1/(1 + 5 * Math.sqrt(Math.trunc(100000/50-1000)/8.5)/100));
 	}
 
-	if (!isFrozen()) {
-		transport();
-	} else {
-		/* enslavement happens even if there's no traffic due to weather */
-		LSCD = 0;
-		enslavement();
+	const frozen = isFrozen();
+
+	if (!frozen) {
+		const apartments = denseApartments();
+		if (apartments.length > 0) {
+			App.Events.addParagraph(el, apartments);
+		}
 	}
 
+	const menialWorkAvailable = processDemand(frozen);
+
 	V.ASlaves = V.NPCSlaves + V.menials + V.fuckdolls + V.menialBioreactors;
 	if (V.secExpEnabled > 0) {
 		V.ASlaves += (V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0) + App.SecExp.Manpower.employedSlave;
 	}
 	V.ACitizens = V.lowerClass + V.middleClass + V.upperClass + V.topClass;
-	let table;
-	if (V.cheatMode === 1 || V.debugMode === 1) {
-		table = App.UI.DOM.appendNewElement("table", el);
-		App.UI.DOM.makeRow(table, `${V.arcologies[0].prosperity} Prosperity`, `${FSScore} FS Score`, `${honeymoon} Honeymoon`, `${transportHub} Transporthub`, `${terrain} Terrain`, `${crime} Crime`);
-		App.UI.DOM.makeRow(table, `${LSCD.toFixed(1)} Lower + Slave Class Demand`, `${SCD.toFixed(1)} Slave Class Demand`, `${slaveProductivity.toFixed(1)} Slave Productivity`);
-		App.UI.DOM.makeRow(table, `${LCD.toFixed(1)} Lower Class Demand`, `${lowerClassP.toFixed(1)} LC Multiplier`);
-		App.UI.DOM.makeRow(table, `${MCD.toFixed(1)} Middle Class Demand`, `${middleClassP.toFixed(1)} MC Multiplier`);
-		App.UI.DOM.makeRow(table, `${UCD.toFixed(1)} Upper Class Demand`, `${upperClassP.toFixed(1)} UC Multiplier`);
-		App.UI.DOM.makeRow(table, `${TCD.toFixed(1)} Top Class Demand`, `${topClassP.toFixed(1)} TC Multiplier`);
-	}
 	const percOfPop = (n) => Math.trunc((n / (V.ACitizens + V.ASlaves)) * 1000) / 10;
 	appendDiv(`${V.arcologies[0].name} is home to the following:`);
-	table = App.UI.DOM.appendNewElement("table", el);
+	const table = App.UI.DOM.appendNewElement("table", el);
 	App.UI.DOM.makeRow(table, `Citizens`, `${num(V.ACitizens)}`, `${percOfPop(V.ACitizens)}%`);
 	App.UI.DOM.makeRow(table, `Lower Class Citizens`, `${num(V.lowerClass)}`, `${percOfPop(V.lowerClass)}%`);
 	App.UI.DOM.makeRow(table, `Middle Class Citizens`, `${num(V.middleClass)}`, `${percOfPop(V.middleClass)}%`);
@@ -312,13 +294,13 @@ App.EndWeek.arcManagement = function() {
 		let fuckdollsEarnings = 0;
 		r.push(`You own`);
 		if (V.menials > 0) {
-			if (V.menials > Math.trunc(LSCD / slaveProductivity - SCD)) {
-				menialEarnings += Math.max(Math.trunc(LSCD / slaveProductivity - SCD) * 10, 0);
+			if (V.menials > menialWorkAvailable) {
+				menialEarnings += Math.max(menialWorkAvailable * 10, 0);
 				r.push(`<span class="red">more menial slaves than there was work,</span> consider selling some.`);
 				if (menialEarnings === 0) {
 					r.push(`Actually, consider selling them all...demand for labor is so low that <span class="red">none of them made any money</span> this week.`);
 				}
-				r.push(`<br> You own`);
+				r.push(`<br>You own`);
 			} else {
 				menialEarnings = V.menials * 10;
 				if (V.Sweatshops > 0) {
@@ -1069,6 +1051,7 @@ App.EndWeek.arcManagement = function() {
 			App.UI.DOM.appendNewElement("h3", el, "Future Societies");
 		}
 		App.Events.addNode(el, r);
+		FSScore = FSScore / V.FSCreditCount;
 		return el;
 	}
 
@@ -1425,22 +1408,22 @@ App.EndWeek.arcManagement = function() {
 
 	function isFrozen() {
 		/* during bad weather and without appropriate upgrades, transport (including visitors and immigration/emigration) will be halted */
-		let weatherFreeze = 0;
+		let weatherFreeze = false;
 		if (V.weatherToday.severity > 3) {
 			if (V.secExpEnabled > 0 && V.SecExp.buildings.transportHub) {
 				if (V.SecExp.buildings.transportHub.surfaceTransport < 4) {
-					weatherFreeze = 1;
+					weatherFreeze = true;
 				}
 			} else if (V.antiWeatherFreeze < 2) {
-				weatherFreeze = 1;
+				weatherFreeze = true;
 			}
 		} else if (V.weatherToday.severity > 2) {
 			if (V.secExpEnabled > 0 && V.SecExp.buildings.transportHub) {
 				if (V.SecExp.buildings.transportHub.surfaceTransport < 3) {
-					weatherFreeze = 1;
+					weatherFreeze = true;
 				}
 			} else if (V.antiWeatherFreeze < 1) {
-				weatherFreeze = 1;
+				weatherFreeze = true;
 			}
 		}
 		if (weatherFreeze) {
@@ -1466,10 +1449,9 @@ App.EndWeek.arcManagement = function() {
 		}
 	}
 
-	function transport() {
-		FSScore = FSScore / V.FSCreditCount;
-		transportHub = 1;
-		crime = 0.8;
+	function processDemand(/** @type {boolean} */ isFrozen) {
+		let transportHub = 1;
+		let crime = 0.8;
 		if (V.secExpEnabled > 0) {
 			transportHub = 0.7;
 			if (V.SecExp.buildings.transportHub) {
@@ -1479,34 +1461,32 @@ App.EndWeek.arcManagement = function() {
 			const waterwayDamaged = App.SecExp.updateFacilityDamage("waterway");
 			appendDiv(waterwayDamaged.text);
 		}
-		if (V.terrain === "urban") {
-			terrain = 1.2;
-		} else if (V.terrain === "rural" || V.terrain === "marine") {
-			terrain = 1;
-		} else {
-			terrain = 0.8;
-		}
+		const terrainFactors = {
+			urban: 1.2,
+			rural: 1.0,
+			marine: 1.0,
+			ravine: 0.8,
+			oceanic: 0.8
+		};
+		const terrain = terrainFactors[V.terrain] || 1.0;
+		const honeymoon = 10 * V.arcologies[0].honeymoon;
 
-		honeymoon = 0;
-		if (V.arcologies[0].honeymoon > 0) {
-			honeymoon = 10 * V.arcologies[0].honeymoon;
-		}
-		const oldVisitors = V.visitors;
-		V.visitors = Math.trunc(((V.arcologies[0].prosperity + FSScore * 5 + honeymoon) * transportHub * terrain * crime) * econMult);
+		NaNCheck({FSScore, transportHub, crime, terrain, honeymoon, econMult}); // eslint-disable-line object-curly-newline
 
-		if (V.visitors < 50) {
-			V.visitors = normalRandInt(50, 2);
-		}
-		if (isNaN(V.visitors)) {
-			appendDiv(`<span class="red">Visitors is NaN, report this issue!</span>`);
-			V.visitors = oldVisitors;
+		if (isFrozen) {
+			// no visitors when frozen, period
+			V.visitors = 0;
+		} else {
+			V.visitors = Math.trunc(((V.arcologies[0].prosperity + FSScore * 5 + honeymoon) * transportHub * terrain * crime) * econMult);
+			if (V.visitors < 50) {
+				V.visitors = normalRandInt(50, 2);
+			}
+			appendDiv(`<span class="green">${num(V.visitors)} traders and tourists</span> visited your arcology this week.`);
+			appendDiv(App.SecExp.propagandaEffects("enslavement").text);
+			enslaved += App.SecExp.propagandaEffects("enslavement").effect;
 		}
-		appendDiv(`<span class="green">${num(V.visitors)} traders and tourists</span> visited your arcology this week.`);
-		appendDiv(App.SecExp.propagandaEffects("enslavement").text);
-		enslaved += App.SecExp.propagandaEffects("enslavement").effect;
 
-		/* slaves*/
-		/* Slaves getting retired*/
+		/* Slaves getting retired - happens even when frozen */
 		if (V.policies.retirement.menial2Citizen === 1) {
 			let weeklyRetiredMenials = V.menials / ((V.customMenialRetirementAge - 15) * 52);
 			let weeklyRetiredNPCMenials = V.NPCSlaves / ((V.customMenialRetirementAge - 15) * 52);
@@ -1547,17 +1527,17 @@ App.EndWeek.arcManagement = function() {
 			V.NPCSlaves -= weeklyRetiredNPCMenials;
 			V.lowerClass += weeklyRetiredMenials + weeklyRetiredNPCMenials;
 		}
+
 		/* Demand for simple labor*/
-		LSCD = Math.trunc((V.LSCBase * econMult) + (V.arcologies[0].prosperity * 4) + ((V.middleClass + V.visitors * 0.6) * 1.5) + ((V.upperClass + V.visitors * 0.2) * 3.5) + (V.topClass * 18));
+		const LSCD = Math.trunc((V.LSCBase * econMult) + (V.arcologies[0].prosperity * 4) + ((V.middleClass + V.visitors * 0.6) * 1.5) + ((V.upperClass + V.visitors * 0.2) * 3.5) + (V.topClass * 18));
 		/* Demand for owning slaves*/
-		SCD = Math.trunc((V.upperClass * (2 + slaveDemandU)) + (V.topClass * (12 + slaveDemandT)));
-		if (isNaN(LSCD)) {
-			appendDiv(`<span class="red">LSCD is NaN, report this issue!</span>`);
-		} else if (isNaN(SCD)) {
-			appendDiv(`<span class="red">SCD is NaN, report this issue!</span>`);
-		} else {
-			/* More slaves than they know what to do with*/
+		const SCD = Math.trunc((V.upperClass * (2 + slaveDemandU)) + (V.topClass * (12 + slaveDemandT)));
+		NaNCheck({LSCD, SCD});
+		const maxSlaveLabor = Math.trunc(LSCD / slaveProductivity);
+		/* Slave import/export only if transport accessible */
+		if (!isFrozen) {
 			if (V.NPCSlaves > SCD * 1.6) {
+				/* More slaves than they know what to do with*/
 				const NPCSlavesSold = V.NPCSlaves - Math.trunc(SCD * 1.6);
 				V.menialDemandFactor -= NPCSlavesSold;
 				V.NPCSlaves = Math.trunc(SCD * 1.6);
@@ -1566,18 +1546,18 @@ App.EndWeek.arcManagement = function() {
 				} else if (NPCSlavesSold > 0) {
 					appendDiv(`<span class="red">One slave</span> was sold by your inhabitants. They've got more than enough of them already.`);
 				}
+			} else if (V.NPCSlaves > maxSlaveLabor - V.menials + SCD) {
 				/* More slaves than there is work*/
-			} else if (V.NPCSlaves > (LSCD / slaveProductivity) - V.menials + SCD) {
-				const NPCSlavesSold = V.NPCSlaves - Math.trunc(LSCD / slaveProductivity - V.menials + SCD);
+				const NPCSlavesSold = V.NPCSlaves - Math.trunc(maxSlaveLabor - V.menials + SCD);
 				V.menialDemandFactor -= NPCSlavesSold;
-				V.NPCSlaves = Math.trunc(LSCD / slaveProductivity);
+				V.NPCSlaves = maxSlaveLabor - V.menials + SCD;
 				if (NPCSlavesSold > 1) {
 					appendDiv(`<span class="red">${num(NPCSlavesSold)}</span> slaves were sold by your inhabitants. There was so little work that they failed to earn their keep.`);
 				} else if (NPCSlavesSold > 0) {
 					appendDiv(`<span class="red">One slave</span> was sold by your inhabitants. There was so little work that it failed to earn its keep.`);
 				}
-				/* Cutting back on slaves*/
 			} else if (V.NPCSlaves > SCD * 1.4) {
+				/* Cutting back on slaves*/
 				if (V.slaveCostFactor > 0.95) {
 					const NPCSlavesSold = Math.trunc((V.NPCSlaves - SCD) * 0.4);
 					V.menialDemandFactor -= NPCSlavesSold;
@@ -1588,8 +1568,8 @@ App.EndWeek.arcManagement = function() {
 						appendDiv(`<span class="red">One slave</span> was sold by your inhabitants. They've got more than enough of them already.`);
 					}
 				}
-				/* Selling excess slaves for profit*/
 			} else if (V.NPCSlaves > SCD * 1.2) {
+				/* Selling excess slaves for profit*/
 				if (V.slaveCostFactor > 1.1) {
 					const NPCSlavesSold = Math.trunc((V.NPCSlaves - SCD) * 0.4);
 					V.menialDemandFactor -= NPCSlavesSold;
@@ -1616,16 +1596,14 @@ App.EndWeek.arcManagement = function() {
 
 		/* Lower Class Citizens*/
 		/* Work left for lower class citizens*/
-		LCD = Math.trunc(((V.LSCBase * econMult) + (V.arcologies[0].prosperity * 4) + lowerClass + ((V.middleClass + V.visitors * 0.6) * 1.5) + ((V.upperClass + V.visitors * 0.2) * 3.5) + (V.topClass * 18) - (V.NPCSlaves + V.menials) * slaveProductivity) * V.rentEffectL * lowerClassP);
+		let LCD = Math.trunc(((V.LSCBase * econMult) + (V.arcologies[0].prosperity * 4) + lowerClass + ((V.middleClass + V.visitors * 0.6) * 1.5) + ((V.upperClass + V.visitors * 0.2) * 3.5) + (V.topClass * 18) - (V.NPCSlaves + V.menials) * slaveProductivity) * V.rentEffectL * lowerClassP);
 		if (V.classSatisfied.lowerClass !== 0) {
 			LCD *= 1 + V.classSatisfied.lowerClass * 0.06;
 		}
-		if (LCD < 0) {
-			LCD = 0;
-		}
-		if (isNaN(LCD)) {
-			appendDiv(`<span class="red">LCD is NaN, report this issue!</span>`);
-		} else { /* Changing population depending on work available*/
+		NaNCheck({LCD});
+		LCD = Math.max(LCD, 0);
+		/* Changing population depending on work available, if transport is accessible */
+		if (!isFrozen) {
 			if (V.classSatisfied.lowerClass < 0) {
 				appendDiv(`Your lower class is <span class="red">sexually frustrated</span> and would rather live elsewhere.`);
 			} else if (V.classSatisfied.lowerClass > 0) {
@@ -1665,8 +1643,11 @@ App.EndWeek.arcManagement = function() {
 				}
 			}
 			App.Events.addNode(el, r, "div");
-			enslavement();
-			/* Need more slaves still*/
+		}
+
+		enslavement();
+		if (!isFrozen) {
+			/* Import more slaves if they're still needed after enslavement */
 			if (V.NPCSlaves < SCD) {
 				const NPCSlavesBought = Math.trunc((SCD - V.NPCSlaves) * 0.75) + 1;
 				V.menialSupplyFactor -= NPCSlavesBought;
@@ -1681,23 +1662,20 @@ App.EndWeek.arcManagement = function() {
 
 		/* Middle Class Citizens*/
 		/* Demand for Middle Class*/
-		MCD = Math.trunc(((V.MCBase * econMult) + V.arcologies[0].prosperity + middleClass + (V.NPCSlaves * 0.15) + (V.lowerClass * 0.1) + ((V.upperClass + V.visitors * 0.2) * 0.5) + (V.topClass * 2.5)) * V.rentEffectM * middleClassP);
+		let MCD = Math.trunc(((V.MCBase * econMult) + V.arcologies[0].prosperity + middleClass + (V.NPCSlaves * 0.15) + (V.lowerClass * 0.1) + ((V.upperClass + V.visitors * 0.2) * 0.5) + (V.topClass * 2.5)) * V.rentEffectM * middleClassP);
 		if (V.classSatisfied.middleClass !== 0) {
 			MCD *= 1 + V.classSatisfied.middleClass * 0.06;
 		}
-		if (MCD < 200) {
-			MCD = 200;
-		}
-		if (isNaN(MCD)) {
-			appendDiv(`<span class="red">MCD is NaN, report this issue!</span>`);
-		} else {
-			/* Middle Class Citizens immigrating*/
+		NaNCheck({MCD});
+		MCD = Math.max(MCD, 200);
+		if (!isFrozen) {
 			if (V.classSatisfied.middleClass < 0) {
 				appendDiv(`Your middle class is <span class="red">sexually frustrated</span> and would rather live elsewhere.`);
 			} else if (V.classSatisfied.middleClass > 0) {
 				appendDiv(`Your middle class is <span class="green">sexually satiated</span> and their happiness attracts others.`);
 			}
 			if (V.middleClass < MCD) {
+				/* Middle Class Citizens immigrating */
 				const MCImmigration = Math.trunc((MCD - V.middleClass) * (0.3 * terrain)) + 1 + secExpImmigrationBonus.effect;
 				V.middleClass += MCImmigration;
 				if (MCImmigration > 1) {
@@ -1705,8 +1683,8 @@ App.EndWeek.arcManagement = function() {
 				} else if (MCImmigration > 0) {
 					appendDiv(`<span class="green">One middle class citizen</span> moved to your arcology.`);
 				}
-				/* Middle Class Citizens emigrating*/
 			} else if (V.middleClass > MCD) {
+				/* Middle Class Citizens emigrating*/
 				const MCEmigration = Math.trunc((V.middleClass - MCD) * 0.4);
 				V.middleClass -= MCEmigration;
 				if (MCEmigration > 1) {
@@ -1719,23 +1697,20 @@ App.EndWeek.arcManagement = function() {
 
 		/* Upper Class Citizens*/
 		/* Demand for Upper Class*/
-		UCD = Math.trunc(((V.UCBase * econMult) + (V.arcologies[0].prosperity * 0.2) + upperClass + (V.NPCSlaves * 0.02) + (V.lowerClass * 0.025) + ((V.middleClass + V.visitors * 0.6) * 0.05) + (V.topClass * 0.3)) * V.rentEffectU * upperClassP);
+		let UCD = Math.trunc(((V.UCBase * econMult) + (V.arcologies[0].prosperity * 0.2) + upperClass + (V.NPCSlaves * 0.02) + (V.lowerClass * 0.025) + ((V.middleClass + V.visitors * 0.6) * 0.05) + (V.topClass * 0.3)) * V.rentEffectU * upperClassP);
 		if (V.classSatisfied.upperClass !== 0) {
 			UCD *= 1 + V.classSatisfied.upperClass * 0.06;
 		}
-		if (UCD < 50) {
-			UCD = 50;
-		}
-		if (isNaN(UCD)) {
-			appendDiv(`<span class="red">UCD is NaN, report this issue!</span>`);
-		} else {
-			/* Upper Class Citizens immigrating*/
+		NaNCheck({UCD});
+		UCD = Math.max(UCD, 50);
+		if (!isFrozen) {
 			if (V.classSatisfied.upperClass < 0) {
 				appendDiv(`Your upper class is <span class="red">sexually frustrated</span> and would rather live elsewhere.`);
 			} else if (V.classSatisfied.upperClass > 0) {
 				appendDiv(`Your upper class is <span class="green">sexually satiated</span> and their happiness attracts others.`);
 			}
 			if (V.upperClass < UCD) {
+				/* Upper Class Citizens immigrating*/
 				const UCImmigration = Math.trunc((UCD - V.upperClass) * (0.3 * terrain)) + 1 + secExpImmigrationBonus.effect;
 				V.upperClass += UCImmigration;
 				if (UCImmigration > 1) {
@@ -1743,8 +1718,8 @@ App.EndWeek.arcManagement = function() {
 				} else if (UCImmigration > 0) {
 					appendDiv(`<span class="green">One upper class citizen</span> moved to your arcology.`);
 				}
-				/* Upper Class Citizens Emigrating*/
 			} else if (V.upperClass > UCD) {
+				/* Upper Class Citizens Emigrating*/
 				const UCEmigration = Math.trunc((V.upperClass - UCD) * 0.4);
 				V.upperClass -= UCEmigration;
 				if (UCEmigration > 1) {
@@ -1757,29 +1732,25 @@ App.EndWeek.arcManagement = function() {
 
 		/* Top Class Citizens*/
 		/* Top Class Interest in living in your arcology*/
+		let TCD = Math.trunc((V.GDP / 15 + topClass) * V.rentEffectT * topClassP + V.TCBase);
 		if (V.eliteFailTimer > 0) {
 			/* when you fail the eugenics Elite and they leave this triggers*/
-			TCD = Math.trunc((V.GDP / 15 + topClass) * V.rentEffectT * topClassP + V.TCBase - (V.eliteFail / 15 * V.eliteFailTimer));
+			TCD -= Math.trunc(V.eliteFail / 15 * V.eliteFailTimer);
 			V.eliteFailTimer -= 1;
-		} else {
-			TCD = Math.trunc((V.GDP / 15 + topClass) * V.rentEffectT * topClassP + V.TCBase);
 		}
 		if (V.classSatisfied.topClass !== 0) {
 			TCD *= 1 + V.classSatisfied.topClass * 0.06;
 		}
-		if (TCD < 15) {
-			TCD = 15;
-		}
-		if (isNaN(TCD)) {
-			appendDiv(`<span class="red">TCD is NaN, report this issue!</span>`);
-		} else {
-			/* Top Class Citizens immigrating*/
+		NaNCheck({TCD});
+		TCD = Math.max(TCD, 15);
+		if (!isFrozen) {
 			if (V.classSatisfied.topClass < 0) {
 				appendDiv(`Your millionaires are <span class="red">sexually frustrated</span> and would rather live elsewhere.`);
 			} else if (V.classSatisfied.topClass > 0) {
 				appendDiv(`Your millionaires are <span class="green">sexually satiated</span> and their happiness attracts others.`);
 			}
 			if (V.topClass < TCD) {
+				/* Top Class Citizens immigrating*/
 				const TCImmigration = Math.trunc((TCD - V.topClass) * (0.3 * terrain)) + 1 + secExpImmigrationBonus.effect;
 				V.topClass += TCImmigration;
 				if (TCImmigration > 1) {
@@ -1787,8 +1758,8 @@ App.EndWeek.arcManagement = function() {
 				} else if (TCImmigration > 0) {
 					appendDiv(`<span class="green">One millionaire</span> moved to your arcology.`);
 				}
-				/* Top Class Citizens emigrating*/
 			} else if (V.topClass > TCD) {
+				/* Top Class Citizens emigrating*/
 				const TCEmigration = Math.trunc((V.topClass - TCD) * 0.4) + 1;
 				V.topClass -= TCEmigration;
 				if (TCEmigration > 1) {
@@ -1798,7 +1769,24 @@ App.EndWeek.arcManagement = function() {
 				}
 			}
 		}
-		appendDiv(secExpImmigrationBonus.text);
+
+		/* report SecExp bonuses if transport is available */
+		if (!isFrozen) {
+			appendDiv(secExpImmigrationBonus.text);
+		}
+
+		/* show calculation breakdown for debug/cheat */
+		if (V.cheatMode === 1 || V.debugMode === 1) {
+			const table = App.UI.DOM.appendNewElement("table", el);
+			App.UI.DOM.makeRow(table, `${V.arcologies[0].prosperity} Prosperity`, `${FSScore} FS Score`, `${honeymoon} Honeymoon`, `${transportHub} Transporthub`, `${terrain} Terrain`, `${crime} Crime`);
+			App.UI.DOM.makeRow(table, `${LSCD.toFixed(1)} Lower + Slave Class Demand`, `${SCD.toFixed(1)} Slave Class Demand`, `${slaveProductivity.toFixed(1)} Slave Productivity`);
+			App.UI.DOM.makeRow(table, `${LCD.toFixed(1)} Lower Class Demand`, `${lowerClassP.toFixed(1)} LC Multiplier`);
+			App.UI.DOM.makeRow(table, `${MCD.toFixed(1)} Middle Class Demand`, `${middleClassP.toFixed(1)} MC Multiplier`);
+			App.UI.DOM.makeRow(table, `${UCD.toFixed(1)} Upper Class Demand`, `${upperClassP.toFixed(1)} UC Multiplier`);
+			App.UI.DOM.makeRow(table, `${TCD.toFixed(1)} Top Class Demand`, `${topClassP.toFixed(1)} TC Multiplier`);
+		}
+
+		return Math.trunc(maxSlaveLabor - SCD);
 	}
 
 	function slaveRetirement() {
@@ -1894,7 +1882,6 @@ App.EndWeek.arcManagement = function() {
 
 	function denseApartments() {
 		/* increases lowerclass attraction based on number of dense apartments */
-		let el = new DocumentFragment();
 		let r = [];
 		let count = 0;
 		V.building.findCells(cell => !(cell instanceof App.Arcology.Cell.Penthouse))
@@ -1919,8 +1906,7 @@ App.EndWeek.arcManagement = function() {
 			r.push(App.UI.DOM.makeElement("span", `A small amount of lower class citizens`, "green"));
 			r.push(`were attracted by your dense apartments.`);
 		}
-		App.Events.addNode(el, r);
-		return el;
+		return r;
 	}
 
 	function getBanishRatio() {
@@ -1951,9 +1937,17 @@ App.EndWeek.arcManagement = function() {
 		}
 	}
 
-	function appendDiv(text) {
+	function appendDiv(/** @type {string} */ text) {
 		const div = document.createElement("div");
 		$(div).append(text);
 		el.append(div);
 	}
+
+	function NaNCheck(/** @type {Object} */ obj) {
+		for (const n of Object.values(obj)) {
+			if (isNaN(n)) {
+				throw new Error(`Economy encountered unexpected NaN: ${JSON.stringify(obj)}.`);
+			}
+		}
+	}
 };
diff --git a/src/events/RESS/kitchenMolestation.js b/src/events/RESS/kitchenMolestation.js
index 8990482d1ba5eb8047e7cf178c642d7af64ffef2..e0cd906e5a309f89255bfbf96ea432a6b599cfde 100644
--- a/src/events/RESS/kitchenMolestation.js
+++ b/src/events/RESS/kitchenMolestation.js
@@ -32,6 +32,7 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve
 		} = getNonlocalPronouns(V.seeDicks).appendSuffix('U');
 		const belly = bellyAdjective(eventSlave);
 		const targetJobs = ["be a servant", "be a subordinate slave", "get milked", "learn in the schoolroom", "please you", "rest in the spa", "rest", "serve in the club", "serve the public", "take classes", "whore", "work a glory hole", "work as a servant", "work in the brothel"];
+		const targetSlaves = V.slaves.filter(s => targetJobs.includes(s.assignment) && s.ID !== eventSlave.ID);
 		const PC = V.PC;
 
 		App.Events.drawEventArt(node, eventSlave, "no clothing");
@@ -54,9 +55,9 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve
 
 		App.Events.addResponses(node, [
 			new App.Events.Result(`Improve on ${his} abusive little game`, improve),
-			canDoAnal(eventSlave)
-				? new App.Events.Result("The rule about consent works both ways", turnTables, analVirginWarning())
-				: new App.Events.Result()
+			canDoAnal(eventSlave) ?
+				new App.Events.Result("The rule about consent works both ways", turnTables, analVirginWarning()) :
+				new App.Events.Result()
 		]);
 
 		function improve() {
@@ -72,8 +73,8 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve
 			t.push(`You leave for the moment, but appear at the next mealtime before even ${he} does. You shut off all the phallic feeders but one, and make an announcement. You decree that just for this one meal, ${eventSlave.slaveName} is to lie in front of the one functional feeder, ${canPenetrate(eventSlave) ? `${his} cock in the air` : `with a dildo jutting up from ${his} crotch`} in order to eat, each slave must ride ${eventSlave.slaveName} for as long as it takes to suck down their ${eventSlave.belly >= 5000 ? `meal (given the ${belly} mass jutting from ${his} middle, it should be quite the sight)` : "meal"}.`);
 			t.push(`${eventSlave.slaveName} gapes at you openmouthed for a long moment, looking like ${he} wants to <span class="hotpink">declaim a speech of thanks,</span> but you cut ${him} off by pointing peremptorily at ${his} place; ${he} almost runs over, ${his} <span class="mediumaquamarine">trust in your whim</span> nearly absolute. But the true shape of your plan isn't apparent yet. When the first slave seats ${himselfU} on ${eventSlave.slaveName} and starts sucking off the dispenser dildo, you crouch behind ${himU} and insert yourself as well; the bitch is now airtight. ${HeU} gags and splutters with the discomfort but keeps working away until ${heU} gets ${hisU} meal down and struggles off the three phalluses ${heU} has in ${himU}. The next in line gets to it with some trepidation: and so it goes, slave by slave.`);
 
-			V.slaves.forEach(function(s) {
-				if (targetJobs.includes(s.assignment) && hasAnyLegs(s) && s.relationship !== -3 && s.ID !== eventSlave.ID) {
+			for (const s of targetSlaves) {
+				if (hasAnyLegs(s) && s.relationship !== -3) {
 					if (canDoAnal(s) && canDoVaginal(s)) {
 						if (s.anus === 0 && s.vagina === 0) {
 							virgins = true;
@@ -153,7 +154,8 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve
 						subLove = true;
 					}
 				}
-			});
+			}
+
 			if (virgins) {
 				t.push(`You let your virgins ${chaste ? "and chaste slaves" : ""} hold their thighs tight together for a little frottage rather than deflowering their holes like this.`);
 			} else if (chaste) {
@@ -195,12 +197,16 @@ App.Events.RESSKitchenMolestation = class RESSKitchenMolestation extends App.Eve
 			t.push(VCheck.Anal(eventSlave, 20));
 
 			if (canGetPregnant(eventSlave) && eventSlave.mpreg === 1) {
-				const pregSources = V.slaves.filter(s => canImpreg(eventSlave, s) && targetJobs.includes(s.assignment) && s.ID !== eventSlave.ID);
+				const pregSources = targetSlaves.filter(s => canImpreg(eventSlave, s));
 				if (pregSources.length > 0) {
-					knockMeUp(eventSlave, 50, 1, pregSources.pluck().ID);
+					knockMeUp(eventSlave, 50, 1, pregSources.random().ID);
+				}
+			}
+			for (const slave of targetSlaves) {
+				if (slave.trust < 50) {
+					slave.trust += 4;
 				}
 			}
-			V.slaves.forEach(function(s) { if (s.trust < 50 && targetJobs.includes(s.assignment) && s.ID !== eventSlave.ID) { s.trust += 4; } });
 			if (eventSlave.anus === 1) {
 				t.push(`Poor ${eventSlave.slaveName}'s butthole <span class="lime">isn't quite the same</span> afterward.`);
 				eventSlave.anus += 1;