diff --git a/slave variables documentation - Pregmod.txt b/slave variables documentation - Pregmod.txt
index a020f3f2c0d8b942f233f1ff4f59f3331f44b5e3..c51108d9c802290f6f89dbfa77e664869d615e67 100644
--- a/slave variables documentation - Pregmod.txt	
+++ b/slave variables documentation - Pregmod.txt	
@@ -795,7 +795,7 @@ slave's devotion
 
 oldDevotion:
 
-used to calculate trust loss/gain
+used to calculate devotion loss/gain
 set to devotion to start
 
 weight:
@@ -1585,11 +1585,13 @@ butt size
 
 buttImplant:
 
-butt implant type
+butt implant type and size
 0 - none
 1 - butt implant
 2 - big butt implant
 3 - fillable butt implants
+5 - 8  - advanced fillable implants
+9+ - hyper fillable implants
 
 buttImplantType:
 
@@ -2261,17 +2263,17 @@ lactationRules:
 
 standardPunishment:
 
-"Confinement"
-"Whipping"
-"Chastity"
-"Situational"
+"confinement"
+"whipping"
+"chastity"
+"situational"
 
 standardReward:
 
-"Relaxation"
-"Drugs"
-"Orgasm"
-"Situational"
+"relaxation"
+"drugs"
+"orgasm"
+"situational"
 
 useRulesAssistant:
 
