diff --git a/src/js/assayJS.js b/src/js/assayJS.js
index b4e64a44434ad42c472495988d56d7c047943612..0d8e416e5db1124c9301a7c85c7c8188d24f3f31 100644
--- a/src/js/assayJS.js
+++ b/src/js/assayJS.js
@@ -1,272 +1,3 @@
-/**
- * @param {App.Entity.SlaveState} A
- * @param {App.Entity.SlaveState} B
- * @returns {boolean}
- */
-globalThis.sameAssignmentP = function(A, B) {
-	return A.assignment === B.assignment;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {boolean}
- */
-globalThis.canImproveIntelligence = function(slave) {
-	let origIntel = V.genePool.find(function(s) { return s.ID === slave.ID; }).intelligence;
-	return (slave.intelligence < origIntel + 15) && (slave.intelligence < 100);
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {number}
- */
-globalThis.maxHeight = function(slave) {
-	let max = Math.trunc(Math.clamp((Height.mean(slave) * 1.25), 0, 274)); /* max achievable height is expected height plus 25% */
-
-	if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-		max = Math.min(max, 160);
-	}
-
-	return max;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {boolean}
- */
-globalThis.canImproveHeight = function(slave) {
-	return slave.height < maxHeight(slave);
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @param {FC.HumanState} target
- * @returns {boolean}
- */
-globalThis.haveRelationshipP = function(slave, target) {
-	return slave.relationshipTarget === target.ID;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @param {App.Entity.SlaveState} target
- * @returns {boolean}
- */
-globalThis.isRivalP = function(slave, target) {
-	return slave.rivalryTarget === target.ID;
-};
-
-/**
- * @param {FC.HumanState} slave
- * @returns {boolean}
- */
-globalThis.supremeRaceP = function(slave) {
-	return V.arcologies[0].FSSupremacistRace === slave.race;
-};
-
-/**
- * @param {FC.HumanState} slave
- * @returns {boolean}
- */
-globalThis.inferiorRaceP = function(slave) {
-	return V.arcologies[0].FSSubjugationistRace === slave.race;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {boolean}
- */
-globalThis.isLeaderP = function(slave) {
-	const leaders = [S.HeadGirl, S.Bodyguard, S.Recruiter, S.Concubine, S.Nurse, S.Attendant, S.Matron, S.Madam, S.DJ, S.Milkmaid, S.Farmer, S.Stewardess, S.Schoolteacher, S.Wardeness];
-
-	return leaders.some(leader => leader && leader.ID === slave.ID);
-};
-
-/**
- * colors skin, eyes and hair based on genetic Color.
- * Takes .override_*_Color into account.
- *
- * @param {App.Entity.SlaveState} slave
- */
-globalThis.applyGeneticColor = function(slave) {
-	if (slave.override_Eye_Color !== 1) {
-		resetEyeColor(slave, "both");
-	}
-	if (slave.override_H_Color !== 1) {
-		slave.hColor = getGeneticHairColor(slave);
-	}
-	if (slave.override_Arm_H_Color !== 1) {
-		slave.underArmHColor = getGeneticHairColor(slave);
-	}
-	if (slave.override_Pubic_H_Color !== 1) {
-		slave.pubicHColor = getGeneticHairColor(slave);
-	}
-	if (slave.override_Brow_H_Color !== 1) {
-		slave.eyebrowHColor = getGeneticHairColor(slave);
-	}
-	if (slave.override_Skin !== 1) {
-		if (!(slave.skin === "sun tanned" || slave.skin === "spray tanned")) {
-			slave.skin = getGeneticSkinColor(slave);
-		}
-	}
-};
-
-/**
- * @param {FC.GingeredSlave} slave
- */
-globalThis.newSlave = function(slave) {
-	if (getSlave(slave.ID)) {
-		throw "Slave already exists";
-	}
-
-	// if the slave is gingered, remove the gingering proxy
-	if (slave.beforeGingering) {
-		slave = slave.beforeGingering;
-	}
-
-	if (slave.override_Race !== 1) {
-		slave.origRace = slave.race;
-	}
-
-	applyGeneticColor(slave);
-
-	/* eslint-disable camelcase */
-	slave.override_Race = 0;
-	slave.override_H_Color = 0;
-	slave.override_Arm_H_Color = 0;
-	slave.override_Pubic_H_Color = 0;
-	slave.override_Brow_H_Color = 0;
-	slave.override_Skin = 0;
-	slave.override_Eye_Color = 0;
-	/* eslint-enable camelcase */
-
-	// too tall to be a dwarf catch for event slaves
-	if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2 && slave.height > 165) {
-		slave.geneticQuirks.dwarfism = 1;
-	}
-
-	if (V.surnamesForbidden === 1) {
-		slave.slaveSurname = 0;
-	}
-
-	if (slave.preg > 0) {
-		slave.pregWeek = slave.preg;
-	} else {
-		slave.pregWeek = 0;
-	}
-
-	if (slave.clone !== 0) {
-		slave.canRecruit = 0;
-	}
-
-	slave.sisters = 0;
-	slave.daughters = 0;
-	if (slave.mother === -1 || slave.father === -1) {
-		V.PC.daughters += 1;
-	}
-	if (areSisters(V.PC, slave) > 0) {
-		V.PC.sisters += 1;
-	}
-	for (let k = 0; k < V.slaves.length; k++) {
-		if (V.slaves[k].mother === slave.ID || V.slaves[k].father === slave.ID) {
-			slave.daughters++;
-		}
-		if (slave.mother === V.slaves[k].ID || slave.father === V.slaves[k].ID) {
-			V.slaves[k].daughters++;
-		}
-		if (areSisters(V.slaves[k], slave) > 0) {
-			slave.sisters++;
-			V.slaves[k].sisters++;
-		}
-	}
-
-	if (slave.genes === "XX") {
-		if (slave.pubertyXX === 1) {
-			if (slave.pubertyXY === 1) {
-				slave.hormoneBalance = 20;
-			} else {
-				slave.hormoneBalance = 60;
-			}
-		} else {
-			if (slave.pubertyXY === 1) {
-				slave.hormoneBalance = -20;
-			} else {
-				slave.hormoneBalance = 20;
-			}
-		}
-	} else if (slave.genes === "XY") {
-		if (slave.pubertyXX === 1) {
-			if (slave.pubertyXY === 1) {
-				slave.hormoneBalance = 20;
-			} else {
-				slave.hormoneBalance = 40;
-			}
-		} else {
-			if (slave.pubertyXY === 1) {
-				slave.hormoneBalance = -40;
-			} else {
-				slave.hormoneBalance = 20;
-			}
-		}
-	}
-
-	if (slave.dick > 0 &&
-		slave.balls > 0 &&
-		slave.vagina < 0 &&
-		slave.anus === 0 &&
-		slave.genes === "XY" &&
-		slave.faceShape === "masculine" &&
-		slave.attrXY <= 35 &&
-		slave.boobs < 400 &&
-		slave.hormoneBalance < 0) {
-		V.REFeminizationCheckinIDs.push(slave.ID);
-	}
-	if (slave.actualAge > 35 && slave.face <= 10 && slave.faceImplant === 0 && slave.energy <= 60) {
-		V.REMILFCheckinIDs.push(slave.ID);
-	}
-	if (slave.attrXY <= 35 && slave.attrXX > 65) {
-		V.REOrientationCheckinIDs.push(slave.ID);
-	}
-	if (slave.face < -10) {
-		V.REUglyCheckinIDs.push(slave.ID);
-	}
-	if (slave.anus < 2) {
-		V.REButtholeCheckinIDs.push(slave.ID);
-	}
-	if (slave.boobs < 800) {
-		V.REReductionCheckinIDs.push(slave.ID);
-	}
-
-	generatePronouns(slave);
-	SetBellySize(slave);
-	V.slaveIndices[slave.ID] = V.slaves.push(slave) - 1;
-
-	if (slave.origin !== "$He was your slave, but you freed $him, which $he repaid by participating in a coup attempt against you. It failed, and $he is again your chattel." && slave.ID !== V.boomerangSlave.ID) {
-		V.genePool.push(clone(slave));
-	} else {
-		if (!V.genePool.some(s => s.ID === slave.ID)) {
-			V.genePool.push(slave);
-		}
-	}
-
-	/* special case for dulling intelligence via drugs in slave acquisition */
-	if (slave.dullIntelligence) {
-		slave.intelligence = -100;
-		delete slave.dullIntelligence;
-	}
-
-	if (slave.assignment) {
-		assignJob(slave, slave.assignment);
-	} else {
-		slave.assignment = Job.CHOICE;
-	}
-
-	/** do not run the Rules Assistant before adding the new slave to the slaves list! **/
-	if (V.ui !== "start" && V.universalRulesNewSlavesRA === 1 && V.rulesAssistantAuto !== 0) {
-		DefaultRules(slave);
-	}
-};
-
 /**
  * @param {App.Entity.SlaveState[]} [slaves]
  * @returns {Object.<number, number>}
@@ -297,924 +28,6 @@ globalThis.getChild = function(ID) {
 	return V.cribs.find(s => s.ID === ID);
 };
 
-/** Get the written title for a given slave, without messing with global state.
- * @param {App.Entity.SlaveState} [slave]
- * @returns {string}
- */
-globalThis.getWrittenTitle = function(slave) {
-	if (slave && slave.custom.title !== undefined && slave.custom.title !== "" && slave.rudeTitle === 0) {
-		return slave.custom.title;
-	}
-	if (V.PC.customTitle !== undefined) {
-		return V.PC.customTitle;
-	} else if (V.PC.title !== 0) {
-		return "Master";
-	} else {
-		return "Mistress";
-	}
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {number}
- */
-globalThis.fetishChangeChance = function(slave) {
-	let chance = 0,
-		fetish = (slave.fetishStrength / 4),
-		sex = 0;
-
-	if (slave.clitSetting !== slave.fetish) {
-		// fetish should be more uncertain leading towards puberty and then steadily become more set in stone afterwards
-		if (slave.balls) {
-			if (V.potencyAge >= slave.actualAge) {
-				sex = (50 - ((V.potencyAge - slave.actualAge) * 10));
-				fetish = (slave.fetishStrength / 2);
-			} else {
-				sex = ((slave.actualAge - V.potencyAge) / 4);
-			}
-		} else if (slave.ovaries || slave.mpreg) {
-			if (V.fertilityAge >= slave.actualAge) {
-				sex = (50 - ((V.fertilityAge - slave.actualAge) * 10));
-				fetish = (slave.fetishStrength / 2);
-			} else {
-				sex = ((slave.actualAge - V.fertilityAge) / 4);
-			}
-		}
-		chance = Math.trunc(Math.clamp((slave.devotion / 4) - (fetish) - (sex), 0, 100));
-	}
-
-	return chance;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {string}
- */
-globalThis.SlaveFullName = function(slave) {
-	const pair = slave.slaveSurname ? [slave.slaveName, slave.slaveSurname] : [slave.slaveName];
-	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
-		pair.reverse();
-	}
-	return pair.join(" ");
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {string}
- */
-globalThis.SlaveFullBirthName = function(slave) {
-	const pair = slave.birthSurname ? [slave.birthName, slave.birthSurname] : [slave.birthName];
-	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
-		pair.reverse();
-	}
-	return pair.join(" ");
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {string}
- */
-globalThis.PoliteRudeTitle = function(slave) {
-	const PC = V.PC;
-	const {s, ss, title} = getEnunciation(slave);
-
-	let r = "";
-	if (slave.nationality === "Japanese") {
-		if (slave.trust > 0) {
-			r += `${PC.slaveName}${PC.title > 0 ? "kun" : "chan"}`;
-		} else {
-			r += (PC.slaveSurname ? PC.slaveSurname : `${PC.slaveName}${s}an`);
-		}
-	} else {
-		if (slave.intelligence + slave.intelligenceImplant < -95) {
-			r += title;
-		} else if (slave.intelligence + slave.intelligenceImplant > 50) {
-			r += (PC.title > 0 ? `Ma${s}ter` : `Mi${s}tre${ss}`);
-		} else if (slave.trust > 0) {
-			r += PC.slaveName;
-		} else {
-			r += (PC.slaveSurname ? PC.slaveSurname : PC.slaveName);
-		}
-	}
-	return r;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {string}
- */
-globalThis.SlaveTitle = function(slave) {
-	let r;
-	if (V.newDescriptions === 1) {
-		if (slave.dick > 0 && slave.balls > 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
-			if (jsRandom(1, 100) > 50) {
-				r = "futanari";
-			} else {
-				r = "herm";
-			}
-		} else if (slave.dick > 0 && slave.balls === 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
-			r = "dickgirl";
-		} else if (slave.dick > 0 && slave.vagina > -1 && slave.ovaries === 0) {
-			r = "shemale";
-		} else if (slave.dick > 0 && slave.balls === 0 && slave.vagina === -1 && slave.ovaries === 0) {
-			r = "eunuch";
-		} else if (slave.dick > 0 && slave.balls > 0 && slave.vagina === -1 && slave.ovaries === 0) {
-			if (slave.face > 10 && slave.hips > -1 && slave.shoulders < 1 && slave.faceShape !== "masculine") {
-				r = "trap";
-			} else if (slave.boobs > 800) {
-				r = "tittyboy";
-			} else if (slave.dick === 1 && slave.balls === 1) {
-				r = "sissy";
-			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 165 && slave.muscles < 5 && slave.visualAge < 19 && slave.faceShape !== "masculine") {
-				r = "twink";
-			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 160 && slave.muscles < 5 && slave.visualAge < 19) {
-				r = "boytoy";
-			} else if (slave.muscles > 95 && slave.height >= 185) {
-				r = "titan";
-			} else if (slave.muscles > 30) {
-				r = "muscleboy";
-			} else {
-				r = "slaveboy";
-			}
-		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina > -1) {
-			if ((slave.shoulders > slave.hips || slave.faceShape === "masculine") && slave.boobs < 400 && slave.genes === "XY") {
-				r = "cuntboy";
-			} else if (slave.ovaries === 0 && slave.genes === "XY") {
-				r = "tranny";
-			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 59) {
-				r = "GMILF";
-			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 35) {
-				r = "MILF";
-			} else if (slave.lips > 70 && slave.boobs > 2000 && slave.butt > 3) {
-				r = "bimbo";
-			} else if (slave.hips > 1 && slave.boobs > 2000 && slave.butt > 3 && slave.waist < 50) {
-				r = "hourglass";
-			} else if (slave.muscles > 95 && slave.height >= 185) {
-				r = "amazon";
-			} else if (slave.muscles > 30) {
-				r = "musclegirl";
-			} else {
-				r = "slavegirl";
-			}
-		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina === -1) {
-			r = "neuter";
-		} else if (slave.dick === 0 && slave.vagina === -1) {
-			r = "ballslave";
-		} else {
-			r = "slave";
-		}
-
-		if (slave.visualAge < 13) {
-			if (slave.actualAge < 3) {
-				if (slave.actualAge < 1) {
-					r = "baby " + r;
-				} else {
-					r = "toddler " + r;
-				}
-			} else {
-				if (slave.genes === "XY" && slave.vagina === -1) {
-					r = "shota " + r;
-				} else {
-					r = "loli " + r;
-				}
-			}
-		}
-
-		if (slave.geneticQuirks.albinism === 2) {
-			r = `albino ${r}`;
-		}
-
-		if (slave.dick > 9 && slave.balls > 9 && slave.boobs > 12000) {
-			r = `hyper ${r}`;
-		}
-
-		if (slave.boobs > 4000 && slave.lactation > 0) {
-			if (slave.physicalAge < 13) {
-				r = `${r} calf`;
-			} else {
-				r = `${r} cow`;
-			}
-		} else if (slave.lactation > 0) {
-			r = `milky ${r}`;
-		}
-
-		if (slave.boobs > 20000) {
-			r = `supermassive titted ${r}`;
-		} else if (slave.boobs > 10000) {
-			r = `giant titted ${r}`;
-		} else if (slave.boobs > 4000) {
-			r = `huge titted ${r}`;
-		} else if (slave.boobs > 1000) {
-			r = `busty ${r}`;
-		}
-
-		if (slave.dick > 5 && slave.balls > 5) {
-			r = `womb filling ${r}`;
-		} else if (slave.dick > 5) {
-			r = `well hung ${r}`;
-		}
-
-		if (slave.butt >= 12) {
-			r = `colossal assed ${r}`;
-		} else if (slave.butt >= 10) {
-			r = `massive assed ${r}`;
-		} else if (slave.butt >= 8) {
-			r = `fat assed ${r}`;
-		} else if (slave.butt >= 6) {
-			r = `bottom heavy ${r}`;
-		} else if (slave.butt >= 4) {
-			r = `big bottomed ${r}`;
-		}
-
-		if (slave.weight > 10 && slave.weight < 100 && slave.boobs > 5000 && slave.butt > 5 && slave.hips >= 2 && slave.bellyPreg >= 30000 && slave.counter.births >= 10) {
-			r = `${r} fertility goddess`;
-		} else if (slave.counter.births >= 6) {
-			r = `${r} broodmother`;
-		} else if (slave.counter.births >= 3) {
-			r = `${r} breeder`;
-		}
-
-		if (slave.indenture > -1) {
-			r = `indentured ${r}`;
-		}
-
-		if (slave.preg > slave.pregData.normalBirth / 4 && slave.pregKnown === 1) {
-			r = `pregnant ${r}`;
-		} else if (slave.bellyFluid >= 5000) {
-			r = `bloated ${r}`;
-		} else if (slave.belly >= 5000) {
-			r = `gravid ${r}`;
-		}
-
-		if (slave.fuckdoll > 0) {
-			r = `${r} fuckdoll`;
-		}
-	} else {
-		r = "slave"; /* I don't think there is an 'else'? */
-		if ((slave.dick === 0) && (slave.vagina === -1)) {
-			/* NULLS */
-			r = "null";
-			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
-				r = `${r} cow`;
-			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-				r = `${r} bimbo `;
-			} else if (slave.boobs > 6000) {
-				r = `${r} boob`;
-			} else if (slave.butt > 6) {
-				r = `${r} ass`;
-			} else if ((slave.muscles > 30) && (slave.height < 185)) {
-				r = `${r} muscle`;
-			}
-			if (slave.visualAge > 55) {
-				r = `${r}GILF`;
-			} else if (slave.visualAge > 35) {
-				r = `${r}MILF`;
-			} else if (slave.visualAge >= 25) {
-				r = `${r}slave`;
-			} else {
-				r = `${r}girl`;
-			}
-		}
-
-		if ((slave.dick === 0) && (slave.vagina !== -1)) {
-			/* FEMALES */
-			if (slave.visualAge > 55) {
-				r = "GILF";
-			} else if (slave.visualAge > 35) {
-				r = "MILF";
-			} else if (slave.visualAge >= 25) {
-				r = "slave";
-			} else {
-				r = "slavegirl";
-			}
-			if ((slave.muscles > 30) && (slave.height < 185)) {
-				r = `muscle ${r}`;
-			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
-				r = `${r} cow`;
-			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-				r = `${r} bimbo`;
-			} else if (slave.boobs > 6000) {
-				r = `boob${r}`;
-			} else if (slave.butt > 6) {
-				r = `ass${r}`;
-			}
-		}
-
-		if ((slave.dick !== 0) && (slave.vagina !== -1)) {
-			if (slave.balls > 0) {
-				/* FUTANARI: cock & balls & vagina */
-				r = "futanari ";
-			} else {
-				/* FUTANARI: cock & vagina */
-				r = "futa ";
-			}
-			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
-				r = `${r}cow`;
-			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-				r = `${r}bimbo `;
-			} else if (slave.boobs > 6000) {
-				r = `${r}boob`;
-			} else if (slave.butt > 6) {
-				r = `${r}ass`;
-			} else if ((slave.muscles > 30) && (slave.height < 185)) {
-				r = `${r}muscle`;
-			}
-			if (slave.visualAge > 55) {
-				r = `${r}GILF`;
-			} else if (slave.visualAge > 35) {
-				r = `${r}MILF`;
-			} else if (slave.visualAge >= 25) {
-				r = `${r}slave`;
-			} else {
-				r = `${r}girl`;
-			}
-			if (slave.dick > 5 && slave.balls > 5 && slave.boobs > 5000) {
-				r = `hyper ${r}`;
-			}
-		}
-
-		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0) && (slave.boobs > 300) && (slave.butt > 2)) {
-			/* SHEMALES: cock & balls, T&A above minimum */
-			if (slave.visualAge > 55) {
-				r = "sheGILF";
-			} else if (slave.visualAge > 35) {
-				r = "sheMILF";
-			} else if (slave.visualAge >= 25) {
-				r = "shemale";
-			} else {
-				r = "tgirl";
-			}
-			if ((slave.muscles > 30) && (slave.height < 185)) {
-				r = `muscle${r}`;
-			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
-				r = `${r} cow`;
-			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-				r = `${r} bimbo`;
-			} else if (slave.boobs > 6000) {
-				r = `topheavy ${r}`;
-			} else if (slave.butt > 6) {
-				r = `bottomheavy ${r}`;
-			}
-		}
-
-		if ((slave.boobs < 300) || (slave.butt < 2)) {
-			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
-				if ((slave.shoulders < 1) || (slave.muscles <= 30)) {
-					if ((slave.faceShape === "masculine") || (slave.faceShape === "androgynous")) {
-						/* SISSIES: feminine shoulders or muscles, masculine faces */
-						if (slave.visualAge > 55) {
-							r = "sissyGILF";
-						} else if (slave.visualAge > 35) {
-							r = "sissyMILF";
-						} else {
-							r = "sissy";
-						}
-					} else {
-						/* TRAPS: feminine shoulders or muscles, feminine faces */
-						if (slave.visualAge > 55) {
-							r = "trapGILF";
-						} else if (slave.visualAge > 35) {
-							r = "trapMILF";
-						} else if (slave.visualAge >= 25) {
-							r = "trap";
-						} else {
-							r = "trapgirl";
-						}
-					}
-					if (slave.lactation > 0) {
-						r = `${r} cow`;
-					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-						r = `${r} bimbo`;
-					}
-				}
-			}
-		}
-
-		if ((slave.boobs < 300) || (slave.butt < 2)) {
-			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
-				if ((slave.shoulders > 1) || (slave.muscles >= 30)) {
-					/* BITCHES: masculine shoulders or muscles */
-					r = "bitch";
-					if ((slave.muscles > 30) && (slave.height < 185)) {
-						r = `muscle${r}`;
-					} else if (slave.lactation > 0) {
-						r = `${r}cow`;
-					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-						r = `bimbo ${r}`;
-					}
-					if (slave.visualAge > 55) {
-						r = `aged ${r}`;
-					} else if (slave.visualAge > 35) {
-						r = `mature ${r}`;
-					} else if (slave.visualAge < 25) {
-						r = `young ${r}`;
-					}
-				}
-			}
-		}
-
-		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls === 0)) {
-			r = "dick";
-			if (slave.visualAge > 55) {
-				r = `${r}GILF`;
-			} else if (slave.visualAge > 35) {
-				r = `${r}MILF`;
-			} else if (slave.visualAge >= 25) {
-				r = `${r}slave`;
-			} else {
-				r = `${r}girl`;
-			}
-			if ((slave.muscles > 30) && (slave.height < 185)) {
-				r = `muscle${r}`;
-			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
-				r = `${r} cow`;
-			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
-				r = `${r} bimbo`;
-			} else if (slave.boobs > 6000) {
-				r = `boob ${r}`;
-			} else if (slave.butt > 6) {
-				r = `ass ${r}`;
-			}
-		}
-
-		if ((slave.muscles > 30) && (slave.height > 185)) {
-			r = `amazon ${r}`;
-		} else if ((slave.muscles < 30) && (slave.height > 185)) {
-			r = `statuesque ${r}`;
-		} else if ((slave.boobs < 800) && (slave.height < 150)) {
-			r = `petite ${r}`;
-		} else if ((slave.boobs > 800) && (slave.height < 150)) {
-			r = `shortstack ${r}`;
-		}
-
-		if (slave.counter.births >= 5) {
-			r = `${r} broodmother`;
-		} else if (slave.counter.births >= 2) {
-			r = `${r} breeder`;
-		}
-
-		if (slave.geneticQuirks.albinism === 2) {
-			r = `albino ${r}`;
-		}
-
-		if (slave.indenture > -1) {
-			r = `indentured ${r}`;
-		}
-
-		if (slave.preg > slave.pregData.normalBirth / 4 && slave.pregKnown === 1) {
-			r = `pregnant ${r}`;
-		} else if (slave.bellyFluid >= 5000) {
-			r = `bloated ${r}`;
-		} else if (slave.belly >= 5000) {
-			r = `gravid ${r}`;
-		}
-
-		if (slave.fuckdoll > 0) {
-			r = `${r} fuckdoll`;
-		}
-	}
-	return r;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- */
-globalThis.DegradingName = function(slave) {
-	const leadershipPosition = [
-		Job.ATTENDANT,
-		Job.MATRON,
-		Job.STEWARD,
-		Job.MILKMAID,
-		Job.FARMER,
-		Job.DJ,
-		Job.CONCUBINE,
-		Job.MADAM,
-		Job.TEACHER,
-		Job.WARDEN,
-		Job.NURSE,
-		Job.HEADGIRL,
-		Job.BODYGUARD,
-		Job.RECRUITER
-	];
-	const names = [];
-	const suffixes = [];
-
-	if (slave.fuckdoll > 0) {
-		slave.slaveName = `Fuckdoll No. ${slave.ID}`;
-		slave.slaveSurname = 0;
-	} else if (slave.assignment === Job.DAIRY && V.dairyRestraintsSetting >= 2) {
-		slave.slaveName = `Bioreactor No. ${slave.ID}`;
-		slave.slaveSurname = 0;
-	} else {
-		if (V.seeRace === 1) {
-			switch (slave.race) {
-				case "white":
-					names.push("Pale", "White");
-					break;
-				case "asian":
-					names.push("Asian", "Yellow");
-					break;
-				case "latina":
-					names.push("Brown", "Latina");
-					break;
-				case "black":
-					names.push("Black", "Dark");
-					break;
-				case "pacific islander":
-					names.push("Islander", "Pacific", "Sea");
-					break;
-				case "malay":
-					names.push("Cinnamon", "Pinoy", "Spice");
-					break;
-				case "southern european":
-					names.push("Mediterranean", "Olive");
-					break;
-				case "amerindian":
-					names.push("Indian", "Reservation");
-					break;
-				case "semitic":
-					names.push("Semite", "Semitic");
-					break;
-				case "middle eastern":
-					names.push("Arab", "Sand");
-					break;
-				case "indo-aryan":
-					names.push("Brown", "Indian");
-					break;
-				case "mixed race":
-					names.push("Mixed", "Mulatto", "Mutt");
-					break;
-			}
-		}
-		names.push(slave.hColor);
-		if (!hasAnyEyes(slave)) {
-			names.push("Blind", "Eyeless", "Sightless");
-		}
-		if (slave.hears === -2) {
-			names.push("Deaf", "Earless", "Unhearing");
-		}
-		if (slave.boobs >= 2000) {
-			suffixes.push("Boob", "Boobs", "Titty");
-		}
-		if (slave.boobs < 500 && slave.butt < 3) {
-			names.push("Girly", "Slim", "Thin");
-		}
-		if (slave.boobs < 300) {
-			names.push("Flat");
-		}
-		if (slave.anus > 2 || slave.vagina > 2) {
-			names.push("Gaping", "Hallway", "Slit", "Wideopen");
-		}
-		if (slave.weight > 160) {
-			names.push("Blimp", "Cow", "Fat", "Fatass", "Whale");
-		} else if (slave.weight > 30) {
-			names.push("Chubby", "Fat", "Whale");
-		} else if (slave.weight <= -30) {
-			names.push("Bony", "Rail", "Skinny");
-		}
-		if (slave.muscles > 30) {
-			names.push("Huge", "Muscles", "Ripped", "Strong");
-		}
-		if (slave.fetishKnown === 1) {
-			if (slave.fetish === "buttslut") {
-				names.push("Anal", "Sodomy");
-			}
-			if (slave.fetish === "cumslut") {
-				names.push("Cum", "Dicksuck", "Sucker");
-			}
-			if (slave.fetish === "humiliation") {
-				names.push("Rape");
-			}
-			if (slave.fetish === "masochist") {
-				names.push("Pain", "Rape", "Struggle");
-			}
-			if (slave.fetish === "pregnancy") {
-				names.push("Fertile");
-			}
-		}
-		if (slave.boobs * slave.lactation > 1000) {
-			names.push("Creamy", "Milky");
-			suffixes.push("Cow");
-		}
-		if (slave.skill.oral <= 30 && slave.skill.anal <= 30) {
-			names.push("Cheap", "Fail", "Gutter");
-		}
-		if (slave.nipples === "fuckable") {
-			names.push("Nipplefuck", "Nipplecunt");
-		} else if (slave.nipples !== "tiny" && slave.nipples !== "cute") {
-			names.push("Pointy", "Titclit");
-			suffixes.push("Nipples");
-		}
-		if (slave.visualAge > 35) {
-			names.push("Mature");
-			suffixes.push("Cougar", "MILF");
-		} else if (slave.visualAge < 25) {
-			names.push("Girly", "Thin", "Young");
-		}
-		if (isAmputee(slave)) {
-			names.push("Stumpy");
-			suffixes.push("Stumpy");
-		}
-		if (slave.boobsImplant > 1000 || slave.buttImplant > 3) {
-			names.push("Fake", "Plastic", "Silicone");
-		}
-		if (slave.dick > 5 && slave.balls > 5) {
-			names.push("Potent");
-			suffixes.push("Cannon", "Daddy");
-		}
-		if (slave.preg > slave.pregData.normalBirth / 1.33) {
-			if (slave.broodmother === 2) {
-				names.push("Bursting", "Seeded");
-				suffixes.push("Factory", "Nursery");
-			} else if (slave.broodmother === 1) {
-				names.push("Bloated", "Stuffed");
-				suffixes.push("Breeder", "Factory");
-			}
-		}
-		if (slave.bellyPreg >= 450000) {
-			names.push("Bulging", "Squirming");
-		}
-		if (slave.bellyPreg >= 5000) {
-			names.push("Preg");
-			suffixes.push("Belly", "Mommy");
-		}
-		if (slave.belly > 150000) {
-			suffixes.push("Balloon");
-		}
-		if (slave.belly > 1500) {
-			suffixes.push("Belly");
-		}
-		if (slave.dick > 0) {
-			if (slave.dick > 4) {
-				names.push("Dangle", "Hung");
-				suffixes.push("Cock", "Dick");
-			}
-			if (slave.balls === 0) {
-				names.push("Cut", "Gelded", "Soft");
-			} else {
-				names.push("Erect", "Hard", "Stiff");
-			}
-		}
-		if (slave.dick === 1) {
-			names.push("Micro", "Tiny");
-			suffixes.push("Bitch");
-		}
-		if (slave.height >= 185) {
-			names.push("Tall", "Top");
-			suffixes.push("Tower");
-		} else if (slave.height < 150) {
-			names.push("Stumpy", "Tiny");
-			suffixes.push("Shortstack", "Stumpy");
-		}
-		if (slave.skill.whoring > 95) {
-			names.push("Money", "Street");
-			suffixes.push("Whore");
-		}
-		if (slave.skill.entertainment > 95) {
-			names.push("Easy", "Club");
-			suffixes.push("Slut");
-		}
-		if (slave.skill.oral > 95) {
-			names.push("Suck");
-			suffixes.push("Throat");
-		}
-		if (slave.skill.vaginal > 95) {
-			suffixes.push("Channel", "Kegel", "Pussy");
-		}
-		if (slave.skill.anal > 95) {
-			suffixes.push("Asspussy", "Sphincter");
-		}
-		if (slave.intelligence + slave.intelligenceImplant > 50) {
-			names.push("Bright", "Clever", "Smart");
-			if (slave.intelligenceImplant >= 15) {
-				names.push("College", "Graduate", "Nerdy");
-			}
-		} else if (slave.intelligence + slave.intelligenceImplant < -50) {
-			names.push("Cretin", "Dumb", "Retarded", "Stupid");
-		}
-		if (slave.vagina === 1 && slave.skill.vaginal <= 10) {
-			names.push("Fresh", "New", "Tight");
-		}
-		if (slave.devotion < -75) {
-			names.push("Angry", "Biter", "Caged");
-		} else if (slave.devotion < -50) {
-			names.push("Cell", "Cuffs");
-		} else if (slave.devotion < -20) {
-			names.push("Bag", "Box");
-		} else if (slave.devotion <= 20) {
-			names.push("Sad", "Whiner");
-		} else if (slave.devotion > 50) {
-			names.push("Prize");
-			if (slave.visualAge > 35) {
-				names.push("Queen");
-			} else if (slave.visualAge < 25) {
-				names.push("Princess");
-			}
-		}
-		if (slave.trust < -50) {
-			names.push("Screaming");
-			suffixes.push("Sobber");
-		} else if (slave.trust < -20) {
-			names.push("Crying");
-			suffixes.push("Meat", "Tears", "Thing", "Weeper");
-		} else if (slave.trust < 20) {
-			names.push("Begging");
-		}
-
-		if (slave.dick === 0) {
-			if (slave.vagina === -1) {
-				suffixes.push("Null");
-			} else {
-				if (slave.visualAge < 25) {
-					suffixes.push("Girl");
-				}
-			}
-		} else {
-			if (slave.vagina !== -1) {
-				suffixes.push("Futa");
-			} else {
-				if (slave.balls > 0) {
-					if (slave.boobs > 300 && slave.butt > 2) {
-						/* SHEMALES: cock & balls, T&A above minimum */
-						suffixes.push("Shemale");
-					} else {
-						if (slave.shoulders < 1 && slave.muscles <= 30) {
-							if (slave.faceShape === "masculine" || slave.faceShape === "androgynous") {
-								/* SISSIES: feminine shoulders or muscles, masculine faces */
-								suffixes.push("Sissy");
-							} else {
-								/* TRAPS: feminine shoulders or muscles, feminine faces */
-								suffixes.push("Trap");
-							}
-						} else {
-							/* BITCHES: masculine shoulders or muscles */
-							suffixes.push("Bitch");
-						}
-					}
-				} else {
-					if (slave.visualAge > 35) {
-						suffixes.push("DickMILF");
-					} else if (slave.visualAge >= 25) {
-						suffixes.push("Dickslave");
-					} else {
-						suffixes.push("Dickgirl");
-					}
-				}
-			}
-		}
-		if (slave.anus > 0) {
-			suffixes.push("Anus", "Asshole", "Backdoor", "Butt", "Butthole");
-		}
-		if (slave.anus === 1) {
-			suffixes.push("Tightass", "Tightbutt");
-		}
-		if (slave.vagina > 0) {
-			suffixes.push("Cunt", "Pussy", "Vagina");
-		}
-		if (slave.boobs < 500 && slave.butt < 3 && slave.dick > 0) {
-			suffixes.push("Bitch", "Bottom", "Sissy", "Trap");
-		}
-		if (slave.energy > 95) {
-			suffixes.push("Fuck", "Fuckaddict", "Nympho", "Sexaddict");
-		}
-		if (slave.fetishKnown === 1) {
-			if (slave.fetish === "humiliation") {
-				suffixes.push("Rapebait", "Showgirl");
-			}
-			if (slave.fetish === "submissive") {
-				suffixes.push("Bottom", "Fuckee", "Rapebait");
-			}
-			if (slave.fetish === "dom") {
-				suffixes.push("Dom", "Fucker", "Top");
-			}
-			if (slave.fetish === "pregnancy") {
-				suffixes.push("Breeder", "Mommy");
-			}
-			if (slave.fetish === "boobs") {
-				suffixes.push("Boob", "Boobie", "Tit", "Titty");
-			}
-		}
-		if (slave.counter.births >= 2) {
-			suffixes.push("Breeder");
-			if (slave.counter.births >= 5) {
-				suffixes.push("Broodmother");
-			}
-		}
-		if (slave.areolae > 2) {
-			suffixes.push("Areolas", "Headlights");
-		}
-		if (slave.lips > 40) {
-			suffixes.push("Lips", "Pillows");
-		}
-		if (slave.labia > 1) {
-			suffixes.push("Curtains", "Flower", "Lips");
-		}
-		if (slave.breedingMark === 1 && V.propOutcome === 1 && V.arcologies[0].FSRestart !== "unset") {
-			suffixes.push("Breeder", "Oven", "Womb");
-		}
-		if (slave.butt > 5) {
-			suffixes.push("Ass", "Bottom", "Butt");
-		}
-		if (slave.vagina === 0) {
-			suffixes.push("Virgin");
-		}
-
-		slave.slaveName = jsEither(names);
-	}
-	if (leadershipPosition.includes(slave.assignment)) {
-		switch (slave.assignment) {
-			case Job.ATTENDANT:
-				slave.slaveName = jsEither(["Bath", "Spa"]);
-				break;
-			case Job.MATRON:
-				slave.slaveName = jsEither(["Matron", "Nursery"]);
-				break;
-			case Job.STEWARD:
-				slave.slaveName = jsEither(["Maid", "Servant"]);
-				break;
-			case Job.MILKMAID:
-				if (V.cumSlaves > 3) {
-					slave.slaveName = jsEither(["Fucker", "Milker"]);
-				} else {
-					slave.slaveName = jsEither(["Dairy", "Farm"]);
-				}
-				break;
-			case Job.FARMER:
-				slave.slaveName = jsEither(["Farmer", "Farmhand"]);
-				break;
-			case Job.DJ:
-				slave.slaveName = jsEither(["Bass", "Booth"]);
-				break;
-			case Job.CONCUBINE:
-				slave.slaveName = jsEither(["Bed", "Master"]);
-				break;
-			case Job.MADAM:
-				slave.slaveName = jsEither(["Madam", "Pimp"]);
-				break;
-			case Job.TEACHER:
-				slave.slaveName = jsEither(["Classroom", "Teacher"]);
-				break;
-			case Job.WARDEN:
-				slave.slaveName = jsEither(["Jail", "Prison"]);
-				break;
-			case Job.NURSE:
-				slave.slaveName = jsEither(["Clinic", "Nurse"]);
-				break;
-			case Job.HEADGIRL:
-				slave.slaveName = jsEither(["Chief", "Head"]);
-				break;
-			case Job.BODYGUARD:
-				slave.slaveName = jsEither(["Battle", "Guard"]);
-				break;
-			case Job.RECRUITER:
-				slave.slaveName = jsEither(["Cam", "Recruiter"]);
-				break;
-		}
-	}
-	const surname = jsEither(suffixes);
-	if (typeof surname === "string" && surname.toLowerCase() === slave.slaveName.toLowerCase()) {
-		DegradingName(slave);
-	}
-	slave.slaveName = capFirstChar(slave.slaveName);
-	slave.slaveSurname = surname;
-};
-
-globalThis.PaternalistName = function(slave) {
-	if (slave.slaveName.search("Miss") === -1) {
-		if (slave.slaveName.search("Ms.") === -1) {
-			if (slave.slaveName.search("Mrs.") === -1) {
-				if (slave.relationship > 4) {
-					slave.slaveName = ("Mrs. " + slave.slaveName);
-				} else if (slave.actualAge > 24) {
-					slave.slaveName = ("Ms. " + slave.slaveName);
-				} else {
-					slave.slaveName = ("Miss " + slave.slaveName);
-				}
-			}
-		}
-	}
-};
-
-globalThis.parentNames = function(parent, child) {
-	const slaves = V.slaves;
-
-	let currentSlaveNames = slaves.map(s => s.slaveName);
-	let continentNationality;
-	const useMaleName = (child.genes === "XY" && V.allowMaleSlaveNames === true);
-
-	child.slaveName = generateName(parent.nationality, child.race, useMaleName, sn => !currentSlaveNames.includes(sn));
-
-	if (!child.slaveName) {
-		for (let i = 0; i < 10; i++) {
-			continentNationality = hashChoice(V.nationalities);
-			child.slaveName = generateName(continentNationality, child.race, useMaleName, sn => !currentSlaveNames.includes(sn));	// jshint ignore: line
-		}
-	}
-	if (!child.slaveName) {
-		child.slaveName = generateName(parent.nationality, child.race, useMaleName);
-	}
-};
-
 globalThis.SlaveSort = function() {
 	const effectivePreg = (slave) => {
 		// slave.preg is only *mostly* usable for sorting
@@ -1379,297 +192,6 @@ globalThis.menialPopCap = function() {
 	return {text: r, value: popCap};
 };
 
-/**
- * @param {App.Entity.SlaveState} slave
- * @param {number} amount
- * @returns {string}
- */
-globalThis.faceIncrease = function(slave, amount) {
-	const pronouns = getPronouns(slave);
-	const his = pronouns.possessive;
-	const His = capFirstChar(his);
-	let r = "";
-	if (slave.face <= -95) {
-		r += `<span class="green">${His} face is no longer horrifying,</span> and is now merely ugly.`;
-	} else if (slave.face <= -40 && slave.face + amount > -40) {
-		r += `<span class="green">${His} face is no longer ugly,</span> and is now merely unattractive.`;
-	} else if (slave.face <= -10 && slave.face + amount > -10) {
-		r += `<span class="green">${His} face is no longer unattractive,</span> and is now somewhat tolerable.`;
-	} else if (slave.face <= 10 && slave.face + amount > 10) {
-		r += `<span class="green">${His} face is now decently attractive,</span> rather than merely tolerable.`;
-	} else if (slave.face <= 40 && slave.face + amount > 40) {
-		r += `<span class="green">${His} face is now quite beautiful,</span> rather than merely pretty.`;
-	} else if (slave.face <= 95 && slave.face + amount > 95) {
-		r += `<span class="green">${His} face is now perfect.</span> It's difficult to imagine how it could be any more beautiful.`;
-	}
-	slave.face = Math.clamp(slave.face + amount, -100, 100);
-	if (slave.face > 95) {
-		slave.face = 100;
-	}
-	return r;
-};
-
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {number}
- */
-globalThis.deadliness = function(slave) {
-	let deadliness = 2;
-
-	if (slave.skill.combat > 0) {
-		deadliness += 2;
-	}
-
-	if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
-		deadliness += 1;
-	} else if (slave.skill.bodyguard >= V.masteredXP) {
-		deadliness += 1;
-	}
-
-	if (V.AgePenalty !== 0) {
-		if (slave.physicalAge >= 100) {
-			deadliness -= 10;
-		} else if (slave.physicalAge >= 85) {
-			deadliness -= 3;
-		} else if (slave.physicalAge >= 70) {
-			deadliness -= 1;
-		}
-	}
-
-	if (slave.muscles > 30 && slave.muscles <= 95) {
-		deadliness += 1;
-	} else if (slave.muscles > 95 && slave.height >= 185) {
-		deadliness += 2;
-	} else if (slave.muscles > 95) {
-		deadliness -= 1;
-	} else if (slave.muscles < -95) {
-		deadliness -= 20;
-	} else if (slave.muscles < -30) {
-		deadliness -= 7;
-	} else if (slave.muscles < -5) {
-		deadliness -= 3;
-	}
-
-	if (slave.height >= 170) {
-		deadliness += 1;
-	}
-
-	if (slave.health.condition > 50) {
-		deadliness += 1;
-	} else if (slave.health.condition < -50) {
-		deadliness -= 1;
-	}
-
-	if (slave.health.illness > 3) {
-		deadliness -= 3;
-	} else if (slave.health.illness > 1) {
-		deadliness -= 2;
-	} else if (slave.health.illness > 0) {
-		deadliness -= 1;
-	}
-
-	if (slave.boobs > 4000) {
-		deadliness -= 2;
-	} else if (slave.boobs > 2000) {
-		deadliness -= 1;
-	}
-
-	if (slave.butt > 6) {
-		deadliness -= 1;
-	}
-
-	if (slave.hips > 2) {
-		deadliness -= 1;
-	}
-
-	if (slave.weight > 190) {
-		deadliness -= 20;
-	} else if (slave.weight > 160) {
-		deadliness -= 10;
-	} else if (slave.weight > 130) {
-		deadliness -= 3;
-	} else if (slave.weight > 30 || slave.weight < -10) {
-		deadliness -= 1;
-	}
-
-	if (slave.bellyFluid >= 10000) {
-		deadliness -= 3;
-	} else if (slave.bellyFluid >= 5000) {
-		deadliness -= 2;
-	} else if (slave.bellyFluid >= 2000) {
-		deadliness -= 1;
-	}
-
-	if (slave.pregKnown === 1 || slave.bellyPreg >= 1500 || slave.bellyImplant >= 1500) {
-		if (slave.belly >= 750000) {
-			deadliness -= 50;
-		} else if (slave.belly >= 600000) {
-			deadliness -= 25;
-		} else if (slave.belly >= 450000) {
-			deadliness -= 15;
-		} else if (slave.belly >= 300000) {
-			deadliness -= 10;
-		} else if (slave.belly >= 150000) {
-			deadliness -= 8;
-		} else if (slave.belly >= 100000) {
-			deadliness -= 7;
-		} else if (slave.belly >= 10000) {
-			deadliness -= 3;
-		} else if (slave.belly >= 5000) {
-			deadliness -= 2;
-		} else {
-			deadliness -= 1;
-		}
-	}
-
-	if (isInLabor(slave)) {
-		deadliness -= 15;
-	} else if (slave.preg >= slave.pregData.normalBirth && slave.pregControl !== "labor suppressors") {
-		deadliness -= 5;
-	}
-
-	if (slave.balls >= 15) {
-		deadliness -= 1;
-	}
-
-	if (slave.dick >= 10) {
-		deadliness -= 1;
-	}
-
-	deadliness -= getLimbCount(slave, 0) * 5;
-	deadliness -= getLimbCount(slave, 2) * 0.25;
-	deadliness -= getLimbCount(slave, 3) * 0.25;
-	deadliness -= getLimbCount(slave, 4) * 0.25;
-	deadliness += getLimbCount(slave, 5) * 1.25;
-	deadliness += getLimbCount(slave, 6) * 2.5;
-	if (hasBothLegs(slave) && !canStand(slave)) {
-		deadliness -= 20;
-	}
-
-	if (!canSee(slave)) {
-		deadliness -= 8;
-	} else if (!canSeePerfectly(slave)) {
-		deadliness -= 1;
-	}
-
-	if (!canHear(slave)) {
-		deadliness -= 4;
-	} else if ((slave.hears === -1 && slave.earwear !== "hearing aids") || (slave.hears === 0 && slave.earwear === "muffling ear plugs")) {
-		deadliness -= 1;
-	}
-
-	if (slave.tail === "combat") {
-		deadliness += 2;
-	}
-
-	if (slave.health.tired > 90) {
-		deadliness -= 10;
-	} else if (slave.health.tired > 60) {
-		deadliness -= 3;
-	} else if (slave.health.tired > 30) {
-		deadliness -= 1;
-	}
-
-	return Math.max(deadliness, 1);
-};
-
-/** Is the slave ready to retire?
- * @param {App.Entity.SlaveState} slave
- * @returns {boolean}
- */
-globalThis.retirementReady = function(slave) {
-	// indentured slaves don't retire, they expire
-	if (slave.indenture >= 0) {
-		return false;
-	}
-
-	// retirement by age
-	if (V.policies.retirement.physicalAgePolicy === 0 && slave.actualAge >= V.retirementAge) {
-		return true;
-	} else if (V.policies.retirement.physicalAgePolicy === 1 && slave.physicalAge >= V.retirementAge) {
-		return true;
-	}
-
-	// retirement by milestone
-	if (V.policies.retirement.sex > 0 && (slave.counter.oral + slave.counter.anal + slave.counter.vaginal + slave.counter.penetrative + slave.counter.mammary) > V.policies.retirement.sex) {
-		return true;
-	}
-	if (V.policies.retirement.milk > 0 && slave.counter.milk > V.policies.retirement.milk) {
-		return true;
-	}
-	if (V.policies.retirement.cum > 0 && slave.counter.cum > V.policies.retirement.cum) {
-		return true;
-	}
-	if (V.policies.retirement.births > 0 && slave.counter.births > V.policies.retirement.births) {
-		return true;
-	}
-	if (V.policies.retirement.kills > 0 && slave.counter.pitKills > V.policies.retirement.kills) {
-		return true;
-	}
-
-	// no retirement for you
-	return false;
-};
-
-/** marks some weeks of time passage for a slave, counting birthdays and invoking aging if game settings require it
- * @param {App.Entity.SlaveState} slave
- * @param {number} [weeks=1]
- */
-globalThis.ageSlaveWeeks = function(slave, weeks = 1) {
-	if (V.seeAge !== 0) { // birthdays enabled
-		for (let i = 0; i < weeks; ++i) {
-			slave.birthWeek++;
-			if (slave.birthWeek >= 52) {
-				slave.birthWeek = 0;
-				if (V.seeAge === 1) { // actual aging enabled
-					ageSlave(slave);
-				}
-			}
-		}
-	}
-};
-
-/** advances the age of a slave by one year, incurring all aging side effects
- * @param {App.Entity.SlaveState} slave
- * @param {boolean} [forceDevelopment=false]
- */
-globalThis.ageSlave = function(slave, forceDevelopment = false) {
-	slave.physicalAge++;
-	slave.actualAge++;
-	if (slave.geneMods.NCS === 1 || (slave.geneticQuirks.neoteny >= 2 && slave.geneticQuirks.progeria !== 2)) {
-		/* Induced NCS completely takes over visual aging. Additionally, because of the neoteny aspects of NCS, ovaries don't age quite as fast. */
-		/* Unsurprisingly, actual neoteny has the same effect as long as progeria isn't in play. */
-		slave.ovaryAge += either(0.5, 0.6, 0.7, 0.7, 0.8, 0.9, 1.0);
-	} else {
-		slave.visualAge++;
-		slave.ovaryAge += either(0.8, 0.9, 0.9, 1.0, 1.0, 1.0, 1.1);
-	}
-	if (slave.broodmother === 1) {
-		slave.ovaryAge += 0.2;
-	}
-	if (slave.physicalAge <= 18 && (forceDevelopment || V.loliGrow > 0)) {
-		physicalDevelopment(slave);
-	}
-};
-
-/** Is the slave a shelter slave?
- * @param {App.Entity.SlaveState} slave
- * @returns {boolean}
- */
-globalThis.isShelterSlave = function(slave) {
-	return (typeof slave.origin === "string" && slave.origin.includes("Slave Shelter"));
-};
-
-/**
- * Returns if a slave appears male, female, or androgynous.
- *
- * @param {App.Entity.SlaveState} slave
- * @returns {number}
- */
-globalThis.perceivedGender = function(slave) {
-	return -1;
-};
-
 globalThis.initRules = function() {
 	const rule = emptyDefaultRule();
 	rule.name = "Obedient Slaves";
diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js
index e2abcde7e020128047694f91e887f0f3bcc2157e..6cfb49ee8a69b5b7e521bfab365902bf13e9f5a3 100644
--- a/src/js/utilsSlave.js
+++ b/src/js/utilsSlave.js
@@ -1,5 +1,3 @@
-/* contains functions that rely on FC specific variables/conventions */
-/* eslint-disable no-unused-vars */
 /*
  * Height.mean(nationality, race, genes, age) - returns the mean height for the given combination and age in years (>=2)
  * Height.mean(nationality, race, genes) - returns the mean adult height for the given combination
@@ -2277,4 +2275,1482 @@ globalThis.deflate = function(slave) {
 globalThis.getExposure = function(slave) {
 	const clothes = App.Data.clothes.get(slave.clothes);
 	return (clothes.topless && clothes.exposure < 3 && (slave.boobs > 299 || (slave.genes === 'XX' && slave.vagina >= 0))) ? 3 : clothes.exposure;
+};
+
+/**
+ * @param {App.Entity.SlaveState} A
+ * @param {App.Entity.SlaveState} B
+ * @returns {boolean}
+ */
+globalThis.sameAssignmentP = function(A, B) {
+	return A.assignment === B.assignment;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+globalThis.canImproveIntelligence = function(slave) {
+	let origIntel = V.genePool.find(function(s) { return s.ID === slave.ID; }).intelligence;
+	return (slave.intelligence < origIntel + 15) && (slave.intelligence < 100);
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+globalThis.maxHeight = function(slave) {
+	let max = Math.trunc(Math.clamp((Height.mean(slave) * 1.25), 0, 274)); /* max achievable height is expected height plus 25% */
+
+	if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
+		max = Math.min(max, 160);
+	}
+
+	return max;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+globalThis.canImproveHeight = function(slave) {
+	return slave.height < maxHeight(slave);
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} target
+ * @returns {boolean}
+ */
+globalThis.haveRelationshipP = function(slave, target) {
+	return slave.relationshipTarget === target.ID;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {App.Entity.SlaveState} target
+ * @returns {boolean}
+ */
+globalThis.isRivalP = function(slave, target) {
+	return slave.rivalryTarget === target.ID;
+};
+
+/**
+ * @param {FC.HumanState} slave
+ * @returns {boolean}
+ */
+globalThis.supremeRaceP = function(slave) {
+	return V.arcologies[0].FSSupremacistRace === slave.race;
+};
+
+/**
+ * @param {FC.HumanState} slave
+ * @returns {boolean}
+ */
+globalThis.inferiorRaceP = function(slave) {
+	return V.arcologies[0].FSSubjugationistRace === slave.race;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+globalThis.isLeaderP = function(slave) {
+	const leaders = [S.HeadGirl, S.Bodyguard, S.Recruiter, S.Concubine, S.Nurse, S.Attendant, S.Matron, S.Madam, S.DJ, S.Milkmaid, S.Farmer, S.Stewardess, S.Schoolteacher, S.Wardeness];
+
+	return leaders.some(leader => leader && leader.ID === slave.ID);
+};
+
+/**
+ * colors skin, eyes and hair based on genetic Color.
+ * Takes .override_*_Color into account.
+ *
+ * @param {App.Entity.SlaveState} slave
+ */
+globalThis.applyGeneticColor = function(slave) {
+	if (slave.override_Eye_Color !== 1) {
+		resetEyeColor(slave, "both");
+	}
+	if (slave.override_H_Color !== 1) {
+		slave.hColor = getGeneticHairColor(slave);
+	}
+	if (slave.override_Arm_H_Color !== 1) {
+		slave.underArmHColor = getGeneticHairColor(slave);
+	}
+	if (slave.override_Pubic_H_Color !== 1) {
+		slave.pubicHColor = getGeneticHairColor(slave);
+	}
+	if (slave.override_Brow_H_Color !== 1) {
+		slave.eyebrowHColor = getGeneticHairColor(slave);
+	}
+	if (slave.override_Skin !== 1) {
+		if (!(slave.skin === "sun tanned" || slave.skin === "spray tanned")) {
+			slave.skin = getGeneticSkinColor(slave);
+		}
+	}
+};
+
+/**
+ * @param {FC.GingeredSlave} slave
+ */
+globalThis.newSlave = function(slave) {
+	if (getSlave(slave.ID)) {
+		throw "Slave already exists";
+	}
+
+	// if the slave is gingered, remove the gingering proxy
+	if (slave.beforeGingering) {
+		slave = slave.beforeGingering;
+	}
+
+	if (slave.override_Race !== 1) {
+		slave.origRace = slave.race;
+	}
+
+	applyGeneticColor(slave);
+
+	/* eslint-disable camelcase */
+	slave.override_Race = 0;
+	slave.override_H_Color = 0;
+	slave.override_Arm_H_Color = 0;
+	slave.override_Pubic_H_Color = 0;
+	slave.override_Brow_H_Color = 0;
+	slave.override_Skin = 0;
+	slave.override_Eye_Color = 0;
+	/* eslint-enable camelcase */
+
+	// too tall to be a dwarf catch for event slaves
+	if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2 && slave.height > 165) {
+		slave.geneticQuirks.dwarfism = 1;
+	}
+
+	if (V.surnamesForbidden === 1) {
+		slave.slaveSurname = 0;
+	}
+
+	if (slave.preg > 0) {
+		slave.pregWeek = slave.preg;
+	} else {
+		slave.pregWeek = 0;
+	}
+
+	if (slave.clone !== 0) {
+		slave.canRecruit = 0;
+	}
+
+	slave.sisters = 0;
+	slave.daughters = 0;
+	if (slave.mother === -1 || slave.father === -1) {
+		V.PC.daughters += 1;
+	}
+	if (areSisters(V.PC, slave) > 0) {
+		V.PC.sisters += 1;
+	}
+	for (let k = 0; k < V.slaves.length; k++) {
+		if (V.slaves[k].mother === slave.ID || V.slaves[k].father === slave.ID) {
+			slave.daughters++;
+		}
+		if (slave.mother === V.slaves[k].ID || slave.father === V.slaves[k].ID) {
+			V.slaves[k].daughters++;
+		}
+		if (areSisters(V.slaves[k], slave) > 0) {
+			slave.sisters++;
+			V.slaves[k].sisters++;
+		}
+	}
+
+	if (slave.genes === "XX") {
+		if (slave.pubertyXX === 1) {
+			if (slave.pubertyXY === 1) {
+				slave.hormoneBalance = 20;
+			} else {
+				slave.hormoneBalance = 60;
+			}
+		} else {
+			if (slave.pubertyXY === 1) {
+				slave.hormoneBalance = -20;
+			} else {
+				slave.hormoneBalance = 20;
+			}
+		}
+	} else if (slave.genes === "XY") {
+		if (slave.pubertyXX === 1) {
+			if (slave.pubertyXY === 1) {
+				slave.hormoneBalance = 20;
+			} else {
+				slave.hormoneBalance = 40;
+			}
+		} else {
+			if (slave.pubertyXY === 1) {
+				slave.hormoneBalance = -40;
+			} else {
+				slave.hormoneBalance = 20;
+			}
+		}
+	}
+
+	if (slave.dick > 0 &&
+		slave.balls > 0 &&
+		slave.vagina < 0 &&
+		slave.anus === 0 &&
+		slave.genes === "XY" &&
+		slave.faceShape === "masculine" &&
+		slave.attrXY <= 35 &&
+		slave.boobs < 400 &&
+		slave.hormoneBalance < 0) {
+		V.REFeminizationCheckinIDs.push(slave.ID);
+	}
+	if (slave.actualAge > 35 && slave.face <= 10 && slave.faceImplant === 0 && slave.energy <= 60) {
+		V.REMILFCheckinIDs.push(slave.ID);
+	}
+	if (slave.attrXY <= 35 && slave.attrXX > 65) {
+		V.REOrientationCheckinIDs.push(slave.ID);
+	}
+	if (slave.face < -10) {
+		V.REUglyCheckinIDs.push(slave.ID);
+	}
+	if (slave.anus < 2) {
+		V.REButtholeCheckinIDs.push(slave.ID);
+	}
+	if (slave.boobs < 800) {
+		V.REReductionCheckinIDs.push(slave.ID);
+	}
+
+	generatePronouns(slave);
+	SetBellySize(slave);
+	V.slaveIndices[slave.ID] = V.slaves.push(slave) - 1;
+
+	if (slave.origin !== "$He was your slave, but you freed $him, which $he repaid by participating in a coup attempt against you. It failed, and $he is again your chattel." && slave.ID !== V.boomerangSlave.ID) {
+		V.genePool.push(clone(slave));
+	} else {
+		if (!V.genePool.some(s => s.ID === slave.ID)) {
+			V.genePool.push(slave);
+		}
+	}
+
+	/* special case for dulling intelligence via drugs in slave acquisition */
+	if (slave.dullIntelligence) {
+		slave.intelligence = -100;
+		delete slave.dullIntelligence;
+	}
+
+	if (slave.assignment) {
+		assignJob(slave, slave.assignment);
+	} else {
+		slave.assignment = Job.CHOICE;
+	}
+
+	/** do not run the Rules Assistant before adding the new slave to the slaves list! **/
+	if (V.ui !== "start" && V.universalRulesNewSlavesRA === 1 && V.rulesAssistantAuto !== 0) {
+		DefaultRules(slave);
+	}
+};
+
+/** Get the written title for a given slave, without messing with global state.
+ * @param {App.Entity.SlaveState} [slave]
+ * @returns {string}
+ */
+globalThis.getWrittenTitle = function(slave) {
+	if (slave && slave.custom.title !== undefined && slave.custom.title !== "" && slave.rudeTitle === 0) {
+		return slave.custom.title;
+	}
+	if (V.PC.customTitle !== undefined) {
+		return V.PC.customTitle;
+	} else if (V.PC.title !== 0) {
+		return "Master";
+	} else {
+		return "Mistress";
+	}
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+globalThis.fetishChangeChance = function(slave) {
+	let chance = 0,
+		fetish = (slave.fetishStrength / 4),
+		sex = 0;
+
+	if (slave.clitSetting !== slave.fetish) {
+		// fetish should be more uncertain leading towards puberty and then steadily become more set in stone afterwards
+		if (slave.balls) {
+			if (V.potencyAge >= slave.actualAge) {
+				sex = (50 - ((V.potencyAge - slave.actualAge) * 10));
+				fetish = (slave.fetishStrength / 2);
+			} else {
+				sex = ((slave.actualAge - V.potencyAge) / 4);
+			}
+		} else if (slave.ovaries || slave.mpreg) {
+			if (V.fertilityAge >= slave.actualAge) {
+				sex = (50 - ((V.fertilityAge - slave.actualAge) * 10));
+				fetish = (slave.fetishStrength / 2);
+			} else {
+				sex = ((slave.actualAge - V.fertilityAge) / 4);
+			}
+		}
+		chance = Math.trunc(Math.clamp((slave.devotion / 4) - (fetish) - (sex), 0, 100));
+	}
+
+	return chance;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+globalThis.SlaveFullName = function(slave) {
+	const pair = slave.slaveSurname ? [slave.slaveName, slave.slaveSurname] : [slave.slaveName];
+	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
+		pair.reverse();
+	}
+	return pair.join(" ");
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+globalThis.SlaveFullBirthName = function(slave) {
+	const pair = slave.birthSurname ? [slave.birthName, slave.birthSurname] : [slave.birthName];
+	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
+		pair.reverse();
+	}
+	return pair.join(" ");
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+globalThis.PoliteRudeTitle = function(slave) {
+	const PC = V.PC;
+	const {s, ss, title} = getEnunciation(slave);
+
+	let r = "";
+	if (slave.nationality === "Japanese") {
+		if (slave.trust > 0) {
+			r += `${PC.slaveName}${PC.title > 0 ? "kun" : "chan"}`;
+		} else {
+			r += (PC.slaveSurname ? PC.slaveSurname : `${PC.slaveName}${s}an`);
+		}
+	} else {
+		if (slave.intelligence + slave.intelligenceImplant < -95) {
+			r += title;
+		} else if (slave.intelligence + slave.intelligenceImplant > 50) {
+			r += (PC.title > 0 ? `Ma${s}ter` : `Mi${s}tre${ss}`);
+		} else if (slave.trust > 0) {
+			r += PC.slaveName;
+		} else {
+			r += (PC.slaveSurname ? PC.slaveSurname : PC.slaveName);
+		}
+	}
+	return r;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+globalThis.SlaveTitle = function(slave) {
+	let r;
+	if (V.newDescriptions === 1) {
+		if (slave.dick > 0 && slave.balls > 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
+			if (jsRandom(1, 100) > 50) {
+				r = "futanari";
+			} else {
+				r = "herm";
+			}
+		} else if (slave.dick > 0 && slave.balls === 0 && slave.boobs > 300 && slave.vagina > -1 && slave.ovaries === 1) {
+			r = "dickgirl";
+		} else if (slave.dick > 0 && slave.vagina > -1 && slave.ovaries === 0) {
+			r = "shemale";
+		} else if (slave.dick > 0 && slave.balls === 0 && slave.vagina === -1 && slave.ovaries === 0) {
+			r = "eunuch";
+		} else if (slave.dick > 0 && slave.balls > 0 && slave.vagina === -1 && slave.ovaries === 0) {
+			if (slave.face > 10 && slave.hips > -1 && slave.shoulders < 1 && slave.faceShape !== "masculine") {
+				r = "trap";
+			} else if (slave.boobs > 800) {
+				r = "tittyboy";
+			} else if (slave.dick === 1 && slave.balls === 1) {
+				r = "sissy";
+			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 165 && slave.muscles < 5 && slave.visualAge < 19 && slave.faceShape !== "masculine") {
+				r = "twink";
+			} else if (slave.dick > 1 && slave.balls > 1 && slave.height < 160 && slave.muscles < 5 && slave.visualAge < 19) {
+				r = "boytoy";
+			} else if (slave.muscles > 95 && slave.height >= 185) {
+				r = "titan";
+			} else if (slave.muscles > 30) {
+				r = "muscleboy";
+			} else {
+				r = "slaveboy";
+			}
+		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina > -1) {
+			if ((slave.shoulders > slave.hips || slave.faceShape === "masculine") && slave.boobs < 400 && slave.genes === "XY") {
+				r = "cuntboy";
+			} else if (slave.ovaries === 0 && slave.genes === "XY") {
+				r = "tranny";
+			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 59) {
+				r = "GMILF";
+			} else if (slave.weight > 10 && slave.boobs > 800 && slave.counter.birthsTotal > 0 && slave.physicalAge > 35) {
+				r = "MILF";
+			} else if (slave.lips > 70 && slave.boobs > 2000 && slave.butt > 3) {
+				r = "bimbo";
+			} else if (slave.hips > 1 && slave.boobs > 2000 && slave.butt > 3 && slave.waist < 50) {
+				r = "hourglass";
+			} else if (slave.muscles > 95 && slave.height >= 185) {
+				r = "amazon";
+			} else if (slave.muscles > 30) {
+				r = "musclegirl";
+			} else {
+				r = "slavegirl";
+			}
+		} else if (slave.dick === 0 && slave.balls === 0 && slave.vagina === -1) {
+			r = "neuter";
+		} else if (slave.dick === 0 && slave.vagina === -1) {
+			r = "ballslave";
+		} else {
+			r = "slave";
+		}
+
+		if (slave.visualAge < 13) {
+			if (slave.actualAge < 3) {
+				if (slave.actualAge < 1) {
+					r = "baby " + r;
+				} else {
+					r = "toddler " + r;
+				}
+			} else {
+				if (slave.genes === "XY" && slave.vagina === -1) {
+					r = "shota " + r;
+				} else {
+					r = "loli " + r;
+				}
+			}
+		}
+
+		if (slave.geneticQuirks.albinism === 2) {
+			r = `albino ${r}`;
+		}
+
+		if (slave.dick > 9 && slave.balls > 9 && slave.boobs > 12000) {
+			r = `hyper ${r}`;
+		}
+
+		if (slave.boobs > 4000 && slave.lactation > 0) {
+			if (slave.physicalAge < 13) {
+				r = `${r} calf`;
+			} else {
+				r = `${r} cow`;
+			}
+		} else if (slave.lactation > 0) {
+			r = `milky ${r}`;
+		}
+
+		if (slave.boobs > 20000) {
+			r = `supermassive titted ${r}`;
+		} else if (slave.boobs > 10000) {
+			r = `giant titted ${r}`;
+		} else if (slave.boobs > 4000) {
+			r = `huge titted ${r}`;
+		} else if (slave.boobs > 1000) {
+			r = `busty ${r}`;
+		}
+
+		if (slave.dick > 5 && slave.balls > 5) {
+			r = `womb filling ${r}`;
+		} else if (slave.dick > 5) {
+			r = `well hung ${r}`;
+		}
+
+		if (slave.butt >= 12) {
+			r = `colossal assed ${r}`;
+		} else if (slave.butt >= 10) {
+			r = `massive assed ${r}`;
+		} else if (slave.butt >= 8) {
+			r = `fat assed ${r}`;
+		} else if (slave.butt >= 6) {
+			r = `bottom heavy ${r}`;
+		} else if (slave.butt >= 4) {
+			r = `big bottomed ${r}`;
+		}
+
+		if (slave.weight > 10 && slave.weight < 100 && slave.boobs > 5000 && slave.butt > 5 && slave.hips >= 2 && slave.bellyPreg >= 30000 && slave.counter.births >= 10) {
+			r = `${r} fertility goddess`;
+		} else if (slave.counter.births >= 6) {
+			r = `${r} broodmother`;
+		} else if (slave.counter.births >= 3) {
+			r = `${r} breeder`;
+		}
+
+		if (slave.indenture > -1) {
+			r = `indentured ${r}`;
+		}
+
+		if (slave.preg > slave.pregData.normalBirth / 4 && slave.pregKnown === 1) {
+			r = `pregnant ${r}`;
+		} else if (slave.bellyFluid >= 5000) {
+			r = `bloated ${r}`;
+		} else if (slave.belly >= 5000) {
+			r = `gravid ${r}`;
+		}
+
+		if (slave.fuckdoll > 0) {
+			r = `${r} fuckdoll`;
+		}
+	} else {
+		r = "slave"; /* I don't think there is an 'else'? */
+		if ((slave.dick === 0) && (slave.vagina === -1)) {
+			/* NULLS */
+			r = "null";
+			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
+				r = `${r} cow`;
+			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+				r = `${r} bimbo `;
+			} else if (slave.boobs > 6000) {
+				r = `${r} boob`;
+			} else if (slave.butt > 6) {
+				r = `${r} ass`;
+			} else if ((slave.muscles > 30) && (slave.height < 185)) {
+				r = `${r} muscle`;
+			}
+			if (slave.visualAge > 55) {
+				r = `${r}GILF`;
+			} else if (slave.visualAge > 35) {
+				r = `${r}MILF`;
+			} else if (slave.visualAge >= 25) {
+				r = `${r}slave`;
+			} else {
+				r = `${r}girl`;
+			}
+		}
+
+		if ((slave.dick === 0) && (slave.vagina !== -1)) {
+			/* FEMALES */
+			if (slave.visualAge > 55) {
+				r = "GILF";
+			} else if (slave.visualAge > 35) {
+				r = "MILF";
+			} else if (slave.visualAge >= 25) {
+				r = "slave";
+			} else {
+				r = "slavegirl";
+			}
+			if ((slave.muscles > 30) && (slave.height < 185)) {
+				r = `muscle ${r}`;
+			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
+				r = `${r} cow`;
+			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+				r = `${r} bimbo`;
+			} else if (slave.boobs > 6000) {
+				r = `boob${r}`;
+			} else if (slave.butt > 6) {
+				r = `ass${r}`;
+			}
+		}
+
+		if ((slave.dick !== 0) && (slave.vagina !== -1)) {
+			if (slave.balls > 0) {
+				/* FUTANARI: cock & balls & vagina */
+				r = "futanari ";
+			} else {
+				/* FUTANARI: cock & vagina */
+				r = "futa ";
+			}
+			if ((slave.lactation > 0) && (slave.boobs > 2000)) {
+				r = `${r}cow`;
+			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+				r = `${r}bimbo `;
+			} else if (slave.boobs > 6000) {
+				r = `${r}boob`;
+			} else if (slave.butt > 6) {
+				r = `${r}ass`;
+			} else if ((slave.muscles > 30) && (slave.height < 185)) {
+				r = `${r}muscle`;
+			}
+			if (slave.visualAge > 55) {
+				r = `${r}GILF`;
+			} else if (slave.visualAge > 35) {
+				r = `${r}MILF`;
+			} else if (slave.visualAge >= 25) {
+				r = `${r}slave`;
+			} else {
+				r = `${r}girl`;
+			}
+			if (slave.dick > 5 && slave.balls > 5 && slave.boobs > 5000) {
+				r = `hyper ${r}`;
+			}
+		}
+
+		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0) && (slave.boobs > 300) && (slave.butt > 2)) {
+			/* SHEMALES: cock & balls, T&A above minimum */
+			if (slave.visualAge > 55) {
+				r = "sheGILF";
+			} else if (slave.visualAge > 35) {
+				r = "sheMILF";
+			} else if (slave.visualAge >= 25) {
+				r = "shemale";
+			} else {
+				r = "tgirl";
+			}
+			if ((slave.muscles > 30) && (slave.height < 185)) {
+				r = `muscle${r}`;
+			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
+				r = `${r} cow`;
+			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+				r = `${r} bimbo`;
+			} else if (slave.boobs > 6000) {
+				r = `topheavy ${r}`;
+			} else if (slave.butt > 6) {
+				r = `bottomheavy ${r}`;
+			}
+		}
+
+		if ((slave.boobs < 300) || (slave.butt < 2)) {
+			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
+				if ((slave.shoulders < 1) || (slave.muscles <= 30)) {
+					if ((slave.faceShape === "masculine") || (slave.faceShape === "androgynous")) {
+						/* SISSIES: feminine shoulders or muscles, masculine faces */
+						if (slave.visualAge > 55) {
+							r = "sissyGILF";
+						} else if (slave.visualAge > 35) {
+							r = "sissyMILF";
+						} else {
+							r = "sissy";
+						}
+					} else {
+						/* TRAPS: feminine shoulders or muscles, feminine faces */
+						if (slave.visualAge > 55) {
+							r = "trapGILF";
+						} else if (slave.visualAge > 35) {
+							r = "trapMILF";
+						} else if (slave.visualAge >= 25) {
+							r = "trap";
+						} else {
+							r = "trapgirl";
+						}
+					}
+					if (slave.lactation > 0) {
+						r = `${r} cow`;
+					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+						r = `${r} bimbo`;
+					}
+				}
+			}
+		}
+
+		if ((slave.boobs < 300) || (slave.butt < 2)) {
+			if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls > 0)) {
+				if ((slave.shoulders > 1) || (slave.muscles >= 30)) {
+					/* BITCHES: masculine shoulders or muscles */
+					r = "bitch";
+					if ((slave.muscles > 30) && (slave.height < 185)) {
+						r = `muscle${r}`;
+					} else if (slave.lactation > 0) {
+						r = `${r}cow`;
+					} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+						r = `bimbo ${r}`;
+					}
+					if (slave.visualAge > 55) {
+						r = `aged ${r}`;
+					} else if (slave.visualAge > 35) {
+						r = `mature ${r}`;
+					} else if (slave.visualAge < 25) {
+						r = `young ${r}`;
+					}
+				}
+			}
+		}
+
+		if ((slave.dick !== 0) && (slave.vagina === -1) && (slave.balls === 0)) {
+			r = "dick";
+			if (slave.visualAge > 55) {
+				r = `${r}GILF`;
+			} else if (slave.visualAge > 35) {
+				r = `${r}MILF`;
+			} else if (slave.visualAge >= 25) {
+				r = `${r}slave`;
+			} else {
+				r = `${r}girl`;
+			}
+			if ((slave.muscles > 30) && (slave.height < 185)) {
+				r = `muscle${r}`;
+			} else if ((slave.lactation > 0) && (slave.boobs > 2000)) {
+				r = `${r} cow`;
+			} else if ((slave.boobsImplant > 0) && (slave.buttImplant > 0)) {
+				r = `${r} bimbo`;
+			} else if (slave.boobs > 6000) {
+				r = `boob ${r}`;
+			} else if (slave.butt > 6) {
+				r = `ass ${r}`;
+			}
+		}
+
+		if ((slave.muscles > 30) && (slave.height > 185)) {
+			r = `amazon ${r}`;
+		} else if ((slave.muscles < 30) && (slave.height > 185)) {
+			r = `statuesque ${r}`;
+		} else if ((slave.boobs < 800) && (slave.height < 150)) {
+			r = `petite ${r}`;
+		} else if ((slave.boobs > 800) && (slave.height < 150)) {
+			r = `shortstack ${r}`;
+		}
+
+		if (slave.counter.births >= 5) {
+			r = `${r} broodmother`;
+		} else if (slave.counter.births >= 2) {
+			r = `${r} breeder`;
+		}
+
+		if (slave.geneticQuirks.albinism === 2) {
+			r = `albino ${r}`;
+		}
+
+		if (slave.indenture > -1) {
+			r = `indentured ${r}`;
+		}
+
+		if (slave.preg > slave.pregData.normalBirth / 4 && slave.pregKnown === 1) {
+			r = `pregnant ${r}`;
+		} else if (slave.bellyFluid >= 5000) {
+			r = `bloated ${r}`;
+		} else if (slave.belly >= 5000) {
+			r = `gravid ${r}`;
+		}
+
+		if (slave.fuckdoll > 0) {
+			r = `${r} fuckdoll`;
+		}
+	}
+	return r;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ */
+globalThis.DegradingName = function(slave) {
+	const leadershipPosition = [
+		Job.ATTENDANT,
+		Job.MATRON,
+		Job.STEWARD,
+		Job.MILKMAID,
+		Job.FARMER,
+		Job.DJ,
+		Job.CONCUBINE,
+		Job.MADAM,
+		Job.TEACHER,
+		Job.WARDEN,
+		Job.NURSE,
+		Job.HEADGIRL,
+		Job.BODYGUARD,
+		Job.RECRUITER
+	];
+	const names = [];
+	const suffixes = [];
+
+	if (slave.fuckdoll > 0) {
+		slave.slaveName = `Fuckdoll No. ${slave.ID}`;
+		slave.slaveSurname = 0;
+	} else if (slave.assignment === Job.DAIRY && V.dairyRestraintsSetting >= 2) {
+		slave.slaveName = `Bioreactor No. ${slave.ID}`;
+		slave.slaveSurname = 0;
+	} else {
+		if (V.seeRace === 1) {
+			switch (slave.race) {
+				case "white":
+					names.push("Pale", "White");
+					break;
+				case "asian":
+					names.push("Asian", "Yellow");
+					break;
+				case "latina":
+					names.push("Brown", "Latina");
+					break;
+				case "black":
+					names.push("Black", "Dark");
+					break;
+				case "pacific islander":
+					names.push("Islander", "Pacific", "Sea");
+					break;
+				case "malay":
+					names.push("Cinnamon", "Pinoy", "Spice");
+					break;
+				case "southern european":
+					names.push("Mediterranean", "Olive");
+					break;
+				case "amerindian":
+					names.push("Indian", "Reservation");
+					break;
+				case "semitic":
+					names.push("Semite", "Semitic");
+					break;
+				case "middle eastern":
+					names.push("Arab", "Sand");
+					break;
+				case "indo-aryan":
+					names.push("Brown", "Indian");
+					break;
+				case "mixed race":
+					names.push("Mixed", "Mulatto", "Mutt");
+					break;
+			}
+		}
+		names.push(slave.hColor);
+		if (!hasAnyEyes(slave)) {
+			names.push("Blind", "Eyeless", "Sightless");
+		}
+		if (slave.hears === -2) {
+			names.push("Deaf", "Earless", "Unhearing");
+		}
+		if (slave.boobs >= 2000) {
+			suffixes.push("Boob", "Boobs", "Titty");
+		}
+		if (slave.boobs < 500 && slave.butt < 3) {
+			names.push("Girly", "Slim", "Thin");
+		}
+		if (slave.boobs < 300) {
+			names.push("Flat");
+		}
+		if (slave.anus > 2 || slave.vagina > 2) {
+			names.push("Gaping", "Hallway", "Slit", "Wideopen");
+		}
+		if (slave.weight > 160) {
+			names.push("Blimp", "Cow", "Fat", "Fatass", "Whale");
+		} else if (slave.weight > 30) {
+			names.push("Chubby", "Fat", "Whale");
+		} else if (slave.weight <= -30) {
+			names.push("Bony", "Rail", "Skinny");
+		}
+		if (slave.muscles > 30) {
+			names.push("Huge", "Muscles", "Ripped", "Strong");
+		}
+		if (slave.fetishKnown === 1) {
+			if (slave.fetish === "buttslut") {
+				names.push("Anal", "Sodomy");
+			}
+			if (slave.fetish === "cumslut") {
+				names.push("Cum", "Dicksuck", "Sucker");
+			}
+			if (slave.fetish === "humiliation") {
+				names.push("Rape");
+			}
+			if (slave.fetish === "masochist") {
+				names.push("Pain", "Rape", "Struggle");
+			}
+			if (slave.fetish === "pregnancy") {
+				names.push("Fertile");
+			}
+		}
+		if (slave.boobs * slave.lactation > 1000) {
+			names.push("Creamy", "Milky");
+			suffixes.push("Cow");
+		}
+		if (slave.skill.oral <= 30 && slave.skill.anal <= 30) {
+			names.push("Cheap", "Fail", "Gutter");
+		}
+		if (slave.nipples === "fuckable") {
+			names.push("Nipplefuck", "Nipplecunt");
+		} else if (slave.nipples !== "tiny" && slave.nipples !== "cute") {
+			names.push("Pointy", "Titclit");
+			suffixes.push("Nipples");
+		}
+		if (slave.visualAge > 35) {
+			names.push("Mature");
+			suffixes.push("Cougar", "MILF");
+		} else if (slave.visualAge < 25) {
+			names.push("Girly", "Thin", "Young");
+		}
+		if (isAmputee(slave)) {
+			names.push("Stumpy");
+			suffixes.push("Stumpy");
+		}
+		if (slave.boobsImplant > 1000 || slave.buttImplant > 3) {
+			names.push("Fake", "Plastic", "Silicone");
+		}
+		if (slave.dick > 5 && slave.balls > 5) {
+			names.push("Potent");
+			suffixes.push("Cannon", "Daddy");
+		}
+		if (slave.preg > slave.pregData.normalBirth / 1.33) {
+			if (slave.broodmother === 2) {
+				names.push("Bursting", "Seeded");
+				suffixes.push("Factory", "Nursery");
+			} else if (slave.broodmother === 1) {
+				names.push("Bloated", "Stuffed");
+				suffixes.push("Breeder", "Factory");
+			}
+		}
+		if (slave.bellyPreg >= 450000) {
+			names.push("Bulging", "Squirming");
+		}
+		if (slave.bellyPreg >= 5000) {
+			names.push("Preg");
+			suffixes.push("Belly", "Mommy");
+		}
+		if (slave.belly > 150000) {
+			suffixes.push("Balloon");
+		}
+		if (slave.belly > 1500) {
+			suffixes.push("Belly");
+		}
+		if (slave.dick > 0) {
+			if (slave.dick > 4) {
+				names.push("Dangle", "Hung");
+				suffixes.push("Cock", "Dick");
+			}
+			if (slave.balls === 0) {
+				names.push("Cut", "Gelded", "Soft");
+			} else {
+				names.push("Erect", "Hard", "Stiff");
+			}
+		}
+		if (slave.dick === 1) {
+			names.push("Micro", "Tiny");
+			suffixes.push("Bitch");
+		}
+		if (slave.height >= 185) {
+			names.push("Tall", "Top");
+			suffixes.push("Tower");
+		} else if (slave.height < 150) {
+			names.push("Stumpy", "Tiny");
+			suffixes.push("Shortstack", "Stumpy");
+		}
+		if (slave.skill.whoring > 95) {
+			names.push("Money", "Street");
+			suffixes.push("Whore");
+		}
+		if (slave.skill.entertainment > 95) {
+			names.push("Easy", "Club");
+			suffixes.push("Slut");
+		}
+		if (slave.skill.oral > 95) {
+			names.push("Suck");
+			suffixes.push("Throat");
+		}
+		if (slave.skill.vaginal > 95) {
+			suffixes.push("Channel", "Kegel", "Pussy");
+		}
+		if (slave.skill.anal > 95) {
+			suffixes.push("Asspussy", "Sphincter");
+		}
+		if (slave.intelligence + slave.intelligenceImplant > 50) {
+			names.push("Bright", "Clever", "Smart");
+			if (slave.intelligenceImplant >= 15) {
+				names.push("College", "Graduate", "Nerdy");
+			}
+		} else if (slave.intelligence + slave.intelligenceImplant < -50) {
+			names.push("Cretin", "Dumb", "Retarded", "Stupid");
+		}
+		if (slave.vagina === 1 && slave.skill.vaginal <= 10) {
+			names.push("Fresh", "New", "Tight");
+		}
+		if (slave.devotion < -75) {
+			names.push("Angry", "Biter", "Caged");
+		} else if (slave.devotion < -50) {
+			names.push("Cell", "Cuffs");
+		} else if (slave.devotion < -20) {
+			names.push("Bag", "Box");
+		} else if (slave.devotion <= 20) {
+			names.push("Sad", "Whiner");
+		} else if (slave.devotion > 50) {
+			names.push("Prize");
+			if (slave.visualAge > 35) {
+				names.push("Queen");
+			} else if (slave.visualAge < 25) {
+				names.push("Princess");
+			}
+		}
+		if (slave.trust < -50) {
+			names.push("Screaming");
+			suffixes.push("Sobber");
+		} else if (slave.trust < -20) {
+			names.push("Crying");
+			suffixes.push("Meat", "Tears", "Thing", "Weeper");
+		} else if (slave.trust < 20) {
+			names.push("Begging");
+		}
+
+		if (slave.dick === 0) {
+			if (slave.vagina === -1) {
+				suffixes.push("Null");
+			} else {
+				if (slave.visualAge < 25) {
+					suffixes.push("Girl");
+				}
+			}
+		} else {
+			if (slave.vagina !== -1) {
+				suffixes.push("Futa");
+			} else {
+				if (slave.balls > 0) {
+					if (slave.boobs > 300 && slave.butt > 2) {
+						/* SHEMALES: cock & balls, T&A above minimum */
+						suffixes.push("Shemale");
+					} else {
+						if (slave.shoulders < 1 && slave.muscles <= 30) {
+							if (slave.faceShape === "masculine" || slave.faceShape === "androgynous") {
+								/* SISSIES: feminine shoulders or muscles, masculine faces */
+								suffixes.push("Sissy");
+							} else {
+								/* TRAPS: feminine shoulders or muscles, feminine faces */
+								suffixes.push("Trap");
+							}
+						} else {
+							/* BITCHES: masculine shoulders or muscles */
+							suffixes.push("Bitch");
+						}
+					}
+				} else {
+					if (slave.visualAge > 35) {
+						suffixes.push("DickMILF");
+					} else if (slave.visualAge >= 25) {
+						suffixes.push("Dickslave");
+					} else {
+						suffixes.push("Dickgirl");
+					}
+				}
+			}
+		}
+		if (slave.anus > 0) {
+			suffixes.push("Anus", "Asshole", "Backdoor", "Butt", "Butthole");
+		}
+		if (slave.anus === 1) {
+			suffixes.push("Tightass", "Tightbutt");
+		}
+		if (slave.vagina > 0) {
+			suffixes.push("Cunt", "Pussy", "Vagina");
+		}
+		if (slave.boobs < 500 && slave.butt < 3 && slave.dick > 0) {
+			suffixes.push("Bitch", "Bottom", "Sissy", "Trap");
+		}
+		if (slave.energy > 95) {
+			suffixes.push("Fuck", "Fuckaddict", "Nympho", "Sexaddict");
+		}
+		if (slave.fetishKnown === 1) {
+			if (slave.fetish === "humiliation") {
+				suffixes.push("Rapebait", "Showgirl");
+			}
+			if (slave.fetish === "submissive") {
+				suffixes.push("Bottom", "Fuckee", "Rapebait");
+			}
+			if (slave.fetish === "dom") {
+				suffixes.push("Dom", "Fucker", "Top");
+			}
+			if (slave.fetish === "pregnancy") {
+				suffixes.push("Breeder", "Mommy");
+			}
+			if (slave.fetish === "boobs") {
+				suffixes.push("Boob", "Boobie", "Tit", "Titty");
+			}
+		}
+		if (slave.counter.births >= 2) {
+			suffixes.push("Breeder");
+			if (slave.counter.births >= 5) {
+				suffixes.push("Broodmother");
+			}
+		}
+		if (slave.areolae > 2) {
+			suffixes.push("Areolas", "Headlights");
+		}
+		if (slave.lips > 40) {
+			suffixes.push("Lips", "Pillows");
+		}
+		if (slave.labia > 1) {
+			suffixes.push("Curtains", "Flower", "Lips");
+		}
+		if (slave.breedingMark === 1 && V.propOutcome === 1 && V.arcologies[0].FSRestart !== "unset") {
+			suffixes.push("Breeder", "Oven", "Womb");
+		}
+		if (slave.butt > 5) {
+			suffixes.push("Ass", "Bottom", "Butt");
+		}
+		if (slave.vagina === 0) {
+			suffixes.push("Virgin");
+		}
+
+		slave.slaveName = jsEither(names);
+	}
+	if (leadershipPosition.includes(slave.assignment)) {
+		switch (slave.assignment) {
+			case Job.ATTENDANT:
+				slave.slaveName = jsEither(["Bath", "Spa"]);
+				break;
+			case Job.MATRON:
+				slave.slaveName = jsEither(["Matron", "Nursery"]);
+				break;
+			case Job.STEWARD:
+				slave.slaveName = jsEither(["Maid", "Servant"]);
+				break;
+			case Job.MILKMAID:
+				if (V.cumSlaves > 3) {
+					slave.slaveName = jsEither(["Fucker", "Milker"]);
+				} else {
+					slave.slaveName = jsEither(["Dairy", "Farm"]);
+				}
+				break;
+			case Job.FARMER:
+				slave.slaveName = jsEither(["Farmer", "Farmhand"]);
+				break;
+			case Job.DJ:
+				slave.slaveName = jsEither(["Bass", "Booth"]);
+				break;
+			case Job.CONCUBINE:
+				slave.slaveName = jsEither(["Bed", "Master"]);
+				break;
+			case Job.MADAM:
+				slave.slaveName = jsEither(["Madam", "Pimp"]);
+				break;
+			case Job.TEACHER:
+				slave.slaveName = jsEither(["Classroom", "Teacher"]);
+				break;
+			case Job.WARDEN:
+				slave.slaveName = jsEither(["Jail", "Prison"]);
+				break;
+			case Job.NURSE:
+				slave.slaveName = jsEither(["Clinic", "Nurse"]);
+				break;
+			case Job.HEADGIRL:
+				slave.slaveName = jsEither(["Chief", "Head"]);
+				break;
+			case Job.BODYGUARD:
+				slave.slaveName = jsEither(["Battle", "Guard"]);
+				break;
+			case Job.RECRUITER:
+				slave.slaveName = jsEither(["Cam", "Recruiter"]);
+				break;
+		}
+	}
+	const surname = jsEither(suffixes);
+	if (typeof surname === "string" && surname.toLowerCase() === slave.slaveName.toLowerCase()) {
+		DegradingName(slave);
+	}
+	slave.slaveName = capFirstChar(slave.slaveName);
+	slave.slaveSurname = surname;
+};
+
+globalThis.PaternalistName = function(slave) {
+	if (slave.slaveName.search("Miss") === -1) {
+		if (slave.slaveName.search("Ms.") === -1) {
+			if (slave.slaveName.search("Mrs.") === -1) {
+				if (slave.relationship > 4) {
+					slave.slaveName = ("Mrs. " + slave.slaveName);
+				} else if (slave.actualAge > 24) {
+					slave.slaveName = ("Ms. " + slave.slaveName);
+				} else {
+					slave.slaveName = ("Miss " + slave.slaveName);
+				}
+			}
+		}
+	}
+};
+
+globalThis.parentNames = function(parent, child) {
+	const slaves = V.slaves;
+
+	let currentSlaveNames = slaves.map(s => s.slaveName);
+	let continentNationality;
+	const useMaleName = (child.genes === "XY" && V.allowMaleSlaveNames === true);
+
+	child.slaveName = generateName(parent.nationality, child.race, useMaleName, sn => !currentSlaveNames.includes(sn));
+
+	if (!child.slaveName) {
+		for (let i = 0; i < 10; i++) {
+			continentNationality = hashChoice(V.nationalities);
+			child.slaveName = generateName(continentNationality, child.race, useMaleName, sn => !currentSlaveNames.includes(sn));	// jshint ignore: line
+		}
+	}
+	if (!child.slaveName) {
+		child.slaveName = generateName(parent.nationality, child.race, useMaleName);
+	}
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {number} amount
+ * @returns {string}
+ */
+globalThis.faceIncrease = function(slave, amount) {
+	const pronouns = getPronouns(slave);
+	const his = pronouns.possessive;
+	const His = capFirstChar(his);
+	let r = "";
+	if (slave.face <= -95) {
+		r += `<span class="green">${His} face is no longer horrifying,</span> and is now merely ugly.`;
+	} else if (slave.face <= -40 && slave.face + amount > -40) {
+		r += `<span class="green">${His} face is no longer ugly,</span> and is now merely unattractive.`;
+	} else if (slave.face <= -10 && slave.face + amount > -10) {
+		r += `<span class="green">${His} face is no longer unattractive,</span> and is now somewhat tolerable.`;
+	} else if (slave.face <= 10 && slave.face + amount > 10) {
+		r += `<span class="green">${His} face is now decently attractive,</span> rather than merely tolerable.`;
+	} else if (slave.face <= 40 && slave.face + amount > 40) {
+		r += `<span class="green">${His} face is now quite beautiful,</span> rather than merely pretty.`;
+	} else if (slave.face <= 95 && slave.face + amount > 95) {
+		r += `<span class="green">${His} face is now perfect.</span> It's difficult to imagine how it could be any more beautiful.`;
+	}
+	slave.face = Math.clamp(slave.face + amount, -100, 100);
+	if (slave.face > 95) {
+		slave.face = 100;
+	}
+	return r;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+globalThis.deadliness = function(slave) {
+	let deadliness = 2;
+
+	if (slave.skill.combat > 0) {
+		deadliness += 2;
+	}
+
+	if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
+		deadliness += 1;
+	} else if (slave.skill.bodyguard >= V.masteredXP) {
+		deadliness += 1;
+	}
+
+	if (V.AgePenalty !== 0) {
+		if (slave.physicalAge >= 100) {
+			deadliness -= 10;
+		} else if (slave.physicalAge >= 85) {
+			deadliness -= 3;
+		} else if (slave.physicalAge >= 70) {
+			deadliness -= 1;
+		}
+	}
+
+	if (slave.muscles > 30 && slave.muscles <= 95) {
+		deadliness += 1;
+	} else if (slave.muscles > 95 && slave.height >= 185) {
+		deadliness += 2;
+	} else if (slave.muscles > 95) {
+		deadliness -= 1;
+	} else if (slave.muscles < -95) {
+		deadliness -= 20;
+	} else if (slave.muscles < -30) {
+		deadliness -= 7;
+	} else if (slave.muscles < -5) {
+		deadliness -= 3;
+	}
+
+	if (slave.height >= 170) {
+		deadliness += 1;
+	}
+
+	if (slave.health.condition > 50) {
+		deadliness += 1;
+	} else if (slave.health.condition < -50) {
+		deadliness -= 1;
+	}
+
+	if (slave.health.illness > 3) {
+		deadliness -= 3;
+	} else if (slave.health.illness > 1) {
+		deadliness -= 2;
+	} else if (slave.health.illness > 0) {
+		deadliness -= 1;
+	}
+
+	if (slave.boobs > 4000) {
+		deadliness -= 2;
+	} else if (slave.boobs > 2000) {
+		deadliness -= 1;
+	}
+
+	if (slave.butt > 6) {
+		deadliness -= 1;
+	}
+
+	if (slave.hips > 2) {
+		deadliness -= 1;
+	}
+
+	if (slave.weight > 190) {
+		deadliness -= 20;
+	} else if (slave.weight > 160) {
+		deadliness -= 10;
+	} else if (slave.weight > 130) {
+		deadliness -= 3;
+	} else if (slave.weight > 30 || slave.weight < -10) {
+		deadliness -= 1;
+	}
+
+	if (slave.bellyFluid >= 10000) {
+		deadliness -= 3;
+	} else if (slave.bellyFluid >= 5000) {
+		deadliness -= 2;
+	} else if (slave.bellyFluid >= 2000) {
+		deadliness -= 1;
+	}
+
+	if (slave.pregKnown === 1 || slave.bellyPreg >= 1500 || slave.bellyImplant >= 1500) {
+		if (slave.belly >= 750000) {
+			deadliness -= 50;
+		} else if (slave.belly >= 600000) {
+			deadliness -= 25;
+		} else if (slave.belly >= 450000) {
+			deadliness -= 15;
+		} else if (slave.belly >= 300000) {
+			deadliness -= 10;
+		} else if (slave.belly >= 150000) {
+			deadliness -= 8;
+		} else if (slave.belly >= 100000) {
+			deadliness -= 7;
+		} else if (slave.belly >= 10000) {
+			deadliness -= 3;
+		} else if (slave.belly >= 5000) {
+			deadliness -= 2;
+		} else {
+			deadliness -= 1;
+		}
+	}
+
+	if (isInLabor(slave)) {
+		deadliness -= 15;
+	} else if (slave.preg >= slave.pregData.normalBirth && slave.pregControl !== "labor suppressors") {
+		deadliness -= 5;
+	}
+
+	if (slave.balls >= 15) {
+		deadliness -= 1;
+	}
+
+	if (slave.dick >= 10) {
+		deadliness -= 1;
+	}
+
+	deadliness -= getLimbCount(slave, 0) * 5;
+	deadliness -= getLimbCount(slave, 2) * 0.25;
+	deadliness -= getLimbCount(slave, 3) * 0.25;
+	deadliness -= getLimbCount(slave, 4) * 0.25;
+	deadliness += getLimbCount(slave, 5) * 1.25;
+	deadliness += getLimbCount(slave, 6) * 2.5;
+	if (hasBothLegs(slave) && !canStand(slave)) {
+		deadliness -= 20;
+	}
+
+	if (!canSee(slave)) {
+		deadliness -= 8;
+	} else if (!canSeePerfectly(slave)) {
+		deadliness -= 1;
+	}
+
+	if (!canHear(slave)) {
+		deadliness -= 4;
+	} else if ((slave.hears === -1 && slave.earwear !== "hearing aids") || (slave.hears === 0 && slave.earwear === "muffling ear plugs")) {
+		deadliness -= 1;
+	}
+
+	if (slave.tail === "combat") {
+		deadliness += 2;
+	}
+
+	if (slave.health.tired > 90) {
+		deadliness -= 10;
+	} else if (slave.health.tired > 60) {
+		deadliness -= 3;
+	} else if (slave.health.tired > 30) {
+		deadliness -= 1;
+	}
+
+	return Math.max(deadliness, 1);
+};
+
+/** Is the slave ready to retire?
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+globalThis.retirementReady = function(slave) {
+	// indentured slaves don't retire, they expire
+	if (slave.indenture >= 0) {
+		return false;
+	}
+
+	// retirement by age
+	if (V.policies.retirement.physicalAgePolicy === 0 && slave.actualAge >= V.retirementAge) {
+		return true;
+	} else if (V.policies.retirement.physicalAgePolicy === 1 && slave.physicalAge >= V.retirementAge) {
+		return true;
+	}
+
+	// retirement by milestone
+	if (V.policies.retirement.sex > 0 && (slave.counter.oral + slave.counter.anal + slave.counter.vaginal + slave.counter.penetrative + slave.counter.mammary) > V.policies.retirement.sex) {
+		return true;
+	}
+	if (V.policies.retirement.milk > 0 && slave.counter.milk > V.policies.retirement.milk) {
+		return true;
+	}
+	if (V.policies.retirement.cum > 0 && slave.counter.cum > V.policies.retirement.cum) {
+		return true;
+	}
+	if (V.policies.retirement.births > 0 && slave.counter.births > V.policies.retirement.births) {
+		return true;
+	}
+	if (V.policies.retirement.kills > 0 && slave.counter.pitKills > V.policies.retirement.kills) {
+		return true;
+	}
+
+	// no retirement for you
+	return false;
+};
+
+/** marks some weeks of time passage for a slave, counting birthdays and invoking aging if game settings require it
+ * @param {App.Entity.SlaveState} slave
+ * @param {number} [weeks=1]
+ */
+globalThis.ageSlaveWeeks = function(slave, weeks = 1) {
+	if (V.seeAge !== 0) { // birthdays enabled
+		for (let i = 0; i < weeks; ++i) {
+			slave.birthWeek++;
+			if (slave.birthWeek >= 52) {
+				slave.birthWeek = 0;
+				if (V.seeAge === 1) { // actual aging enabled
+					ageSlave(slave);
+				}
+			}
+		}
+	}
+};
+
+/** advances the age of a slave by one year, incurring all aging side effects
+ * @param {App.Entity.SlaveState} slave
+ * @param {boolean} [forceDevelopment=false]
+ */
+globalThis.ageSlave = function(slave, forceDevelopment = false) {
+	slave.physicalAge++;
+	slave.actualAge++;
+	if (slave.geneMods.NCS === 1 || (slave.geneticQuirks.neoteny >= 2 && slave.geneticQuirks.progeria !== 2)) {
+		/* Induced NCS completely takes over visual aging. Additionally, because of the neoteny aspects of NCS, ovaries don't age quite as fast. */
+		/* Unsurprisingly, actual neoteny has the same effect as long as progeria isn't in play. */
+		slave.ovaryAge += either(0.5, 0.6, 0.7, 0.7, 0.8, 0.9, 1.0);
+	} else {
+		slave.visualAge++;
+		slave.ovaryAge += either(0.8, 0.9, 0.9, 1.0, 1.0, 1.0, 1.1);
+	}
+	if (slave.broodmother === 1) {
+		slave.ovaryAge += 0.2;
+	}
+	if (slave.physicalAge <= 18 && (forceDevelopment || V.loliGrow > 0)) {
+		physicalDevelopment(slave);
+	}
+};
+
+/** Is the slave a shelter slave?
+ * @param {App.Entity.SlaveState} slave
+ * @returns {boolean}
+ */
+globalThis.isShelterSlave = function(slave) {
+	return (typeof slave.origin === "string" && slave.origin.includes("Slave Shelter"));
+};
+
+/**
+ * Returns if a slave appears male, female, or androgynous.
+ *
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number}
+ */
+globalThis.perceivedGender = function(slave) {
+	return -1;
 };
\ No newline at end of file