diff --git a/src/endWeek/saChoosesOwnClothes.js b/src/endWeek/saChoosesOwnClothes.js
index c25cdec1ab1783c4f493e9591363f0cfc802970a..18d0119a6a942e9765632e785686ad8234a3e03a 100644
--- a/src/endWeek/saChoosesOwnClothes.js
+++ b/src/endWeek/saChoosesOwnClothes.js
@@ -13,6 +13,7 @@ window.saChoosesOwnClothes = (function() {
 	let He;
 	let His;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function saChoosesOwnClothes(slave) {
 		V = State.variables;
 		player = V.PC;
@@ -90,6 +91,7 @@ window.saChoosesOwnClothes = (function() {
 		return r;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function todaysOutfit(slave) {
 		let clothing = [];
 		let chosenClothing;
@@ -924,8 +926,9 @@ window.saChoosesOwnClothes = (function() {
 		}
 
 		return selection;
-	};
+	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function todaysShoes(slave) {
 		let shoes = [];
 
@@ -966,12 +969,13 @@ window.saChoosesOwnClothes = (function() {
 			}
 		}
 		return jsEither(shoes);
-	};
+	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function todaysCollar(slave) {
 		let neck = [];
 
-		if(slave.fetish == 'mindbroken') {
+		if(slave.fetish === 'mindbroken') {
 
 		} else if(slave.devotion <= 20) {
 
@@ -979,13 +983,13 @@ window.saChoosesOwnClothes = (function() {
 			if(V.arcologies[0].FSEgyptianRevivalist > 0) {
 				neck.push({text: `dons a wesekh to support your ancient Egyptian pretensions,`, collar: "ancient Egyptian"});
 			}
-			if(slave.fetish == "masochist") {
+			if(slave.fetish === "masochist") {
 				neck.push({text: `dons a tight steel collar around ${his} neck,`, collar: "tight steel"});
 				neck.push({text: `dons a painful leather collar,`, collar: "uncomfortable leather"});
 				neck.push({text: `dons a painfully tight neck corset,`, collar: "neck corset"});
-			} else if(slave.fetish == "pregnancy" && (canGetPregnant(slave) || slave.pregKnown == 1)) {
+			} else if(slave.fetish === "pregnancy" && (canGetPregnant(slave) || slave.pregKnown == 1)) {
 				neck.push({text: `dons a digital display that tells everything about ${his} womb,`, collar: "preg biometrics"});
-			} else if(slave.fetish == "boobs" && slave.boobs >= 1000) {
+			} else if(slave.fetish === "boobs" && slave.boobs >= 1000) {
 				neck.push({text: `dons a cowbell to draw attention to ${his} luscious udders,`, collar: "leather with cowbell"});
 			}
 			neck.push({text: `decides ${his} neck needs no accenting,`, collar: "none"});
@@ -994,13 +998,14 @@ window.saChoosesOwnClothes = (function() {
 			neck.push({text: `dons a simple silk ribbon around ${his} neck,`, collar: "silk ribbon"});
 		}
 		return jsEither(neck);
-	};
+	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function todaysCorset(slave) {
 		let belly = [];
 		const empathyBellies = ["a small empathy belly", "a medium empathy belly", "a large empathy belly", "a huge empathy belly"];
 
-		if(slave.fetish == 'mindbroken') {
+		if(slave.fetish === 'mindbroken') {
 			if(V.arcologies[0].FSRepopulationFocus > 0 && slave.belly < 1500) {
 				if(slave.weight > 130) {
 					belly.push({text: `${He} notices the fake bellies; since every girl ${he} has ever met has a rounded middle, it's only natural ${he} is compelled to wear one. ${He} struggles to fit it around ${his} huge gut, only stopping when another slave takes it away from ${him} so ${he} moves on and stops blocking the wardrobe with ${his} fat ass.`, bellyAccessory: "none"});
@@ -1050,4 +1055,4 @@ window.saChoosesOwnClothes = (function() {
 
 	return saChoosesOwnClothes;
 
-})();
\ No newline at end of file
+})();
diff --git a/src/endWeek/saPorn.js b/src/endWeek/saPorn.js
index 99cab8b193e15d1220139c1e26b560e2e0c623c1..4e24b16a148ee7859679f1c2c81a375d5b06b4e4 100644
--- a/src/endWeek/saPorn.js
+++ b/src/endWeek/saPorn.js
@@ -1,6 +1,6 @@
 /* to later be rolled into saPorn */
 
-window.getHighestPorn = function(slave) {
+window.getHighestPorn = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 
 	var max = {value: 0, type: "none"};
 
diff --git a/src/endWeek/saRest.js b/src/endWeek/saRest.js
index f5688294be8c0470bc423f4da3c538b5404ae0ef..88155b8e6b420f3d14b8f373e6a24a2eba798625 100644
--- a/src/endWeek/saRest.js
+++ b/src/endWeek/saRest.js
@@ -1,4 +1,4 @@
-window.saRest = function saRest(slave) {
+window.saRest = /** @param {App.Entity.SlaveState} slave */ function saRest(slave) {
 
 	var pronouns = getPronouns(slave);
 	var he = pronouns.pronoun, him = pronouns.object, his = pronouns.possessive, hers = pronouns.possessivePronoun, himself = pronouns.objectReflexive, boy = pronouns.noun;
diff --git a/src/endWeek/saServant.js b/src/endWeek/saServant.js
index 7de4c4983135bc0456ebadd8e1bde270d04d834f..bedd05212833e868a79df2c1a3c6c11d16e513e5 100644
--- a/src/endWeek/saServant.js
+++ b/src/endWeek/saServant.js
@@ -1,4 +1,4 @@
-window.saServant = function saServant(slave) {
+window.saServant = /** @param {App.Entity.SlaveState} slave */ function saServant(slave) {
 
 	var pronouns = getPronouns(slave);
 	var he = pronouns.pronoun, him = pronouns.object, his = pronouns.possessive, hers = pronouns.possessivePronoun, himself = pronouns.objectReflexive, boy = pronouns.noun;
diff --git a/src/endWeek/saStayConfined.js b/src/endWeek/saStayConfined.js
index 6ccc3d087fa9de453002fc32ccff0830c78c3cd7..4d494b2e836a365b912c83a95151bf8a8ca0310f 100644
--- a/src/endWeek/saStayConfined.js
+++ b/src/endWeek/saStayConfined.js
@@ -1,4 +1,4 @@
-window.saStayConfined = function saStayConfined(slave) {
+window.saStayConfined = /** @param {App.Entity.SlaveState} slave */ function saStayConfined(slave) {
 
 	var pronouns = getPronouns(slave);
 	var he = pronouns.pronoun, him = pronouns.object, his = pronouns.possessive, hers = pronouns.possessivePronoun, himself = pronouns.objectReflexive, boy = pronouns.noun;
diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js
index 5a88854bce35a4ac08b86ff9733a430d651ee1c1..a55c854f33f1a2e8f7ba880b21286480c32b1872 100644
--- a/src/js/DefaultRules.js
+++ b/src/js/DefaultRules.js
@@ -5,6 +5,7 @@ window.DefaultRules = (function() {
 	let V;
 	let r;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function DefaultRules(slave) {
 		if (slave.useRulesAssistant === 0) return r; //exempted
 
@@ -62,6 +63,7 @@ window.DefaultRules = (function() {
 		return r;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function MergeRules(slave) {
 		// merge all rules applying on a slave into one big rule
 		const rules = V.defaultRules.filter(x => ruleAppliesP(x.condition, slave));
@@ -69,6 +71,7 @@ window.DefaultRules = (function() {
 		return mergeRules(rules.map(x => ProcessAssignments(slave, Object.assign({}, x.set))));
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAssignments(slave, rule) {
 		// Before merging rules, we process assignments for each rule separately so we can remove slaves from facilities when they no longer qualify, even if the final "winning" rule assigns them elsewhere
 		// We also ignore inapplicable assignments for the current slave, so we only merge assignments that are valid
@@ -279,6 +282,7 @@ window.DefaultRules = (function() {
 		return rule;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function AssignJobToSlave(slave, rule) {
 		// place slave on assignment defined by the rule
 		if ((rule.setAssignment !== undefined && rule.setAssignment !== "no default setting")) {
@@ -335,6 +339,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessClothing(slave, rule) {
 		// apply clothes to slave
 		if ((rule.clothes !== undefined) && (rule.clothes !== "no default setting")) {
@@ -352,6 +357,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessCollar(slave, rule) {
 		// apply collar to slave
 		if ((rule.collar !== undefined) && (rule.collar !== "no default setting")) {
@@ -377,6 +383,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessEyewear(slave, rule) {
 		// apply glasses, contacts to slave
 		if ((rule.eyewear !== undefined) && (rule.eyewear !== "no default setting")) {
@@ -467,6 +474,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessEarwear(slave, rule) {
 		// apply earplugs to slave
 		if ((rule.earwear !== undefined) && (rule.earwear !== "no default setting")) {
@@ -526,6 +534,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessDildos(slave, rule) {
 		// apply vaginal dildos to slave
 		if (slave.vagina === 0)
@@ -536,6 +545,7 @@ window.DefaultRules = (function() {
 			ProcessNonVirginDildos(slave, rule);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessVVirginDildos(slave, rule) {
 		// apply vaginal dildos to varginal virgins
 		if ((rule.virginAccessory !== undefined) && (rule.virginAccessory !== "no default setting")) {
@@ -593,6 +603,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAVirginDildos(slave, rule) {
 		// apply vaginal dildos to anal virgins
 		if ((rule.aVirginAccessory !== undefined) && (rule.aVirginAccessory !== "no default setting")) {
@@ -650,6 +661,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessNonVirginDildos(slave, rule) {
 		// apply vaginal dildos to non-virgins
 		if ((rule.vaginalAccessory !== undefined) && (rule.vaginalAccessory !== "no default setting")) {
@@ -706,6 +718,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessDickAccessories(slave, rule) {
 		// apply dick accessories to slave
 		if ((slave.dick > 0)) {
@@ -733,6 +746,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessShoes(slave, rule) {
 		// apply shoes to slave
 		if ((rule.shoes !== undefined) && (rule.shoes !== "no default setting")) {
@@ -745,6 +759,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessBellyAccessories(slave, rule) {
 		// apply belly accessories to slave
 		if ((rule.bellyAccessory !== undefined) && (rule.bellyAccessory !== "no default setting")) {
@@ -763,6 +778,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessLegAccessory(slave, rule) {
 		if (rule.legAccessory !== undefined && rule.legAccessory !== "no default setting" && slave.amp !== 1 && slave.legAccessory !== rule.legAccessory) {
 			slave.legAccessory = rule.legAccessory;
@@ -770,6 +786,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAnalAccessories(slave, rule) {
 		// apply buttplugs and buttplug accessories to slave
 		if ((slave.vaginalAccessory !== "anal chastity") && (slave.vaginalAccessory !== "combined chastity") && (slave.dickAccessory !== "anal chastity") && (slave.dickAccessory !== "combined chastity")) {
@@ -781,6 +798,7 @@ window.DefaultRules = (function() {
 		ProcessButtplugAttachments(slave, rule);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAnalVirginButtplugs(slave, rule) {
 		// apply buttplugs to virgins
 		if ((rule.aVirginButtplug !== undefined) && (rule.aVirginButtplug !== "no default setting")) {
@@ -838,6 +856,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessNonVirginButtplugs(slave, rule) {
 		// apply buttplugs to non-virgins
 		if ((rule.buttplug !== undefined) && (rule.buttplug !== "no default setting")) {
@@ -895,6 +914,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessButtplugAttachments(slave, rule) {
 		// apply buttplug accessories to slaves
 		if (slave.buttplug === "none" && slave.buttplugAttachment !== "none") {
@@ -916,6 +936,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessBellyImplant(slave, rule) {
 		// Here is belly implant size control, it's used in Surgery Degradation passage to setup devotion and trust changes.
 		// silent calls to surgery degradation have been replaced with a js function, which is less hacky
@@ -948,6 +969,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function BellySurgery(slave, volume) {
 		// this is a port of the belly implant portion of surgeryDegradation.tw
 		// that way, we don't have to use ugly hacks
@@ -989,6 +1011,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessContraceptives(slave, rule) {
 		if ((rule.preg !== undefined) && (rule.preg !== "no default setting")) {
 			if (rule.preg === true && slave.preg === 0) {
@@ -1001,6 +1024,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAssetGrowthDrugs(slave, rule) {
 		// Asset Growth
 		const growth_drugs = new Set(["breast injections", "breast redistributors", "butt injections", "butt redistributors", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper testicle enhancement", "intensive breast injections", "intensive butt injections", "intensive penis enhancement", "intensive testicle enhancement", "lip atrophiers", "lip injections", "penis atrophiers", "penis enhancement", "testicle atrophiers", "testicle enhancement"]);
@@ -1207,6 +1231,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessOtherDrugs(slave, rule) {
 		// Other Drugs
 		if (slave.indentureRestrictions < 2 && rule.drug !== "no default setting" && slave.drugs !== rule.drug) {
@@ -1360,6 +1385,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessEnema(slave, rule) {
 		if ((rule.inflationType !== undefined) && (rule.inflationType !== "no default setting")) {
 			if (slave.inflationType !== rule.inflationType) {
@@ -1400,6 +1426,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessDiet(slave, rule) {
 		// Diet Setting
 		if (rule.diet !== undefined && rule.diet !== "no default setting") {
@@ -1578,6 +1605,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessCuratives(slave, rule) {
 		if ((rule.curatives !== undefined) && (rule.curatives !== "no default setting")) {
 			if (slave.curatives !== rule.curatives) {
@@ -1599,6 +1627,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessAphrodisiacs(slave, rule) {
 		if ((rule.aphrodisiacs !== undefined) && (rule.aphrodisiacs !== "no default setting")) {
 			if (slave.aphrodisiacs !== rule.aphrodisiacs) {
@@ -1608,6 +1637,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessPenisHormones(slave, rule) {
 		if ((slave.dick > 0)) {
 			if ((slave.balls === 0)) {
@@ -1646,6 +1676,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessFemaleHormones(slave, rule) {
 		if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== "no default setting")) {
 			if ((slave.hormones !== rule.XX)) {
@@ -1661,6 +1692,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessPregnancyDrugs(slave, rule) {
 		if (slave.pregKnown === 1 && rule.pregSpeed !== "no default setting" && (slave.breedingMark !== 1 || V.propOutcome === 0) && slave.indentureRestrictions < 1 && slave.broodmother === 0) {
 			if (rule.pregSpeed === "slow" && slave.preg < slave.pregData.minLiveBirth) {
@@ -1687,6 +1719,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessLivingStandard(slave, rule) {
 		if ((rule.livingRules !== undefined) && (rule.livingRules !== "no default setting")) {
 			if (setup.facilityCareers.includes(slave.assignment)) {
@@ -1719,6 +1752,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessSpeech(slave, rule) {
 		if ((rule.speechRules !== undefined) && (rule.speechRules !== "no default setting")) {
 			if (slave.fetish === "mindbroken") {
@@ -1749,6 +1783,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessRelationship(slave, rule) {
 		if ((slave.fetish !== "mindbroken")) {
 			if ((rule.relationshipRules !== undefined) && (rule.relationshipRules !== "no default setting")) {
@@ -1760,6 +1795,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessRelease(slave, rule) {
 		if ((rule.releaseRules !== undefined) && (rule.releaseRules !== "no default setting")) {
 			let _release = 0;
@@ -1781,6 +1817,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessPunishment(slave, rule) {
 		if ((rule.standardPunishment !== undefined) && (rule.standardPunishment !== "no default setting")) {
 			if ((slave.standardPunishment !== rule.standardPunishment)) {
@@ -1790,6 +1827,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessReward(slave, rule) {
 		if ((rule.standardReward !== undefined) && (rule.standardReward !== "no default setting")) {
 			if ((slave.standardReward !== rule.standardReward)) {
@@ -1799,6 +1837,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessToyHole(slave, rule) {
 		if ((rule.toyHole !== undefined) && (rule.toyHole !== "no default setting")) {
 			if (rule.toyHole === "pussy") {
@@ -1832,6 +1871,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessDietCum(slave, rule) {
 		if ((rule.dietCum !== undefined) && (rule.dietCum !== "no default setting")) {
 			if (slave.dietCum !== rule.dietCum) {
@@ -1848,6 +1888,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessDietMilk(slave, rule) {
 		if ((rule.dietMilk !== undefined) && (rule.dietMilk !== "no default setting")) {
 			if (slave.dietMilk !== rule.dietMilk) {
@@ -1864,6 +1905,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessSolidFood(slave, rule) {
 		if ((rule.onDiet !== undefined) && (rule.onDiet !== "no default setting")) {
 			if ((slave.onDiet !== rule.onDiet)) {
@@ -1876,6 +1918,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessTeeth(slave, rule) {
 		if ((rule.teeth !== undefined) && (rule.teeth !== "no default setting")) {
 			if ((rule.teeth === "universal")) {
@@ -1917,6 +1960,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessStyle(slave, rule) {
 		if (rule.eyeColor !== undefined && (rule.eyeColor !== "no default setting")) {
 			if ((slave.eyeColor !== rule.eyeColor)) {
@@ -2290,6 +2334,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessSmartPiercings(slave, rule) {
 		if ((slave.clitPiercing === 3)) {
 			let _used = 0;
@@ -2356,6 +2401,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessTattoos(slave, rule) {
 		if (rule.boobsTat !== undefined && (rule.boobsTat !== "no default setting")) {
 			if ((slave.boobsTat !== rule.boobsTat)) {
@@ -2461,6 +2507,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessPornFeedEnabled(slave, rule) {
 		if (rule.pornFeed === undefined || rule.pornFeed === "no default setting") {
 			return;
@@ -2485,6 +2532,7 @@ window.DefaultRules = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessLabel(slave, rule) {
 		if (rule.label !== "no default setting" && !slave.customLabel.includes("["+rule.label+"]")) {
 			slave.customLabel = slave.customLabel + "[" + rule.label + "]";
diff --git a/src/js/SetBellySize.js b/src/js/SetBellySize.js
index cc164d372eaac91885b57e1079896b982eaf171d..546c270af5145523a820bb47ad2d5e9b5a244d51 100644
--- a/src/js/SetBellySize.js
+++ b/src/js/SetBellySize.js
@@ -1,3 +1,4 @@
+/** @param {App.Entity.SlaveState} slave */
 window.SetBellySize = function SetBellySize(slave) {
 
 	let _implantSize;
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
new file mode 100644
index 0000000000000000000000000000000000000000..1edddbae266619fe45cbefdfb98e7ebb4a81912e
--- /dev/null
+++ b/src/js/SlaveState.js
@@ -0,0 +1,2194 @@
+/**
+ * Encapsulates the full description of a slave state. Serializable by the SugarCube state
+ * management.
+ */
+App.Entity.SlaveState = class SlaveState {
+
+	constructor() {
+		/** Slave's current name */
+		this.slaveName = "blank";
+		/** Slave's current surname */
+		this.slaveSurname = 0;
+		/** slave's original name */
+		this.birthName = "blank";
+		/** slave's original surname
+		 * @type {string|number} */
+		this.birthSurname = 0;
+		/** slave sex ("XX", "XY") */
+		this.genes = "XX";
+		this.pronoun = "she";
+		this.possessive = "her";
+		this.possessivePronoun = "hers";
+		this.objectReflexive = "herself";
+		this.object = "her";
+		this.noun = "girl";
+		/** game week slave was acquired.
+		 *
+		 * _0: Obtained prior to game start / at game start_ */
+		this.weekAcquired = 0;
+		/** slave's origin
+		 * @type {string|number} */
+		this.origin = 0;
+		/** career prior to enslavement
+		 * @type {string|number} */
+		this.career = 0;
+		/** slave's ID */
+		this.ID = 0;
+		/** slave's prestige */
+		this.prestige = 0;
+		/** is the studio outputting porn of her?
+		 * 0: no; 1: yes */
+		this.pornFeed = 0;
+		/** how famous her porn is? */
+		this.pornFame = 0;
+		/** how much money is being spent on promoting her porn */
+		this.pornFameSpending = 0;
+		/**
+		 * how famous she is in porn
+		 * * 0: not
+		 * * 1: some
+		 * * 2: recognized
+		 * * 3: world renowned
+		 */
+		this.pornPrestige = 0;
+		/** description to go with @see pornPrestige
+		 * @type {string|number} */
+		this.pornPrestigeDesc = 0;
+		/** what porn she is known for */
+		this.pornFameType = "none";
+		/** what aspect of her the upgraded studio is focusing on for porn */
+		this.pornFocus = "none";
+		/** generic porn fame */
+		this.pornTypeGeneral = 0;
+		/** fuckdoll porn fame */
+		this.pornTypeFuckdoll = 0;
+		/** rape porn fame */
+		this.pornTypeRape = 0;
+		/** preggo porn fame */
+		this.pornTypePreggo = 0;
+		/** BBW porn fame */
+		this.pornTypeBBW = 0;
+		/** weight gain porn fame */
+		this.pornTypeGainer = 0;
+		/** well hung porn fame */
+		this.pornTypeStud = 0;
+		/** underage porn fame */
+		this.pornTypeLoli = 0;
+		/** gagfuck queen porn fame */
+		this.pornTypeDeepThroat = 0;
+		/** strugglefuck queen porn fame */
+		this.pornTypeStruggleFuck = 0;
+		/** painal queen porn fame */
+		this.pornTypePainal = 0;
+		/** tease porn fame */
+		this.pornTypeTease = 0;
+		/** romantic porn fame */
+		this.pornTypeRomantic = 0;
+		/** pervert porn fame */
+		this.pornTypePervert = 0;
+		/** caring porn fame */
+		this.pornTypeCaring = 0;
+		/** unflinching porn fame */
+		this.pornTypeUnflinching = 0;
+		/** size queen porn fame */
+		this.pornTypeSizeQueen = 0;
+		/** neglectful porn fame */
+		this.pornTypeNeglectful = 0;
+		/** cum addict porn fame */
+		this.pornTypeCumAddict = 0;
+		/** anal addict porn fame */
+		this.pornTypeAnalAddict = 0;
+		/** attention whore porn fame */
+		this.pornTypeAttentionWhore = 0;
+		/** breast growth porn fame */
+		this.pornTypeBreastGrowth = 0;
+		/** abusive porn fame */
+		this.pornTypeAbusive = 0;
+		/** malicious porn fame */
+		this.pornTypeMalicious = 0;
+		/** self hating porn fame */
+		this.pornTypeSelfHating = 0;
+		/** breeder porn fame */
+		this.pornTypeBreeder = 0;
+		/** submissive porn fame */
+		this.pornTypeSub = 0;
+		/** cumslut porn fame */
+		this.pornTypeCumSlut = 0;
+		/** buttslut porn fame */
+		this.pornTypeAnal = 0;
+		/** humiliation porn fame */
+		this.pornTypeHumiliation = 0;
+		/** boob porn fame */
+		this.pornTypeBoobs = 0;
+		/** dom porn fame */
+		this.pornTypeDom = 0;
+		/** sadist porn fame */
+		this.pornTypeSadist = 0;
+		/** masochist porn fame */
+		this.pornTypeMasochist = 0;
+		/** pregnancy porn fame*/
+		this.pornTypePregnancy = 0;
+		/** reason for prestige
+		 * @type {string|number} */
+		this.prestigeDesc = 0;
+		/** slave's relation to recruited slave? (used in some events)
+		 * @type {string|number} */
+		this.recruiter = 0;
+		/** relation to relationTarget
+		 * @type {string|number} */
+		this.relation = 0;
+		/** target of relation (ID) */
+		this.relationTarget = 0;
+		/**
+		 *  slave's relationship
+		 * * -3: married to you
+		 * * -2: emotionally bound to you
+		 * * -1: emotional slut
+		 * * 0: none
+		 * * 1: friends with relationshipTarget
+		 * * 2: best friends with relationshipTarget
+		 * * 3: friends with benefits with relationshipTarget
+		 * * 4: lover with relationshipTarget
+		 * * 5: relationshipTarget 's slave wife
+		*/
+		this.relationship = 0;
+		/** target of relationship (ID) */
+		this.relationshipTarget = 0;
+		/**
+		 * slave's rivalry
+		 * * 0: none
+		 * * 1: dislikes rivalryTarget
+		 * * 2: rival of rivalryTarget
+		 * * 3: bitterly hates rivalryTarget
+		 */
+		this.rivalry = 0;
+		/** target of rival (ID) */
+		this.rivalryTarget = 0;
+		/** slave will serve subTarget (ID) */
+		this.subTarget = 0;
+		this.father = 0;
+		this.mother = 0;
+		this.daughters = 0;
+		this.sisters = 0;
+		this.canRecruit = 0;
+		/**
+		 * can slave choose own assignment
+		 *
+		 * 0: no; 1: yes */
+		this.choosesOwnAssignment = 0;
+		/** slave's assignment */
+		this.assignment = "rest";
+		/** shows assignment in descriptions */
+		this.assignmentVisible = 1;
+		/** how many weeks a slave is sentenced to work a job */
+		this.sentence = 0;
+		/** how far along slave is with being trained (skills, flaws, quirks) */
+		this.training = 0;
+		/** which hole to focus on when serving you */
+		this.toyHole = "all her holes";
+		/**
+		 * How long her servitude will be.
+		 *
+		 * -1: not; 0+: number of weeks remaining */
+		this.indenture = -1;
+		/** 2: complete protection; 1: some protection; 0: no protection */
+		this.indentureRestrictions = 0;
+		/** week she was born (int between 0-51) */
+		this.birthWeek = random(0, 51);
+		/** How old she really is. */
+		this.actualAge = 18;
+		/** How old her body looks. */
+		this.visualAge = 18;
+		/** How old her body is. */
+		this.physicalAge = 18;
+		/** How old her ovaries are. (used to trick menopause) */
+		this.ovaryAge = 18;
+		/** has has facial surgery to reduce age. 0: no, 1: yes */
+		this.ageImplant = 0;
+		/**
+		 * slave's health
+		 * * -90 - : On the edge of death
+		 * * -90 - -51: Extremely unhealthy
+		 * * -50 - -21: Unhealthy
+		 * * -20 -  20: Healthy
+		 * * 21  -  50: Very healthy
+		 * * 50  -  90: Extremely healthy
+		 * * 90  -  : Unnaturally healthy
+		 */
+		this.health = 0;
+		/**
+		 * slave has a minor injury ("black eye", "bruise", "split lip")
+		 * @type {number | string}
+		 */
+		this.minorInjury = 0;
+		/**
+		 * slave 's trust.
+		 * * -96-: abjectly terrified
+		 * * -95 - -51: terrified
+		 * * -50 - -21: frightened
+		 * * -20 - 20: fearful
+		 * * 21 - 50: careful
+		 * * 51 - 95: trusting
+		 * * 96+: profoundly trusting
+		 */
+		this.trust = 0;
+		/** used to calculate trust loss/gain */
+		this.oldTrust = 0;
+		/**
+		 * slave 's devotion
+		 * * -96 - : hate-filled
+		 * * -95 - -51: hateful
+		 * * -50 - -21: reluctant
+		 * * -20 - 20: careful
+		 * * 21 - 50: accepting
+		 * * 51 - 95: devoted
+		 * * 96+: worshipful */
+		this.devotion = 0;
+		/** used to calculate devotion loss/gain */
+		this.oldDevotion = 0;
+		/**
+		 * slave 's weight
+		 * * 191+: dangerously obese
+		 * * 190 - 161: super obese
+		 * * 160 - 131: obese
+		 * * 130 - 96: fat
+		 * * 95 - 31: overweight
+		 * * 30 - 11: curvy
+		 * * 10 - -10: neither to fat nor to skinny
+		 * * -11 - -30: thin
+		 * * -31 - -95: very thin
+		 * * -96 - : emaciated
+		 */
+		this.weight = 0;
+		/**
+		 * slave 's muscles
+		 * * 96+ : extremely muscular
+		 * * 31 - 95: muscular
+		 * * 6 - 30: toned
+		 * * -5 - 5: none
+		 * * -30 - -6: weak
+		 * * -95 - -31: very weak
+		 * * -96- : frail
+		 */
+		this.muscles = 0;
+		/**
+		 * slave's height in cm
+		 * * < 150: petite
+		 * * 150 - 159: short
+		 * * 160 - 169: average
+		 * * 170 - 185: tall
+		 * * 186+ : very tall
+		 */
+		this.height = 170;
+		/** slave has height implant
+		 * -1: -10 cm, 0: none, 1: +10 cm */
+		this.heightImplant = 0;
+		/** slave's nationality */
+		this.nationality = "slave";
+		/** slave's race */
+		this.race = "white";
+		/** slave's original race */
+		this.origRace = "white";
+		/**
+		 * slave markings
+		 * * "beauty mark"
+		 * * "birthmark"
+		 * * "freckles"
+		 * * "heavily freckled"
+		 */
+		this.markings = "none";
+		/**
+		 * slave eyesight
+		 * * -3: empty (no descriptions)
+		 * * -2: blind
+		 * * -1: nearsighted
+		 * * 1: normal
+		 */
+		this.eyes = 1;
+		/** eye color */
+		this.eyeColor = "brown";
+		/** slave's original eye color, defaults to their initial eye color. */
+		this.origEye = "brown";
+		/** shape of slave pupils */
+		this.pupil = "circular";
+		/** color of slave sclerae */
+		this.sclerae = "white";
+		/** "none", "glasses", "blurring glasses", "corrective glasses", "blurring contacts", "corrective contacts" */
+		this.eyewear = "none";
+		/** slave hearing
+		 *
+		 * -2: deaf; -1: hard of hearing; 0: normal */
+		this.hears = 0;
+		/** "none", "hearing aids", "muffling ear plugs", "deafening ear plugs" */
+		this.earwear = "none";
+		/** is there an inner ear implant device
+		 * 0: no; 1: yes */
+		this.earImplant = 0;
+		/** */
+		this.earShape = "normal";
+		/** slave's original hair color, defaults to their initial hair color. */
+		this.origHColor = "brown";
+		/** hair color */
+		this.hColor = "brown";
+		/** pubic hair color */
+		this.pubicHColor = "brown";
+		/** armpit hair style */
+		this.underArmHColor = "brown";
+		/**  eyebrowHColor*/
+		this.eyebrowHColor = "brown";
+		/** Slave's original skin color. */
+		this.origSkin = "light";
+		/** skin color */
+		this.skin = "light";
+		/**
+		 * hair length
+		 * * 150: calf-length
+		 * * 149-100: ass-length
+		 * * 99-30: long
+		 * * 29-10: shoulder-length
+		 * * 9-0: short
+		 */
+		this.hLength = 60;
+		/**
+		 * eyebrow thickness
+		 * * "pencil-thin"
+		 * * "thin"
+		 * * "threaded"
+		 * * "natural"
+		 * * "tapered"
+		 * * "thick"
+		 * * "bushy"
+		 */
+		this.eyebrowFullness = "natural";
+		/** hair style */
+		this.hStyle = "short";
+		/** pubic hair style */
+		this.pubicHStyle = "neat";
+		/** armpit hair style */
+		this.underArmHStyle = "neat";
+		/** eyebrowHStyle */
+		this.eyebrowHStyle = "natural";
+		/**
+		 * slave waist
+		 * * 96+: masculine
+		 * * 95 - 41: ugly
+		 * * 40 - 11: unattractive
+		 * * 10 - -10: average
+		 * * -11 - -40: feminine
+		 * * -40 - -95: hourglass
+		 * * -96-: absurd
+		 */
+		this.waist = 0;
+		/** series of rings up the back that can be tied together. 0: no, 1: yes */
+		this.corsetPiercing = 0;
+		/**
+		 * What level of prosthetic interface she has installed
+		 * * 0: no interface
+		 * * 1: basic interface (used both in and out of cyberMod)
+		 * * 2: advanced interface (used only in cyberMod)
+		 */
+		this.PLimb = 0;
+		/**
+		 * is slave amputee
+		 * * -5: swiss army limbs
+		 * * -4: artificial limbs - Combat
+		 * * -3: artificial limbs - Beauty
+		 * * -2: artificial limbs - Sex
+		 * * -1: artificial limbs
+		 * * 0: no;
+		 * * 1: yes
+		 */
+		this.amp = 0;
+		/** are heels clipped
+		 *
+		 * 0: no, 1: yes */
+		this.heels = 0;
+		/** slave voice
+		 *
+		 * 0: mute, 1: deep, 2: feminine, 3: high, girly */
+		this.voice = 2;
+		/** has voice implant
+		 *
+		 * 0: no; 1: yes, high; -1: yes, low */
+		this.voiceImplant = 0;
+		/** has cybernetic voicebox
+		 *
+		 * 0: no; 1: yes */
+		this.electrolarynx = 0;
+		/**
+		 * slave accent
+		 * * 0: none
+		 * * 1: attractive
+		 * * 2: heavy
+		 * * 3: does not speak language
+		 */
+		this.accent = 0;
+		/**
+		 * shoulder width
+		 * * -2: very narrow
+		 * * -1: narrow
+		 * * 0: feminine
+		 * * 1: broad
+		 * * 2: very broad
+		 */
+		this.shoulders = 0;
+		/**
+		 * has shoulder implant
+		 *
+		 * * -1: shoulders -1
+		 * * 0: none
+		 * * 1: shoulders +1
+		 */
+		this.shouldersImplant = 0;
+		/**
+		 *  slave boob size (in cc)
+		 * * 0-299    - flat;
+		 * * 300-399   - A-cup;
+		 * * 400-499   - B-cup
+		 * * 500-649   - C-cup
+		 * * 650-799   - D-cup
+		 * * 800-999   - DD-cup
+		 * * 1000-1199 - F-cup
+		 * * 1200-1399 - G-cup
+		 * * 1400-1599 - H-cup
+		 * * 1600-1799 - I-cup
+		 * * 1800-2049 - J-cup
+		 * * 2050-2299 - K-cup
+		 * * 2300-2599 - L-cup
+		 * * 2600-2899 - M-cup
+		 * * 2900-3249 - N-cup
+		 * * 3250-3599 - O-cup
+		 * * 3600-3949 - P-cup
+		 * * 3950-4299 - Q-cup
+		 * * 4300-4699 - R-cup
+		 * * 4700-5099 - S-cup
+		 * * 5100-10499- massive
+		 */
+		this.boobs = 0;
+		/** breast engorgement from unmilked tits */
+		this.boobsMilk = 0;
+		/**
+		 *  slave implant size
+		 * * 0: no implants;
+		 * * 1-199: small implants;
+		 * * 200-399: normal implants;
+		 * * 400-599: large implants;
+		 * * 600+: boobsImplant size fillable implants
+		 */
+		this.boobsImplant = 0;
+		/** Implants type. 0: normal/none; 1: string */
+		this.boobsImplantType = 0;
+		/**
+		 * breast shape
+		 * * "normal"
+		 * * "perky"
+		 * * "saggy"
+		 * * "torpedo-shaped"
+		 * * "downward-facing"
+		 * * "wide-set"
+		 */
+		this.boobShape = "normal";
+		/**
+		 * nipple shape
+		 * * "huge"
+		 * * "puffy"
+		 * * "inverted"
+		 * * "tiny"
+		 * * "cute"
+		 * * "partially inverted"
+		 * * "fuckable"
+		 */
+		this.nipples = "cute";
+		/**
+		 * nipple are pierced
+		 * @default 0
+		 * 0: none; 1: yes; 2: heavily */
+		this.nipplesPiercing = 0;
+		/** what accessory, if any, or on her nipples */
+		this.nipplesAccessory = "none";
+		/** slave areolae
+		 *
+		 * 0: normal; 1: large; 2: unusually wide; 3: huge */
+		this.areolae = 0;
+		/** edge of areolae are pierced
+		 * @default 0
+		 * 0: none; 1: yes; 2: heavy */
+		this.areolaePiercing = 0;
+		/** slave areolae shape ("heart"; "star"; "circle") */
+		this.areolaeShape = "circle";
+		/**
+		 * boobs tattoo
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string | number}
+		 */
+		this.boobsTat = 0;
+		/** slave lactation
+		 *
+		 * 0: none; 1: natural; 2: implant */
+		this.lactation = 0;
+		/** how many more weeks until lactation dries up
+		 *
+		 * usually 2 as interactions and lact. implant reset it to 2 */
+		this.lactationDuration = 0;
+		/**
+		 * odds of inducing lactation
+		 *
+		 * begins trying on breast play if over 10 */
+		this.induceLactation = 0;
+		/** 0: 10: not used to producing milk(no bonuses);
+		 * 11: 50: used to producing milk;
+		 * 51: 100: heavily adapted to producing milk(big bonus) */
+		this.lactationAdaptation = 0;
+		/** amount of milk given */
+		this.milk = 0;
+		/** amount of cum given */
+		this.cum = 0;
+		/**
+		 *  hip size
+		 * * -2: very narrow
+		 * * -1: narrow
+		 * * 0: normal
+		 * * 1: wide hips
+		 * * 2: very wide hips
+		 * * 3: inhumanly wide hips
+		 */
+		this.hips = 0;
+		/** slave has hip implant
+		 *
+		 * -1: hips -1; 0: none; 1: hips +1 */
+		this.hipsImplant = 0;
+		/**
+		 *  butt size
+		 * * 0	 : flat
+		 * * 1	 : small
+		 * * 2   : plump *
+		 * * 3	 : big bubble butt
+		 * * 4	 : huge
+		 * * 5	 : enormous
+		 * * 6	 : gigantic
+		 * * 7	 : ridiculous
+		 * * 8 - 10: immense
+		 * * 11 - 20: inhuman
+		 *
+		 * _* Descriptions vary for just how big 2 is, as such, it may be better to just go with 3_
+		 */
+		this.butt = 0;
+		/**
+		 * butt implant type and size
+		 *
+		 * * 0: none
+		 * * 1: butt implant
+		 * * 2: big butt implant
+		 * * 3: fillable butt implants
+		 * * 5 - 8: advanced fillable implants
+		 * * 9+: hyper fillable implants
+		 */
+		this.buttImplant = 0;
+		/** butt implant type
+		 *
+		 * 0: normal/none; 1: string */
+		this.buttImplantType = 0;
+		/**
+		 * butt tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.buttTat = 0;
+		/**
+		 * face attractiveness
+		 *
+		 * * -96 - : very ugly
+		 * * -95 - -41: ugly
+		 * * -40 - -11: unattractive
+		 * * -10 - 10: attractive
+		 * * 11 - 40: very pretty
+		 * * 41 - 95: gorgeous
+		 * * 96+: mind blowing
+		 */
+		this.face = 0;
+		/**
+		 * facial surgery degree
+		 *
+		 * * 0 - 14: none
+		 * * 15 - 34: Subtle Improvements
+		 * * 35 - 64: Noticeable Work
+		 * * 65 - 99: Heavily Reworked
+		 * * 100: Uncanny Valley
+		 */
+		this.faceImplant = 0;
+		/**
+		 * accepts string (will be treated as "normal")
+		 * * "normal"
+		 * * "masculine"
+		 * * "androgynous"
+		 * * "cute"
+		 * * "sensual"
+		 * * "exotic"
+		 */
+		this.faceShape = "normal";
+		/**
+		 * lip size (0 - 100)
+		 * * 0 - 10: thin
+		 * * 11 - 20: normal
+		 * * 21 - 40: pretty
+		 * * 41 - 70: plush
+		 * * 71 - 95: huge(lisps)
+		 * * 96 - 100: facepussy(mute)
+		 */
+		this.lips = 15;
+		/**
+		 * how large her lip implants are
+		 * @see lips
+		 */
+		this.lipsImplant = 0;
+		/**
+		 * lips pierced
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.lipsPiercing = 0;
+		/**
+		 * lip tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "permanent makeup"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.lipsTat = 0;
+		/**
+		 * teeth type
+		 * * "normal"
+		 * * "crooked"
+		 * * "straightening braces"
+		 * * "cosmetic braces"
+		 * * "removable"
+		 * * "pointy"
+		 * * "baby"
+		 * * "mixed"
+		 */
+		this.teeth = "normal";
+		/**
+		 * has tongue piercing
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.tonguePiercing = 0;
+		/**
+		 * vagina type
+		 * * -1: no vagina
+		 * * 0: virgin
+		 * * 1: tight
+		 * * 2: reasonably tight
+		 * * 3: loose
+		 * * 4: cavernous
+		 * * 10: ruined
+		 */
+		this.vagina = 0;
+		/** how wet she is
+		 *
+		 * 0: dry; 1: wet; 2: soaking wet */
+		this.vaginaLube = 0;
+		/** has vagina piercing
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.vaginaPiercing = 0;
+		/**
+		 * vagina tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.vaginaTat = 0;
+		/**
+		 * pregnancy time or state.See Pregnancy Control section for more.
+		 * * -3: sterilized
+		 * * -2: sterile
+		 * * -1: contraceptives
+		 * * 0: fertile
+		 * * 1 - 10: pregnant, not showing
+		 * * 11 - 20: showing
+		 * * 21 - 30: pregnant
+		 * * 30 - 35: very pregnant
+		 */
+		this.preg = -1;
+		/**
+		 * accepts ID See Pregnancy Control section for more.
+		 *
+		 * Who sired her pregnancy
+		 * * -8: an animal
+		 * * -7: designer baby
+		 * * -2: Citizen of your arcology
+		 * * -1: You
+		 * * 0: Unidentifiable
+		 */
+		this.pregSource = 0;
+		/**
+		 * Number of children.
+		 *
+		 * **Warning!** Should be not changed after initial impregnation setup.
+		 * See Pregnancy Control section for more.
+		 */
+		this.pregType = 0;
+		/**
+		 * Number of ready to be impregnated ova (override normal cases),
+		 *
+		 * For delayed impregnations with multiples.Used onetime on next call of the SetPregType
+		 * widget. After SetPregType use it to override .pregType, it set back to 0 automatically.
+		 */
+		this.pregAdaptation = 50;
+		/**
+		 * Ovary implant type.
+		 *
+		 * * 0: no implants
+		 * * "fertility": higher chance of twins (or more)
+		 * * "sympathy": doubles eggs released
+		 * * "asexual": self-fertilizing
+		 */
+		this.ovaImplant = 0;
+		/**
+		 * Womb focused enhancements.
+		 *
+		 * * "none"
+		 * * "restraint": Provides structural support for extremely oversized pregnancies
+		 */
+		this.wombImplant = "none";
+		/**
+		 * has the slave been turned into a broodmother
+		 *
+		 * * 0: no
+		 * * 1: standard 1 birth / week
+		 * * 2: black market 12 births / week
+		 * * 3: black market upgrade for implant firmware, to allow change weekly number
+		 * of ova in range of 1 to 12 in remote surgery block. (broodmotherFetuses change
+		 * through remote surgery). (future usage)
+		 */
+		this.broodmother = 0;
+		/**
+		 * count of ova that broodmother implant force to release.
+		 *
+		 * Should be set with "broodmother" property together. If broodmother == 0 has no meaning.
+		 */
+		this.broodmotherFetuses = 0;
+		/**
+		 * If broodmother implant set to pause it 's work.
+		 *
+		 * 1: implant on pause !1: working.
+		 *
+		 * If broodmother birth her last baby and her implant is on pause, she will be in contraception like state.
+		 */
+		this.broodmotherOnHold = 0;
+		/**
+		 * Number of weeks left until last baby will be birthed.
+		 *
+		 * Mainly informative only. Updated automatically at birth process based on remaining fetuses. 0 - 37
+		 */
+		this.broodmotherCountDown = 0;
+		/**
+		 * variable used to set off the birth events
+		 *
+		 * 1: birth this week; 0: not time yet */
+		this.labor = 0;
+		/** number of births as your slave */
+		this.births = 0;
+		this.laborCount = 0;
+		/** does she have a c-section scar
+		 *
+		 * 1: yes; 0: no */
+		this.cSec = 0;
+		/**
+		 * may accept strings, use at own risk
+		 *
+		 * * "none"
+		 * * "a small empathy belly"
+		 * * "a medium empathy belly"
+		 * * "a large empathy belly"
+		 * * "a huge empathy belly"
+		 * * "a corset"
+		 * * "an extreme corset"
+		 */
+		this.bellyAccessory = "none";
+		/**
+		 * labia type
+		 * * 0: minimal
+		 * * 1: big
+		 * * 2: huge
+		 * * 3: huge dangling
+		 */
+		this.labia = 0;
+		/**
+		 * clit size
+		 * * 0: normal
+		 * * 1: large
+		 * * 2: huge
+		 * * 3: enormous
+		 * * 4: penis-like
+		 * * 5: like a massive penis
+		 */
+		this.clit = 0;
+		/**
+		 * is clit pierced
+		 * * 0: no
+		 * * 1: yes
+		 * * 2: heavy
+		 * * 3: smart
+		 */
+		this.clitPiercing = 0;
+		/**
+		 * smart piercing setting
+		 * * "off"
+		 * * "none"
+		 * * "all"
+		 * * "no default setting"
+		 * * "women"
+		 * * "men"
+		 * * "vanilla"
+		 * * "oral"
+		 * * "anal"
+		 * * "boobs"
+		 * * "submissive"
+		 * * "humiliation"
+		 * * "pregnancy"
+		 * * "dom"
+		 * * "masochist"
+		 * * "sadist"
+		 */
+		this.clitSetting = "vanilla";
+		/** 0: circumcised; 1+:uncut, also affects foreskin size */
+		this.foreskin = 0;
+		/**
+		 * anus size
+		 * * 0: virgin
+		 * * 1: tight
+		 * * 2: loose
+		 * * 3: very loose
+		 * * 4: gaping
+		 */
+		this.anus = 0;
+		/**
+		 * dick size
+		 * * 0: none
+		 * * 1: tiny
+		 * * 2: little
+		 * * 3: normal
+		 * * 4: big
+		 * * 5: huge
+		 * * 6: gigantic
+		 * * 7: massive/gigantic
+		 * * 8: truly imposing/titanic
+		 * * 9: monstrous/absurd
+		 * * 10: awe-inspiring/inhuman
+		 * * 11+: hypertrophied
+		 */
+		this.dick = 0;
+		/** used to calculate size of area around anus. */
+		this.analArea = 1;
+		/**
+		 * is dick pierced
+		 * * 0: no
+		 * * 1: yes
+		 * * 2: heavy
+		 */
+		this.dickPiercing = 0;
+		/**
+		 * dick tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.dickTat = 0;
+		/**
+		 * does the slave have a prostate?
+		 * * 0: no
+		 * * 1: normal
+		 * * 2: hyperstimulated +20%
+		 * * 3: modified hyperstimulated +50%
+		 */
+		this.prostate = 0;
+		/**
+		 * ball size
+		 * * 0: none
+		 * * 1: vestigial
+		 * * 2: small
+		 * * 3: average
+		 * * 4: large
+		 * * 5: massive
+		 * * 6: huge
+		 * * 7: giant
+		 * * 8: enormous
+		 * * 9: monstrous
+		 * * 10: inhuman
+		 * * 11+: hypertrophied
+		 */
+		this.balls = 0;
+		/**
+		 * scrotum size
+		 *
+		 * function relative to .ballSize
+		 *
+		 * *If .balls > 0 and .scrotum == 0, balls are internal*
+		 */
+		this.scrotum = 0;
+		/** has ovaries
+		 *
+		 * 0: no; 1: yes */
+		this.ovaries = 0;
+		/** has anus piercing
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.anusPiercing = 0;
+		/**
+		 * anus tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "bleached"
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.anusTat = 0;
+		/**
+		 * has makeup
+		 * * 0: none
+		 * * 1: minimal
+		 * * 2: expensive, luxurious
+		 * * 3: color-coordinated with hair
+		 * * 4: heavy
+		 * * 5: neon
+		 * * 6: color-coordinated neon
+		 * * 7: metallic
+		 * * 8: color-coordinated metallic
+		 */
+		this.makeup = 0;
+		/**
+		 * nail type
+		 * * 0: neatly clipped
+		 * * 1: long and elegant
+		 * * 2: color-coordinated with hair
+		 * * 3: sharp and claw-like
+		 * * 4: bright and glittery
+		 * * 5: very long and garish
+		 * * 6: neon
+		 * * 7: color-coordinated neon
+		 * * 8: metallic
+		 * * 9: color-coordinated metallic
+		 */
+		this.nails = 0;
+		/**
+		 * has brand
+		 *
+		 * 0: no; 1: yes */
+		this.brand = 0;
+		/**
+		 * brand location
+		 *
+		 * accepts string
+		 * * "back"
+		 * * "chest"
+		 * * "ankles"
+		 * * "wrists"
+		 * * "thighs"
+		 * @type {string|number} */
+		this.brandLocation = 0;
+		/** has pierced ears
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.earPiercing = 0;
+		/** has pierced nose
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.nosePiercing = 0;
+		/** has eyebrow piercing
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.eyebrowPiercing = 0;
+		/** has navel piercing
+		 *
+		 * 0: no; 1: yes; 2: heavy */
+		this.navelPiercing = 0;
+		/**
+		 * shoulder tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.shouldersTat = 0;
+		/**
+		 * arm tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.armsTat = 0;
+		/**
+		 * leg tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 *  @type {string|number} */
+		this.legsTat = 0;
+		/**
+		 * back tattoo
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.backTat = 0;
+		/**
+		 * tramp stamp
+		 *
+		 * takes one of the following strings or 0
+		 * * "tribal patterns"
+		 * * "flowers"
+		 * * "scenes"
+		 * * "Asian art"
+		 * * "degradation"
+		 * * "counting"
+		 * * "advertisements"
+		 * * "rude words"
+		 * * "bovine patterns"
+		 * * "sacrament"
+		 * * "Sacrilege"
+		 * * "Possessive"
+		 * * "Paternalist"
+		 * @type {string|number} */
+		this.stampTat = 0;
+		/**
+		 * skill in vaginal sex
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.vaginalSkill = 0;
+		/**
+		 * skill in oral sex
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.oralSkill = 0;
+		/**
+		 * skill in anal sex
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.analSkill = 0;
+		/**
+		 * whoring skill
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.whoreSkill = 0;
+		/**
+		 * entertaining skill
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.entertainSkill = 0;
+		/**
+		 * combating skill
+		 * * 0-10: unskilled
+		 * * 11-30: basic
+		 * * 31-60: skilled
+		 * * 61-99: expert
+		 * * 100+: master
+		 */
+		this.combatSkill = 0;
+		/**
+		 * * "spare"
+		 * * "normal"
+		 * * "luxurious"
+		 */
+		this.livingRules = "spare";
+		/**
+		 * * "restrictive"
+		 * * "permissive"
+		 * * "accent elimination"
+		 * * "language lessons"
+		 */
+		this.speechRules = "restrictive";
+		/**
+		 * * "permissive"
+		 * * "sapphic"
+		 * * "masturbation"
+		 * * "restrictive"
+		 * * "chastity"
+		 */
+		this.releaseRules = "restrictive";
+		/**
+		 * * "restrictive"
+		 * * "just friends"
+		 * * "permissive"
+		 */
+		this.relationshipRules = "restrictive";
+		/**
+		 * * "none"
+		 * * "induce"
+		 * * "maintain"
+		 */
+		this.lactationRules = "none";
+		/**
+		 * * "confinement"
+		 * * "whipping"
+		 * * "chastity"
+		 * * "situational"
+		 */
+		this.standardPunishment = "situational";
+		/**
+		 * * "relaxation"
+		 * * "drugs"
+		 * * "orgasm"
+		 * * "situational"
+		 */
+		this.standardReward = "situational";
+		/** follows rules or is exempt from them
+		 *
+		 * 0: exempt; 1: obeys */
+		this.useRulesAssistant = 1;
+		/**
+		 * * "healthy"
+		 * * "restricted"
+		 * * "muscle building"
+		 * * "fattening"
+		 * * "slimming"
+		 * * "XX"
+		 * * "XY"
+		 * * "XXY"
+		 * * "cum production"
+		 * * "cleansing"
+		 * * "fertility"
+		 */
+		this.diet = "healthy";
+		/** how much of her diet is cum
+		 *
+		 * 0: none; 1: supplemented; 2: nearly entirely */
+		this.dietCum = 0;
+		/** how much of her diet is milk
+		 *
+		 * 0: none; 1: supplemented; 2: nearly entirely */
+		this.dietMilk = 0;
+		/** affects work performance, i.e. decreased pay for whoring
+		 * caused by poor/overcrowded sleeping conditions
+		 *
+		 * 0: not tired; 1: tired */
+		this.tired = 0;
+		/**
+		 * * -2: heavy male hormones
+		 * * -1: male hormones
+		 * * 0: none
+		 * * 1: female hormones
+		 * * 2: heavy female hormones
+		 */
+		this.hormones = 0;
+		/**
+		 * * "no drugs"
+		 * * "breast injections"
+		 * * "butt injections"
+		 * * "lip injections"
+		 * * "fertility drugs"
+		 * * "penis enhancement"
+		 * * "testicle enhancement"
+		 * * "psychosuppressants"
+		 * * "steroids"
+		 * * "hormone enhancers"
+		 * * "hormone blockers"
+		 * * "super fertility drugs"
+		 * * "hyper breast injections"
+		 * * "hyper butt injections"
+		 * * "hyper penis enhancement"
+		 * * "hyper testicle enhancement"
+		 * * "female hormone injections"
+		 * * "male hormone injections"
+		 * * "anti-aging cream"
+		 * * "appetite suppressors"
+		 * * "penis atrophiers"
+		 * * "testicle atrophiers"
+		 * * "clitoris atrophiers"
+		 * * "labia atrophiers"
+		 * * "nipple atrophiers"
+		 * * "lip atrophiers"
+		 * * "breast redistributors"
+		 * * "butt redistributors"
+		 * * "sag-B-gone"
+		 * * "growth stimulants"
+		 */
+		this.drugs = "no drugs";
+		/** 0: none; 1: preventatives; 2: curatives */
+		this.curatives = 0;
+		/** if greater than 10 triggers side effects from drug use. */
+		this.chem = 0;
+		/** 0: none; 1: standard; 2: powerful */
+		this.aphrodisiacs = 0;
+		/**
+		 * how addict to aphrodisiacs slave is
+		 * * 0: not
+		 * * 1-2: new addict
+		 * * 3-9: confirmed addict
+		 * * 10+: dependent
+		 */
+		this.addict = 0;
+		/** fuckdoll degree
+		 *
+		 * 0: not; 1+: fuckdoll */
+		this.fuckdoll = 0;
+		/** 0: no; 1: yes */
+		this.choosesOwnClothes = 0;
+		/**
+		 * may accept strings, use at own risk
+		 *
+		 * * "a ball gown"
+		 * * "a biyelgee costume"
+		 * * "a bra"
+		 * * "a bunny outfit"
+		 * * "a burkini"
+		 * * "a burqa"
+		 * * "a button-up shirt"
+		 * * "a button-up shirt and panties"
+		 * * "a chattel habit"
+		 * * "a cheerleader outfit"
+		 * * "a comfortable bodysuit"
+		 * * "a cybersuit"
+		 * * "a dirndl"
+		 * * "a fallen nuns habit"
+		 * * "a Fuckdoll suit"
+		 * * "a gothic lolita dress"
+		 * * "a halter top dress"
+		 * * "a hanbok"
+		 * * "a hijab and abaya"
+		 * * "a hijab and blouse"
+		 * * "a huipil"
+		 * * "a kimono"
+		 * * "a klan robe"
+		 * * "a latex catsuit"
+		 * * "a leotard"
+		 * * "a long qipao"
+		 * * "a maternity dress"
+		 * * "a military uniform"
+		 * * "a mini dress"
+		 * * "a monokini"
+		 * * "a mounty outfit"
+		 * * "a nice maid outfit"
+		 * * "a nice nurse outfit"
+		 * * "a nice pony outfit"
+		 * * "a niqab and abaya"
+		 * * "a one-piece swimsuit"
+		 * * "a penitent nuns habit"
+		 * * "a police uniform"
+		 * * "a red army uniform"
+		 * * "a scalemail bikini"
+		 * * "a schoolgirl outfit"
+		 * * "a schutzstaffel uniform"
+		 * * "a skimpy loincloth"
+		 * * "a slave gown"
+		 * * "a slutty klan robe"
+		 * * "a slutty maid outfit"
+		 * * "a slutty nurse outfit"
+		 * * "a slutty outfit"
+		 * * "a slutty pony outfit"
+		 * * "a slutty qipao"
+		 * * "a slutty schutzstaffel uniform"
+		 * * "a sports bra"
+		 * * "a string bikini"
+		 * * "a striped bra"
+		 * * "a succubus outfit"
+		 * * "a sweater"
+		 * * "a sweater and cutoffs"
+		 * * "a sweater and panties"
+		 * * "a t-shirt"
+		 * * "a t-shirt and jeans"
+		 * * "a t-shirt and panties"
+		 * * "a t-shirt and thong"
+		 * * "a tank-top"
+		 * * "a tank-top and panties"
+		 * * "a thong"
+		 * * "a toga"
+		 * * "a tube top"
+		 * * "a tube top and thong"
+		 * * "an apron"
+		 * * "an oversized t-shirt"
+		 * * "an oversized t-shirt and boyshorts"
+		 * * "attractive lingerie"
+		 * * "attractive lingerie for a pregnant woman"
+		 * * "battlearmor"
+		 * * "battledress"
+		 * * "body oil"
+		 * * "boyshorts"
+		 * * "chains"
+		 * * "choosing her own clothes"
+		 * * "clubslut netting"
+		 * * "conservative clothing"
+		 * * "cutoffs"
+		 * * "cutoffs and a t-shirt"
+		 * * "harem gauze"
+		 * * "jeans"
+		 * * "kitty lingerie"
+		 * * "leather pants"
+		 * * "leather pants and a tube top"
+		 * * "leather pants and pasties"
+		 * * "lederhosen"
+		 * * "nice business attire"
+		 * * "no clothing"
+		 * * "panties"
+		 * * "panties and pasties"
+		 * * "restrictive latex"
+		 * * "shibari ropes"
+		 * * "slutty business attire"
+		 * * "slutty jewelry"
+		 * * "spats and a tank top"
+		 * * "sport shorts"
+		 * * "sport shorts and a sports bra"
+		 * * "sport shorts and a t-shirt"
+		 * * "stretch pants and a crop-top"
+		 * * "striped panties"
+		 * * "striped underwear"
+		 * * "uncomfortable straps"
+		 * * "Western clothing"
+		 */
+		this.clothes = "no clothing";
+		/**
+		 * may accept strings, use at own risk 	"none"
+		 * * "ancient Egyptian"
+		 * * "cruel retirement counter"
+		 * * "uncomfortable leather"
+		 * * "tight steel"
+		 * * "shock punishment"
+		 * * "dildo gag"
+		 * * "heavy gold"
+		 * * "pretty jewelry"
+		 * * "nice retirement counter"
+		 * * "bell collar"
+		 * * "leather with cowbell"
+		 * * "bowtie"
+		 * * "neck corset"
+		 * * "stylish leather"
+		 * * "satin choker"
+		 * * "preg biometrics"
+		 * * "massive dildo gag"
+		 * * "silk ribbon"
+		 * * "ball gag"
+		 * * "bit gag"
+		 * * "porcelain mask"
+		 */
+		this.collar = "none";
+		/**
+		 * may accept strings, use at own risk
+		 * * "none"
+		 * * "heels"
+		 * * "pumps"
+		 * * "extreme heels"
+		 * * "boots"
+		 * * "flats"
+		 */
+		this.shoes = "none";
+		/**
+		 * may accept strings, use at own risk
+		 * * "none"
+		 * * "chastity belt"
+		 * * "combined chastity"
+		 * * "anal chastity"
+		 * * "dildo"
+		 * * "large dildo"
+		 * * "huge dildo"
+		 * * "long dildo"
+		 * * "long, large dildo"
+		 * * "long, huge dildo"
+		 */
+		this.vaginalAccessory = "none";
+		/**
+		 * may accept strings, use at own risk
+		 * * "none"
+		 * * "chastity"
+		 * * "anal chastity"
+		 * * "combined chastity"
+		 */
+		this.dickAccessory = "none";
+		/**
+		 * * "none"
+		 * * "short stockings"
+		 * * "long stockings"
+		 */
+		this.legAccessory = "none";
+		/**
+		 * may accept strings, use at own risk
+		 * * "none"
+		 * * "plug"
+		 * * "large plug"
+		 * * "huge plug"
+		 * * "long plug"
+		 * * "long, large plug"
+		 * * "long, huge plug"
+		 */
+		this.buttplug = "none";
+		/**
+		 * Does the slave have an attachment on their buttplug
+		 *
+		 *  may accept strings, use at own risk
+		 * * "none"
+		 * * "tail"
+		 * * "fox tail"
+		 * * "cat tail"
+		 */
+		this.buttplugAttachment = "none";
+		/**
+		 * slave intelligence
+		 * * -100 - -96: borderline retarded
+		 * * -95 - -51: very slow
+		 * * -50 - -16: slow
+		 * * -15 - 15: average
+		 * * 16 - 50: smart
+		 * * 51 - 95: very smart
+		 * * 96 - 100: brilliant
+		 */
+		this.intelligence = 0;
+		/**
+		 * Degree of slave 's education
+		 * * 0: uneducated
+		 * * 1+: partial education (not really used)
+		 * * 15+: educated
+		 * * 30: well educated
+		 */
+		this.intelligenceImplant = 0;
+		/**
+		 * sex drive
+		 * * 0 - 20: no sex drive
+		 * * 21 - 40: poor sex drive
+		 * * 41 - 60: average sex drive
+		 * * 61 - 80: good sex drive
+		 * * 81 - 95: powerful sex drive
+		 * * 96+: nymphomaniac
+		 */
+		this.energy = 50;
+		/**
+		 * how badly she needs sex.
+		 *
+		 *  0: sated
+		 */
+		this.need = 0;
+		/**
+		 * attraction to women
+		 * * 0 - 5: disgusted by women
+		 * * 6 - 15: turned off by women
+		 * * 15 - 35: not attracted to women
+		 * * 36 - 65: indifferent to women
+		 * * 66 - 85: attracted to women
+		 * * 86 - 95: aroused by women
+		 * * 96+: passionate about women
+		 *
+		 * *if both attrXX and attrXY > 95, slave will be omnisexual*
+		 *
+		 * *if energy > 95 and either attrXX or attrXY > 95, slave will be nymphomaniac*
+		 */
+		this.attrXX = 0;
+		/**
+		 * attraction to men
+		 * * 0 - 5: disgusted by men
+		 * * 6 - 15: turned off by men
+		 * * 15 - 35: not attracted to men
+		 * * 36 - 65: indifferent to men
+		 * * 66 - 85: attracted to men
+		 * * 86 - 95: aroused by men
+		 * * 96+: passionate about men
+		 *
+		 * *if both attrXX and attrXY > 95, slave will be omnisexual*
+		 *
+		 * *if energy > 95 and either attrXX or attrXY > 95, slave will be nymphomaniac*
+		*/
+		this.attrXY = 0;
+		/** 0: no; 1: yes */
+		this.attrKnown = 0;
+		/**
+		 * * "none"
+		 * * "mindbroken"
+		 * * "submissive"
+		 * * "cumslut"
+		 * * "humiliation"
+		 * * "buttslut"
+		 * * "boobs"
+		 * * "sadist"
+		 * * "masochist"
+		 * * "dom"
+		 * * "pregnancy"
+		 */
+		this.fetish = "none";
+		/** how strong her fetish is (10-100)
+		 *
+		 * 10+: enjoys fetish; 60+: likes fetish; 95+: loves fetish */
+		this.fetishStrength = 70;
+		/** is fetish known to player
+		 *
+		 * 0: no; 1: yes */
+		this.fetishKnown = 0;
+		/**
+		 * * "none"
+		 * * "arrogant": clings to her dignity, thinks slavery is beneath her
+		 * * "bitchy": can 't keep her opinions to herself
+		 * * "odd": says and does odd things
+		 * * "hates men": hates men
+		 * * "hates women": hates women
+		 * * "gluttonous": likes eating, gains weight
+		 * * "anorexic": dislikes eating and being forced to eat, loses weight
+		 * * "devout": resistance through religious faith
+		 * * "liberated": believes slavery is wrong
+		 */
+		this.behavioralFlaw = "none";
+		/**
+		 * * "none"
+		 * * "confident": believes she has value as a slave
+		 * * "cutting": often has as witty or cunning remark ready, knows when to say it
+		 * * "funny": is funny
+		 * * "fitness": loves working out
+		 * * "adores women": likes spending time with women
+		 * * "adores men": likes spending time with men
+		 * * "insecure": defines herself on the thoughts of others
+		 * * "sinful": breaks cultural norms
+		 * * "advocate": advocates slavery
+		 */
+		this.behavioralQuirk = "none";
+		/**
+		 * * "none"
+		 * * "hates oral": hates oral sex
+		 * * "hates anal": hates anal sex
+		 * * "hates penetration": dislikes penetrative sex
+		 * * "shamefast": nervous when naked
+		 * * "idealistic": believes sex should be based on love and consent
+		 * * "repressed": dislikes sex
+		 * * "apathetic": inert during sex
+		 * * "crude": sexually crude and has little sense of what partners find disgusting during sex
+		 * * "judgemental": sexually judgemental and often judges her sexual partners' performance
+		 * * "neglectful": disregards herself in sex
+		 * * "cum addict": addicted to cum
+		 * * "anal addict": addicted to anal
+		 * * "attention whore": addicted to being the center of attention
+		 * * "breast growth": addicted to her own breasts
+		 * * "abusive": sexually abusive
+		 * * "malicious": loves causing pain and suffering
+		 * * "self hating": hates herself
+		 * * "breeder": addicted to being pregnant
+		 */
+		this.sexualFlaw = "none";
+		/**
+		 * * "none"
+		 * * "gagfuck queen": can take a facefucking
+		 * * "painal queen": knows how far she can go without getting hurt
+		 * * "strugglefuck queen": knows how much resistance her partners want
+		 * * "tease": is a tease
+		 * * "romantic": enjoys the closeness of sex
+		 * * "perverted": enjoys breaking sexual boundaries
+		 * * "caring": enjoys bring her partners to orgasm
+		 * * "unflinching": willing to do anything
+		 * * "size queen": prefers big cocks
+		 */
+		this.sexualQuirk = "none";
+		/** 0: does not have; 1: carrier; 2: active */
+		this.geneticQuirks = {
+			/** Oversized breasts. Increased growth rate, reduced shrink rate. Breasts try to return to oversized state if reduced. */
+			macromastia: 0,
+			/** Greatly oversized breasts. Increased growth rate, reduced shrink rate. Breasts try to return to oversized state if reduced.
+			 *
+			 * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */
+			gigantomastia: 0,
+			/** is prone to having twins, shorter pregnancy recovery rate */
+			fertility: 0,
+			/** is prone to having multiples, even shorter pregnancy recovery rate
+			 *
+			 * **fertility + hyperFertility** - will have multiples, even shorter pregnancy recovery rate */
+			hyperFertility: 0,
+			/** pregnancy does not block ovulation, slave can become pregnant even while pregnant */
+			superfetation: 0,
+			/** is abnormally tall.  gigantism + dwarfism - is very average*/
+			gigantism: 0,
+			/** is abnormally short.  gigantism + dwarfism - is very average*/
+			dwarfism: 0,
+			/** has a flawless face. pFace + uFace - Depends on carrier status, may swing between average and above/below depending on it */
+			pFace: 0,
+			/** has a hideous face. pFace + uFace - Depends on carrier status, may swing between average and above/below depending on it */
+			uFace: 0,
+			/**  has pale skin, white hair and red eyes */
+			albinism: 0,
+			/** ass never stops growing. Increased growth rate, reduced shrink rate. */
+			rearLipedema: 0,
+			/** has (or will have) a huge dong */
+			wellHung: 0,
+			/** constantly gains weight unless dieting, easier to gain weight. wGain + wLoss - weight gain/loss fluctuates randomly */
+			wGain: 0,
+			/** constantly loses weight unless gaining, easier to lose weight. wGain + wLoss - weight gain/loss fluctuates randomly */
+			wLoss: 0,
+			/** body attempts to normalize to an androgynous state */
+			androgyny: 0
+		};
+		/** oral sex count */
+		this.oralCount = 0;
+		/** vaginal sex count */
+		this.vaginalCount = 0;
+		/** anal sex count */
+		this.analCount = 0;
+		/** breast sex count */
+		this.mammaryCount = 0;
+		/** penetrative sex count */
+		this.penetrativeCount = 0;
+		/**  */
+		this.publicCount = 0;
+		/**  number of slaves killed in pit fights*/
+		this.pitKills = 0;
+		/** adds a custom tattoo */
+		this.customTat = "";
+		/** a label appended after the slave's name */
+		this.customLabel = "";
+		/** adds a custom description */
+		this.customDesc = "";
+		/** What the slave refers to you as. */
+		this.customTitle = "";
+		/**  What the slave refers to you as, with a lisp.*/
+		this.customTitleLisp = "";
+		/** Does this slave refer to you rudely?
+		 *
+		 * 0: not being rude; 1: insists on calling you a rude title */
+		this.rudeTitle = 0;
+		/**
+		 * holds the custom slave image file name (used	if images are enabled)
+		 *
+		 * 0: no custom image
+		 * @type {string|number} */
+		this.customImage = 0;
+		/** @type {number[]} */
+		this.currentRules = [];
+		/**
+		 * Slave has a tattoo that is only recognizable when she has a big belly.
+		 * * "a heart"
+		 * * "a star"
+		 * * "a butterfly"
+		 * @type {string|number} */
+		this.bellyTat = 0;
+		/** Slave will give birth this week.
+		 *
+		 * 1: true; 0: false */
+		this.induce = 0;
+		/** Male slave has an anal womb and can get pregnant.
+		 *
+		 * 1: true; 0: false */
+		this.mpreg = 0;
+		/** How much fluid is distending the slave.
+		 *
+		 * 1: 2L; 2: 4L; 3: 8L */
+		this.inflation = 0;
+		/**
+		 * What kind of fluid is in the slave.
+		 * * "none"
+		 * * "water"
+		 * * "cum"
+		 * * "milk"
+		 * * "food"
+		 * * "aphrodisiac"
+		 * * "curative"
+		 * * "tightener"
+		 */
+		this.inflationType = "none";
+		/**
+		 * How she is being filled.
+		 * * 0: not
+		 * * 1: oral
+		 * * 2: anal
+		 * * 3: orally by another slave
+		 */
+		this.inflationMethod = 0;
+		/** If inflationMethod == 3, ID of the slave filling her with milk. */
+		this.milkSource = 0;
+		/** If inflationMethod 3, ID of the slave filling her with cum. */
+		this.cumSource = 0;
+		/** Slave's internals have ruptured. Used with poor health and overinflation.
+		 *
+		 * 1: true; 0: false */
+		this.burst = 0;
+		/** Do you and the slave know she is pregnant.
+		 *
+		 * 0: no; 1: yes */
+		this.pregKnown = 0;
+		/** How long she has been pregnant
+		 *
+		 * used in place of .preg when pregnancy speed up and slow down are used on a slave
+		 *
+		 * if negative, designates postpartum. */
+		this.pregWeek = 0;
+		/**
+		 * how big their belly is in CCs
+		 *
+		 * ||thresholds:|
+		 * |-|-|
+		 * 100    | bloated
+		 * 1500   | early pregnancy
+		 * 5000   | obviously pregnant
+		 * 10000  | very pregnant
+		 * 15000  | full term
+		 * 30000  | full term twins
+		 * 45000  | full term triplets
+		 * 60000  | full term quads
+		 * 75000  | full term quints
+		 * 90000  | full term sextuplets
+		 * 105000 | full term septuplets
+		 * 120000 | full term octuplets
+		 * 150000 | oversized pregnancy
+		 * 300000 | hyperpreg state 1
+		 * 450000 | hyperpreg state 2
+		 * 600000 | hyperpreg state 3
+		 * 750000 | hyperpreg state 4
+		 */
+		this.belly = 0;
+		/**
+		 * how big their belly is in CCs (pregnancy only)
+		 *
+		 * ||thresholds|
+		 * |-|-|
+		 * 100    | bloated
+		 * 1500   | early pregnancy
+		 * 5000   | obviously pregnant
+		 * 10000  | very pregnant
+		 * 15000  | full term
+		 * 30000  | full term twins
+		 * 45000  | full term triplets
+		 * 60000  | full term quads
+		 * 75000  | full term quints
+		 * 90000  | full term sextuplets
+		 * 105000 | full term septuplets
+		 * 120000 | full term octuplets
+		 * 150000 | oversized pregnancy (9+ babies)
+		 * 300000 | hyperpreg state 1 (20+ babies)
+		 * 450000 | hyperpreg state 2 (30+ babies)
+		 * 600000 | hyperpreg state 3 (40+ babies)
+		 * 750000 | hyperpreg state 4 (50+ babies)
+		 */
+		this.bellyPreg = 0;
+		/**
+		 * how big their belly is in CCs (fluid distension only)
+		 *
+		 * ||thresholds|
+		 * |-|-|
+		 * 100   | bloated
+		 * 2000  | clearly bloated (2 L)
+		 * 5000  | very full (~1 gal)
+		 * 10000 | full to bursting (~2 gal)
+		 */
+		this.bellyFluid = 0;
+		/**
+		 * Does the slave have a fillable abdominal implant.
+		 * * -1: no
+		 * * 0+: yes
+		 * * 2000+: Early pregnancy
+		 * * 4000+: looks pregnant
+		 * * 8000+: looks full term
+		 * * 16000+: hyperpregnant 1
+		 * * 32000+: hyperpregnant 2
+		*/
+		this.bellyImplant = -1;
+		/** How saggy her belly is after being distended for too long.
+		 *
+		 * 1+ changes belly description */
+		this.bellySag = 0;
+		/** How saggy her belly is from being too pregnant.
+		 *
+		 * 1+ changes belly description and overrides/coincides with bellySag */
+		this.bellySagPreg = 0;
+		/**
+		 * Has the slave 's belly implant been filled this week. Causes health damage for overfilling.
+		 *
+		 * 0: no pain; 1: will experience pain; 2: cannot be filled this week */
+		this.bellyPain = 0;
+		/** Does the slave have a cervical implant that slowly feeds cum from being fucked into a fillable implant.
+		 *
+		 * 0: no; 1: vaginal version only; 2: anal version only; 3: both vaginal and anal */
+		this.cervixImplant = 0;
+		/** How many known times the slave has given birth. */
+		this.birthsTotal = 0;
+		/** Target .physicalAge for female puberty to occur. */
+		this.pubertyAgeXX = 13;
+		/** Has the slave gone through female puberty.
+		 *
+		 * 0: no; 1: yes */
+		this.pubertyXX = 0;
+		/** Target .physicalAge for male puberty to occur. */
+		this.pubertyAgeXY = 13;
+		/** Has the slave gone through male puberty.
+		 *
+		 * 0: no; 1: yes */
+		this.pubertyXY = 0;
+		/**
+		 * not fully implemented.
+		 * * 0: no scars
+		 * * 1: light scarring
+		 * * 2: heavy scarring
+		 * * 3: fresh scarring
+		 * * 4: burns
+		 * * 5: menacing scar
+		 * * 6: exotic scar
+		 */
+		this.scars = 0;
+		/**
+		 * In a eugenics society, this slave is a designated breeder.
+		 *
+		 * 1: yes; 0: no */
+		this.breedingMark = 0;
+		/** Slave is in original body.
+		 *
+		 * 0: yes; 1+: number of swaps (increases upkeep each time) */
+		this.bodySwap = 0;
+		/**  Is the Head Girl permitted to fuck this slave pregnant.
+		 *
+		 * 0: no; 1: yes */
+		this.HGExclude = 0;
+		/**
+		 * What species of sperm she produces.
+		 * * "human"
+		 * * "sterile"
+		 * * "dog"
+		 * * "pig"
+		 * * "horse"
+		 * * "cow"
+		 */
+		this.ballType = "human";
+		/**
+		 * What species of ovum she produces.
+		 * * "human"
+		 * * "dog"
+		 * * "pig"
+		 * * "horse"
+		 * * "cow"
+		 */
+		this.eggType = "human";
+		/** Eugenics variable. Is the slave allowed to choose to wear chastity.
+		 *
+		 * 0: no; 1: yes */
+		this.choosesOwnChastity = 0;
+		/**
+		 * Is she on gestation altering drugs?
+		 * * "none"
+		 * * "slow gestation"
+		 * * "speed up"
+		 * * "labor suppressors"
+		 */
+		this.pregControl = "none";
+		/**
+		 * Array that holds an amputee 's constructed limbs for anon's hotswap mod.
+		 *
+		 * Elements of the array should be objects.
+		 * * .type: type of prosthetic limb, ranges from -1 to -5, see.amp for more information
+		 * * .armsTat: any string, see.armsTat for standard strings
+		 * * .legsTat: any string, see.legsTat for standard strings
+		 * @type {Array.<{type:number, armsTat:string, legsTat:string}>} */
+		this.readyLimbs = [];
+		/**  */
+		this.ageAdjust = 0;
+		/** Slave has undergone hair removal surgery
+		 *
+		 * 0: no; 1: yes */
+		this.bald = 0;
+		/** Who, if relevant, the body belonged to. */
+		this.origBodyOwner = "";
+		/** Who, if relevant, the body belonged to. */
+		this.origBodyOwnerID = 0;
+		/** Cause of slave death. */
+		this.death = "";
+		/**
+		 * Slave's current hormonal balance, directs saHormones changes
+		 *
+		 * ||tresholds|
+		 * |-|-|
+		 * -500 - -400 | overwhelmingly masculine
+		 * -399 - -300 | extremely masculine
+		 * -299 - -200 | heavily masculine
+		 * -199 - -100 | very masculine
+		 * -99 - -21 | masculine
+		 * -20 - 20 | neutral
+		 * 21 - 99 | feminine
+		 * 100 - 199 | very feminine
+		 * 200 - 299 | heavily feminine
+		 * 300 - 399 | extremely feminine
+		 * 400 - 500 | overwhelmingly feminine
+		 */
+		this.hormoneBalance = 0;
+		/** Whether a slave is permitted to eat Hedonistic Decadence's specialized slave food.
+		 *
+		 * 0: no; 1: yes */
+		this.onDiet = 0;
+		/** Does the slave have the breast shape maintaining mesh implant.
+		 *
+		 * 0: no; 1: yes */
+		this.breastMesh = 0;
+		/** How many slaves she has sired under your ownership. */
+		this.slavesFathered = 0;
+		/** How many children she has fucked into you that you later birthed. */
+		this.PCChildrenFathered = 0;
+		/** How many of your slaves she has knocked up. */
+		this.slavesKnockedUp = 0;
+		/** How many times she has knocked you up. */
+		this.PCKnockedUp = 0;
+		/** Used to denote a slave giving birth prematurely.
+		 *
+		 * 0: no; 1: yes */
+		this.prematureBirth = 0;
+		/** Was the slave born prematurely?
+		 *
+		 * 0: no; 1: yes */
+		this.premature = 0;
+		/** Has the slave had a vasectomy?
+		 *
+		 * 0: no; 1: yes */
+		this.vasectomy = 0;
+		/** Is the slave's hair under constant maintenance?
+		 *
+		 * 0: no; 1: yes */
+		this.haircuts = 0;
+		/** Used to tell if the slave is from this game or a previous.
+		 *
+		 * 0: no; 1: yes */
+		this.newGamePlus = 0;
+		/** Her skill as a Head Girl
+		 *
+		 * default cap is 200 */
+		this.skillHG = 0;
+		/** Her skill as a recruiter
+		 *
+		 * default cap is 200 */
+		this.skillRC = 0;
+		/** Her skill as a bodyguard
+		 *
+		 * default cap is 200 */
+		this.skillBG = 0;
+		/** Her skill as a brothel madam
+		 *
+		 * default cap is 200 */
+		this.skillMD = 0;
+		/**  Her skill as a DJ
+		 *
+		 * default cap is 200 */
+		this.skillDJ = 0;
+		/** Her skill as a nurse
+		 *
+		 * default cap is 200 */
+		this.skillNU = 0;
+		/** Her skill as a teacher
+		 *
+		 * default cap is 200 */
+		this.skillTE = 0;
+		/** Her skill as an attendant
+		 *
+		 * default cap is 200 */
+		this.skillAT = 0;
+		/** Her skill as a matron
+		 *
+		 * default cap is 200 */
+		this.skillMT = 0;
+		/** Her skill as a stewardess
+		 *
+		 * default cap is 200 */
+		this.skillST = 0;
+		/** Her skill as a milk maid
+		 *
+		 * default cap is 200 */
+		this.skillMM = 0;
+		/** Her skill as a farmer
+		 *
+		 * default cap is 200 */
+		this.skillFA = 0;
+		/** Her skill as a wardeness
+		 *
+		 * default cap is 200 */
+		this.skillWA = 0;
+		/** Her skill as a servant.
+		 *
+		 * default cap is 200 */
+		this.skillS = 0;
+		/** Her skill as an entertainer
+		 *
+		 * default cap is 200 */
+		this.skillE = 0;
+		/** Her skill as a whore
+		 *
+		 * default cap is 200 */
+		this.skillW = 0;
+		/** Whether she was put in the incubator at birth
+		 *
+		 * 0: no; 1: yes, comforting; 2: yes, terrifying */
+		this.tankBaby = 0;
+		/** */
+		this.clone = 0;
+		/**  */
+		this.geneMods = {
+			/** Does slave have induced NCS?
+			 *
+			 * 0: no; 1: yes */
+			NCS: 0,
+			/** Has the slave undergone the elasticity (plasticity) treatment?
+			 *
+			 * 0: no; 1: yes */
+			rapidCellGrowth: 0
+		};
+
+		this.NCSyouthening = 0;
+		this.override_Race = 0;
+		this.override_Skin = 0;
+		this.override_Eye_Color = 0;
+		this.override_H_Color = 0;
+		this.override_Pubic_H_Color = 0;
+		this.override_Arm_H_Color = 0;
+		this.override_Brow_H_Color = 0;
+		/** are eyes missing?
+		 *
+		 * 0: none; 1: yes, left; 2: yes, right; 3: yes, both */
+		this.missingEyes = 0;
+		/** are arms missing?
+		 *
+		 * 0: none; 1: yes, left; 2: yes, right; 3: yes, both */
+		this.missingArms = 0;
+		/** are legs missing?
+		 *
+		 * 0: none; 1: yes, left; 2: yes, right; 3: yes, both */
+		this.missingLegs = 0;
+		/** Amount of cash paid to acquire the slave
+		 *
+		 * accepts negative numbers, 0, or 1.
+		 * 1: unknown price; 0: free; negative: amount paid */
+		this.slaveCost = 0;
+		/** Amount of cash you have spent because of this slave
+		 *
+		 * accepts negative numbers or 0 */
+		this.lifetimeCashExpenses = 0;
+		/** Total amount of cash you have earned because of this slave
+		 *
+		 * accepts positive numbers or 0 */
+		this.lifetimeCashIncome = 0;
+		/**  Amount of cash you have earned because of this slave last week
+		 *
+		 * accepts positive numbers or 0 */
+		this.lastWeeksCashIncome = 0;
+		/** Not currently used, will work similarly to the cash variables above */
+		this.lifetimeRepExpenses = 0;
+		/** Not currently used, will work similarly to the cash variables above */
+		this.lifetimeRepIncome = 0;
+		/** Not currently used, will work similarly to the cash variables above */
+		this.lastWeeksRepIncome = 0;
+	}
+};
diff --git a/src/js/assayJS.js b/src/js/assayJS.js
index f778ef1d8e78c1d3ccdc56ac821477b0de3f5c40..62ea88d163ae3c8e1fb13e00e316f4aafdb3140f 100644
--- a/src/js/assayJS.js
+++ b/src/js/assayJS.js
@@ -1,4 +1,4 @@
-window.isSlim = function(slave) {
+window.isSlim = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let slim = false;
 	const ArcologyZero = State.variables.arcologies[0];
 
@@ -27,11 +27,11 @@ window.isSlim = function(slave) {
 	return slim;
 };
 
-window.isStacked = function(slave) {
+window.isStacked = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return (slave.butt > 4) && (slave.boobs > 800);
 };
 
-window.isModded = function(slave) {
+window.isModded = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let tatScore = TatScore(slave);
 	let piercingScore = PiercingScore(slave);
 	let modScore = piercingScore+tatScore;
@@ -39,38 +39,38 @@ window.isModded = function(slave) {
 	return ((modScore > 15) || (piercingScore > 8 && tatScore > 5));
 };
 
-window.isUnmodded = function(slave) {
+window.isUnmodded = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return (!isModded(slave) && (slave.corsetPiercing === 0) && (PiercingScore(slave) < 3) && (TatScore(slave) < 2));
 };
 
-window.isXY = function(slave) {
+window.isXY = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return (slave.dick > 0);
 };
 
-window.isYoung = function(slave) {
+window.isYoung = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return (slave.visualAge < 30);
 };
 
-window.isPreg = function(slave) {
+window.isPreg = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return ((slave.bellyPreg >= 5000) || (slave.bellyImplant >= 5000));
 };
 
-window.isNotPreg = function(slave) {
+window.isNotPreg = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return (!isPreg(slave) && (slave.belly < 100) && (slave.weight < 30) && !setup.fakeBellies.includes(slave.bellyAccessory));
 };
 
-window.isPure = function(slave) {
+window.isPure = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant < 30) && (slave.bellyImplant === -1) && (Math.abs(slave.shouldersImplant) < 2) && (Math.abs(slave.hipsImplant) < 2));
 };
 
-window.modScore = function modScore(slave) {
+window.modScore = /** @param {App.Entity.SlaveState} slave */ function modScore(slave) {
 	const V = State.variables;
 	V.piercingScore = PiercingScore(slave);
 	V.tatScore = TatScore(slave);
 	V.modScore = V.tatScore + V.piercingScore;
 };
 
-window.PiercingScore = function(slave) {
+window.PiercingScore = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let piercingScore = 0;
 
 	if (slave.earPiercing > 0) {
@@ -117,7 +117,7 @@ window.PiercingScore = function(slave) {
 	return piercingScore;
 };
 
-window.TatScore = function(slave) {
+window.TatScore = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let tatScore = 0;
 
 	if (slave.boobsTat !== 0) {
@@ -174,7 +174,7 @@ window.TatScore = function(slave) {
 	return tatScore;
 };
 
-window.slimPass = function(slave) {
+window.slimPass = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let slimPass = 0;
 	let ArcologyZero = State.variables.arcologies[0];
 
@@ -213,16 +213,17 @@ window.isRivalP = function isRivalP(slave, target) {
 	return slave.rivalryTarget === target.ID;
 };
 
-window.supremeRaceP = function supremeRaceP(slave) {
+window.supremeRaceP = /** @param {App.Entity.SlaveState} slave */ function supremeRaceP(slave) {
 	return State.variables.arcologies[0].FSSupremacistRace === slave.race;
 };
 
-window.inferiorRaceP = function inferiorRaceP(slave) {
+window.inferiorRaceP = /** @param {App.Entity.SlaveState} slave */ function inferiorRaceP(slave) {
 	return State.variables.arcologies[0].FSSubjugationistRace === slave.race;
 };
 
-window.isLeaderP = function isLeaderP(slave) {
+window.isLeaderP = /** @param {App.Entity.SlaveState} slave */ function isLeaderP(slave) {
 	const V = State.variables;
+	/** @type {App.Entity.SlaveState[]}*/
 	const leaders = [V.HeadGirl, V.Bodyguard, V.Recruiter, V.Concubine, V.Nurse, V.Attendant, V.Matron, V.Madam, V.DJ, V.Milkmaid, V. Farmer, V.Stewardess, V.Schoolteacher, V.Wardeness];
 	return leaders.some(leader => leader.ID && leader.ID === slave.ID);
 };
@@ -243,7 +244,7 @@ window.properMaster = function properMaster() {
 	else return "Mistress";
 };
 
-window.newSlave = function newSlave(slave) {
+window.newSlave = /** @param {App.Entity.SlaveState} slave */ function newSlave(slave) {
 	const V = State.variables;
 
 	if (slave.override_Eye_Color !== 1) {
@@ -371,7 +372,7 @@ window.newSlave = function newSlave(slave) {
 	}
 };
 
-window.newChild = function newChild(child) {
+window.newChild = /** @param {App.Entity.SlaveState} slave */ function newChild(child) {
 	const V = State.variables;
 
 	child.age = 0; /* not sure if this is the correct way to do this or if more is required */
@@ -453,7 +454,7 @@ window.newChild = function newChild(child) {
 	State.variables.nurseryBabies++;
 };
 
-window.addSlave = function addSlave(slave) {
+window.addSlave = /** @param {App.Entity.SlaveState} slave */ function addSlave(slave) {
 	State.variables.slaves.push(slave);
 	State.variables.slaveIndices[slave.ID] = State.variables.slaves.length - 1;
 };
@@ -471,7 +472,7 @@ window.slaves2indices = function slaves2indices() {
 	State.variables.slaves.forEach((slave, i) => obj[slave.ID] = i);
 	return obj;
 };
-window.getSlave = function getSlave(ID) {
+window.getSlave = /** @returns {App.Entity.SlaveState} */ function getSlave(ID) {
 	const index = State.variables.slaveIndices[ID];
 	if (index === undefined) return undefined;
 	else return State.variables.slaves[index];
@@ -480,7 +481,7 @@ window.getChild = function getChild(ID) {
 	const V = State.variables;
 	return V.cribs.find(function(s) { return s.ID == ID; });
 };
-window.getPronouns = function getPronouns(slave) {
+window.getPronouns = /** @param {App.Entity.SlaveState} slave */ function getPronouns(slave) {
 	return {
 		pronoun: slave.pronoun,
 		possessivePronoun: slave.possessivePronoun,
@@ -490,7 +491,7 @@ window.getPronouns = function getPronouns(slave) {
 		noun: slave.noun };
 };
 
-window.SlavePronouns = function SlavePronouns(slave) {
+window.SlavePronouns = /** @param {App.Entity.SlaveState} slave */ function SlavePronouns(slave) {
 	const V = State.variables;
 	const pronouns = getPronouns(slave);
 	V.pronoun = pronouns.pronoun;
@@ -500,7 +501,7 @@ window.SlavePronouns = function SlavePronouns(slave) {
 	V.object = pronouns.object;
 };
 
-window.WrittenMaster = function WrittenMaster(slave) {
+window.WrittenMaster = /** @param {App.Entity.SlaveState} slave */ function WrittenMaster(slave) {
 	const V = State.variables;
 	if (slave !== undefined)
 		Enunciate(slave);
@@ -509,7 +510,7 @@ window.WrittenMaster = function WrittenMaster(slave) {
 	return V.writtenTitle;
 };
 
-window.Enunciate = function Enunciate(slave) {
+window.Enunciate = /** @param {App.Entity.SlaveState} slave */ function Enunciate(slave) {
 	const V = State.variables;
 	if (SlaveStatsChecker.checkForLisp(slave)) {
 		if (V.PC.customTitleLisp !== undefined)
@@ -642,7 +643,7 @@ window.Enunciate = function Enunciate(slave) {
 	}
 };
 
-window.fetishChangeChance = function fetishChangeChance(slave) {
+window.fetishChangeChance = /** @param {App.Entity.SlaveState} slave */ function fetishChangeChance(slave) {
 	const V = State.variables;
 	var chance = 0, sex = 0;
 
@@ -659,7 +660,7 @@ window.fetishChangeChance = function fetishChangeChance(slave) {
 	return chance;
 };
 
-window.SlaveFullName = function SlaveFullName(slave) {
+window.SlaveFullName = /** @param {App.Entity.SlaveState} slave */ function SlaveFullName(slave) {
 	const V = State.variables;
 	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))
@@ -667,7 +668,7 @@ window.SlaveFullName = function SlaveFullName(slave) {
 	return pair.join(" ");
 };
 
-window.SlaveFullBirthName = function SlaveFullBirthName(slave) {
+window.SlaveFullBirthName = /** @param {App.Entity.SlaveState} slave */ function SlaveFullBirthName(slave) {
 	const V = State.variables;
 	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))
@@ -1226,7 +1227,7 @@ window.PCTitle = function PCTitle() {
 	}
 };
 
-window.PoliteRudeTitle = function PoliteRudeTitle(slave) {
+window.PoliteRudeTitle = /** @param {App.Entity.SlaveState} slave */ function PoliteRudeTitle(slave) {
 	const V = State.variables, PC = V.PC, s = V.sEnunciate, ss = V.ssEnunciate;
 
 	var r = "";
@@ -1250,7 +1251,7 @@ window.PoliteRudeTitle = function PoliteRudeTitle(slave) {
 	return r;
 };
 
-window.SlaveTitle = function SlaveTitle(slave) {
+window.SlaveTitle = /** @param {App.Entity.SlaveState} slave */ function SlaveTitle(slave) {
 	const V = State.variables;
 	let r = "";
 	if (V.newDescriptions === 1) {
@@ -1600,7 +1601,7 @@ window.SlaveTitle = function SlaveTitle(slave) {
 	return r;
 };
 
-window.DegradingName = function DegradingName(slave) {
+window.DegradingName = /** @param {App.Entity.SlaveState} slave */ function DegradingName(slave) {
 	const V = State.variables;
 	const leadershipPosition = [
 		"be the Attendant",
@@ -1996,7 +1997,7 @@ window.DegradingName = function DegradingName(slave) {
 	slave.slaveSurname = surname;
 };
 
-window.SlaveSort = function SlaveSort(slaves, main=false) {
+window.SlaveSort = /** @param {App.Entity.SlaveState[]} slaves */ function SlaveSort(slaves, main = false) {
 	const V = State.variables;
 	if (main) {
 		switch (V.sortSlavesBy) {
@@ -2051,7 +2052,7 @@ window.SlaveSort = function SlaveSort(slaves, main=false) {
 	}
 };
 
-window.slaveSortMinor = function slaveSortMinor(slaves) {
+window.slaveSortMinor = /** @param {App.Entity.SlaveState[]} slaves */ function slaveSortMinor(slaves) {
 	slaves = slaves.sort((a, b) => a.slaveName < b.slaveName ? -1 : 1);
 };
 
@@ -2109,7 +2110,7 @@ window.MenialPopCap = function MenialPopCap () {
 	return r;
 };
 
-window.faceIncrease = function faceIncrease(slave, amount) {
+window.faceIncrease = /** @param {App.Entity.SlaveState} slave */ function faceIncrease(slave, amount) {
 	const pronouns = getPronouns(slave);
 	const his = pronouns.possessive;
 	const His = capFirstChar(his);
@@ -2131,7 +2132,7 @@ window.faceIncrease = function faceIncrease(slave, amount) {
 	return r;
 };
 
-window.Deadliness = function Deadliness(slave) {
+window.Deadliness = /** @param {App.Entity.SlaveState} slave */ function Deadliness(slave) {
 	const V = State.variables;
 	let deadliness = 2;
 
diff --git a/src/js/birthJS.js b/src/js/birthJS.js
index 87cdbf48095cbdc775475aba8cf8fd04487cdcdc..fe3c117fcc06812453909bca19df30512854af2c 100644
--- a/src/js/birthJS.js
+++ b/src/js/birthJS.js
@@ -1,4 +1,5 @@
-window.BirthDestinationText = function(choice,slave) {
+/** @param {App.Entity.SlaveState} slave */
+window.BirthDestinationText = function (choice, slave) {
 	var pronouns = getPronouns(slave);
 	var he = pronouns.pronoun, him = pronouns.object, his = pronouns.possessive, hers = pronouns.possessivePronoun, himself = pronouns.objectReflexive, boy = pronouns.noun;
 	var He = capFirstChar(he), His = capFirstChar(his);
@@ -39,7 +40,7 @@ window.BirthDestinationText = function(choice,slave) {
 			break;
 		case "Orphanage":
 			if (slave.burst < 1) {
-				if (slave.fetish == "mindbroken" || slave.fuckdoll > 0) {
+				if (slave.fetish === "mindbroken" || slave.fuckdoll > 0) {
 					r += `has few thoughts about the matter.`;
 				} else if (slave.devotion > 95) {
 					r += `worships you so completely that ${he} will not resent this.`;
diff --git a/src/js/datatypeCleanupJS.js b/src/js/datatypeCleanupJS.js
index 99bb6c3af11fc0e214bfb0898ccc6e090ba40dca..1a477e4b2e1d1d3f028c71a7a5f4069e773e5229 100644
--- a/src/js/datatypeCleanupJS.js
+++ b/src/js/datatypeCleanupJS.js
@@ -30,6 +30,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 	let V;
 	return SlaveDatatypeCleanup;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function SlaveDatatypeCleanup(slave) {
 		V = State.variables;
 		slaveAgeDatatypeCleanup(slave);
@@ -57,9 +58,10 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		generatePronouns(slave);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveAgeDatatypeCleanup(slave) {
 		slave.birthWeek = Math.clamp(+slave.birthWeek, 0, 51) || 0;
-		if (slave.age > 0) {
+		if (slave.age > 0) { // delete slave.age?
 			slave.actualAge = Math.clamp(+slave.actualAge, V.minimumSlaveAge, Infinity) || slave.age; /* if undefined, this sets to slave.age */
 		} else {
 			slave.actualAge = Math.clamp(+slave.actualAge, V.minimumSlaveAge, Infinity) || 18;
@@ -74,6 +76,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.NCSyouthening = Math.max(+slave.NCSyouthening, 0) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slavePhysicalDatatypeCleanup(slave) {
 		if (typeof slave.nationality !== "string") {
 			slave.nationality = "slave";
@@ -102,6 +105,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.hips = Math.clamp(+slave.hips, -2, 3) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveFaceDatatypeCleanup(slave) {
 		slave.face = Math.clamp(+slave.face, -100, 100) || 0;
 		if (typeof slave.faceShape !== "string") {
@@ -125,6 +129,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveHairDatatypeCleanup(slave) {
 		if (typeof slave.hColor !== "string") {
 			slave.hColor = "brown";
@@ -163,6 +168,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveBoobsDatatypeCleanup(slave) {
 		slave.boobs = Math.max(+slave.boobs, 100) || 200;
 		if (typeof slave.boobShape !== "string") {
@@ -183,6 +189,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.lactationAdaptation = Math.clamp(+slave.lactationAdaptation, 0, 100) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveButtDatatypeCleanup(slave) {
 		if (slave.butt !== 0) {
 			slave.butt = Math.clamp(+slave.butt, 0, 20) || 1;
@@ -191,6 +198,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.analArea = Math.max(+slave.analArea, 0) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slavePregnancyDatatypeCleanup(slave) {
 		slave.induce = Math.clamp(+slave.induce, 0, 1) || 0;
 		slave.labor = Math.clamp(+slave.labor, 0, 1) || 0;
@@ -215,6 +223,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		WombNormalizePreg(slave);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveBellyDatatypeCleanup(slave) {
 		slave.inflation = Math.clamp(+slave.inflation, 0, 3) || 0;
 		if (typeof slave.inflationType !== "string") {
@@ -234,6 +243,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		SetBellySize(slave);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveGenitaliaDatatypeCleanup(slave) {
 		slave.vagina = Math.clamp(+slave.vagina, -1, 10) || 0;
 		slave.vaginaLube = Math.clamp(+slave.vaginaLube, 0, 2) || 0;
@@ -252,6 +262,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveImplantsDatatypeCleanup(slave) {
 		slave.ageImplant = Math.clamp(+slave.ageImplant, 0, 1) || 0;
 		slave.faceImplant = Math.clamp(+slave.faceImplant, 0, 100) || 0;
@@ -268,6 +279,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.hipsImplant = Math.clamp(+slave.hipsImplant, -1, 1) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slavePiercingsDatatypeCleanup(slave) {
 		slave.earPiercing = Math.clamp(+slave.earPiercing, 0, 2) || 0;
 		slave.nosePiercing = Math.clamp(+slave.nosePiercing, 0, 2) || 0;
@@ -284,6 +296,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.anusPiercing = Math.clamp(+slave.anusPiercing, 0, 2) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveTattooDatatypeCleanup(slave) {
 		if (typeof slave.shouldersTat !== "string") {
 			slave.shouldersTat = 0;
@@ -326,6 +339,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveCosmeticsDatatypeCleanup(slave) {
 		slave.makeup = Math.clamp(+slave.makeup, 0, 8) || 0;
 		slave.nails = Math.clamp(+slave.nails, 0, 9) || 0;
@@ -381,6 +395,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveDietDatatypeCleanup(slave) {
 		if (typeof slave.diet !== "string") {
 			slave.diet = "healthy";
@@ -397,6 +412,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.curatives = Math.clamp(+slave.curatives, 0, 2) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slavePornDatatypeCleanup(slave) {
 		slave.pornFeed = Math.clamp(+slave.pornFeed, 0, 1) || 0;
 		slave.pornFame = Math.max(+slave.pornFame, 0) || 0;
@@ -448,6 +464,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.pornTypePregnancy = Math.max(+slave.pornTypePregnancy, 0) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveRelationDatatypeCleanup(slave) {
 		slave.mother = +slave.mother || 0;
 		slave.father = +slave.father || 0;
@@ -462,6 +479,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.cloneID = +slave.cloneID || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveSkillsDatatypeCleanup(slave) {
 		slave.oralSkill = Math.clamp(+slave.oralSkill, 0, 100) || 0;
 		slave.vaginalSkill = Math.clamp(+slave.vaginalSkill, 0, 100) || 0;
@@ -487,6 +505,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.skillW = Math.clamp(+slave.skillW, 0, 200) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveStatCountDatatypeCleanup(slave) {
 		slave.oralCount = Math.max(+slave.oralCount, 0) || 0;
 		slave.vaginalCount = Math.max(+slave.vaginalCount, 0) || 0;
@@ -507,6 +526,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.bodySwap = Math.max(+slave.bodySwap, 0) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slavePreferencesDatatypeCleanup(slave) {
 		slave.energy = Math.clamp(+slave.energy, 0, 100) || 0;
 		slave.need = Math.max(+slave.need, 0) || 0;
@@ -517,6 +537,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.fetishKnown = Math.clamp(+slave.fetishKnown, 0, 1) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveRulesDatatypeCleanup(slave) {
 		if (typeof slave.standardPunishment !== "string") {
 			slave.standardPunishment = "situational";
@@ -534,6 +555,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		slave.rudeTitle = Math.clamp(+slave.rudeTitle, 0, 1) || 0;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveCustomStatsDatatypeCleanup(slave) {
 		if (typeof slave.customLabel !== "string") {
 			slave.customLabel = "";
@@ -552,6 +574,7 @@ window.SlaveDatatypeCleanup = (function SlaveDatatypeCleanup() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveMiscellaneousDatatypeCleanup(slave) {
 		slave.weekAcquired = Math.max(+slave.weekAcquired, 0) || 0;
 		slave.newGamePlus = Math.clamp(+slave.newGamePlus, 0, 1) || 0;
diff --git a/src/js/extendedFamilyModeJS.js b/src/js/extendedFamilyModeJS.js
index 805f26b5a82fd5e0a56db4942456ad37fc14ecb3..89a00a747d7b55dcf59b333d9be65de448eea44a 100644
--- a/src/js/extendedFamilyModeJS.js
+++ b/src/js/extendedFamilyModeJS.js
@@ -113,11 +113,12 @@ window.areSisters = function(c1, c2) {
 }
 */
 
-window.areRelated = function (slave1, slave2) {
+window.areRelated = /** @param {App.Entity.SlaveState} slave1, @param {App.Entity.SlaveState} slave2 */
+	function (slave1, slave2) {
 	return (slave1.father === slave2.ID || slave1.mother === slave2.ID || slave2.father === slave1.ID || slave2.mother === slave1.ID || areSisters(slave1, slave2) > 0);
 };
 
-window.totalRelatives = function(slave) {
+window.totalRelatives = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	var relatives = 0;
 	if (slave.mother > 0) {
 		relatives += 1;
@@ -134,11 +135,16 @@ window.totalRelatives = function(slave) {
 	return relatives;
 };
 
+/**
+ * @param {App.Entity.SlaveState} slave1
+ * @param {App.Entity.SlaveState} slave2
+ * @param {App.Entity.SlaveState[]} slaves
+ */
 window.mutualChildren = function (slave1, slave2, slaves) {
 	return slaves.filter(function (s) { return s.ID !== slave1.ID && s.ID !== slave2.ID && s.mother > 0 && s.father > 0 && ((s.mother === slave1.ID && s.father === slave2.ID) || (s.mother === slave2.ID && s.father === slave1.ID)); }).length;
 };
 
-window.isSlaveAvailable = function(slave) {
+window.isSlaveAvailable = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.assignment === "be your agent") {
@@ -173,7 +179,7 @@ window.randomRelatedSlave = function(slave, filterFunction) {
 }
 */
 
-window.randomRelatedSlave = function (slave, filterFunction) {
+window.randomRelatedSlave = /** @param {App.Entity.SlaveState} slave */ function (slave, filterFunction) {
 	if (!slave || !SugarCube) { return undefined; }
 	if (typeof filterFunction !== 'function') {
 		filterFunction = function (/*s, index, array*/) { return true; };
@@ -189,39 +195,39 @@ window.randomRelatedSlave = function (slave, filterFunction) {
 	});
 };
 
-window.randomRelatedAvailableSlave = function (slave) {
+window.randomRelatedAvailableSlave = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return isSlaveAvailable(s); });
 };
 
-window.randomSister = function (slave) {
+window.randomSister = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return areSisters(slave, s); });
 };
 
-window.randomTwinSister = function(slave) {
+window.randomTwinSister = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function(s) { return areSisters(slave, s) === 1; });
 };
 
-window.randomAvailableSister = function (slave) {
+window.randomAvailableSister = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return isSlaveAvailable(s) && areSisters(slave, s); });
 };
 
-window.randomAvailableTwinSister = function (slave) {
+window.randomAvailableTwinSister = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return isSlaveAvailable(s) && areSisters(slave, s) === 1; });
 };
 
-window.randomDaughter = function (slave) {
+window.randomDaughter = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return s.mother === slave.ID || s.father === slave.ID; });
 };
 
-window.randomAvailableDaughter = function (slave) {
+window.randomAvailableDaughter = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return isSlaveAvailable(s) && (s.mother === slave.ID || s.father === slave.ID); });
 };
 
-window.randomParent = function (slave) {
+window.randomParent = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return s.ID === slave.mother || s.ID === slave.father; });
 };
 
-window.randomAvailableParent = function (slave) {
+window.randomAvailableParent = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	return randomRelatedSlave(slave, function (s) { return isSlaveAvailable(s) && (s.ID === slave.mother || s.ID === slave.father); });
 };
 
@@ -242,7 +248,8 @@ window.totalPlayerRelatives = function(pc) {
 	return relatives;
 };
 
-window.relativeTerm = function (slave1, slave2) {
+window.relativeTerm = /** @param {App.Entity.SlaveState} slave1 @param {App.Entity.SlaveState} slave2 */
+	function (slave1, slave2) {
 	if (slave2.mother === slave1.ID || slave2.father === slave1.ID) {
 		return "daughter";
 	} else if (slave1.mother === slave2.ID) {
diff --git a/src/js/food.js b/src/js/food.js
index 1d5986b25f2430f25a401cbd3f9955038ffaeeec..e0a29d904ad28c1f856194183a7aab9c05491666 100644
--- a/src/js/food.js
+++ b/src/js/food.js
@@ -1,3 +1,4 @@
+/** @param {App.Entity.SlaveState} slave */
 window.foodAmount = function (slave) {
 	const V = State.variables;
 	var food = 400;									 //kg / food produced by base slave / week
@@ -53,6 +54,7 @@ window.foodAmount = function (slave) {
 	}
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.farmShowsIncome = function (slave) {
 	//TODO: incorporate farmyardRestraints
 	const V = State.variables;
diff --git a/src/js/generateNewSlaveJS.js b/src/js/generateNewSlaveJS.js
index 9a2bb25283f7049f97bc4e2890a4dadf32a114d0..f4dee9f0c0ae93aca3a1c856b740bf3b3d9db091 100644
--- a/src/js/generateNewSlaveJS.js
+++ b/src/js/generateNewSlaveJS.js
@@ -1,6 +1,8 @@
 window.GenerateNewSlave = (function(){
 	'use strict';
-	let V, slave, chance;
+	let V, chance;
+	/** @type {App.Entity.SlaveState} */
+	let slave;
 
 	function GenerateNewSlave(sex) {
 		V = State.variables;
diff --git a/src/js/pregJS.js b/src/js/pregJS.js
index 1014ba089db7e107db5276e14a266c088b718d6b..74c2dabe3087e6b4d27181cc66abfa0a0dd9e2fa 100644
--- a/src/js/pregJS.js
+++ b/src/js/pregJS.js
@@ -16,6 +16,7 @@ window.getPregBellySize = function(s) {
 	return bellySize;
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.bellyAdjective = function(slave) {
 	slave = slave || State.variables.activeSlave;
 	if(slave.belly >= 1500) {
@@ -512,6 +513,7 @@ window.adjustFatherProperty = function(actor, property, newValue) {
 */
 
 /* not to be used until that last part is defined. It may become slave.boobWomb.volume or some shit */
+/** @param {App.Entity.SlaveState} slave */
 window.getBaseBoobs = function(slave) {
 	return slave.boobs-slave.boobsImplant-slave.boobsMilk-slave.boobsWombVolume;
 };
diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js
index 04f337e56d3cdcb0817ab116ccc331a1284e0146..71186a3b55707ef6876b8d5a764ae28d43279e3a 100644
--- a/src/js/rulesAssistant.js
+++ b/src/js/rulesAssistant.js
@@ -1,25 +1,31 @@
-window.hasSurgeryRule = function(slave, rules) {
+/** @param {App.Entity.SlaveState} slave */
+window.hasSurgeryRule = function (slave, rules) {
 	return rules.some(
 		rule => ruleApplied(slave, rule) && rule.set.autoSurgery > 0);
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.hasRuleFor = function(slave, rules, what) {
 	return rules.some(
 		rule => ruleApplied(slave, rule) && rule[what] !== "no default setting");
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.hasHColorRule = function(slave, rules) {
 	return hasRuleFor(slave, rules, "hColor");
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.hasHStyleRule = function(slave, rules) {
 	return hasRuleFor(slave, rules, "hStyle");
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.hasEyeColorRule = function(slave, rules) {
 	return hasRuleFor(slave, rules, "eyeColor");
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.lastPregRule = function(slave, rules) {
 	return rules.some(rule =>
 		ruleApplied(slave, rule) && rule.set.preg === -1);
@@ -44,11 +50,13 @@ window.mergeRules = function mergeRules(rules) {
 };
 
 // return if a rule is applied on a slave
+/** @param {App.Entity.SlaveState} slave */
 window.ruleApplied = function(slave, rule) {
 	return slave.currentRules.includes(rule.ID);
 };
 
 // remove slave from the facility described by the rule
+/** @param {App.Entity.SlaveState} slave */
 window.RAFacilityRemove = function RAFacilityRemove(slave, rule) {
 	const V = State.variables;
 	let r = "";
@@ -148,6 +156,7 @@ window.RAFacilityRemove = function RAFacilityRemove(slave, rule) {
 };
 
 // return whether the rule applies to the slave
+/** @param {App.Entity.SlaveState} slave */
 window.ruleAppliesP = function ruleAppliesP(cond, slave) {
 	let flag;
 
@@ -321,6 +330,7 @@ window.emptyDefaultRule = function emptyDefaultRule() {
 
 // Saves the slave, silently fires the RA, saves the slave's after-RA state, and then reverts the slave.
 // Call and then check potential change against $slaveAfterRA to see if the RA would revert it.
+/** @param {App.Entity.SlaveState} slave */
 window.RulesDeconfliction = function RulesDeconfliction(slave) {
 	const before = clone(slave);
 	DefaultRules(slave);
diff --git a/src/js/rulesAutosurgery.js b/src/js/rulesAutosurgery.js
index 0ed9519c497f3f51b5d1bb2e7cb09f7e73de9829..5ea93996ffc11ed0593907c1e12353dea69817d1 100644
--- a/src/js/rulesAutosurgery.js
+++ b/src/js/rulesAutosurgery.js
@@ -4,6 +4,7 @@ window.rulesAutosurgery = (function() {
 	let r;
 	return rulesAutoSurgery;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function rulesAutoSurgery(slave) {
 		V = State.variables;
 		r = "";
@@ -16,6 +17,7 @@ window.rulesAutosurgery = (function() {
 		return r;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function autoSurgerySelector(slave, ruleset) {
 		const surgery = {};
 		ruleset.forEach(rule => {
@@ -28,6 +30,7 @@ window.rulesAutosurgery = (function() {
 		return surgery;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function ProcessHGTastes(slave) {
 		let thisSurgery;
 		switch (V.HGTastes) {
@@ -123,6 +126,7 @@ window.rulesAutosurgery = (function() {
 		return thisSurgery;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function CommitSurgery(slave, thisSurgery, surgeries) {
 		if ((slave.eyes === -1) && (thisSurgery.surgery_eyes === 1)) {
 			surgeries.push("surgery to correct her vision");
@@ -534,6 +538,7 @@ window.rulesAutosurgery = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function PrintResult(slave, thisSurgery, surgeries) {
 		let surgeriesDisplay = "";
 		if (surgeries.length === 1)
@@ -545,6 +550,7 @@ window.rulesAutosurgery = (function() {
 		r += `${V.assistantName === "your personal assistant" ? "Your personal assistant" : V.assistantName}, ordered to apply surgery, gives ${slave.slaveName} <span class="lime">${surgeriesDisplay}.</span>`;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function bellyIn(slave) {
 		// less hacky version of calling surgery degradation silently
 		if (slave.devotion > 50)
diff --git a/src/js/sexActsJS.js b/src/js/sexActsJS.js
index ee6328300eda2782e8ee70149daf38bec6036ece..1662add29c0da75051c5a7e6e6a0d1bc02bd2f26 100644
--- a/src/js/sexActsJS.js
+++ b/src/js/sexActsJS.js
@@ -360,11 +360,11 @@ window.PartnerVCheck = function PartnerVCheck(analTimes, bothTimes) {
 	return r;
 };
 
-/*
+/**
  count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave.
  If count is left undefined it will assume it to be 1.
  Intended to be a simple "I want to fuck x and not have to code a bunch of logic for it".
-*/
+ @param {App.Entity.SlaveState} slave */
 window.SimpleSexAct = function SimpleSexAct(slave, count) {
 	const V = State.variables;
 	let fuckTarget = 0;
@@ -398,11 +398,12 @@ window.SimpleSexAct = function SimpleSexAct(slave, count) {
 	return r;
 };
 
-/*
+/**
  count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave.
  If count is left undefined it will assume it to be 1.
  Intended to be a simple "x got fucked y times and I don't want to keep coding it".
  Pregnancy chance is handled in saLongTermEffects.tw.
+ @param {App.Entity.SlaveState} slave
 */
 window.SimpleSlaveFucking = function SimpleSlaveFucking(slave, count) {
 	const V = State.variables;
@@ -430,10 +431,12 @@ window.SimpleSlaveFucking = function SimpleSlaveFucking(slave, count) {
 	return;
 };
 
-/*
+/**
  count is how many times to increment either the Vaginal, Anal, or Oral counts, depending on availability of slave.
  If count is left undefined it will assume it to be 1.
  Intended to be a simple "x got fucked y times by z and I don't want to keep coding it".
+ @param {App.Entity.SlaveState} subslave
+ @param {App.Entity.SlaveState} domslave
 */
 window.SimpleSlaveSlaveFucking = function SimpleSlaveSlaveFucking(subslave, domslave, count) {
 	const V = State.variables;
@@ -518,6 +521,7 @@ window.SimpleSlaveSlaveFucking = function SimpleSlaveSlaveFucking(subslave, doms
 	return r;
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.SimpleVaginaFuck = function SimpleVaginaFuck(slave, count) {
 	if (count) {
 		State.variables.vaginalTotal += count;
@@ -528,6 +532,7 @@ window.SimpleVaginaFuck = function SimpleVaginaFuck(slave, count) {
 	}
 };
 
+/** @param {App.Entity.SlaveState} slave */
 window.SimpleAssFuck = function SimpleAssFuck(slave, count) {
 	if (count) {
 		State.variables.analTotal += count;
diff --git a/src/js/slaveCostJS.js b/src/js/slaveCostJS.js
index 0bcdefa256fa343f0f02405493592da5242ce406..d3ab4af31bc72467daabdc753096c705ecb1fb7f 100644
--- a/src/js/slaveCostJS.js
+++ b/src/js/slaveCostJS.js
@@ -2,6 +2,7 @@ window.Beauty = (function() {
 	"use strict";
 	let V, arcology, beauty;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function Beauty(slave) {
 		V = State.variables;
 		arcology = V.arcologies[0];
@@ -67,6 +68,7 @@ window.Beauty = (function() {
 		return beauty;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcInitBeauty(slave) {
 		beauty -= slave.waist/20;
 		beauty -= slave.muscles/30;
@@ -83,6 +85,7 @@ window.Beauty = (function() {
 
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFaceBeauty(slave) {
 		beauty += slave.face/5;
 		switch (slave.faceShape) {
@@ -116,6 +119,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcTeethBeauty(slave) {
 		switch (slave.teeth) {
 			case "crooked":
@@ -167,6 +171,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcCosmeticsBeauty(slave) {
 		if (slave.brand !== 0) {
 			if (V.rep > 10000) {
@@ -214,6 +219,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFSNotFuckdollBeauty(slave) {
 		if (arcology.FSSupremacist !== "unset") {
 			if (slave.race === arcology.FSSupremacistRace) {
@@ -283,6 +289,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcMiscNotFuckdollBeauty(slave) {
 		beauty += Math.min(slave.health, 100)/5;
 		beauty += slave.voice;
@@ -302,6 +309,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcDickBeauty(slave) {
 		if (arcology.FSAssetExpansionist > 20 && arcology.FSGenderFundamentalist === "unset") {
 			if (slave.dick >= 20) {
@@ -328,6 +336,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcBallsBeauty(slave) {
 		if (arcology.FSAssetExpansionist > 20 && arcology.FSGenderFundamentalist === "unset") {
 			if (slave.balls > 100) {
@@ -367,6 +376,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcButtBeauty(slave) {
 		if (slave.butt <= 10) {
 			beauty += 1.5*slave.butt; /*max 15*/
@@ -419,6 +429,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcHipsBeauty(slave) { /* butts in general may need buffs */
 		switch (slave.hips) {
 			case -2:
@@ -486,6 +497,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcBoobsBeauty(slave) {
 		if ((arcology.FSTransformationFetishist > 20 && arcology.FSSlimnessEnthusiast === "unset") || arcology.FSAssetExpansionist > 20) {
 			if (slave.boobs <= 500) {
@@ -593,6 +605,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcWeightBeauty(slave) {
 		if (arcology.FSHedonisticDecadence > 20) {
 			if (slave.weight < -95) {
@@ -650,6 +663,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcMusclesBeauty(slave) {
 		if (arcology.FSPhysicalIdealist !== "unset") {
 			if (arcology.FSPhysicalIdealistLaw === 1) {
@@ -676,6 +690,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcBodyHairBeauty(slave) {
 		if (slave.physicalAge < 11) {
 			beauty += 4;
@@ -726,6 +741,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcImplantBeauty(slave) {
 		if (arcology.FSTransformationFetishist !== "unset") {
 			if (Math.abs(slave.shouldersImplant) > 1) {
@@ -754,6 +770,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcRepopulationPregBeauty(slave) {
 		if (slave.preg > slave.pregData.normalBirth/1.33) { /*limited huge boost for full term */
 			if (slave.broodmother > 0) {
@@ -797,6 +814,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcTrendyPregBeauty(slave) {
 		if (slave.preg > slave.pregData.normalBirth/1.33) { /*limited huge boost for full term */
 			beauty += 20;
@@ -805,6 +823,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcRestartPregBeauty(slave) {
 		if (slave.breedingMark === 1 && V.propOutcome === 1) {
 			if (slave.preg > slave.pregData.normalBirth/8 && slave.pregSource === -1) {
@@ -850,6 +869,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcTrendyMilfBeauty(slave) {
 		if (slave.births > 50) {
 			beauty += 6;
@@ -858,6 +878,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFutaLawBeauty(slave) {
 		switch (arcology.FSGenderRadicalistLawFuta) {
 			case 1:
@@ -883,6 +904,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFutaLawTrueFutaBeauty(slave) {
 		if (slave.dick <= 10) {
 			beauty += slave.dick;
@@ -893,6 +915,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFutaLawBigDickBeauty(slave) {
 		beauty += slave.dick;
 		if (slave.balls > 120) {
@@ -914,6 +937,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFutaLawBigBootyBeauty(slave) {
 		if (slave.hips >= 1) {
 			beauty += 4*(slave.hips - 1); /*8*/
@@ -932,6 +956,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFutaLawFemboyBeauty(slave) {
 		if (arcology.FSSlimnessEnthusiast === "unset") { /*balance with slimness*/
 			beauty += 20;
@@ -961,6 +986,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcBodyProportionBeauty(slave) {
 		if (arcology.FSGenderFundamentalist !== "unset") {
 			if (slave.shoulders > slave.hips) {
@@ -977,6 +1003,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcVoiceBeauty(slave) {
 		if (canTalk(slave)) {
 			if (slave.accent >= 3) {
@@ -989,6 +1016,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcLimbsBeauty(slave) {
 		switch (slave.amp) {
 			case 1:
@@ -1002,6 +1030,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPubertyBeauty(slave) {
 		if (slave.pubertyXX === 1) {
 			beauty += 5;
@@ -1014,6 +1043,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFSMiscBeauty(slave) {
 		if (arcology.FSTransformationFetishist > 20) {
 			if (slave.lips > 70) {
@@ -1049,6 +1079,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPurityBeauty(slave) {
 		if (isPure(slave)) {
 			V.pure = V.pure++ || 1;
@@ -1063,6 +1094,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPhysiqueBeauty(slave) {
 		let physiquePass = 0;
 
@@ -1104,6 +1136,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcSlimBeauty(slave) {
 		if (slimPass(slave) === 1) {
 			beauty += 40 + (arcology.FSSlimnessEnthusiast/20); /*45*/
@@ -1112,6 +1145,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcGenderLawBeauty(slave) {
 		V.genderLawPass = 1;
 
@@ -1139,6 +1173,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcMultipliersBeauty(slave) {
 		calcBellyBeauty(slave);
 		if (slave.breedingMark === 1) {
@@ -1156,6 +1191,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcBellyBeauty(slave) {
 		if (slave.bellySag > 0) {
 			if (slave.belly < 100) {
@@ -1204,6 +1240,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcAgeBeauty(slave) {
 		if (slave.physicalAge === V.minimumSlaveAge) {
 			beauty += 1;
@@ -1230,6 +1267,7 @@ window.Beauty = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPrestigeBeauty(slave) { /* multipliers */
 		if (slave.prestige >= 3) {
 			beauty += 2*beauty;
@@ -1260,6 +1298,7 @@ window.FResult = (function() {
 	// we can't initialize our global variables on load, because SugarCube.State isn't initialized
 	// instead, declare them and initialize on run time
 	let V, result, incest_bonus;
+	/** @param {App.Entity.SlaveState} slave */
 	function FResult(slave) {
 		V = State.variables;
 		incest_bonus = V.arcologies[0].FSEgyptianRevivalist > 20 || V.arcologies[0].FSEgyptianRevivalistIncestPolicy === 1;
@@ -1304,6 +1343,7 @@ window.FResult = (function() {
 		return result;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcUseWeights(slave) {
 		result = (3 - slave.anus)+(slave.muscles/30);
 		if (slave.muscles < -95)
@@ -1331,12 +1371,14 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFuckableTits(slave) {
 		result += 2;
 		if (slave.fetish === "boobs")
 			result += Math.trunc(slave.fetishStrength/20);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcWorksWithRelatives(slave) {
 		V.slaves.forEach(islave => {
 			if (isParentP(slave, islave) && sameAssignmentP(slave, islave)) {
@@ -1350,6 +1392,7 @@ window.FResult = (function() {
 		});
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcWorksWithRelativesVanilla(slave) {
 		const fre = getSlave(slave.relationTarget);
 		if (fre !== undefined && sameAssignmentP(slave, fre)) {
@@ -1358,6 +1401,7 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcWorksWithRelationship(slave) {
 		const fre = V.slaves.findIndex(s => {
 			return haveRelationshipP(slave, s) && sameAssignmentP(slave, s);
@@ -1365,11 +1409,13 @@ window.FResult = (function() {
 		if (fre !== -1) result += 1;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcWorksWithRival(slave) {
 		const en = getSlave(slave.rivalryTarget);
 		if (en !== undefined && sameAssignmentP(slave, en)) result -= 1;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcHInjectionsDiet(slave) {
 		if (slave.drugs === "male hormone injections" || slave.drugs === "female hormone injections")
 			result -= 10;
@@ -1382,6 +1428,8 @@ window.FResult = (function() {
 		else if (slave.diet === "fertility")
 			result += 1;
 	}
+
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPreg(slave) {
 		if (V.arcologies[0].FSRepopulationFocus > 20) {
 			if (slave.belly >= 1500) result += 2;
@@ -1402,6 +1450,7 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcRace(slave) {
 		if (V.arcologies[0].FSSupremacist !== "unset" && supremeRaceP(slave))
 			result -= (V.arcologies[0].FSSupremacist/5) + (V.arcologies[0].FSSupremacistLawME*10);
@@ -1409,6 +1458,7 @@ window.FResult = (function() {
 			result += (V.arcologies[0].FSSubjugationist/10) + (V.arcologies[0].FSSubjugationistLawME);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcSexAttributes(slave) {
 		if (slave.clitPiercing > 2) result += 1;
 		if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish !== "none")
@@ -1429,6 +1479,7 @@ window.FResult = (function() {
 		if (slave.behavioralQuirk !== "none") result += 2;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcCareer(slave) {
 		if (setup.whoreCareers.includes(slave.career))
 			result += 1;
@@ -1436,6 +1487,7 @@ window.FResult = (function() {
 			result += 1;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcSight(slave) {
 		if (!canSee(slave)) result -= 3;
 		else if (slave.eyes <= -1) {
@@ -1447,6 +1499,7 @@ window.FResult = (function() {
 			result -= 1;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcHearing(slave) {
 		if (!canHear(slave)) result -= 2;
 		else if (slave.hears <= -1) {
@@ -1456,12 +1509,14 @@ window.FResult = (function() {
 			result -= 1;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcEgyptianBonus(slave) {
 		if (V.racialVarieties === undefined) V.racialVarieties = [];
 		if (!V.racialVarieties.includes(slave.race))
 			V.racialVarieties.push(slave.race);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcYouthBonus(slave) {
 		if (slave.visualAge < 30) {
 			if (slave.actualAge > 30)
@@ -1471,11 +1526,13 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcMatureBonus(slave) {
 		if (slave.visualAge >= 30 && slave.actualAge >= 30 && slave.physicalAge < slave.visualAge)
 			result += Math.min((slave.physicalAge - slave.visualAge) * 2, 20); // looks and acts mature, but has a body that just won't quit
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcNotFuckdoll(slave) {
 		if (V.familyTesting === 1 && totalRelatives(slave) > 0)
 			calcWorksWithRelatives(slave);
@@ -1498,6 +1555,7 @@ window.FResult = (function() {
 			calcMatureBonus(slave);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcAge(slave) {
 		if ((V.arcologies[0].FSRepopulationFocus !== "unset" || V.arcologies[0].FSGenderFundamentalist !== "unset") && slave.physicalAge === V.minimumSlaveAge && slave.physicalAge === V.fertilityAge && canGetPregnant(slave)) {
 			result += 1;
@@ -1516,6 +1574,7 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcAmputation(slave) {
 		switch(slave.amp) {
 		case 0:
@@ -1530,6 +1589,7 @@ window.FResult = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcHedonismWeight(slave) {
 		if (slave.weight < 10)
 			result -= 2;
@@ -1543,6 +1603,7 @@ window.slaveCost = (function() {
 	"use strict";
 	let V, arcology, multiplier, cost;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function slaveCost(slave, isStartingSlave) {
 		V = State.variables;
 		arcology = V.arcologies[0];
@@ -1571,6 +1632,7 @@ window.slaveCost = (function() {
 		return cost;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcGenitalsCost(slave) {
 		if (slave.vagina === 0) {
 			multiplier += 0.1;
@@ -1602,6 +1664,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcDevotionTrustCost(slave) {
 		if (V.specialSlavesPriceOverride === 1) {
 			if (slave.devotion > 50) {
@@ -1624,6 +1687,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPreferencesCost(slave) {
 		if (slave.behavioralFlaw !== "none") {
 			multiplier -= 0.1;
@@ -1655,6 +1719,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPregCost(slave) {
 		if (slave.mpreg === 1) {
 			multiplier += 0.2;
@@ -1692,6 +1757,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcPrestigeCost(slave) {
 		if (slave.prestige > 0) {
 			multiplier += 0.7*slave.prestige;
@@ -1705,6 +1771,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcFSCost(slave) {
 		if (arcology.FSSupremacistLawME !== 0) {
 			if (slave.race !== arcology.FSSupremacistRace) {
@@ -1759,6 +1826,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcAgeCost(slave) {
 		if (slave.physicalAge === V.minimumSlaveAge && slave.physicalAge === V.fertilityAge && canGetPregnant(slave) && (arcology.FSRepopulationFocus !== "unset" || arcology.FSGenderFundamentalist !== "unset")) {
 			if (slave.birthWeek === 0) {
@@ -1781,6 +1849,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcCareersCost(slave) {
 		if (slave.career !== 0) {
 			if (slave.career === "a slave") {
@@ -1878,6 +1947,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcMiscCost(slave) {
 		let totalInt = Math.clamp(slave.intelligence + slave.intelligenceImplant,-130,130); /* make absolutely certain we do not use +-131 in the next line */
 		multiplier += Math.floor((Math.asin(totalInt/131))*50)/50;
@@ -1899,6 +1969,7 @@ window.slaveCost = (function() {
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcIndentureCost(slave) {
 		if (slave.indenture > -1) {
 			multiplier -= 0.1*slave.indentureRestrictions;
@@ -1937,6 +2008,7 @@ window.slaveCost = (function() {
 		cost = 500*Math.trunc(cost/500);
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function calcStartingSlaveCost(slave) {
 		let startingSlaveMultiplier = 0;
 
@@ -1980,6 +2052,6 @@ window.slaveCost = (function() {
 	return slaveCost;
 })();
 
-window.startingSlaveCost = function startingSlaveCost(slave) {
+window.startingSlaveCost = /** @param {App.Entity.SlaveState} slave */ function startingSlaveCost(slave) {
 	return slaveCost(slave, true);
 };
diff --git a/src/js/slaveGenerationJS.js b/src/js/slaveGenerationJS.js
index 6cd4ed3ccd159115ba36fe5f141c7748b69dc338..6cbbe9b08178d4777ba52f9111495289936368d6 100644
--- a/src/js/slaveGenerationJS.js
+++ b/src/js/slaveGenerationJS.js
@@ -1,8 +1,8 @@
-window.nationalityToRace = function nationalityToRace(slave) {
+window.nationalityToRace = /** @param {App.Entity.SlaveState} slave */ function nationalityToRace(slave) {
 	slave.race = hashChoice(setup.raceSelector[slave.nationality] || setup.raceSelector[""]);
 };
 
-window.raceToNationality = function raceToNationality(slave) {
+window.raceToNationality = /** @param {App.Entity.SlaveState} slave */ function raceToNationality(slave) {
 	/* consider this placeholder until raceNationalities gets fixed up */
 	const V = State.variables;
 	slave.nationality = hashChoice(V.nationalities);
@@ -52,7 +52,7 @@ window.isMaleName = function isMaleName(name, nationality, race) {
 	return names && names.includes(name);
 };
 
-window.nationalityToName = function nationalityToName(slave) {
+window.nationalityToName = /** @param {App.Entity.SlaveState} slave */ function nationalityToName(slave) {
 	const V = State.variables;
 	const male = (slave.genes === "XY");
 
@@ -81,7 +81,7 @@ window.nationalityToName = function nationalityToName(slave) {
 	}
 };
 
-window.nationalityToAccent = function nationalityToAccent(slave) {
+window.nationalityToAccent = /** @param {App.Entity.SlaveState} slave */ function nationalityToAccent(slave) {
 	const V = State.variables;
 	const naturalAccent = jsEither([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]);
 
@@ -1354,7 +1354,7 @@ window.removeGingering = function removeGingering() {
 	}
 };
 
-window.randomizeAttraction = function randomizeAttraction(slave) {
+window.randomizeAttraction = /** @param {App.Entity.SlaveState} slave*/ function randomizeAttraction(slave) {
 	const sexuality = jsRandom(0, 100);
 	let attraction = Math.clamp(slave.energy * 2, 60, 180);
 
@@ -1390,374 +1390,10 @@ window.randomizeAttraction = function randomizeAttraction(slave) {
 };
 
 window.BaseSlave = function BaseSlave() {
-	State.variables.activeSlave = {
-		slaveName: "blank",
-		slaveSurname: 0,
-		birthName: "blank",
-		birthSurname: 0,
-		genes: "XX",
-		pronoun: "she",
-		possessive: "her",
-		possessivePronoun: "hers",
-		objectReflexive: "herself",
-		object: "her",
-		noun: "girl",
-		weekAcquired: 0,
-		origin: 0,
-		career: 0,
-		ID: 0,
-		prestige: 0,
-		pornFeed: 0,
-		pornFame: 0,
-		pornFameSpending: 0,
-		pornPrestige: 0,
-		pornPrestigeDesc: 0,
-		pornFameType: "none",
-		pornFocus: "none",
-		pornTypeGeneral: 0,
-		pornTypeFuckdoll: 0,
-		pornTypeRape: 0,
-		pornTypePreggo: 0,
-		pornTypeBBW: 0,
-		pornTypeGainer: 0,
-		pornTypeStud: 0,
-		pornTypeLoli: 0,
-		pornTypeDeepThroat: 0,
-		pornTypeStruggleFuck: 0,
-		pornTypePainal: 0,
-		pornTypeTease: 0,
-		pornTypeRomantic: 0,
-		pornTypePervert: 0,
-		pornTypeCaring: 0,
-		pornTypeUnflinching: 0,
-		pornTypeSizeQueen: 0,
-		pornTypeNeglectful: 0,
-		pornTypeCumAddict: 0,
-		pornTypeAnalAddict: 0,
-		pornTypeAttentionWhore: 0,
-		pornTypeBreastGrowth: 0,
-		pornTypeAbusive: 0,
-		pornTypeMalicious: 0,
-		pornTypeSelfHating: 0,
-		pornTypeBreeder: 0,
-		pornTypeSub: 0,
-		pornTypeCumSlut: 0,
-		pornTypeAnal: 0,
-		pornTypeHumiliation: 0,
-		pornTypeBoobs: 0,
-		pornTypeDom: 0,
-		pornTypeSadist: 0,
-		pornTypeMasochist: 0,
-		pornTypePregnancy: 0,
-		prestigeDesc: 0,
-		recruiter: 0,
-		relation: 0,
-		relationTarget: 0,
-		relationship: 0,
-		relationshipTarget: 0,
-		rivalry: 0,
-		rivalryTarget: 0,
-		subTarget: 0,
-		father: 0,
-		mother: 0,
-		daughters: 0,
-		sisters: 0,
-		canRecruit: 0,
-		choosesOwnAssignment: 0,
-		assignment: "rest",
-		assignmentVisible: 1,
-		sentence: 0,
-		training: 0,
-		toyHole: "all her holes",
-		indenture: -1,
-		indentureRestrictions: 0,
-		birthWeek: random(0,51),
-		actualAge: 18,
-		visualAge: 18,
-		physicalAge: 18,
-		ovaryAge: 18,
-		ageImplant: 0,
-		health: 0,
-		minorInjury: 0,
-		trust: 0,
-		oldTrust: 0,
-		devotion: 0,
-		oldDevotion: 0,
-		weight: 0,
-		muscles: 0,
-		height: 170,
-		heightImplant: 0,
-		nationality: "slave",
-		race: "white",
-		origRace: "white",
-		markings: "none",
-		eyes: 1,
-		eyeColor: "brown",
-		origEye: "brown",
-		pupil: "circular",
-		sclerae: "white",
-		eyewear: "none",
-		hears: 0,
-		earwear: "none",
-		earImplant: 0,
-		earShape: "normal",
-		origHColor: "brown",
-		hColor: "brown",
-		pubicHColor: "brown",
-		underArmHColor: "brown",
-		eyebrowHColor: "brown",
-		origSkin: "light",
-		skin: "light",
-		hLength: 60,
-		eyebrowFullness: "natural",
-		hStyle: "short",
-		pubicHStyle: "neat",
-		underArmHStyle: "neat",
-		eyebrowHStyle: "natural",
-		waist: 0,
-		corsetPiercing: 0,
-		PLimb: 0,
-		amp: 0,
-		heels:0,
-		voice: 2,
-		voiceImplant: 0,
-		accent: 0,
-		shoulders: 0,
-		shouldersImplant: 0,
-		boobs: 0,
-		boobsMilk: 0,
-		boobsImplant: 0,
-		boobsImplantType: 0,
-		boobShape: "normal",
-		nipples: "cute",
-		nipplesPiercing: 0,
-		nipplesAccessory: "none",
-		areolae: 0,
-		areolaePiercing: 0,
-		areolaeShape: "circle",
-		boobsTat: 0,
-		lactation: 0,
-		lactationDuration: 0,
-		induceLactation: 0,
-		lactationAdaptation: 0,
-		milk: 0,
-		cum: 0,
-		hips: 0,
-		hipsImplant: 0,
-		butt: 0,
-		buttImplant: 0,
-		buttImplantType: 0,
-		buttTat: 0,
-		face: 0,
-		faceImplant: 0,
-		faceShape: "normal",
-		lips: 15,
-		lipsImplant: 0,
-		lipsPiercing: 0,
-		lipsTat: 0,
-		teeth: "normal",
-		tonguePiercing: 0,
-		vagina: 0,
-		vaginaLube: 0,
-		vaginaPiercing: 0,
-		vaginaTat: 0,
-		preg: -1,
-		pregSource: 0,
-		pregType: 0,
-		pregAdaptation: 50,
-		ovaImplant: 0,
-		wombImplant: "none",
-		broodmother: 0,
-		broodmotherFetuses: 0,
-		broodmotherOnHold: 0,
-		broodmotherCountDown: 0,
-		labor: 0,
-		births: 0,
-		laborCount: 0,
-		cSec: 0,
-		bellyAccessory: "none",
-		labia: 0,
-		clit: 0,
-		clitPiercing: 0,
-		clitSetting: "vanilla",
-		foreskin: 0,
-		anus: 0,
-		dick: 0,
-		analArea: 1,
-		dickPiercing: 0,
-		dickTat: 0,
-		prostate: 0,
-		balls: 0,
-		scrotum: 0,
-		ovaries: 0,
-		anusPiercing: 0,
-		anusTat: 0,
-		makeup: 0,
-		nails: 0,
-		brand: 0,
-		brandLocation: 0,
-		earPiercing: 0,
-		nosePiercing: 0,
-		eyebrowPiercing: 0,
-		navelPiercing: 0,
-		shouldersTat: 0,
-		armsTat: 0,
-		legsTat: 0,
-		backTat: 0,
-		stampTat: 0,
-		vaginalSkill: 0,
-		oralSkill: 0,
-		analSkill: 0,
-		whoreSkill: 0,
-		entertainSkill: 0,
-		combatSkill: 0,
-		livingRules: "spare",
-		speechRules: "restrictive",
-		releaseRules: "restrictive",
-		relationshipRules: "restrictive",
-		lactationRules: "none",
-		standardPunishment: "situational",
-		standardReward: "situational",
-		useRulesAssistant: 1,
-		diet: "healthy",
-		dietCum: 0,
-		dietMilk: 0,
-		tired: 0,
-		hormones: 0,
-		drugs: "no drugs",
-		curatives: 0,
-		chem: 0,
-		aphrodisiacs: 0,
-		addict: 0,
-		fuckdoll: 0,
-		choosesOwnClothes: 0,
-		clothes: "no clothing",
-		collar: "none",
-		shoes: "none",
-		vaginalAccessory: "none",
-		dickAccessory: "none",
-		legAccessory: "none",
-		buttplug: "none",
-		buttplugAttachment: "none",
-		intelligence: 0,
-		intelligenceImplant: 0,
-		energy: 50,
-		need: 0,
-		attrXX: 0,
-		attrXY: 0,
-		attrKnown: 0,
-		fetish: "none",
-		fetishStrength: 70,
-		fetishKnown: 0,
-		behavioralFlaw: "none",
-		behavioralQuirk: "none",
-		sexualFlaw: "none",
-		sexualQuirk: "none",
-		geneticQuirks: {macromastia: 0, gigantomastia: 0, fertility: 0, hyperFertility: 0, superfetation: 0, gigantism: 0, dwarfism: 0, pFace: 0, uFace: 0, albinism: 0, rearLipedema: 0, wellHung: 0, wGain: 0, wLoss: 0, androgyny: 0},
-		oralCount: 0,
-		vaginalCount: 0,
-		analCount: 0,
-		mammaryCount: 0,
-		penetrativeCount: 0,
-		publicCount: 0,
-		pitKills: 0,
-		customTat: "",
-		customLabel: "",
-		customDesc: "",
-		customTitle: "",
-		customTitleLisp: "",
-		rudeTitle: 0,
-		customImage: 0,
-		currentRules: [],
-		bellyTat: 0,
-		induce: 0,
-		mpreg: 0,
-		inflation: 0,
-		inflationType: "none",
-		inflationMethod: 0,
-		milkSource: 0,
-		cumSource: 0,
-		burst: 0,
-		pregKnown: 0,
-		pregWeek: 0,
-		belly: 0,
-		bellyPreg: 0,
-		bellyFluid: 0,
-		bellyImplant: -1,
-		bellySag: 0,
-		bellySagPreg: 0,
-		bellyPain: 0,
-		cervixImplant: 0,
-		birthsTotal: 0,
-		pubertyAgeXX: 13,
-		pubertyAgeXY: 13,
-		scars: 0,
-		breedingMark: 0,
-		bodySwap: 0,
-		HGExclude: 0,
-		ballType: "human",
-		eggType: "human",
-		choosesOwnChastity: 0,
-		pregControl: "none",
-		readyLimbs: [],
-		ageAdjust: 0,
-		bald: 0,
-		origBodyOwner: "",
-		origBodyOwnerID: 0,
-		death: "",
-		hormoneBalance: 0,
-		onDiet: 0,
-		breastMesh: 0,
-		slavesFathered: 0,
-		PCChildrenFathered: 0,
-		slavesKnockedUp: 0,
-		PCKnockedUp: 0,
-		prematureBirth: 0,
-		premature: 0,
-		vasectomy: 0,
-		haircuts: 0,
-		newGamePlus: 0,
-		skillHG: 0,
-		skillRC: 0,
-		skillBG: 0,
-		skillMD: 0,
-		skillDJ: 0,
-		skillNU: 0,
-		skillTE: 0,
-		skillAT: 0,
-		skillMT: 0,
-		skillST: 0,
-		skillMM: 0,
-		skillFA: 0,
-		skillWA: 0,
-		skillS: 0,
-		skillE: 0,
-		skillW: 0,
-		tankBaby: 0,
-		clone: 0,
-		geneMods: {NCS: 0, rapidCellGrowth: 0},
-		NCSyouthening: 0,
-		override_Race: 0,
-		override_Skin: 0,
-		override_Eye_Color: 0,
-		override_H_Color: 0,
-		override_Pubic_H_Color: 0,
-		override_Arm_H_Color: 0,
-		override_Brow_H_Color: 0,
-		missingEyes: 0,
-		missingArms: 0,
-		missingLegs: 0,
-		slaveCost: 0,
-		lifetimeCashExpenses: 0,
-		lifetimeCashIncome: 0,
-		lastWeeksCashIncome: 0,
-		lifetimeRepExpenses: 0,
-		lifetimeRepIncome: 0,
-		lastWeeksRepIncome: 0
-	};
+	State.variables.activeSlave = new App.Entity.SlaveState();
 };
 
-window.generatePronouns = function generatePronouns(slave) {
+window.generatePronouns = /** @param {App.Entity.SlaveState} slave*/ function generatePronouns(slave) {
 	if (slave.fuckdoll > 0) {
 		slave.pronoun = "it";
 		slave.possessivePronoun = "its";
diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js
index e151473be1930989a1f28ef841e6b59f1203d2d4..10485bc49124e4a386320ba667cfce3609fa1cfa 100644
--- a/src/js/slaveSummaryWidgets.js
+++ b/src/js/slaveSummaryWidgets.js
@@ -1,4 +1,4 @@
-window.clearSummaryCache = function clearSummaryCache(slave) {
+window.clearSummaryCache = /** @param {App.Entity.SlaveState} slave */ function clearSummaryCache(slave) {
 	if (!slave)
 		setup.summaryCache = {};
 	else if (slave instanceof Object && slave.ID !== Infinity && slave.ID !== -Infinity)
@@ -7,7 +7,7 @@ window.clearSummaryCache = function clearSummaryCache(slave) {
 		setup.summaryCache[slave] = undefined;
 };
 
-window.SlaveSummary = function SlaveSummary(slave) {
+window.SlaveSummary = /** @param {App.Entity.SlaveState} slave */ function SlaveSummary(slave) {
 	const V = State.variables;
 	if(V.useSummaryCache) {
 		if (setup.summaryCache[slave.ID] === undefined)
@@ -21,6 +21,7 @@ window.SlaveSummaryUncached = (function(){
 	"use strict";
 	let V, r;
 
+	/** @param {App.Entity.SlaveState} slave */
 	function SlaveSummaryUncached(slave) {
 		V = State.variables;
 		r = "";
@@ -264,6 +265,7 @@ window.SlaveSummaryUncached = (function(){
 		return r;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_devotion(slave) {
 		if (slave.fetish === "mindbroken") {
 			r += `<span class="red">MB</span>`;
@@ -315,6 +317,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_devotion(slave) {
 		if (slave.fetish === "mindbroken") {
 			r += `<span class="red">Mindbroken.</span>`;
@@ -366,6 +369,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_rules(slave) {
 		switch (slave.livingRules) {
 			case "luxurious":
@@ -458,6 +462,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_rules(slave) {
 		r += `Living standard: ${slave.livingRules}. `;
 		if (canTalk(slave)) {
@@ -469,6 +474,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `Release rules: ${slave.releaseRules}. `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_weight(slave) {
 		if (slave.weight < -95) {
 			r += `<strong><span class="red">W---${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`;
@@ -518,6 +524,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_weight(slave) {
 		if (slave.weight < -95) {
 			r += `<span class="red">Emaciated${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`;
@@ -568,6 +575,7 @@ window.SlaveSummaryUncached = (function(){
 
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_diet(slave) {
 		r += `<span class="teal">`;
 		switch (slave.diet) {
@@ -618,6 +626,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_diet(slave) {
 		r += `<span class="teal">`;
 		switch (slave.diet) {
@@ -667,6 +676,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_health(slave) {
 		if (slave.health < -20) {
 			r += `<strong><span class="red">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`;
@@ -678,6 +688,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_health(slave) {
 		if (slave.health < -90) {
 			r += `<span class="red">On the edge of death${V.summaryStats? `[${slave.health}]` : ''}.</span>`;
@@ -697,6 +708,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_drugs(slave) {
 		r += `<span class="tan">`;
 		switch (slave.drugs) {
@@ -878,6 +890,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_drugs(slave) {
 		if ((slave.drugs !== "no drugs") && (slave.drugs !== "none")) {
 			r += `<span class="tan">On ${slave.drugs}.</span> `;
@@ -985,6 +998,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_race(slave) {
 		switch (slave.race) {
 			case "white":
@@ -1030,6 +1044,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_race(slave) {
 		switch (slave.race) {
 			case "white":
@@ -1075,6 +1090,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_nationality(slave) {
 		r += `<span class="tan">`;
 		switch (slave.nationality) {
@@ -1749,6 +1765,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_nationality(slave) {
 		r += `<span class="tan">`;
 		switch (slave.nationality) {
@@ -1784,6 +1801,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_skin(slave) {
 		r += `<span class="pink">`;
 		switch (slave.skin) {
@@ -1841,6 +1859,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_genitals(slave) {
 		if (slave.dick > 0) {
 			r += `<span class="pink">`;
@@ -1899,6 +1918,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_genitals(slave) {
 		if (slave.dick > 0) {
 			r += `<span class="pink">`;
@@ -1957,6 +1977,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_age(slave) {
 		r += `<span class="pink">`;
 		if (V.showAgeDetail === 1) {
@@ -1983,6 +2004,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_face(slave) {
 		if (slave.face < -95) {
 			r += `<span class="red">Face---${V.summaryStats? `[${slave.face}]` : ''}</span>`;
@@ -2002,6 +2024,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_eyes(slave) {
 		if (slave.eyes === -2) {
 			r += `<span class="red">Blind</span>`;
@@ -2011,6 +2034,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_ears(slave) {
 		if (slave.hears === -2) {
 			r += `<span class="red">Deaf</span>`;
@@ -2020,6 +2044,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_lips(slave) {
 		if (slave.lips > 95) {
 			r += `Facepussy`;
@@ -2037,6 +2062,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_teeth(slave) {
 		if (slave.teeth === "crooked") {
 			r += `<span class="yellow">Cr Teeth</span>`;
@@ -2058,6 +2084,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_muscles(slave) {
 		if (slave.muscles > 95) {
 			r += `Musc++${V.summaryStats? `[${slave.muscles}]`: ''}`;
@@ -2085,6 +2112,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_limbs(slave) {
 		if (slave.amp !== 0) {
 			if (slave.amp === -1) {
@@ -2111,6 +2139,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_voice(slave) {
 		if (slave.voice === 0) {
 			r += `<span class="pink">Mute</span>`;
@@ -2128,6 +2157,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_tits_ass(slave) {
 		r += `<span class="pink">`;
 		if ((slave.boobs >= 12000) && (slave.butt > 9)) {
@@ -2160,6 +2190,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_hips(slave) {
 		r += `<span class="red">`;
 		if (slave.hips < -1) {
@@ -2198,6 +2229,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_waist(slave) {
 		if (slave.waist > 95) {
 			r += `<span class="red">Wst---${V.summaryStats? `[${slave.waist}]` : ''}</span>`;
@@ -2217,6 +2249,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_implants(slave) {
 		r += `<span class="pink">`;
 		if ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant <= 5) && (slave.bellyImplant === -1)) {
@@ -2227,6 +2260,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_lactation(slave) {
 		if (slave.lactation === 1) {
 			r += `Lact`;
@@ -2236,6 +2270,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_mods(slave) {
 		modScore(slave);
 		if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) {
@@ -2253,6 +2288,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_age(slave) {
 		r += `<span class="pink">`;
 		if (V.showAgeDetail === 1) {
@@ -2303,6 +2339,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_face(slave) {
 		if (slave.face < -95) {
 			r += `<span class="red">Very ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`;
@@ -2322,6 +2359,7 @@ window.SlaveSummaryUncached = (function(){
 		r += ` ${slave.faceShape} face. `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_eyes(slave) {
 		if (slave.eyes <= -2) {
 			r += `<span class="red">Blind.</span>`;
@@ -2331,6 +2369,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_ears(slave) {
 		if (slave.hears <= -2) {
 			r += `<span class="red">Deaf.</span>`;
@@ -2340,6 +2379,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_lips(slave) {
 		if (slave.lips > 95) {
 			r += `Facepussy${V.summaryStats? `[${slave.lips}]`: ''}.`;
@@ -2357,6 +2397,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_teeth(slave) {
 		if (slave.teeth === "crooked") {
 			r += `<span class="yellow">Crooked teeth.</span>`;
@@ -2378,6 +2419,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_muscles(slave) {
 		if (slave.muscles > 95) {
 			r += `Hugely muscular${V.summaryStats? `[${slave.muscles}]` : ''}.`;
@@ -2405,6 +2447,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_limbs(slave) {
 		if (slave.amp !== 0) {
 			if (slave.amp === -1) {
@@ -2431,6 +2474,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_voice(slave) {
 		if (slave.voice === 0) {
 			r += `<span class="pink">Mute.</span>`;
@@ -2448,6 +2492,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_tits_ass(slave) {
 		r += `<span class="pink">`;
 		if ((slave.boobs >= 12000) && (slave.butt > 9)) {
@@ -2480,6 +2525,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_hips(slave) {
 		r += `<span class="red">`;
 		if (slave.hips < -1) {
@@ -2518,6 +2564,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_waist(slave) {
 		if (slave.waist > 95) {
 			r += `<span class="red">Masculine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`;
@@ -2537,6 +2584,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_implants(slave) {
 		r += `<span class="pink">`;
 		if ((slave.boobsImplant !== 0) || (slave.buttImplant !== 0) || (slave.lipsImplant !== 0) || (slave.bellyImplant !== -1)) {
@@ -2549,6 +2597,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_lactation(slave) {
 		if (slave.lactation === 1) {
 			r += `Lactating naturally.`;
@@ -2558,6 +2607,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_mods(slave) {
 		modScore(slave);
 		if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) {
@@ -2572,6 +2622,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_intelligence(slave) {
 		var intelligence = slave.intelligence + slave.intelligenceImplant;
 		if (slave.fetish === "mindbroken") {
@@ -2630,6 +2681,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_sex_skills(slave) {
 		let _SSkills = slave.analSkill + slave.oralSkill;
 		r += `<span class="aquamarine">`;
@@ -2686,6 +2738,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_prestige(slave) {
 		if (slave.prestige > 0) {
 			r += `<span class="green">`;
@@ -2700,6 +2753,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_porn_prestige(slave) {
 		if (slave.pornPrestige > 0) {
 			r += `<span class="green">`;
@@ -2714,6 +2768,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_intelligence(slave) {
 		var intelligence = slave.intelligence + slave.intelligenceImplant;
 		if (slave.fetish === "mindbroken") {
@@ -2772,6 +2827,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_sex_skills(slave) {
 		let _SSkills = (slave.analSkill + slave.oralSkill);
 		r += `<span class="aquamarine">`;
@@ -2814,6 +2870,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_prestige(slave) {
 		if (slave.prestige > 0) {
 			r += `<span class="green">`;
@@ -2828,6 +2885,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_porn_prestige(slave) {
 		if (slave.pornPrestige > 0) {
 			r += `<span class="green">`;
@@ -2842,6 +2900,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_fetish(slave) {
 		r += `<span class="lightcoral">`;
 		switch (slave.fetish) {
@@ -2936,6 +2995,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_attraction(slave) {
 		if (slave.attrXY <= 5) {
 			r += `<span class="red">XY---${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`;
@@ -2993,6 +3053,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_smart_fetish(slave) {
 		if (slave.fetishKnown === 1) {
 			if (slave.clitSetting === "off") {
@@ -3073,6 +3134,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_smart_attraction(slave) {
 		if (slave.attrKnown === 1) {
 			if (slave.clitSetting === "women") {
@@ -3114,6 +3176,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_behavior_flaw(slave) {
 		r += `<span class="red">`;
 		switch (slave.behavioralFlaw) {
@@ -3151,6 +3214,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_sex_flaw(slave) {
 		switch (slave.sexualFlaw) {
 			case "hates oral":
@@ -3214,6 +3278,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_behavior_quirk(slave) {
 		r += `<span class="green">`;
 		switch (slave.behavioralQuirk) {
@@ -3251,6 +3316,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_sex_quirk(slave) {
 		switch (slave.sexualQuirk) {
 			case "gagfuck queen":
@@ -3287,6 +3353,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_fetish(slave) {
 		r += `<span class="lightcoral">`;
 		switch (slave.fetish) {
@@ -3378,6 +3445,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_attraction(slave) {
 		if (slave.attrXY <= 5) {
 			r += `<span class="red">Disgusted by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `;
@@ -3433,6 +3501,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_smart_fetish(slave) {
 		if (slave.fetishKnown === 1) {
 			if (slave.clitSetting === "off") {
@@ -3510,6 +3579,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_smart_attraction(slave) {
 		if (slave.attrKnown === 1) {
 			if ((slave.attrXX < 100) && (slave.clitSetting === "women")) {
@@ -3527,6 +3597,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_behavior_flaw(slave) {
 		r += `<span class="red">`;
 		switch (slave.behavioralFlaw) {
@@ -3564,6 +3635,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_sex_flaw(slave) {
 		switch (slave.sexualFlaw) {
 			case "hates oral":
@@ -3627,6 +3699,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_behavior_quirk(slave) {
 		r += `<span class="green">`;
 		switch (slave.behavioralQuirk) {
@@ -3664,6 +3737,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_sex_quirk(slave) {
 		switch (slave.sexualQuirk) {
 			case "gagfuck queen":
@@ -3700,6 +3774,7 @@ window.SlaveSummaryUncached = (function(){
 		r += `</span> `;
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_extended_family(slave) {
 		let handled = 0;
 		if (slave.mother > 0) {
@@ -3817,6 +3892,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_legacy_family(slave) {
 		if (slave.relation !== 0) {
 			let _ssj = V.slaves.findIndex(function(s) {
@@ -3848,12 +3924,14 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_clone(slave) {
 		if (slave.clone !== 0) {
 			r += ` Clone`;
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function short_rival(slave) {
 		if (slave.rivalry !== 0) {
 			r += `&nbsp;&nbsp;&nbsp;&nbsp;`;
@@ -3874,6 +3952,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_extended_family(slave) {
 		let handled = 0;
 		if (slave.mother > 0) {
@@ -4004,6 +4083,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_legacy_family(slave) {
 		if (slave.relation !== 0) {
 			let _ssj = V.slaves.findIndex(function(s) {
@@ -4043,12 +4123,14 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_clone(slave) {
 		if (slave.clone !== 0) {
 			r += ` <span class="skyblue">Clone of ${slave.clone}.</span>`;
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_rival(slave) {
 		if (slave.rivalry !== 0) {
 			r += `&nbsp;&nbsp;&nbsp;&nbsp;`;
@@ -4068,6 +4150,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_clothes(slave) {
 		switch (slave.clothes) {
 			case "attractive lingerie":
@@ -4389,6 +4472,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_collar(slave) {
 		switch (slave.collar) {
 			case "uncomfortable leather":
@@ -4458,6 +4542,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_belly(slave) {
 		switch (slave.bellyAccessory) {
 			case "shapewear":
@@ -4485,6 +4570,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_legs(slave) {
 		if (slave.legAccessory === "short stockings") {
 			r += `Short stockings.`;
@@ -4494,6 +4580,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_shoes(slave) {
 		if (slave.shoes === "heels") {
 			r += `Heels.`;
@@ -4511,6 +4598,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_vaginal_acc(slave) {
 		switch (slave.vaginalAccessory) {
 			case "chastity belt":
@@ -4544,6 +4632,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_dick_acc(slave) {
 		if (slave.dickAccessory === "chastity") {
 			r += `Chastity cage.`;
@@ -4555,6 +4644,7 @@ window.SlaveSummaryUncached = (function(){
 		r += " ";
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function long_buttplug(slave) {
 		switch (slave.buttplug) {
 			case "plug":
@@ -4590,6 +4680,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function rules_assistant(slave) {
 		if (slave.useRulesAssistant === 0) {
 			r += `<span class="lightgreen">RA-Exempt</span> `;
@@ -4598,6 +4689,7 @@ window.SlaveSummaryUncached = (function(){
 		}
 	}
 
+	/** @param {App.Entity.SlaveState} slave */
 	function origins(slave) {
 		r += `<br>`;
 		if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) {
diff --git a/src/js/storyJS.js b/src/js/storyJS.js
index 2955def2ffc70ff6ce64a382eb7d8e89c030448d..64b3a1b087f7f0d13d454192e36bc2f30ffa5c3a 100644
--- a/src/js/storyJS.js
+++ b/src/js/storyJS.js
@@ -14,7 +14,7 @@ window.variableAsNumber = function(x, defaultValue, minValue, maxValue) {
 	}
 	return x;
 };
-window.isSexuallyPure = function(slave) {
+window.isSexuallyPure = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	}
@@ -37,7 +37,7 @@ if (typeof interpolate === "undefined") {
 	window.interpolate = interpolate;
 }
 
-window.isFullyPotent = function(slave) {
+window.isFullyPotent = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.dick > 0 && slave.balls > 0 && slave.ballType !== 'sterile' && slave.hormoneBalance < 100 && slave.drugs !== 'hormone blockers') {
@@ -126,7 +126,7 @@ if (typeof FertilityAge === "undefined") {
 	window.FertilityAge = FertilityAge;
 }
 
-window.canGetPregnant = function(slave) {
+window.canGetPregnant = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.preg === -1) { /* contraceptives check */
@@ -142,7 +142,10 @@ window.canGetPregnant = function(slave) {
 	}
 };
 
-/* pregmod: are slave2's sperm compatible with slave1's eggs? */
+/** pregmod: are slave2's sperm compatible with slave1's eggs?
+ * @param {App.Entity.SlaveState} slave1
+ * @param {App.Entity.SlaveState} slave2
+ */
 window.canBreed = function(slave1, slave2) {
 	if (!slave1 || !slave2) {
 		return null;
@@ -153,7 +156,12 @@ window.canBreed = function(slave1, slave2) {
 	}
 };
 
-/* assuming slave1 is fertile, could slave2 impregnate slave1? slave2 must have dick and balls with compatible sperm; both slaves must not be in chastity; slave2 need not achieve erection */
+/** assuming slave1 is fertile, could slave2 impregnate slave1?
+ * slave2 must have dick and balls with compatible sperm;
+ * both slaves must not be in chastity; slave2 need not achieve erection
+ * @param {App.Entity.SlaveState} slave1
+ * @param {App.Entity.SlaveState} slave2
+ */
 window.canImpreg = function(slave1, slave2) {
 	if (!slave1 || !slave2) {
 		return null;
@@ -194,7 +202,8 @@ window.canImpreg = function(slave1, slave2) {
 	}
 };
 
-/* contraceptives (.preg == -1) do not negate this function */
+/** contraceptives (.preg == -1) do not negate this function
+ * @param {App.Entity.SlaveState} slave */
 window.isFertile = function(slave) {
 	if (!slave) {
 		return null;
@@ -241,7 +250,7 @@ window.isPlayerFertile = function(PC) {
 	}
 };
 
-window.canAchieveErection = function(slave) {
+window.canAchieveErection = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.dick < 7 && slave.dick > 0 && slave.drugs !== 'hormone blockers' && (slave.balls > 0 ? slave.hormoneBalance < 100 : slave.hormoneBalance <= -100) && slave.ballType !== 'sterile') {
@@ -251,7 +260,7 @@ window.canAchieveErection = function(slave) {
 	}
 };
 
-window.canPenetrate = function(slave) {
+window.canPenetrate = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (!canAchieveErection(slave)) {
@@ -266,7 +275,7 @@ window.canPenetrate = function(slave) {
 	return true;
 };
 
-window.canSee = function(slave) {
+window.canSee = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.eyes > -2) {
@@ -276,7 +285,7 @@ window.canSee = function(slave) {
 	}
 };
 
-window.canHear = function(slave) {
+window.canHear = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if ((slave.hears > -2) && (slave.earwear !== "deafening ear plugs")) {
@@ -286,7 +295,7 @@ window.canHear = function(slave) {
 	}
 };
 
-window.canWalk = function(slave) {
+window.canWalk = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.amp === 1) {
@@ -316,7 +325,7 @@ window.canWalk = function(slave) {
 	}
 };
 
-window.canTalk = function(slave) {
+window.canTalk = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.accent > 2) {
@@ -338,7 +347,7 @@ window.canTalk = function(slave) {
 	}
 };
 
-window.canDoAnal = function(slave) {
+window.canDoAnal = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.vaginalAccessory === "anal chastity") {
@@ -353,7 +362,7 @@ window.canDoAnal = function(slave) {
 	return true;
 };
 
-window.canDoVaginal = function(slave) {
+window.canDoVaginal = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.vagina < 0) {
@@ -366,7 +375,7 @@ window.canDoVaginal = function(slave) {
 	return true;
 };
 
-window.tooFatSlave = function(slave){
+window.tooFatSlave = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.weight > 190+(slave.muscles/5) && slave.physicalAge >= 18) {
@@ -382,7 +391,7 @@ window.tooFatSlave = function(slave){
 	}
 };
 
-window.tooBigBreasts = function(slave){
+window.tooBigBreasts = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.boobs > 30000+(slave.muscles*100) && slave.physicalAge >= 18) {
@@ -398,7 +407,7 @@ window.tooBigBreasts = function(slave){
 	}
 };
 
-window.tooBigBelly = function(slave){
+window.tooBigBelly = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.belly >= 450000+(slave.muscles*2000) && slave.physicalAge >= 18) {
@@ -414,7 +423,7 @@ window.tooBigBelly = function(slave){
 	}
 };
 
-window.tooBigBalls = function(slave){
+window.tooBigBalls = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.balls >= 30+(slave.muscles*.3) && slave.physicalAge <= 3) {
@@ -428,7 +437,7 @@ window.tooBigBalls = function(slave){
 	}
 };
 
-window.tooBigDick = function(slave){
+window.tooBigDick = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.dick >= 20+(slave.muscles*.1) && slave.physicalAge <= 3 && slave.dick !== 0) {
@@ -442,7 +451,7 @@ window.tooBigDick = function(slave){
 	}
 };
 
-window.tooBigButt = function(slave){
+window.tooBigButt = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.butt > 10 && slave.physicalAge <= 3) {
@@ -454,7 +463,7 @@ window.tooBigButt = function(slave){
 	}
 };
 
-window.relationTargetWord = function(slave) {
+window.relationTargetWord = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if (!slave) {
 		return null;
 	} else if (slave.relation === "daughter") {
@@ -465,7 +474,7 @@ window.relationTargetWord = function(slave) {
 	return slave.relation;
 };
 
-window.milkAmount = function(slave) {
+window.milkAmount = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	var milk;
 	var calcs;
 	if (!slave) {
@@ -514,7 +523,7 @@ window.milkAmount = function(slave) {
 
 
 
-window.cumAmount = function(slave) {
+window.cumAmount = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	var cum = 0;
 	var calcs = 0;
 	if (!slave) {
@@ -644,13 +653,13 @@ window.lispReplace = function (text) {
 	return text;
 };
 
-window.isVegetable = function(slave) {
+window.isVegetable = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	slave = slave || State.variables.activeSlave;
 	if(!slave) { return false; }
 	return (slave.fetish === 'mindbroken');
 };
 
-window.repGainSacrifice = function(slave, arcology) {
+window.repGainSacrifice = /** @param {App.Entity.SlaveState} slave */ function (slave, arcology) {
 	slave = slave || State.variables.activeSlave;
 	arcology = arcology || State.variables.arcologies[0];
 	if(!slave || !arcology || arcology.FSAztecRevivalist === "unset" || arcology.FSAztecRevivalist <= 0) {
@@ -661,7 +670,7 @@ window.repGainSacrifice = function(slave, arcology) {
 			* arcology.FSAztecRevivalist / 100 / ((State.variables.slavesSacrificedThisWeek || 0) + 1));
 };
 
-window.bodyguardSuccessorEligible = function(slave) {
+window.bodyguardSuccessorEligible = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if(!slave) { return false; }
 	return (slave.devotion > 50 && slave.muscles >= 0 && slave.weight < 100 && slave.boobs < 8000 && slave.butt < 10 && slave.belly < 5000 && slave.balls < 10 && slave.dick < 10 && slave.preg < 20 && slave.fuckdoll === 0 && slave.fetish !== "mindbroken" && canWalk(slave));
 };
@@ -700,7 +709,7 @@ window.toJson = function(obj) {
 	return jsontext;
 };
 
-window.nippleColor = function(slave) {
+window.nippleColor = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	slave = slave || State.variables.activeSlave;
 	if(slave.skin === 'tanned' || slave.skin === 'fair') {
 		if(slave.preg > slave.pregData.normalBirth/4 || (slave.birthsTotal > 0 && slave.lactation > 0)) {
@@ -729,7 +738,7 @@ window.nippleColor = function(slave) {
 	}
 };
 
-window.overpowerCheck = function(slave, PC) {
+window.overpowerCheck = /** @param {App.Entity.SlaveState} slave */ function (slave, PC) {
 	var strength;
 
 	if(State.variables.arcologies[0].FSPhysicalIdealist !== "unset") {
@@ -749,7 +758,12 @@ window.overpowerCheck = function(slave, PC) {
 	return strength;
 };
 
-window.impregnatedBy = function(slave) { /* returns array of IDs of all characters who impregnated slave */
+/**
+ * returns array of IDs of all characters who impregnated slave
+ * @param {App.Entity.SlaveState} slave
+ * @returns {number[]}
+ */
+window.impregnatedBy = function(slave) {
 	var IDArray = [];
 	if (!Array.isArray(slave.womb)) {
 		WombInit(slave);
@@ -760,7 +774,12 @@ window.impregnatedBy = function(slave) { /* returns array of IDs of all characte
 	return IDArray;
 };
 
-window.isImpregnatedBy = function(mother, father) { /* returns true if mother was impregnated by father */
+/**
+ * returns true if mother was impregnated by father
+ * @param {App.Entity.SlaveState} mother
+ * @param {App.Entity.SlaveState} father
+ */
+window.isImpregnatedBy = function(mother, father) {
 	return impregnatedBy(mother).includes(father.ID);
 };
 
@@ -774,7 +793,7 @@ window.jsConsoleInfo = function(obj)
 	console.info(obj);
 };
 
-window.SoftenBehavioralFlaw = function SoftenBehavioralFlaw(slave) {
+window.SoftenBehavioralFlaw = /** @param {App.Entity.SlaveState} slave */ function SoftenBehavioralFlaw(slave) {
 	switch (slave.behavioralFlaw) {
 		case "arrogant":
 			slave.behavioralQuirk = "confident";
@@ -807,7 +826,7 @@ window.SoftenBehavioralFlaw = function SoftenBehavioralFlaw(slave) {
 	slave.behavioralFlaw = "none";
 };
 
-window.SoftenSexualFlaw = function SoftenSexualFlaw(slave) {
+window.SoftenSexualFlaw = /** @param {App.Entity.SlaveState} slave */ function SoftenSexualFlaw(slave) {
 	switch (slave.sexualFlaw) {
 		case "hates oral":
 			slave.sexualQuirk = "gagfuck queen";
diff --git a/src/js/summaryWidgets.js b/src/js/summaryWidgets.js
index 66563b9ae6a42101fd3b9a3a1cdff5373dc7ddf0..3968bde692870838e3ae2d5f3dc2346419b3fdc7 100644
--- a/src/js/summaryWidgets.js
+++ b/src/js/summaryWidgets.js
@@ -1,4 +1,4 @@
-window.SlaveStatClamp = function SlaveStatClamp(slave) {
+window.SlaveStatClamp = /** @param {App.Entity.SlaveState} slave */ function SlaveStatClamp(slave) {
 	slave.energy = Math.clamp(slave.energy, 0, 100);
 	const V = State.variables;
 
diff --git a/src/js/utilJS.js b/src/js/utilJS.js
index b39be0d3b56144bd16d4c7d8f142d54c0fdc8ab6..0e9ed708c54704484c003c24619aca8f1efafbd7 100644
--- a/src/js/utilJS.js
+++ b/src/js/utilJS.js
@@ -725,7 +725,7 @@ window.capFirstChar = function capFirstChar(string) {
 	return string.charAt(0).toUpperCase() + string.substr(1);
 };
 
-window.getSlaveDevotionClass = function (slave) {
+window.getSlaveDevotionClass = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if ((!slave) || (!State))
 		return undefined;
 	if ('mindbroken' === slave.fetish)
@@ -746,7 +746,7 @@ window.getSlaveDevotionClass = function (slave) {
 		return 'worshipful';
 };
 
-window.getSlaveTrustClass = function (slave) {
+window.getSlaveTrustClass = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	if ((!slave) || (!State))
 		return undefined;
 
@@ -1147,7 +1147,7 @@ window.removeDuplicates = function removeDuplicates(array) {
 	return [...new Set(array)];
 };
 
-window.induceLactation = function induceLactation(slave) {
+window.induceLactation = /** @param {App.Entity.SlaveState} slave */ function induceLactation(slave) {
 	let pronouns = getPronouns(slave);
 	let His = capFirstChar(pronouns.possessive);
 	let r = ``;
@@ -1181,7 +1181,7 @@ window.ResearchLabStockPile = function() {
 	Electrolarynx: $stockpile.electrolarynx`;
 };
 
-window.originPronounReplace = function(slave) {
+window.originPronounReplace = /** @param {App.Entity.SlaveState} slave */ function (slave) {
 	let r = slave.origin;
 	switch (r) {
 		case "She was the result of unprotected sex with a client. Her mother tracked you down years after her birth to force her upon you.":
diff --git a/src/js/vignettes.js b/src/js/vignettes.js
index 7402b866e21df6c83c7649f8a68e2d45f51e98ae..44c5337e1a00fcdd559a103fa011c31414597bf7 100644
--- a/src/js/vignettes.js
+++ b/src/js/vignettes.js
@@ -1,4 +1,4 @@
-window.GetVignette = function GetVignette(slave) {
+window.GetVignette = /** @param {App.Entity.SlaveState} slave */ function GetVignette(slave) {
 	const V = State.variables;
 	let vignettes = [];