code:
App.UI.managePersonalAffairs = function() {
	const frag = new DocumentFragment();

	const appearanceDiv = document.createElement("div");
	const skillsDiv = document.createElement("div");
	const reputationDiv = document.createElement("div");
	const drugsDiv = document.createElement("div");
	const dietDiv = document.createElement("div");
	const lactationDiv = document.createElement("div");
	const pervertDiv = document.createElement("div");
	const socialDiv = document.createElement("div");
	const breederExamDiv = document.createElement("div");

	const PC = V.PC;
	const arcology = V.arcologies[0];

	if (V.cheatMode) {
		if (V.cheatMode === 1) {
			App.UI.DOM.appendNewElement("div", frag,
				App.UI.DOM.passageLink("Cheat Edit Player", "PCCheatMenu", () => {
					V.cheater = 1;
					// @ts-ignore
					V.backupSlave = clone(PC);
				}),
				["cheat-menu"]);
		}
	}

	App.UI.DOM.appendNewElement("h1", frag, `Personal Affairs`);

	frag.append(
		appearance(),
		reputation(),
		diet(),
		drugs(),
	);

	if (PC.lactation > 0 || PC.boobs >= 300) {
		frag.append(lactation());
	}

	if (V.propOutcome === 1 && arcology.FSRestart !== "unset") {
		frag.append(breederExam());
	}

	frag.append(perversions());

	frag.append(socials());

	frag.append(skills());

	return frag;

	function appearance() {
		const doctorDiv = document.createElement("div");
		const surgeonDiv = document.createElement("div");
		const hairColorsDiv = document.createElement("div");

		let text = [];

		App.UI.DOM.appendNewElement("h2", appearanceDiv, `Appearance`);

		text.push(`You pause for a moment from your busy day to day life`);
		if (onBedRest(PC)) {
			if (canMove(PC)) {
				text.push(`to get up and stretch your legs a little while considering`);
			} else {
				text.push(`to push yourself upright and consider`);
			}
		} else {
			text.push(`to return to ${V.masterSuite ? V.masterSuiteName : `your room`} to consider`);
		}
		text.push(`some things about yourself.`);
		App.Events.addParagraph(appearanceDiv, text);
		text = [];

		text.push(App.Desc.Player.longDescription(PC));
		App.Events.addParagraph(appearanceDiv, text);
		text = [];

		// text.push(doctor());

		text.push(surgeon());

		// salon style passage this!
		text.push(App.Medicine.Modification.eyeSelector(PC));
		text.push(hairColors());

		App.Events.addNode(appearanceDiv, text);

		return appearanceDiv;

		function doctor() {
			const text = [];

			if (V.doctor.state > 0) {
				text.push(App.UI.DOM.passageLink(`Consult your doctor`, "Doctor Consultation", () => {
					cashX(forceNeg(500), "PCmedical");
				}));
			} else {
				text.push(App.UI.DOM.passageLink(`Seek out a local doctor`, "Doctor Consultation", () => {
					cashX(forceNeg(500), "PCmedical");
				}));
			}
			App.Events.addNode(doctorDiv, text);
			return doctorDiv;
		}

		function surgeon() {
			const text = [];

			if (V.pSurgery.cooldown === 0) {
				if (V.pSurgery.state > 0) {
					text.push(App.UI.DOM.passageLink(`Visit your plastic surgeon`, "Elective Surgery", () => {
						V.pSurgery.cooldown = 4;
					}));
				} else {
					text.push(App.UI.DOM.passageLink(`Seek out a local plastic surgeon`, "Elective Surgery", () => {
						V.pSurgery.cooldown = 4;
					}));
				}
			} else if (V.pSurgery.cooldown === 1) {
				text.push(`Your favorite plastic surgeon is booked solid for the next week.`);
			} else {
				text.push(`Your favorite plastic surgeon is booked solid for the next ${V.pSurgery.cooldown} weeks.`);
			}
			App.Events.addNode(surgeonDiv, text);
			return surgeonDiv;
		}

		function hairColors() {
			const colors = ["auburn", "black", "blonde", "blue", "blue-violet", "brown", "burgundy", "chestnut", "chocolate brown", "copper", "crimson", "dark blue", "dark brown", "dark orchid", "ginger", "golden", "green", "green-yellow", "grey", "hazel", "jet black", "pink", "platinum blonde", "purple", "red", "sea green", "silver", "strawberry-blonde", "white"];
			const links = [];

			hairColorsDiv.append(`You have a selection of hair dyes available: `);

			colors.forEach(color => links.push(
				PC.hColor === color
					? App.UI.DOM.disabledLink(capFirstChar(color),
						[`Your hair is already ${color}.`])
					: App.UI.DOM.link(capFirstChar(color), () => {
						V.PC.hColor = color;

						App.UI.DOM.replace(appearanceDiv, appearance);
					})
			));

			hairColorsDiv.append(App.UI.DOM.generateLinksStrip(links));

			return hairColorsDiv;
		}
	}

	function reputation() {
		const customTitleDiv = document.createElement("div");
		const textBoxDiv = document.createElement("div");
		const renamePlayerDiv = document.createElement("div");
		const newNameDiv = document.createElement("div");
		const rumorsDiv = document.createElement("div");
		const familyDiv = document.createElement("div");
		const pregnancyDiv = document.createElement("div");
		const birthsDiv = document.createElement("div");
		const partnersDiv = document.createElement("div");
		const knockedUpDiv = document.createElement("div");
		const fatheredDiv = document.createElement("div");
		const breedingDiv = document.createElement("div");

		App.UI.DOM.appendNewElement("h2", reputationDiv, `Reputation`);
		App.UI.DOM.appendNewElement("h3", reputationDiv, `Name`);

		reputationDiv.append(
			`On formal occasions, you are announced as ${PCTitle()}. By slaves, however, you prefer to be called ${properMaster()}.`,
			customTitle(),
			renamePlayer(),
			rumors(),
			family(),
		);

		if (PC.ovaries === 1 || PC.mpreg === 1) {
			reputationDiv.append(pregnancy());
		}

		const links = [];

		if (PC.preg > 0 && V.pregnancyMonitoringUpgrade) {
			links.push(App.UI.DOM.passageLink(`Inspect pregnancy`, 'Analyze PC Pregnancy'));
		}

		if (PC.preg >= 0 && PC.ovaries && PC.ovaryAge < 47) {
			links.push(App.UI.DOM.passageLink(`Harvest and implant an egg`, 'Surrogacy Workaround', () => {
				// @ts-ignore
				V.donatrix = V.PC;
				// @ts-ignore
				V.impregnatrix = "undecided";
				// @ts-ignore
				V.receptrix = "undecided";

				V.nextLink = 'Manage Personal Affairs';
			}));
		}

		reputationDiv.append(App.UI.DOM.generateLinksStrip(links));

		if (PC.counter.birthsTotal > 0) {
			reputationDiv.append(births());
		}

		if (PC.partners.size > 0) {
			reputationDiv.append(partners());
		}

		if (PC.counter.slavesKnockedUp > 0) {
			reputationDiv.append(knockedUp());
		} else if (PC.counter.slavesFathered > 0) {
			reputationDiv.append(fathered());
		}

		if (PC.vagina !== -1 && arcology.FSRestartDecoration >= 100) {
			reputationDiv.append(breeding());
		}

		return reputationDiv;

		function customTitle() {
			if (!PC.customTitle) {
				textBoxDiv.append(
					`Custom title: `,
					App.UI.DOM.makeTextBox(PC.customTitle || '', (title) => {
						if (!title) {
							title = '';
						}

						V.PC.customTitle = title;
						V.PC.customTitleLisp = lispReplace(PC.customTitle);

						App.UI.DOM.replace(reputationDiv, reputation);
					}),
				);

				customTitleDiv.append(App.UI.DOM.makeElement("div", App.UI.DOM.linkReplace(`Set a custom title for slaves to address you as`, textBoxDiv)));
			} else {
				customTitleDiv.append(
					`Your custom title is `,
					App.UI.DOM.makeTextBox(PC.customTitle || '', (title) => {
						V.PC.customTitle = title;
						V.PC.customTitleLisp = lispReplace(PC.customTitle);

						App.UI.DOM.replace(reputationDiv, reputation);
					}),
					App.UI.DOM.link(`Stop using a custom title`, () => {
						V.PC.customTitle = undefined;
						V.PC.customTitleLisp = undefined;

						App.UI.DOM.replace(reputationDiv, reputation);
					}),
				);
			}

			return customTitleDiv;
		}

		function renamePlayer() {
			newNameDiv.append(
				`New name: `,
				App.UI.DOM.makeTextBox(PC.slaveName, (name) => {
					V.PC.slaveName = name;
					repX(-500, "event");

					App.UI.DOM.replace(reputationDiv, reputation);
				}),
			);

			renamePlayerDiv.append(App.UI.DOM.linkReplace(`Rename yourself`, newNameDiv));
			App.UI.DOM.appendNewElement("span", renamePlayerDiv, ` Will cost you some reputation`, ['note']);

			return renamePlayerDiv;
		}

		function rumors() {
			App.UI.DOM.appendNewElement("h3", rumorsDiv, `Rumors`);

			App.Events.addNode(rumorsDiv, [getPlayerRumors()]);

			return rumorsDiv;

			function getPlayerRumors() {
				if (PC.degeneracy > 100) {
					return `There are severe and devastating rumors about you spreading across the arcology.`;
				} else if (PC.degeneracy > 75) {
					return `There are severe rumors about you spreading across the arcology.`;
				} else if (PC.degeneracy > 50) {
					return `There are bad rumors about you spreading across the arcology.`;
				} else if (PC.degeneracy > 25) {
					return `There are rumors about you spreading across the arcology.`;
				} else if (PC.degeneracy > 10) {
					return `There are minor rumors about you spreading across the arcology.`;
				} else {
					return `The occasional rumor about you can be heard throughout the arcology.`;
				}
			}
		}

		function family() {
			App.UI.DOM.appendNewElement("h3", familyDiv, `Family`);

			familyDiv.append(App.UI.DOM.linkReplace(`Pull up the file on your family tree`, renderFamilyTree(V.slaves, -1)));

			if (totalPlayerRelatives(PC) > 0 || (V.showMissingSlaves && (PC.mother in V.missingTable || PC.father in V.missingTable))) {
				App.Events.addNode(familyDiv, [App.Desc.family(PC)]);
			}

			return familyDiv;
		}

		function pregnancy() {
			const text = [];
			const links = [];

			const miniSceneSpan = App.UI.DOM.appendNewElement("span", pregnancyDiv);
			const abortLink = App.UI.DOM.link(`Abort the child`, () => {
				TerminatePregnancy(V.PC);

				// App.UI.DOM.linkReplace does not support handlers afaik
				App.UI.DOM.replace(miniSceneSpan, `You take a syringe filled with abortifacients and make yourself comfortable. Injecting the vial through your belly into your womb, your close your eyes and wait for what is coming. Once you feel it is over, you clean yourself up and go on your way, child free.`);
				App.UI.DOM.replace(appearanceDiv, appearance);
				App.UI.DOM.replace(drugsDiv, drugs);
			});

			App.UI.DOM.appendNewElement("h2", pregnancyDiv, `Contraceptives and Fertility`);

			if (PC.labor === 1) {
				text.push(`You are beginning to feel contractions; you'll be giving birth soon.`);
			} else if (PC.preg >= 39) {
				text.push(`Your due date is looming, but your ${PC.pregType > 1 ? `children don't` : `child doesn't`} seem to be interested in coming out just yet.`);

				text.push(miniSceneSpan, App.UI.DOM.link(`Induce childbirth`, () => {
					V.PC.labor = 1;
					App.UI.DOM.replace(pregnancyDiv, pregnancy);
				}));
			} else if (PC.preg >= 8) {
				text.push(`You're currently ${num(PC.preg)} ${PC.preg > 1 ? `weeks` : `week`} pregnant${V.PC.pregSource !== -1 && V.PC.pregSource !== -6 ? ", something rather unbecoming for an arcology owner" : ""}.`);

				if (arcology.FSRestart === "unset" || V.eugenicsFullControl === 1 || (V.PC.pregSource !== -1 && V.PC.pregSource !== -6)) {
					miniSceneSpan.append(abortLink);
					text.push(miniSceneSpan);
				}
			} else if (PC.preg >= 4 && PC.pregKnown) {
				text.push(`You're having morning sickness${V.PC.pregSource !== -1 && V.PC.pregSource !== -6 ? "; it isn't too late to hide your pregnancy if desired.." : ""}.`);

				if (arcology.FSRestart === "unset" || V.eugenicsFullControl === 1 || (V.PC.pregSource !== -1 && V.PC.pregSource !== -6)) {
					miniSceneSpan.append(abortLink);
					text.push(miniSceneSpan);
				}
			} else if (PC.preg >= 4) {
				miniSceneSpan.append(`Your period is late, so the first thing you do is test yourself for a potential pregnancy. A pregnancy test confirms that `, App.UI.DOM.makeElement("span", `you are pregnant. `, ['pregnant']));

				PC.pregKnown = 1;
				if (arcology.FSRestart === "unset" || V.eugenicsFullControl === 1 || (V.PC.pregSource !== -1 && V.PC.pregSource !== -6)) {
					miniSceneSpan.append(abortLink);

					text.push(miniSceneSpan);
				}
			} else if (PC.preg > 0 && PC.pregKnown) {
				text.push(`You have a bun baking in the oven.`);

				if (arcology.FSRestart === "unset" || V.eugenicsFullControl === 1 || (V.PC.pregSource !== -1 && V.PC.pregSource !== -6)) {
					text.push(App.UI.DOM.link(`Pop some morning after pills`, () => {
						WombFlush(V.PC);

						App.UI.DOM.replace(appearanceDiv, appearance);
						App.UI.DOM.replace(reputationDiv, reputation);
						App.UI.DOM.replace(pregnancyDiv, pregnancy);
					}));
				}
			} else if (PC.preg > 0) {
				text.push(`Your fertile ${PC.mpreg === 1 ? "ass" : ""}pussy has been thoroughly seeded; there is a chance you are pregnant.`);

				if (arcology.FSRestart === "unset" || V.eugenicsFullControl === 1 || (V.PC.pregSource !== -1 && V.PC.pregSource !== -6)) {
					text.push(App.UI.DOM.link(`Pop some morning after pills`, () => {
						WombFlush(V.PC);

						App.UI.DOM.replace(appearanceDiv, appearance);
						App.UI.DOM.replace(reputationDiv, reputation);
						App.UI.DOM.replace(pregnancyDiv, pregnancy);
					}));
				}
			} else if (PC.pregWeek < 0) {
				text.push(`You're still recovering from your recent pregnancy.`);
			} else if (PC.bellyImplant > -1) {
				text.push(`Your abdominal implant rests in your womb, blocking any chance of conception.`);
			} else if (PC.preg === -3) {
				text.push(`You've been sterilized and will never have children.`);
			} else if (PC.preg === -2) {
				text.push(`You're barren and can't get pregnant.`);
			} else if (PC.pubertyXX === 0) {
				text.push(`Your eggs aren't quite ready yet.`);
			} else if (PC.ovaryAge >= 47) {
				text.push(`You're menopausal. Your time to bear children has passed.`);
			} else if (PC.preg === -1) {
				text.push(`You're currently on birth control.`);
				links.push(
					App.UI.DOM.disabledLink(`Start taking birth control`, [
						`You are already taking birth control.`
					]),
					App.UI.DOM.link(`Stop taking birth control`, () => {
						V.PC.preg = 0;

						App.UI.DOM.replace(pregnancyDiv, pregnancy);
					}),
				);
				text.push(App.UI.DOM.generateLinksStrip(links));
			} else if (PC.preg === 0) {
				// check if the player is already taking fertility drugs as refreshment
				const fertRefresh = PC.refreshment.toLowerCase().indexOf("fertility") !== -1 ? 1 : 0;
				if (fertRefresh) {
					text.push(`You're currently fertile and enjoying ${PC.refreshment}; a risky combination.`);
				} else {
					text.push(`You're currently fertile.`);
				}
				if (PC.forcedFertDrugs > 0) {
					text.push(`You feel a strange eagerness whenever you think of bareback sex.`);
				}
				links.push(
					App.UI.DOM.link(`Start taking birth control`, () => {
						V.PC.preg = -1;
						V.PC.fertDrugs = 0;

						App.UI.DOM.replace(pregnancyDiv, pregnancy);
					}),
					App.UI.DOM.disabledLink(`Stop taking birth control`, [
						`You are not currently taking birth control.`
					]),
				);
				text.push(App.UI.DOM.generateLinksStrip(links));
			}

			App.Events.addNode(pregnancyDiv, text);

			return pregnancyDiv;
		}

		function births() {
			const babies = count => count === 1 ? `${count} baby` : `${count} babies`;

			if (PC.vagina !== -1) {
				App.UI.DOM.appendNewElement("div", birthsDiv, `In total, you have given birth to:`);
			} else {
				App.UI.DOM.appendNewElement("div", birthsDiv, `Before your sex change, you had given birth to:`);
			}

			const list = App.UI.DOM.appendNewElement("ul", birthsDiv);
			if (PC.counter.birthElite > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthElite)} for the Societal Elite.`);
			}
			if (PC.counter.birthMaster > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthMaster)} for your former Master.`);
			}
			if (PC.counter.birthClient > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthClient)} from clients you've slept with.`);
			}
			if (PC.counter.birthDegenerate > 0) {
				App.UI.DOM.appendNewElement("li", list, `${PC.counter.birthDegenerate} bastard ${PC.counter.birthDegenerate > 1 ? `babies` : `baby`} from getting fucked by slaves.`);
			}
			if (PC.counter.birthArcOwner > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthArcOwner)} from your time with male arcology owners.`);
			}
			if (PC.counter.birthCitizen > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthCitizen)} from sex with arcology citizens.`);
			}
			if (PC.counter.birthOther > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthOther)} from sources you can't quite recall.`);
			}
			if (PC.counter.birthSelf > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthSelf)} that ${PC.counter.birthSelf > 1 ? `are` : `is`} literally all you.`);
			}
			if (PC.counter.birthLab > 0) {
				App.UI.DOM.appendNewElement("li", list, `${babies(PC.counter.birthLab)} specially designed in the lab.`);
			}

			return birthsDiv;
		}

		function partners() {
			const text = [];

			const slaves = [...PC.partners].filter(i => i > 0);
			const ownedSlaves = slaves.filter(s => getSlave(s));
			const unownedSlaves = slaves.length - ownedSlaves.length;
			const other = [];

			const ownedSlavesSpan = document.createElement("span");

			for (let i = 0; i < ownedSlaves.length; i++) {
				const innerSpan = document.createElement("span");
				const slave = getSlave(ownedSlaves[i]);

				innerSpan.style.display = 'inline-block';	// hack to prevent span breaking line and giving unusable tooltip
				innerSpan.style.marginRight = '4px';

				if (ownedSlaves.length > 1) {
					if (i === ownedSlaves.length - 1) {
						innerSpan.append(
							` and `,
							contextualIntro(PC, slave, true),
						);

						if (unownedSlaves > 0) {
							innerSpan.append(`, as well as ${numberWithPlural(unownedSlaves, 'slave')} you don't currently own`);
						}

						innerSpan.append(`.`);
					} else {
						innerSpan.append(contextualIntro(PC, slave, true),);

						if (ownedSlaves.length > 2) {
							innerSpan.append(`, `);
						}
					}
				} else {
					innerSpan.append(
						contextualIntro(PC, slave, true, true),
						`.`,
					);
				}

				ownedSlavesSpan.append(innerSpan);
			}

			const partners = new Map([
				[-1, "you"],
				[-2, `citizens of ${arcology.name}`],
				[-3, `your former master`],
				[-4, `another arcology owner`],
				[-6, `members of the Societal Elite`],
				[-8, `your animals`],
				[-9, `members of the Futanari Sisters`],
			]);

			for (const [ID, name] of partners) {
				if (V.PC.partners.has(ID)) {
					other.push(name);
				}
			}

			const link = App.UI.DOM.link(`${num(slaves.length)} of your slaves`, () => {
				const innerDiv = document.createElement("div");

				innerDiv.append(
					`You have slept with ${other.length > 0 ? `${toSentence(other)}, as well as `: ``}`,
					ownedSlavesSpan
				);

				App.UI.DOM.replace(partnersDiv, innerDiv);
			});

			if (slaves.length > 0) {
				text.push(
					`You've had sex with`,
					link,
					`so far.`,
				);
			} else if (other.length > 0) {
				text.push(`You haven't had sex with any of your slaves yet.`);
			} else {
				text.push(`You haven't had sex with anyone yet.`);
			}

			if (other.length > 0) {
				text.push(`You have ${slaves.length > 0 ? `also` : ``} had sex with ${toSentence(other)}${slaves.length > 0 ? `` : `, though`}.`);
			}

			App.Events.addNode(partnersDiv, text);

			return partnersDiv;
		}

		function knockedUp() {
			const text = [];

			let fathered = '';

			if (PC.counter.slavesFathered > 0) {
				fathered = ` and fathered ${num(PC.counter.slavesFathered)} new ${PC.counter.slavesFathered > 1 ? `slaves` : `slave`}`;
			}

			if (PC.dick > 0) {
				text.push(`You've knocked up ${num(PC.counter.slavesKnockedUp)} fertile slave ${PC.counter.slavesKnockedUp > 1 ? `girls` : `girl`}${fathered} as an arcology owner so far.`);
			} else {
				text.push(`Before your sex change, you knocked up ${num(PC.counter.slavesKnockedUp)} fertile slave ${PC.counter.slavesKnockedUp > 1 ? `girls` : `girl`}${fathered}.`);
			}

			App.Events.addNode(knockedUpDiv, text);

			return knockedUpDiv;
		}

		function fathered() {
			const text = [];

			if (PC.dick > 0) {
				text.push(`You've fathered ${num(PC.counter.slavesFathered)} new ${PC.counter.slavesFathered > 1 ? `slaves` : `slave`} as an arcology owner so far.`);
			} else {
				text.push(`Before your sex change, you fathered ${num(PC.counter.slavesFathered)} new ${PC.counter.slavesFathered > 1 ? `slaves` : `slave`}.`);
			}

			App.Events.addNode(fatheredDiv, text);

			return fatheredDiv;
		}

		function breeding() {
			const text = [];

			if (!V.playerBred) {
				text.push(
					`You are currently not bearing children for the Societal Elite.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.link(`List your womb as available`, () => {
							V.playerBred = 1;
							App.UI.DOM.replace(breedingDiv, breeding);
						}),
						App.UI.DOM.link(`Sign up for artificial insemination`, () => {
							V.playerBred = 2;
							App.UI.DOM.replace(breedingDiv, breeding);
						})
					]),
				);
			} else {
				text.push(`Your womb is dedicated to carrying the Societal Elites' children.`);

				if (PC.counter.birthElite > 0) {
					text.push(App.UI.DOM.link(`List your womb as unavailable`, () => {
						V.playerBred = 0;

						App.UI.DOM.replace(breedingDiv, breeding);
					}));
				} else {
					text.push(App.UI.DOM.disabledLink(`List your womb as unavailable`, [
						'You must bear at least one child for the Societal Elite before removing yourself from the breeding program.'
					]));
				}
			}

			App.Events.addNode(breedingDiv, text);

			return breedingDiv;
		}
	}

	function diet() {
		App.UI.DOM.appendNewElement("h2", dietDiv, `Diet`);

		const text = [];
		const links = [];

		if (!canEatFood(PC)) {
			text.push(`Your body is dependent on slave food for nutrition as your digestive tract has atrophied.`);
		}

		if (PC.diet === "healthy") {
			text.push(`You are eating healthy.`);
		} else if (PC.diet === "restricted") {
			text.push(`You are eating less in order to lose weight.`);
		} else if (PC.diet === "fattening") {
			text.push(`You are eating more in order to gain weight.`);
		} else if (PC.diet === "muscle building" || PC.diet === "slimming") {
			text.push(`You are eating energy rich food and spending ${PC.muscles > 0 ? "extra " : ""}time in the gym.`);
		} else if (PC.diet === "exotic") {
			text.push(`You are eating exotic foods to boost your energy in bed.`);
		} else if (PC.diet === "medicinal") {
			text.push(`You are eating medicinal foods to ${PC.health.condition < 90 ? "better" : "solidify"} your health.`);
		} else if (PC.diet === "corrective") {
			text.push(`The automated feeder is controlling your portions in order to correct your weight.`);
		} else if (PC.diet === "cum production") {
			text.push(`You are eating a blend formulated to increase cum production.`);
		} else if (PC.diet === "XX") {
			text.push(`You are eating a blend laced with female hormones.`);
		} else if (PC.diet === "XY") {
			text.push(`You are eating a blend laced with male hormones.`);
		} else if (PC.diet === "XXY") {
			text.push(`You are eating a blend loaded with sex hormones.`);
		} else if (PC.diet === "cleansing") {
			text.push(`You are eating a blend formulated to flush carcinogens from your system.`);
		} else if (PC.diet === "fertility") {
			text.push(`You are eating a blend formulated to increase fertility.`);
		} else if (PC.diet === "weaning") {
			text.push(`You are on a special diet to wean you of your slave food dependency. You must stick with it until completion for it to have any lasting effect; quitting means you'll have to start it over again.`);
		}

		// I hate everything about what comes after this line.
		const onDiet = "You are on this diet";
		if (PC.diet === "healthy") {
			links.push(App.UI.DOM.disabledLink(`Healthy`, [
				`${onDiet}`,
			]));
		} else {
			links.push(App.UI.DOM.link(`Healthy`, () => {
				PC.diet = "healthy";
				App.UI.DOM.replace(dietDiv, diet);
			}));
		}
		if (!canEatFood(PC) && V.dietCleanse === 1) {
			if (PC.diet === "cleansing") {
				links.push(App.UI.DOM.disabledLink(`Cleanse`, [
					`${onDiet}`,
				]));
			} else if (PC.health.condition < 90 || PC.chem >= 10) {
				links.push(App.UI.DOM.link(`Cleanse`, () => {
					PC.diet = "cleansing";
					App.UI.DOM.replace(dietDiv, diet);
				}));
			} else {
				links.push(App.UI.DOM.disabledLink(`Cleanse`, [
					`You are already healthy`,
				]));
			}
		}
		if (PC.diet === "restricted") {
			links.push(App.UI.DOM.disabledLink(`Lose weight`, [
				`${onDiet}`,
			]));
		} else if (PC.weight >= -95) {
			links.push(App.UI.DOM.link(`Lose weight`, () => {
				PC.diet = "restricted";
				App.UI.DOM.replace(dietDiv, diet);
			}));
		} else {
			links.push(App.UI.DOM.disabledLink(`Lose weight`, [
				`You have nothing left to lose`,
			]));
		}
		if (!canEatFood(PC) && V.feeder === 1) {
			if (PC.diet === "corrective") {
				links.push(App.UI.DOM.disabledLink(`Correct weight`, [
					`${onDiet}`,
				]));
			} else if (PC.weight > 10 || PC.weight < -10) {
				links.push(App.UI.DOM.link(`Correct weight`, () => {
					PC.diet = "corrective";
					App.UI.DOM.replace(dietDiv, diet);
				}));
			} else {
				links.push(App.UI.DOM.disabledLink(`Correct weight`, [
					`You are already a healthy weight`,
				]));
			}
		}
		if (PC.diet === "fattening") {
			links.push(App.UI.DOM.disabledLink(`Gain weight`, [
				`${onDiet}`,
			]));
		} else if (PC.weight >= -95) {
			links.push(App.UI.DOM.link(`Gain weight`, () => {
				PC.diet = "fattening";
				App.UI.DOM.replace(dietDiv, diet);
			}));
		} else {
			links.push(App.UI.DOM.disabledLink(`Gain weight`, [
				`You can't risk getting any fatter`,
			]));
		}
		if (PC.diet === "muscle building") {
			links.push(App.UI.DOM.disabledLink(`Build muscle`, [
				`${onDiet}`,
			]));
		} else if (PC.muscles < 100 && !isAmputee(PC)) {
			links.push(App.UI.DOM.link(`Build muscle`, () => {
				PC.diet = "muscle building";
				App.UI.DOM.replace(dietDiv, diet);
			}));
		} else if (!isAmputee(PC)) {
			links.push(App.UI.DOM.disabledLink(`Build muscle`, [
				`You can't get any stronger`,
			]));
		} else {
			links.push(App.UI.DOM.disabledLink(`Build muscle`, [
				`You can't work out with no limbs`,
			]));
		}
		if (PC.diet === "slimming") {
			links.push(App.UI.DOM.disabledLink(`Slim down`, [
				`${onDiet}`,
			]));
		} else if (PC.muscles > 0 && canWalk(PC)) {
			links.push(App.UI.DOM.link(`Slim down`, () => {
				PC.diet = "slimming";
				App.UI.DOM.replace(dietDiv, diet);
			}));
		} else if (!canWalk(PC)) {
			links.push(App.UI.DOM.disabledLink(`Slim down`, [
				`You can't focus on cardio if you can't walk`,
			]));
		} else {
			links.push(App.UI.DOM.disabledLink(`Slim down`, [
				`You have no more muscle left to lose`,
			]));
		}
		if (!canEatFood(PC)) {
			if (PC.balls > 0 && V.cumProDiet === 1) {
				if (PC.diet === "cum production") {
					links.push(App.UI.DOM.disabledLink(`Cum production`, [
						`${onDiet}`,
					]));
				} else {
					links.push(App.UI.DOM.link(`Cum production`, () => {
						PC.diet = "cum production";
						App.UI.DOM.replace(dietDiv, diet);
					}));
				}
			}
			if (V.dietFertility === 1 && (PC.ovaries === 1 || PC.mpreg === 1)) {
				const superFetKnown = (PC.geneticQuirks.superfetation === 2 && (V.geneticMappingUpgrade >= 1 || PC.counter.birthsTotal > 0 || PC.pregWeek > 3));
				if (PC.diet === "fertility") {
					links.push(App.UI.DOM.disabledLink(`Fertility`, [
						`${onDiet}`,
					]));
				} else if (!isFertile(PC) || (PC.preg !== 0 && !superFetKnown)) {
					links.push(App.UI.DOM.disabledLink(`Fertility`, [
						`You can't get pregnant`,
					]));
				} else {
					links.push(App.UI.DOM.link(`Fertility`, () => {
						PC.diet = "fertility";
						App.UI.DOM.replace(dietDiv, diet);
					}));
				}
			}
			if (V.feeder === 1) {
				if (PC.diet === "XX") {
					links.push(App.UI.DOM.disabledLink(`Estrogen enriched`, [
						`${onDiet}`,
					]));
				} else {
					links.push(App.UI.DOM.link(`Estrogen enriched`, () => {
						PC.diet = "XX";
						App.UI.DOM.replace(dietDiv, diet);
					}));
				}
				if (PC.diet === "XY") {
					links.push(App.UI.DOM.disabledLink(`Testosterone enriched`, [
						`${onDiet}`,
					]));
				} else {
					links.push(App.UI.DOM.link(`Testosterone enriched`, () => {
						PC.diet = "XY";
						App.UI.DOM.replace(dietDiv, diet);
					}));
				}
				if (V.dietXXY === 1 && PC.balls > 0 && (PC.ovaries === 1 || PC.mpreg === 1)) {
					if (PC.diet === "XXY") {
						links.push(App.UI.DOM.disabledLink(`Herm hormone blend`, [
							`${onDiet}`,
						]));
					} else {
						links.push(App.UI.DOM.link(`Herm hormone blend`, () => {
							PC.diet = "XXY";
							App.UI.DOM.replace(dietDiv, diet);
						}));
					}
				}
			}
		} else {
			if (PC.diet === "exotic") {
				links.push(App.UI.DOM.disabledLink(`Exotic`, [
					`${onDiet}`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Exotic`, () => {
					PC.diet = "exotic";
					App.UI.DOM.replace(dietDiv, diet);
				}));
			}
			if (PC.diet === "medicinal") {
				links.push(App.UI.DOM.disabledLink(`Medicinal`, [
					`${onDiet}`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Medicinal`, () => {
					PC.diet = "medicinal";
					App.UI.DOM.replace(dietDiv, diet);
				}));
			}
		}

		text.push(App.UI.DOM.generateLinksStrip(links));

		App.Events.addNode(dietDiv, text);

		return dietDiv;
	}

	function drugs() {
		const hormonesDiv = document.createElement("div");
		const playerDrugsDiv = document.createElement("div");
		const pregDrugsDiv = document.createElement("div");
		const aphrodisiacDiv = document.createElement("div");

		App.UI.DOM.appendNewElement("h2", drugsDiv, `Drugs`);

		drugsDiv.append(playerDrugs());
		if (PC.hormones !== 0 || V.consumerDrugs !== 0) {
			drugsDiv.append(hormones());
		}
		if (PC.pregControl !== "none") {
			drugsDiv.append(pregDrugs());
		}
		// drugsDiv.append(aphrodisiacs());

		return drugsDiv;

		function hormones() {
			App.UI.DOM.appendNewElement("h3", hormonesDiv, `Hormones`);
			if (PC.hormones !== 0) {
				const linkDiv = App.UI.DOM.makeElement("div", null, ['indent']);
				hormonesDiv.append(`You are currently taking ${PC.hormones === 1 ? "female" : "male"} hormones.`);
				if (V.consumerDrugs !== 1) {
					linkDiv.append(App.UI.DOM.link(`Stop filling your prescription`, () => {
						V.PC.hormones = 0;
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
					App.UI.DOM.appendNewElement("div", linkDiv, `You will need to visit your doctor to start a new prescription.`, ["indent", "note"]);
				} else {
					linkDiv.append(App.UI.DOM.link(`Stop taking them`, () => {
						V.PC.hormones = 0;
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}
				hormonesDiv.append(linkDiv);
			} else {
				const links = [];
				hormonesDiv.append(`You are not taking any hormones. `);
				links.push(App.UI.DOM.link(`Male hormones`, () => {
					V.PC.hormones = -1;
					App.UI.DOM.replace(drugsDiv, drugs);
				}));
				links.push(App.UI.DOM.link(`Female hormones`, () => {
					V.PC.hormones = 1;
					App.UI.DOM.replace(drugsDiv, drugs);
				}));
				hormonesDiv.append(App.UI.DOM.generateLinksStrip(links));
			}

			return hormonesDiv;
		}

		function playerDrugs() {
			const consumerDrugsDiv = document.createElement("div");
			const buyDrugsDiv = document.createElement("div");
			const slaveDrugsDiv = document.createElement("div");

			if (PC.drugs !== "no drugs") {
				playerDrugsDiv.append(`You are currently using ${PC.drugs}.`);
				playerDrugsDiv.append(App.UI.DOM.link(` Stop taking them`, () => {
					V.PC.drugs = "no drugs";
					App.UI.DOM.replace(drugsDiv, drugs);
				}));
				if (["breast enhancers", "butt enhancers", "lip enhancers", "penis enlargers", "testicle enlargers", "fertility supplements"].includes(PC.drugs) && V.consumerDrugs === 0) {
					App.UI.DOM.appendNewElement("div", linkDiv, `You will need to visit your doctor to start a new prescription.`, ["indent", "note"]);
				}
			} else {
				playerDrugsDiv.append(`You are not using any pharmaceutical drugs.`);
			}

			App.UI.DOM.appendNewElement("h3", playerDrugsDiv, `Consumer-grade`);
			playerDrugsDiv.append(consumerDrugs());
			if (V.consumerDrugs === 0 && V.dispensary === 1 && PC.skill.medicine >= 100) {
				playerDrugsDiv.append(buyConsumerDrugs());
			}
			App.UI.DOM.appendNewElement("h3", playerDrugsDiv, `Slave-grade`);
			playerDrugsDiv.append(slaveDrugs());

			return playerDrugsDiv;

			function consumerDrugs() {
				const text = [];
				const links = [];

				if (V.consumerDrugs === 1) {
					if (PC.drugs !== "breast enhancers") {
						if (PC.boobs < 50000) {
							links.push(App.UI.DOM.link(`Breast enhancers`, () => {
								PC.drugs = "breast enhancers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Breast enhancers`, [
								`Breasts are too big for the patches to work`,
							]));
						}
					}
					if (PC.drugs !== "butt enhancers") {
						if (PC.butt < 20) {
							links.push(App.UI.DOM.link(`Butt enhancers`, () => {
								PC.drugs = "butt enhancers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Butt enhancers`, [
								`Butt is too large for the patches to work`,
							]));
						}
					}
					if (PC.drugs !== "lip enhancers") {
						if (PC.lips < 100 || (PC.lips <= 85 && V.seeExtreme !== 1)) {
							links.push(App.UI.DOM.link(`Lip enhancers`, () => {
								PC.drugs = "lip enhancers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Lip enhancers`, [
								`Lips cannot grow larger`,
							]));
						}
					}
					if (PC.drugs !== "penis enlargers") {
						if (PC.dick < 30) {
							links.push(App.UI.DOM.link(`Penis enlargers`, () => {
								PC.drugs = "penis enlargers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Penis enlargers`, [
								`Penis is too large for the patches to work`,
							]));
						}
					}
					if (PC.drugs !== "testicle enlargers") {
						if (PC.balls < 125) {
							links.push(App.UI.DOM.link(`Testicle enlargers`, () => {
								PC.drugs = "testicle enlargers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Testicle enlargers`, [
								`Balls are too large for the patches to work`,
							]));
						}
					}
				}

				if (PC.drugs !== "stamina enhancers") {
					links.push(App.UI.DOM.link(`Stamina enhancers`, () => {
						PC.drugs = "stamina enhancers";
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}
				if (PC.drugs !== "appetite suppressors") {
					links.push(App.UI.DOM.link(`Appetite suppressors`, () => {
						PC.drugs = "appetite suppressors";
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}

				text.push(App.UI.DOM.generateLinksStrip(links));

				App.Events.addNode(consumerDrugsDiv, text);

				return consumerDrugsDiv;
			}

			function buyConsumerDrugs() {
				const drugsCash = 20000;
				buyDrugsDiv.append(
					App.UI.DOM.link(`Purchase a prescription drug license`, () => {
						V.consumerDrugs = 1;
						cashX(forceNeg(drugsCash), "capEx");

						App.UI.DOM.replace(drugsDiv, drugs);
					}),
				);
				App.UI.DOM.appendNewElement("span", buyDrugsDiv, ` Will cost you ${(cashFormat(drugsCash))}`, ['note']);

				return buyDrugsDiv;
			}

			function slaveDrugs() {
				const text = [];
				const links = [];
				/*
				if (arcology.FSSlaveProfessionalismResearch === 1) {
					if (PC.drugs !== "psychostimulants") {
						if (canImproveIntelligence(PC)) {
							links.push(App.UI.DOM.link(`Psychostimulants`, () => {
								PC.drugs = "psychostimulants";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Psychostimulants`, [
								`Cannot improve intelligence further this way`,
							]));
						}
					}
				}
				*/
				if (arcology.FSAssetExpansionistResearch === 1) {
					if (PC.drugs !== "hyper breast injections") {
						if (PC.boobs < 50000) {
							links.push(App.UI.DOM.link(`Hyper breast injections`, () => {
								PC.drugs = "hyper breast injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Hyper breast injections`, [
								`Breasts are too big for the drugs to work`,
							]));
						}
					}
				}
				if (PC.drugs !== "breast injections" && PC.drugs !== "intensive breast injections") {
					if (PC.boobs < 50000) {
						if (PC.drugs !== "breast injections") {
							links.push(App.UI.DOM.link(`Breast injections`, () => {
								PC.drugs = "breast injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
						if (PC.drugs !== "intensive breast injections") {
							links.push(App.UI.DOM.link(`Intensive breast injections`, () => {
								PC.drugs = "intensive breast injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					} else {
						links.push(App.UI.DOM.disabledLink(`Breast injections`, [
							`Breasts are too big for the drugs to work`,
						]));
					}
				}
				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "breast redistributors") {
						if ((PC.boobs - PC.boobsImplant - PC.boobsMilk) > 100) {
							links.push(App.UI.DOM.link(`Breast redistributors`, () => {
								PC.drugs = "breast redistributors";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Breast redistributors`, [
								`Already flat enough`,
							]));
						}
					}
				}

				if (V.dispensary) {
					if (PC.drugs !== "nipple enhancers") {
						if (["inverted", "partially inverted", "cute", "tiny", "puffy", "flat"].includes(PC.nipples)) {
							links.push(App.UI.DOM.link(`Nipple enhancers`, () => {
								PC.drugs = "nipple enhancers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else if (PC.nipples === "huge") {
							links.push(App.UI.DOM.disabledLink(`Nipple enhancers`, [
								`Nipples cannot get any larger`,
							]));
						} else {
							links.push(App.UI.DOM.disabledLink(`Nipple enhancers`, [
								`Will not affect your nipples`,
							]));
						}
					}
				}
				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "nipple atrophiers") {
						if (PC.nipples === "huge" || PC.nipples === "puffy" || PC.nipples === "cute") {
							links.push(App.UI.DOM.link(`Nipple atrophiers`, () => {
								PC.drugs = "nipple atrophiers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Nipple atrophiers`, [
								`Will not affect your nipples`,
							]));
						}
					}
				}

				if (arcology.FSAssetExpansionistResearch === 1) {
					if (PC.drugs !== "hyper butt injections") {
						if (PC.butt < 20) {
							links.push(App.UI.DOM.link(`Hyper butt injections`, () => {
								PC.drugs = "hyper butt injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Hyper butt injections`, [
								`Ass cannot grow larger`,
							]));
						}
					}
				}
				if (PC.drugs !== "butt injections" && PC.drugs !== "intensive butt injections") {
					if (PC.butt < 9) {
						if (PC.drugs !== "butt injections") {
							links.push(App.UI.DOM.link(`Butt injections`, () => {
								PC.drugs = "butt injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
						if (PC.drugs !== "intensive butt injections") {
							links.push(App.UI.DOM.link(`Intensive butt injections`, () => {
								PC.drugs = "intensive butt injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					} else {
						links.push(App.UI.DOM.disabledLink(`Butt injections`, [
							`Ass is too big for the drugs to work`,
						]));
					}
				}
				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "butt redistributors") {
						if (PC.butt - PC.buttImplant > 0) {
							links.push(App.UI.DOM.link(`Butt redistributors`, () => {
								PC.drugs = "butt redistributors";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Butt redistributors`, [
								`No ass left to lose`,
							]));
						}
					}
				}

				if (V.dispensary) {
					if (PC.drugs !== "lip injections") {
						if (PC.lips <= 95 || (PC.lips <= 85 && V.seeExtreme !== 1)) {
							links.push(App.UI.DOM.link(`lip injections`, () => {
								PC.drugs = "lip injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`lip injections`, [
								`Lips cannot grow larger`,
							]));
						}
					}
				}
				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "lip atrophiers") {
						if (PC.lips - PC.lipsImplant > 0) {
							links.push(App.UI.DOM.link(`Lip atrophiers`, () => {
								PC.drugs = "lip atrophiers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Lip atrophiers`, [
								`No lip left to give`,
							]));
						}
					}
				}

				if (arcology.FSAssetExpansionistResearch === 1) {
					if (PC.drugs !== "hyper penis enhancement") {
						if (PC.dick > 0) {
							if (PC.dick < 30) {
								links.push(App.UI.DOM.link(`Hyper penis enhancement`, () => {
									PC.drugs = "hyper penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							} else {
								links.push(App.UI.DOM.disabledLink(`Hyper penis enhancement`, [
									`Dick cannot grow larger`,
								]));
							}
						} else {
							if (PC.clit < 5) {
								links.push(App.UI.DOM.link(`Hyper clitoris enhancement`, () => {
									PC.drugs = "hyper penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							} else {
								links.push(App.UI.DOM.disabledLink(`Hyper clitoris enhancement`, [
									`Clit cannot grow larger`,
								]));
							}
						}
					}
				}
				if (PC.drugs !== "penis enhancement" && PC.drugs !== "intensive penis enhancement") {
					if (PC.dick > 0) {
						if (PC.dick < 10) {
							if (PC.drugs !== "penis enhancement") {
								links.push(App.UI.DOM.link(`Penis enhancement`, () => {
									PC.drugs = "penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							}
							if (PC.drugs !== "intensive penis enhancement") {
								links.push(App.UI.DOM.link(`Intensive penis enhancement`, () => {
									PC.drugs = "intensive penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							}
						} else {
							links.push(App.UI.DOM.disabledLink(`Penis enhancement`, [
								`Dick is too big for the drugs to work`,
							]));
						}
					} else {
						if (PC.clit < 5) {
							if (PC.drugs !== "penis enhancement") {
								links.push(App.UI.DOM.link(`Clitoris enhancement`, () => {
									PC.drugs = "penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							}
							if (PC.drugs !== "intensive penis enhancement") {
								links.push(App.UI.DOM.link(`Intensive clitoris enhancement`, () => {
									PC.drugs = "intensive penis enhancement";
									App.UI.DOM.replace(drugsDiv, drugs);
								}));
							}
						} else {
							links.push(App.UI.DOM.disabledLink(`Penis enhancement`, [
								`Clit cannot grow larger`,
							]));
						}
					}
				}
				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "penis atrophiers") {
						if (PC.dick > 1) {
							links.push(App.UI.DOM.link(`Penile atrophiers`, () => {
								PC.drugs = "penis atrophiers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Penile atrophiers`, [
								`Dick cannot possibly get smaller`,
							]));
						}
					}
					if (PC.drugs !== "clitoris atrophiers") {
						if (PC.clit > 0) {
							links.push(App.UI.DOM.link(`Clitoral atrophiers`, () => {
								PC.drugs = "clitoris atrophiers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Clitoral atrophiers`, [
								`Clit cannot possibly get smaller`,
							]));
						}
					}
				}
				if (PC.drugs !== "priapism agents") {
					if (PC.dick.isBetween(0, 11) && !canAchieveErection(PC)) {
						links.push(App.UI.DOM.link(`Priapism agents`, () => {
							PC.drugs = "priapism agents";
							App.UI.DOM.replace(drugsDiv, drugs);
						}));
					}
				}

				if (PC.balls > 0) {
					if (arcology.FSAssetExpansionistResearch === 1) {
						if (PC.drugs !== "hyper testicle enhancement") {
							links.push(App.UI.DOM.link(`Hyper testicle enhancement`, () => {
								PC.drugs = "hyper testicle enhancement";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					}
					if (PC.drugs !== "testicle enhancement" && PC.drugs !== "intensive testicle enhancement") {
						links.push(App.UI.DOM.link(`Testicle enhancement`, () => {
							PC.drugs = "testicle enhancement";
							App.UI.DOM.replace(drugsDiv, drugs);
						}));
						links.push(App.UI.DOM.link(`Intensive testicle enhancement`, () => {
							PC.drugs = "intensive testicle enhancement";
							App.UI.DOM.replace(drugsDiv, drugs);
						}));
					}
				}

				if (PC.drugs !== "fertility drugs") {
					links.push(App.UI.DOM.link(`Fertility drugs`, () => {
						PC.drugs = "fertility drugs";
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}
				if (PC.drugs !== "super fertility drugs") {
					if (V.seeHyperPreg === 1 && V.superFertilityDrugs === 1) {
						links.push(App.UI.DOM.link(`Super fertility drugs`, () => {
							PC.drugs = "super fertility drugs";
							App.UI.DOM.replace(drugsDiv, drugs);
						}));
					}
				}

				if (V.precociousPuberty === 1 && V.pubertyHormones === 1) {
					if (PC.balls > 0 && PC.pubertyXY === 0) {
						if (PC.drugs !== "male hormone injections") {
							links.push(App.UI.DOM.link(`XY injections`, () => {
								PC.drugs = "male hormone injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					}
					if ((PC.ovaries === 1 || PC.mpreg === 1) && PC.pubertyXX === 0) {
						if (PC.drugs !== "female hormone injections") {
							links.push(App.UI.DOM.link(`XX injections`, () => {
								PC.drugs = "female hormone injections";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					}
				}
				if (PC.drugs !== "hormone blockers") {
					links.push(App.UI.DOM.link(`Hormone blockers`, () => {
						PC.drugs = "hormone blockers";
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}
				if (PC.drugs !== "hormone enhancers") {
					links.push(App.UI.DOM.link(`Hormone enhancers`, () => {
						PC.drugs = "hormone enhancers";
						App.UI.DOM.replace(drugsDiv, drugs);
					}));
				}

				if (arcology.FSSlimnessEnthusiastResearch === 1) {
					if (PC.drugs !== "labia atrophiers") {
						if (PC.labia > 0) {
							links.push(App.UI.DOM.link(`Labia atrophiers`, () => {
								PC.drugs = "labia atrophiers";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						}
					}
				}
				if (V.growthStim === 1) {
					if (PC.drugs !== "growth stimulants") {
						if (canImproveHeight(PC)) {
							links.push(App.UI.DOM.link(`Growth stimulants`, () => {
								PC.drugs = "growth stimulants";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Growth stimulants`, [
								`Your body just cannot grow any more`,
							]));
						}
					}
				}
				links.push(App.UI.DOM.link(`Steroids`, () => {
					PC.drugs = "steroids";
					App.UI.DOM.replace(drugsDiv, drugs);
				}));
				if (PC.boobs > 250 && PC.boobShape !== "saggy" && V.purchasedSagBGone === 1) {
					if (PC.drugs !== "sag-B-gone") {
						links.push(App.UI.DOM.link(`Sag-B-Gone breast lifting cream`, () => {
							PC.drugs = "sag-B-gone";
							App.UI.DOM.replace(drugsDiv, drugs);
						}));
					}
				}
				if (arcology.FSYouthPreferentialistResearch === 1) {
					if (PC.drugs !== "anti-aging cream") {
						if (PC.visualAge > 18) {
							links.push(App.UI.DOM.link(`Anti-aging cream`, () => {
								PC.drugs = "anti-aging cream";
								App.UI.DOM.replace(drugsDiv, drugs);
							}));
						} else {
							links.push(App.UI.DOM.disabledLink(`Anti-aging cream`, [
								`Cream alone can only get you so far`,
							]));
						}
					}
				}

				text.push(App.UI.DOM.generateLinksStrip(links));

				App.Events.addNode(slaveDrugsDiv, text);

				if (canEatFood(PC)) {
					if ((arcology.FSBodyPuristLaw === 0 && V.healthyDrugsUpgrade === 0) || (["hyper breast injections", "hyper butt injections", "growth stimulants", "hyper penis enhancement", "hyper testicle enhancement", "super fertility drugs"].includes(PC.drugs))) {
						App.UI.DOM.appendNewElement("div", slaveDrugsDiv, `Most slave-grade drugs are unhealthy and should be used sparingly.`, ["indent", "note"]);
					}
				}

				return slaveDrugsDiv;
			}
		}

		function pregDrugs() {
			const text = [];

			App.UI.DOM.appendNewElement("h3", pregDrugsDiv, `Pregnancy Drugs`);
			pregDrugsDiv.append(`You are currently using labor suppressors to delay birth.`);
			text.push(
				App.UI.DOM.link(`Stop taking them`, () => {
					PC.pregControl = "none";
					App.UI.DOM.replace(appearanceDiv, appearance);
					App.UI.DOM.replace(drugsDiv, drugs);
				})
			);
			App.Events.addNode(pregDrugsDiv, text);

			return pregDrugsDiv;
		}

		function aphrodisiacs() {
			const text = [];

			App.UI.DOM.appendNewElement("h3", aphrodisiacDiv, `Aphrodisiacs`);
			if (PC.aphrodisiacs > 0) {
				if (PC.addict > 10) {
					text.push(`You are enjoying aphrodisiacs and how fun they are to use.`);
				} else if (PC.addict > 3) {
					text.push(`You are currently enjoying aphrodisiacs and how fun they make sex.`);
				} else {
					text.push(`You are currently using aphrodisiacs to supercharge your sex drive.`);
				}
				if (random(1, 100) > PC.addict * 4) {
					text.push(
						App.UI.DOM.link(`Stop taking them`, () => {
							PC.aphrodisiacs = 0;
							App.UI.DOM.replace(appearanceDiv, appearance);
							App.UI.DOM.replace(drugsDiv, drugs);
						})
					);
				} else {
					const addicted = ["Yeah right", "How about not?", "Maybe later...", "Tomorrow seems better...", "Yeah, no", "Not happening", "Would rather not", "Feels too good", "No stopping it"];
					text.push(
						App.UI.DOM.disabledLink(`Stop taking them`, [
							`${jsEither(addicted)}`,
						])
					);
				}
			} else if (PC.aphrodisiacs < 0) {
				text.push(`You are currently using anaphrodisiacs to reign in your sex drive.`);
				text.push(
					App.UI.DOM.link(`Stop taking them`, () => {
						PC.aphrodisiacs = 0;
						App.UI.DOM.replace(appearanceDiv, appearance);
						App.UI.DOM.replace(drugsDiv, drugs);
					})
				);
			} else if (PC.addict > 10) {
				text.push(`You are currently cut off from your aphrodisiacs by that fucking bitch of a PA.`);
				text.push(
					App.UI.DOM.link(`Override your decision`, () => {
						PC.aphrodisiacs = 1;
						App.UI.DOM.replace(appearanceDiv, appearance);
						App.UI.DOM.replace(drugsDiv, drugs);
					})
				);
			} else {
				text.push(`You are not taking any aphrodisiacs.`);
				if (PC.addict > 0) {
					text.push(
						App.UI.DOM.link(`But you could be...`, () => {
							PC.aphrodisiacs = 1;
							App.UI.DOM.replace(appearanceDiv, appearance);
							App.UI.DOM.replace(drugsDiv, drugs);
						})
					);
				} else {
					text.push(
						App.UI.DOM.link(`Start taking them`, () => {
							PC.aphrodisiacs = 1;
							App.UI.DOM.replace(appearanceDiv, appearance);
							App.UI.DOM.replace(drugsDiv, drugs);
						})
					);
				}
			}
			App.Events.addNode(aphrodisiacDiv, text);
			if (PC.aphrodisiacs === 0 && PC.addict === 0) {
				App.UI.DOM.appendNewElement("div", aphrodisiacDiv, `Aphrodisiacs will increase the amount of sex you can have in a week, but are dangerously addictive.`, ["indent", "note"]);
			}

			return aphrodisiacDiv;
		}
	}

	function lactation() {
		App.UI.DOM.appendNewElement("h2", lactationDiv, `Lactation`);

		const text = [];

		if (PC.lactation > 1) {
			text.push(`Your breasts are swollen with milk.`);

			if (PC.rules.lactation === "sell") {
				text.push(
					`You are spending time with the penthouse milkers and making a quick ¤ from your efforts.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.disabledLink(`Stop milking yourself`, [
							`Your breasts would leak uncontrollably.`
						]),
						App.UI.DOM.link(`Stop using the milkers`, () => {
							V.PC.rules.lactation = "maintain";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
						App.UI.DOM.disabledLink(`Use the penthouse milkers`, [
							`You are already selling your breast milk.`
						])
					])
				);
			} else if (PC.rules.lactation === "maintain") {
				text.push(
					`You have no choice but to regularly drain yourself.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.disabledLink(`Stop milking yourself`, [
							`Your breasts would leak uncontrollably.`
						]),
						App.UI.DOM.disabledLink(`Keep yourself milked`, [
							`You need to do this to remain comfortable.`
						]),
						App.UI.DOM.link(`Use the penthouse milkers`, () => {
							V.PC.rules.lactation = "sell";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
					])
				);
			}
		} else if (PC.lactation > 0) {
			text.push(`Your breasts are laden with milk.`);

			if (PC.rules.lactation === "sell") {
				text.push(
					`You are spending time with the penthouse milkers and making a quick ¤ from your efforts.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.link(`Stop milking yourself`, () => {
							V.PC.rules.lactation = "none";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
						App.UI.DOM.link(`Stop using the milkers`, () => {
							V.PC.rules.lactation = "maintain";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
						App.UI.DOM.disabledLink(`Use the penthouse milkers`, [
							`You are already selling your breast milk.`
						])
					])
				);
			} else if (PC.rules.lactation === "maintain") {
				text.push(
					`You are taking the time to keep yourself lactating.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.link(`Stop milking yourself`, () => {
							V.PC.rules.lactation = "none";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
						App.UI.DOM.disabledLink(`Keep yourself milked`, [
							`You are already maintaining lactation.`
						]),
						App.UI.DOM.link(`Use the penthouse milkers`, () => {
							V.PC.rules.lactation = "sell";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
					])
				);
			} else {
				text.push(
					`You are currently letting nature run its course.`,
					App.UI.DOM.generateLinksStrip([
						App.UI.DOM.disabledLink(`Stop milking yourself`, [
							`You aren't currently milking yourself.`
						]),
						App.UI.DOM.link(`Keep yourself milked`, () => {
							V.PC.rules.lactation = "maintain";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
						App.UI.DOM.link(`Use the penthouse milkers`, () => {
							V.PC.rules.lactation = "sell";
							App.UI.DOM.replace(lactationDiv, lactation);
						}),
					])
				);
			}
		} else {
			text.push(`You could induce yourself to begin lactating.`);

			if (PC.rules.lactation === "induce") {
				text.push(
					`You are spending time stimulating your breasts and nipples to bring in your milk.`,
					App.UI.DOM.link(`Lose interest.`, () => {
						V.PC.rules.lactation = "none";
						App.UI.DOM.replace(lactationDiv, lactation);
					})
				);
			} else {
				text.push(
					App.UI.DOM.link(`Sounds fun!`, () => {
						V.PC.rules.lactation = "induce";
						App.UI.DOM.replace(lactationDiv, lactation);
					})
				);
			}
		}

		App.Events.addNode(lactationDiv, text);

		return lactationDiv;
	}

	function breederExam() {
		App.UI.DOM.appendNewElement("h2", breederExamDiv, `Elite Breeder Qualifications`);

		breederExamDiv.append(App.Interact.eliteBreedingExam());

		return breederExamDiv;
	}

	function perversions() {
		const bloatingDiv = document.createElement("div");
		const cumTapDiv = document.createElement("div");
		const impregnateSelfDiv = document.createElement("div");

		App.UI.DOM.appendNewElement("h2", pervertDiv, `Perversions`);

		// set these to use standard preg/inflation bars
		if (PC.preg === 0 && PC.pregWeek === 0 && PC.vagina > -1) {
			pervertDiv.append(
				cumTap(),
				impregnateSelf(),
			);
		}

		function bloating() {
			const text = [];

			let bloating = document.createElement('div');
			if (PC.inflation > 0) {
				let intro = document.createElement('span');
				intro.textContent = "Required Bloating";
				intro.style.textDecoration = "underline";
				bloating.append(intro);

				bloating.append(": ");

				let requirement = document.createElement('span');
				requirement.style.fontWeight = "bold";
				requirement.id = "inflate";
				if (PC.inflation === 3) {
					requirement.textContent = `he is required to keep 2 gallons of ${PC.inflationType} in him at all times`;
				} else if (PC.inflation === 2) {
					requirement.textContent = `he is required to keep 4 liters of ${PC.inflationType} in him at all times`;
				} else if (PC.inflation === 1) {
					requirement.textContent = `he is required to keep 2 liters of ${PC.inflationType} in him at all times`;
				}
				bloating.append(requirement);
				bloating.append(". ");

				let link = App.UI.DOM.link(
					`Let $him deflate`,
					() => {
						deflate(PC);
					},
				);
				bloating.append(link);
			}

			return bloatingDiv;
		}

		function cumTap() {
			const text = [];

			if (V.dairyPiping && (cumSlaves().length > 0 || arcology.FSPastoralistLaw === 1)) {
				if (PC.skill.cumTap === 0) {
					text.push(
						`The tap connected to ${V.dairyName} has a variety of attachments, one of which being a very tantalizing dick-shaped nozzle. It looks like it would be a perfect fit for you, if you were curious, that is.`,
						App.UI.DOM.passageLink(`No one is looking...`, 'FSelf'),
					);
				} else {
					text.push(
						`The tap connected to ${V.dairyName} is calling to you. Begging to let it fill you with cum again. If you wanted to try and go bigger, that is.`,
						App.UI.DOM.generateLinksStrip([
							App.UI.DOM.passageLink(`Sounds fun!`, 'FSelf'),
							App.UI.DOM.link(`You only want to get pregnant`, () => {
								V.PC.preg = 1;
								V.PC.pregSource = 0;
								V.PC.pregKnown = 1;
								V.PC.pregType = setPregType(V.PC);

								WombImpregnate(V.PC, V.PC.pregType, 0, 1);

								App.UI.DOM.replace(cumTapDiv, cumTap);
							})
						])
					);
				}
			}
			/*
			if (V.dairyPiping && (cumSlaves().length > 0 || arcology.FSPastoralistLaw === 1)) {
				if (PC.vagina > 0 || PC.anus > 0)
				if (PC.skill.cumTap === 0) {
					text.push(
						`The tap connected to ${V.dairyName} has a variety of attachments, one of which being a very tantalizing dick-shaped nozzle. It looks like it would be a perfect fit for you, if you were curious, that is.`,
						App.UI.DOM.passageLink(`No one is looking...`, 'FSelf'),
					);
				} else {
					text.push(
						`The tap connected to ${V.dairyName} is calling to you. Begging to let it fill you with cum again. If you wanted to try and go bigger, that is.`,
						App.UI.DOM.passageLink(`Sounds fun!`, 'FSelf');
						if (canGetPregnant(PC)) {
							App.UI.DOM.link(`You only want to get pregnant`, () => {
								PC.preg = 1;
								PC.pregSource = 0;
								PC.pregKnown = 1;
								PC.pregType = setPregType(V.PC);

								WombImpregnate(PC, PC.pregType, 0, 1);

								App.UI.DOM.replace(cumTapDiv, cumTap);
							});
						}
					);
				}
			}
			*/

			App.Events.addNode(cumTapDiv, text);

			return cumTapDiv;
		}

		function impregnateSelf() {
			const text = [];

			if (V.PC.vagina > 0 && V.PC.dick) {
				if (V.PC.counter.birthSelf > 0) {
					text.push(
						`Who better to impregnate you than you?`,
						App.UI.DOM.passageLink(`Impregnate yourself`, 'MpregSelf'),
					);
				} else {
					text.push(
						`You have an empty vagina, a working set of balls, and a strong craving for a hot creampie. Who better to give it to you than you?`,
						App.UI.DOM.passageLink(`Grab an extra syringe`, 'MpregSelf'),
					);
				}
			}
			/*
			if ((canImpreg(PC, PC) || canFemPreg(PC, PC)) && PC.counter.birthSelf > 0) {
				text.push(
					`Who better to impregnate you than you?`,
					App.UI.DOM.passageLink(`Impregnate yourself`, 'MpregSelf'),
				);
			} else if (PC.balls > 0 && PC.energy > 20) {
				if (PC.vagina >= 0) {
					text.push(
						`You have a${PC.vagina > 0 ? "n empty" : " tingling feeling in your"} vagina, a working set of balls, and a strong craving for a hot creampie. Who better to give it to you than you?`,
						App.UI.DOM.passageLink(`Grab an extra syringe`, 'MpregSelf'),
					);
				} else if (PC.anus > 0) {
					text.push(
						`You have an empty anus, a working set of balls, and a strong craving for a hot creampie. Who better to give it to you than you?`,
						App.UI.DOM.passageLink(`Grab an extra syringe`, 'MpregSelf'),
					);
				}
			}
			*/

			App.Events.addNode(impregnateSelfDiv, text);

			return impregnateSelfDiv;
		}

		return pervertDiv;
	}

	function socials() {
		const weddingDiv = document.createElement("div");
		const FCTVDiv = document.createElement("div");
		let text = [];

		if (V.weddingPlanned) {
			text.push(wedding());
		}

		if (V.FCTV.receiver) {
			text.push(FCTV());
		}

		App.Events.addNode(socialDiv, text);

		function wedding() {
			const text = [];

			App.UI.DOM.appendNewElement("h2", weddingDiv, `Wedding`);

			text.push(`You have a wedding planned for this weekend; you are`);

			if (V.weddingPlanned === 1) {
				text.push(`marrying`);
			} else if (V.weddingPlanned === 2) {
				text.push(`sharing`);
			} else if (V.weddingPlanned === 3) {
				text.push(`knocking up`);
			} else {
				throw new Error(`Invalid V.weddingPlanned value of '${V.weddingPlanned}' in managePersonalAffairs()`);
			}

			text.push(
				marryingList(),
				App.UI.DOM.link(`Cancel it`, () => {
					V.weddingPlanned = 0;
					V.marrying = [];

					App.UI.DOM.replace(appearanceDiv, appearance);
				})
			);

			App.Events.addNode(weddingDiv, text);

			return weddingDiv;

			function marryingList() {
				const listSpan = document.createElement("span");

				listSpan.append(
					App.UI.DOM.toSentence(V.marrying.map(id => App.UI.DOM.passageLink(SlaveFullName(getSlave(id)), 'Slave Interact'))),
					`.`,
				);

				return listSpan;
			}
		}

		function FCTV() {
			const text = [];
			const links = [];

			App.UI.DOM.appendNewElement("h2", FCTVDiv, `FCTV`);

			if (V.FCTV.pcViewership.frequency === 1) {
				text.push(`You make sure to tune in to FCTV at least once a week.`);
			} else if (V.FCTV.pcViewership.frequency === 2) {
				text.push(`You make sure to tune in to FCTV at least once biweekly.`);
			} else if (V.FCTV.pcViewership.frequency === 4) {
				text.push(`You make sure to tune in to FCTV at least once a month.`);
			} else {
				text.push(`You don't watch FCTV.`);
			}

			if (V.FCTV.pcViewership.frequency === 1) {
				links.push(App.UI.DOM.disabledLink(`Watch every week`, [
					`You are already watching every week.`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Watch every week`, () => {
					V.FCTV.pcViewership.frequency = 1;
					App.UI.DOM.replace(FCTVDiv, FCTV);
				}));
			}
			if (V.FCTV.pcViewership.frequency === 2) {
				links.push(App.UI.DOM.disabledLink(`Watch every other week`, [
					`You are already watching every other week.`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Watch every other week`, () => {
					V.FCTV.pcViewership.frequency = 2;
					App.UI.DOM.replace(FCTVDiv, FCTV);
				}));
			}
			if (V.FCTV.pcViewership.frequency === 4) {
				links.push(App.UI.DOM.disabledLink(`Watch once a month`, [
					`You are already watching once a month.`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Watch once a month`, () => {
					V.FCTV.pcViewership.frequency = 4;
					App.UI.DOM.replace(FCTVDiv, FCTV);
				}));
			}
			if (V.FCTV.pcViewership.frequency === -1) {
				links.push(App.UI.DOM.disabledLink(`Ignore it`, [
					`You are already not watching.`,
				]));
			} else {
				links.push(App.UI.DOM.link(`Ignore it`, () => {
					V.FCTV.pcViewership.frequency = -1;
					App.UI.DOM.replace(FCTVDiv, FCTV);
				}));
			}

			if (V.saveImported > 0 && !V.FCTV.remote) {
				text.push(
					`You know TVs should have a remote.`,
					App.UI.DOM.link(`Buy one yourself`, () => {
						V.FCTV.remote = 1;

						cashX(forceNeg(100 * V.upgradeMultiplierTrade), "capEx");
						App.UI.DOM.replace(FCTVDiv, FCTV);
					})
				);
			}

			text.push(App.UI.DOM.generateLinksStrip(links));

			App.Events.addNode(FCTVDiv, text);

			return FCTVDiv;
		}

		return socialDiv;
	}

	function skills() {
		App.UI.DOM.appendNewElement("h2", skillsDiv, `Personal Skills`);

		skillsDiv.append(`You ponder what skills may be useful in running your arcology.`);

		App.UI.DOM.appendNewElement("div", skillsDiv, `Trading: ${getPlayerTradingSkill()}`);
		App.UI.DOM.appendNewElement("div", skillsDiv, `Warfare: ${getPlayerWarfareSkill()}`);
		App.UI.DOM.appendNewElement("div", skillsDiv, `Slaving: ${getPlayerSlavingSkill()}`);
		App.UI.DOM.appendNewElement("div", skillsDiv, `Engineering: ${getPlayerEngineeringSkill()}`);
		App.UI.DOM.appendNewElement("div", skillsDiv, `Medicine: ${getPlayerMedicineSkill()}`);
		App.UI.DOM.appendNewElement("div", skillsDiv, `Hacking: ${getPlayerHackingSkill()}`);

		return skillsDiv;

		function getPlayerTradingSkill() {
			if (PC.skill.trading >= 100) {
				return `You are a master at economics and trading.`;
			} else if (PC.skill.trading >= 80) {
				return `You are an expert at economics and trading.`;
			} else if (PC.skill.trading >= 60) {
				return `You are skilled in economics and trading.`;
			} else if (PC.skill.trading >= 40) {
				return `You know some things about economics and trading.`;
			} else if (PC.skill.trading >= 20) {
				return `You are a beginner in economics.`;
			} else if (PC.skill.trading >= 0) {
				return `You know only the basics of trading.`;
			} else if (PC.skill.trading >= -20) {
				return `You know how to haggle a little.`;
			} else if (PC.skill.trading >= -40) {
				return `You know how to shop around.`;
			} else if (PC.skill.trading >= -60) {
				return `You know not to pay sticker price.`;
			} else if (PC.skill.trading >= -80) {
				return `People always give you discounts, but you never save any money.`;
			} else {
				return `They said it was a bear market, so where are the bears?`;
			}
		}

		function getPlayerWarfareSkill() {
			if (PC.skill.warfare >= 100) {
				return `You are a master of warfare.`;
			} else if (PC.skill.warfare >= 80) {
				return `You are an expert at tactics and strategy.`;
			} else if (PC.skill.warfare >= 60) {
				return `You are skilled in combat.`;
			} else if (PC.skill.warfare >= 40) {
				return `You know some things about combat.`;
			} else if (PC.skill.warfare >= 20) {
				return `You are a beginner in tactics and strategy.`;
			} else if (PC.skill.warfare >= 0) {
				return `You know only the basics of fighting.`;
			} else if (PC.skill.warfare >= -20) {
				return `You know how to hold a gun.`;
			} else if (PC.skill.warfare >= -40) {
				return `You know how to stab with a knife.`;
			} else if (PC.skill.warfare >= -60) {
				return `Go for the throat?`;
			} else if (PC.skill.warfare >= -80) {
				return `Just kick them in the balls, right?`;
			} else {
				return `People like you are usually the first raped in a war.`;
			}
		}

		function getPlayerSlavingSkill() {
			if (PC.skill.slaving >= 100) {
				return `You are a master slaver.`;
			} else if (PC.skill.slaving >= 80) {
				return `You are an expert at enslaving.`;
			} else if (PC.skill.slaving >= 60) {
				return `You are skilled in slaving.`;
			} else if (PC.skill.slaving >= 40) {
				return `You know some things about getting slaves.`;
			} else if (PC.skill.slaving >= 20) {
				return `You are a beginner in slaving.`;
			} else if (PC.skill.slaving >= 0) {
				return `You know only the basics of slaving.`;
			} else if (PC.skill.slaving >= -20) {
				return `You know how to avoid becoming a slave.`;
			} else if (PC.skill.slaving >= -40) {
				return `You know to read contracts before you sign them.`;
			} else if (PC.skill.slaving >= -60) {
				return `You know to be careful.`;
			} else if (PC.skill.slaving >= -80) {
				return `You know better than to trust anyone.`;
			} else {
				return `It would be easy to enslave you.`;
			}
		}

		function getPlayerEngineeringSkill() {
			if (PC.skill.engineering >= 100) {
				return `You are a master engineer.`;
			} else if (PC.skill.engineering >= 80) {
				return `You are an expert at engineering.`;
			} else if (PC.skill.engineering >= 60) {
				return `You are skilled in engineering.`;
			} else if (PC.skill.engineering >= 40) {
				return `You know some things about engineering.`;
			} else if (PC.skill.engineering >= 20) {
				return `You are a beginner in engineering.`;
			} else if (PC.skill.engineering >= 0) {
				return `You know only the basics of engineering.`;
			} else if (PC.skill.engineering >= -20) {
				return `You can build a gingerbread house that doesn't collapse.`;
			} else if (PC.skill.engineering >= -40) {
				return `You can tie a tight knot, does that count?`;
			} else if (PC.skill.engineering >= -60) {
				return `Glue is your friend; lots of it.`;
			} else if (PC.skill.engineering >= -80) {
				return `You know better than to even try to build something.`;
			} else {
				return `You can cook; that's sort of like building something, right?`;
			}
		}

		function getPlayerMedicineSkill() {
			if (PC.skill.medicine >= 100) {
				return `You are a master surgeon.`;
			} else if (PC.skill.medicine >= 80) {
				return `You are an expert at medicine and surgery.`;
			} else if (PC.skill.medicine >= 60) {
				return `You are skilled in surgery.`;
			} else if (PC.skill.medicine >= 40) {
				return `You know some things about medicine.`;
			} else if (PC.skill.medicine >= 20) {
				return `You are a beginner in medicine.`;
			} else if (PC.skill.medicine >= 0) {
				return `You know the basics of treating injuries.`;
			} else if (PC.skill.medicine >= -20) {
				return `You can stop a wound from getting infected.`;
			} else if (PC.skill.medicine >= -40) {
				return `Gauze is your friend. Just keep wrapping.`;
			} else if (PC.skill.medicine >= -60) {
				return `You know how to apply a band-aid.`;
			} else if (PC.skill.medicine >= -80) {
				return `Cure-alls are wonderful. Why aren't they sold in stores, though?`;
			} else {
				return `Alcohol makes pain go away, right?`;
			}
		}

		function getPlayerHackingSkill() {
			if (PC.skill.hacking >= 100) {
				return `You are a master of hacking.`;
			} else if (PC.skill.hacking >= 80) {
				return `You are an expert at hacking.`;
			} else if (PC.skill.hacking >= 60) {
				return `You are skilled in hacking.`;
			} else if (PC.skill.hacking >= 40) {
				return `You know some things about hacking.`;
			} else if (PC.skill.hacking >= 20) {
				return `You are a beginner in hacking.`;
			} else if (PC.skill.hacking >= 0) {
				return `You know only the basics of hacking.`;
			} else if (PC.skill.hacking >= -20) {
				return `You know how to click a mouse.`;
			} else if (PC.skill.hacking >= -40) {
				return `Enter does something?`;
			} else if (PC.skill.hacking >= -60) {
				return `Where is the "any" key?`;
			} else if (PC.skill.hacking >= -80) {
				return `You can push the power button, good job.`;
			} else {
				return `This black box thingy is magical.`;
			}
		}
	}
};


code:
App.UI.Player.personalAttention = function() {
	const frag = new DocumentFragment();

	App.UI.DOM.appendNewElement("h1", frag, `Personal Attention`);

	V.nextButton = "Back to Main";
	V.nextLink = "Main";

	// set up div for refreshing options
	const refreshDiv = App.UI.DOM.appendNewElement("div", frag, content());

	return frag;

	function content() {
		const frag = new DocumentFragment();

		frag.append(
			focus(),
			proclamations(),
			skills(),
			attention(),
			slaves(),
		);

		return frag;
	}

	function focus() {
		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
		const text = [];
		const links = [];
		App.UI.DOM.appendNewElement("h2", div, `Focus`);
		text.push(`This week you are`);

		if (V.personalAttention.task === PersonalAttention.TRAINING) {
			const r = [];
			for (const slave of V.personalAttention.slaves) {
				slave.objective = slave.objective || getRegimen(getSlave(slave.ID));
				r.push(`<span class="slave-name">${SlaveFullName(getSlave(slave.ID))}</span> to <span class="bold">${App.PersonalAttention.getText(slave.objective, getSlave(slave.ID))}</span>`);
			}
			text.push(`training ${toSentence(r)}.`);
		} else {
			switch (V.personalAttention.task) {
				case PersonalAttention.WHORING:
					text.push(`using your body to make some side cash.`);
					break;
				case PersonalAttention.MAID:
					text.push(`using your housekeeping skills to help reduce upkeep costs on your home.`);
					break;
				case PersonalAttention.BUSINESS:
					text.push(`using your business acumen to earn some extra money.`);
					break;
				case PersonalAttention.SMUGGLING:
					text.push(`going to try to make some easy (but dirty) money.`);
					break;
				case PersonalAttention.SURVEY:
					text.push(`surveying ${V.arcologies[0].name}'s defenses in person.`);
					break;
				case PersonalAttention.DEVELOPMENT:
					text.push(`going to try to help raise ${V.arcologies[0].name}'s prosperity by contributing your talents to a local development project.`);
					break;
				case PersonalAttention.TECH:
					text.push(`contracting out your hacking skills to earn some extra cash.`);
					break;
				case PersonalAttention.SUPPORTHG:
					text.push(`going to support ${S.HeadGirl.slaveName} in ${getPronouns(S.HeadGirl).his} day-to-day routine.`);
					break;
				case PersonalAttention.SEX:
					text.push(`going to have as much sex as you possibly can.`);
					break;
				case PersonalAttention.TRADE:
					text.push(`training in trade.`);
					break;
				case PersonalAttention.WAR:
					text.push(`training in warfare.`);
					break;
				case PersonalAttention.SLAVING:
					text.push(`training in slaving.`);
					break;
				case PersonalAttention.ENGINEERING:
					text.push(`training in engineering.`);
					break;
				case PersonalAttention.MEDICINE:
					text.push(`training in medicine.`);
					break;
				case PersonalAttention.HACKING:
					text.push(`training in hacking.`);
					break;
				case PersonalAttention.PROCLAMATION:
					if (V.SecExp.proclamation.type === "security") {
						text.push(`issuing a new proclamation about the security of ${V.arcologies[0].name}.`);
					} else {
						text.push(`issuing a new proclamation about crime in ${V.arcologies[0].name}.`);
					}
					break;
				default:
					throw new Error(`Unknown V.personalAttention.task value of '${V.personalAttention.task}'. Please report this.`);
			}
		}

		App.Events.addNode(div, text);

		addFocusLinks(links,
			{
				link: `Focus on "connecting"`,
				value: PersonalAttention.WHORING,
				prereqs: [
					() => isPCCareerInCategory("escort"),
				],
			},
			{
				link: `Maintain your home`,
				value: PersonalAttention.MAID,
				prereqs: [
					() => isPCCareerInCategory("servant"),
				],
			},
			{
				link: `Focus on business`,
				value: PersonalAttention.BUSINESS,
			},
			{
				link: `Help people "pass" things around`,
				value: PersonalAttention.SMUGGLING,
				prereqs: [
					() => isPCCareerInCategory("gang"),
				],
			},
			{
				link: `Survey your arcology's defenses in person`,
				value: PersonalAttention.SURVEY,
				prereqs: [
					() => V.PC.skill.warfare > 25,
				],
			},
			{
				link: `Contribute to a local development project`,
				value: PersonalAttention.DEVELOPMENT,
				prereqs: [
					() => V.PC.skill.engineering > 25,
					() => V.arcologies[0].prosperity + 1 * (1 + Math.ceil(V.PC.skill.engineering / 100)) < V.AProsperityCap,
				],
			},
			{
				link: `Sell your intrusion services `,
				value: PersonalAttention.TECH,
				prereqs: [
					() => V.PC.skill.hacking > 25,
				],
			},
			{
				link: `Support your Head Girl`,
				value: PersonalAttention.SUPPORTHG,
				prereqs: [
					() => !!S.HeadGirl,
				],
			},
			{
				link: `Focus on sex`,
				value: PersonalAttention.SEX,
			},
		);

		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);

		return div;

		/**
		 * @param {Array<HTMLSpanElement|HTMLAnchorElement>} links
		 * @param {{link: string, value: PersonalAttention, prereqs?: Array<function():boolean>}[]} args
		 */
		function addFocusLinks(links, ...args) {
			args.forEach(link => {
				if (!link.prereqs || link.prereqs.every(prereq => prereq())) {
					if (V.personalAttention.task === link.value) {
						links.push(App.UI.DOM.disabledLink(link.link, [
							`Currently selected.`,
						]));
					} else {
						links.push(App.UI.DOM.link(link.link, () => {
							V.personalAttention = {task: link.value};

							refresh();
						}));
					}
				}
			});
		}
	}

	function proclamations() {
		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);

		const links = [];

		if (V.secExpEnabled) {
			App.UI.DOM.appendNewElement("h2", div, `Proclamations`);

			if (V.SecExp.proclamation.cooldown === 0) {
				const options = new App.UI.OptionsGroup();
				const option = options.addOption(null, "currency", V.SecExp.proclamation);

				App.UI.DOM.appendNewElement("div", div, `You can dedicate the week to issuing a proclamation, a powerful tool that will have an immediate noticeable effect on the arcology.`, ['note']);

				App.Events.addNode(div, [
					`You are using <span class="bold">${V.SecExp.proclamation.currency || 'cash'}.</span>`,
				]);

				if (V.SecExp.core.authority >= 2000) {
					option.addValue(`Authority`, 'authority');
				}

				if (V.rep >= 4000) {
					option.addValue(`Reputation`, 'reputation');
				}

				option.addValue(`Cash`, 'cash');

				App.UI.DOM.appendNewElement("div", div, options.render(), ['margin-left']);

				if (V.SecExp.core.authority >= 2000 ||
					V.rep >= 4000 ||
					V.cash >= 8000) {
					if (V.personalAttention.task === PersonalAttention.PROCLAMATION) {
						if (V.SecExp.proclamation.type === "security") {
							links.push(
								App.UI.DOM.disabledLink(`Issue a proclamation about security`, [
									`Currently selected.`
								]),

								App.UI.DOM.link(`Issue a proclamation about crime`, () => {
									V.personalAttention.task = PersonalAttention.PROCLAMATION;
									V.SecExp.proclamation.type = "crime";

									refresh();
								},
								null, ``, `You will use your ${V.SecExp.proclamation.currency === "authority"
									? `control over the arcology`
									: V.SecExp.proclamation.currency === "reputation"
										? `great influence`
										: `vast financial means`
								} to force the arrest of suspected citizens without passing through the normal legal procedures.`),
							);
						} else {
							links.push(
								App.UI.DOM.link(`Issue a proclamation about security`, () => {
									V.personalAttention.task = PersonalAttention.PROCLAMATION;
									V.SecExp.proclamation.type = "security";

									refresh();
								},
								null, ``, `You will use your ${V.SecExp.proclamation.currency === "authority"
									? `control over the arcology`
									: V.SecExp.proclamation.currency === "reputation"
										? `great influence`
										: `vast financial means`
								} to force citizens to give up on sensitive information for the good of the arcology.`),

								App.UI.DOM.disabledLink(`Issue a proclamation about crime`, [
									`Currently selected.`
								]),
							);
						}
					} else {
						links.push(
							App.UI.DOM.link(`Issue a proclamation about security`, () => {
								V.personalAttention.task = PersonalAttention.PROCLAMATION;
								V.SecExp.proclamation.type = "security";

								refresh();
							},
							null, ``, `You will use your ${V.SecExp.proclamation.currency === "authority"
								? `control over the arcology`
								: V.SecExp.proclamation.currency === "reputation"
									? `great influence`
									: `vast financial means`
							} to force citizens to give up on sensitive information for the good of the arcology.`),

							App.UI.DOM.link(`Issue a proclamation about crime`, () => {
								V.personalAttention.task = PersonalAttention.PROCLAMATION;
								V.SecExp.proclamation.type = "crime";

								refresh();
							},
							null, ``, `You will use your ${V.SecExp.proclamation.currency === "authority"
								? `control over the arcology`
								: V.SecExp.proclamation.currency === "reputation"
									? `great influence`
									: `vast financial means`
							} to force the arrest of suspected citizens without passing through the normal legal procedures.`),
						);
					}

					App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
				}
			} else {
				App.UI.DOM.appendNewElement("div", div, `It's too early to issue another proclamation. Another will be available in ${numberWithPluralOne(V.SecExp.proclamation.cooldown, "week")}.`, ['note']);
			}
		}

		return div;
	}

	function skills() {
		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
		const cost = 10000 * V.AgeEffectOnTrainerPricingPC;

		App.UI.DOM.appendNewElement("h2", div, `Skills`);

		div.append(addSkills(
			{
				skill: "trading",
				text: `trader`,
				link: {
					value: PersonalAttention.TRADE,
					text: `Hire a merchant to train you in commerce`,
				},
			},
			{
				skill: "warfare",
				text: `tactician`,
				link: {
					value: PersonalAttention.WAR,
					text: `Hire a mercenary to train you in warfare`,
				},
			},
			{
				skill: "slaving",
				text: `slaver`,
				link: {
					value: PersonalAttention.SLAVING,
					text: `Hire a slaver to train you in slaving`,
				},
			},
			{
				skill: "engineering",
				text: `arcology engineer`,
				link: {
					value: PersonalAttention.ENGINEERING,
					text: `Hire an engineer to train you in arcology engineering`,
				},
			},
			{
				skill: "medicine",
				text: `surgeon`,
				link: {
					value: PersonalAttention.MEDICINE,
					text: `Hire a doctor to train you in medicine`,
				},
			},
			{
				skill: "hacking",
				text: `hacker`,
				link: {
					value: PersonalAttention.HACKING,
					text: `Hire a specialist to train you in hacking`,
				},
			},
		));

		return div;

		/**
		 * @param {Array<{skill: string, text: string, link: {value: PersonalAttention, text: string}}>} args
		 * @returns {HTMLDivElement}
		 */
		function addSkills(...args) {
			const div = document.createElement("div");
			const skillMaster = [];

			args.forEach(skill => {
				div.append(
					addSkill(skill.skill, skill.text, {
						value: skill.link.value,
						text: skill.link.text,
					}),
				);
			});

			if (skillMaster.length > 0) {
				div.append(`You are a master ${toSentence(skillMaster)}.`);
			}
			return div;

			/**
			 * @param {string} skill
			 * @param {string} text
			 * @param {{value: PersonalAttention, text: string}} link
			 */
			function addSkill(skill, text, link) {
				const div = document.createElement("div");

				if (V.PC.skill[skill] >= 100) {
					skillMaster.push(`${text}`);
				} else {
					if (V.PC.skill[skill] > 60) {
						div.append(`You are an expert ${text}.`);
					} else if (V.PC.skill.hacking > 30) {
						div.append(`You have some skill as ${addA(text)}.`);
					} else if (V.PC.skill.hacking > 10) {
						div.append(`You have basic knowledge as ${addA(text)}.`);
					} else {
						div.append(`You have no knowledge as ${addA(text)}.`);
					}

					addLink(div, {
						value: link.value,
						link: link.text,
					});
				}

				return div;

				/**
				 * @param {HTMLDivElement} div
				 * @param {{value: PersonalAttention, link: string}} skill
				 */
				function addLink(div, skill) {
					if (V.personalAttention.task === skill.value) {
						App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink(skill.link, [
							`Currently selected.`,
						]), ['margin-left']);
					} else {
						App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(skill.link, () => {
							V.personalAttention = {task: skill.value};

							refresh();
						}, null, '', `Training will cost ${cashFormat(cost)} per week.`), ['margin-left']);
					}
				}
			}
		}
	}

	function attention() {
		/**
		 * @param {number} index
		 * @param {string} text
		 * @param {string} target
		 * @returns {HTMLSpanElement|HTMLAnchorElement}
		 */
		function attentionLink(index, text, target) {
			if (V.personalAttention.slaves[index].objective === target) {
				return App.UI.DOM.disabledLink(text, [
					'Currently selected.'
				]);
			} else {
				return App.UI.DOM.link(text, () => {
					V.personalAttention.slaves[index].objective = target;
					refresh();
				});
			}
		}

		const frag = new DocumentFragment();
		App.UI.DOM.appendNewElement("h2", frag, `Slaves`);
		if (!V.personalAttention.slaves || V.personalAttention.slaves.length === 0) {
			frag.append(`You have not selected a slave for your personal attention.`);
		} else {
			if (V.personalAttention.slaves.length > (V.PC.skill.slaving >= 100 ? 2 : 1)) {	// ensure only the maximum number of slaves are being trained
				V.personalAttention.slaves.shift();
			}

			for (let i = 0; i < V.personalAttention.slaves.length; i++) {
				const div = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom', 'card']);
				const slave = getSlave(V.personalAttention.slaves[i].ID);
				const regimen = V.personalAttention.slaves[i].objective;
				div.id = `attention-${slave.ID}`;	// used for scrolling back up after selecting a slave
				if (V.personalAttention.slaves.filter(s => s.ID === slave.ID).length > 1) {
					V.personalAttention.slaves = [];
				}

				const {He, him, his} = getPronouns(slave);
				let text = [];
				let links = [];
				V.personalAttention.slaves[i].objective = V.personalAttention.slaves[i].objective || getRegimen(slave);
				text.push(
					`You will give`,
					App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave)),
					`your personal attention this week to ${App.PersonalAttention.getText(V.personalAttention.slaves[i].objective, slave)}.`,
					App.UI.DOM.link(`Stop`, () => {
						if (V.personalAttention.slaves.length === 1) {
							V.personalAttention = {task: PersonalAttention.SEX};
						} else {
							V.personalAttention.slaves.deleteAt(i);
						}
						refresh();
					}),
				);
				App.Events.addNode(div, text);
				App.UI.DOM.appendNewElement("h3", div, `Change training objective`);

				// Devotion
				App.Events.addNode(div, [
					`Current devotion: `,
					devotionText(slave),
				]);
				if (slave.devotion <= 20 && slave.trust >= -20) {
					links.push(
						attentionLink(i, `Break ${his} will`, "break will"),
						attentionLink(i, `Use enhanced breaking techniques`, "harshly break will"),
					);
				} else {
					links.push(attentionLink(i, `Build ${his} devotion`, "build devotion"));
				}

				// Sexuality
				if (!slave.fetishKnown || !slave.attrKnown) {
					links.push(attentionLink(i, `Explore ${his} sexuality and fetishes`, "explore sexuality"));
				} else {
					links.push(App.UI.DOM.disabledLink(`Explore ${his} sexuality and fetishes`, [
						`You already understand ${his} sexuality.`
					]));
				}

				// Education
				const whoreSkillCap = isPCCareerInCategory("escort") ? 60 : 30;
				if (slave.devotion <= 20 && slave.trust >= -20) {
					links.push(App.UI.DOM.disabledLink(`Teach ${him}`, [
						`${He}'s too disobedient to learn sex skills`
					]));
				} else if (slave.skill.anal >= 100 &&
					slave.skill.oral >= 100 &&
					slave.skill.whoring >= whoreSkillCap &&
					slave.skill.entertainment >= whoreSkillCap) {
					if (slave.skill.vaginal >= 100) {
						links.push(App.UI.DOM.disabledLink(`Teach ${him}`, [
							`${He} knows all the skills you can teach`
						]));
					} else if (slave.vagina < 0) {
						links.push(App.UI.DOM.disabledLink(`Teach ${him}`, [
							`${He} knows all the skills you can teach a slave without a vagina`
						]));
					} else {
						links.push(attentionLink(i, `Teach ${him}`, "learn skills"));
					}
				} else {
					links.push(attentionLink(i, `Teach ${him}`, "learn skills"));
				}

				// Health
				App.Events.addNode(div, [
					`Current health: `,
					healthText(slave),
				]);
				links.push(attentionLink(i, `Care for ${him}`, "health"));

				// Behavioral Flaws
				if (slave.behavioralFlaw !== "none") {
					App.Events.addNode(div, [
						`Current behavioral flaw: <span class="red">${slave.behavioralFlaw}.</span> `,
					]);
					links.push(attentionLink(i, `Remove ${his} behavioral flaw`, "fix behavioral flaw"));

					if (slave.devotion < -20) {
						links.push(App.UI.DOM.disabledLink(`Soften ${his} behavioral flaw`, [
							`${He} must be broken before ${his} flaws can be softened`
						]));
					} else {
						links.push(attentionLink(i, `Soften ${his} behavioral flaw`, "soften behavioral flaw"));
					}
				}
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
				links = [];

				div.append(
					App.UI.DOM.makeElement("h3", `Induce a behavioral flaw`),
				);
				addLinks(
					slave,
					regimen,
					links,
					i,
					{
						quirk: "confident",
						flaw: "arrogant",
						type: "induce arrogance",
						link: `Arrogance`,
					},
					{
						quirk: "cutting",
						flaw: "bitchy",
						type: "induce bitchiness",
						link: `Bitchiness`,
					},
					{
						quirk: "funny",
						flaw: "odd",
						type: "induce odd behavior",
						link: `Odd behavior`,
					},
					{
						quirk: "adores women",
						flaw: "hates men",
						type: "induce hatred of men",
						link: `Hatred of men`,
					},
					{
						quirk: "adores men",
						flaw: "hates women",
						type: "induce hatred of women",
						link: `Hatred of women`,
					},
					{
						quirk: "fitness",
						flaw: "gluttonous",
						type: "induce gluttony",
						link: `Gluttony`,
					},
					{
						quirk: "insecure",
						flaw: "anorexic",
						type: "induce anorexia",
						link: `Anorexia`,
					},
					{
						quirk: "sinful",
						flaw: "devout",
						type: "induce religious devotion",
						link: `Religious devotion`,
					},
					{
						quirk: "advocate",
						flaw: "liberated",
						type: "induce liberation",
						link: `Liberation`,
					},
				);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
				links = [];

				// Sexual Flaws
				if (slave.sexualFlaw !== "none") {
					const isParaphilia = App.Data.misc.paraphiliaList.includes(slave.sexualFlaw);
					const r = new SpacedTextAccumulator(div);
					r.push("Current sexual flaw:", App.UI.DOM.makeElement("span", `${capFirstChar(slave.sexualFlaw)}.`, isParaphilia ? "yellow" : "red"));
					r.toNode("div");
					links.push(attentionLink(i, `Remove ${his} ${isParaphilia ? "paraphilia" : "sexual flaw"}`, "fix sexual flaw"));

					if (slave.devotion < -20) {
						links.push(App.UI.DOM.disabledLink(`Soften ${his} sexual flaw`, [
							`${He} must be broken before ${his} flaws can be softened`
						]));
					} else if (isParaphilia) {
						links.push(App.UI.DOM.disabledLink(`Soften ${his} sexual flaw`, [
							`Paraphilias cannot be softened`
						]));
					} else {
						links.push(attentionLink(i, `Soften ${his} sexual flaw`, "soften sexual flaw"));
					}
				}
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
				links = [];

				div.append(
					App.UI.DOM.makeElement("h3", `Induce a sexual flaw`),
				);
				addLinks(
					slave,
					regimen,
					links,
					i,
					{
						quirk: "gagfuck queen",
						flaw: "hates oral",
						type: "induce hatred of oral",
						link: `Hatred of oral`,
					},
					{
						quirk: "painal queen",
						flaw: "hates anal",
						type: "induce hatred of anal",
						link: `Hatred of anal`,
					},
					{
						quirk: "strugglefuck queen",
						flaw: "hates penetration",
						type: "induce hatred of penetration",
						link: `Hatred of penetration`,
					},
					{
						quirk: "tease",
						flaw: "shamefast",
						type: "induce shame",
						link: `Shame`,
					},
					{
						quirk: "romantic",
						flaw: "idealistic",
						type: "induce sexual idealism",
						link: `Sexual idealism`,
					},
					{
						quirk: "perverted",
						flaw: "repressed",
						type: "induce sexual repression",
						link: `Sexual repression`,
					},
					{
						quirk: "caring",
						flaw: "apathetic",
						type: "induce sexual apathy",
						link: `Sexual apathy`,
					},
					{
						quirk: "unflinching",
						flaw: "crude",
						type: "induce crudity",
						link: `Crudity`,
					},
					{
						quirk: "size queen",
						flaw: "judgemental",
						type: "induce judgement",
						link: `Judgment`,
					},
				);
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
				links = [];

				// Paraphilias
				App.UI.DOM.appendNewElement("h3", div, `Induce a paraphilia`);
				if (slave.fetishStrength >= 95) {
					addLinks(
						slave,
						regimen,
						links,
						i,
						{
							fetish: "cumslut",
							flaw: "cum addict",
							type: "induce cum addiction",
							link: `Cum addiction`,
						},
						{
							fetish: "buttslut",
							flaw: "anal addict",
							type: "induce anal addiction",
							link: `Anal addiction`,
						},
						{
							fetish: "humiliation",
							flaw: "attention whore",
							type: "induce attention whoring",
							link: `Attention whoring`,
						},
						{
							fetish: "boobs",
							flaw: "breast growth",
							type: "induce breast growth obsession",
							link: `Breast growth obsession`,
						},
						{
							fetish: "dom",
							flaw: "abusive",
							type: "induce abusiveness",
							link: `Abusiveness`,
						},
						{
							fetish: "sadist",
							flaw: "malicious",
							type: "induce maliciousness",
							link: `Maliciousness`,
						},
						{
							fetish: "masochist",
							flaw: "self hating",
							type: "induce self hatred",
							link: `Self hatred`,
						},
						{
							fetish: "submissive",
							flaw: "neglectful",
							type: "induce sexual self neglect",
							link: `Sexual self neglect`,
						},
						{
							fetish: "pregnancy",
							flaw: "breeder",
							type: "induce breeding obsession",
							link: `Breeding obsession`,
						},
					);
					App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['margin-left']);
					links = [];
				} else {
					App.UI.DOM.appendNewElement("div", div, `Paraphilias can be induced from a strong fetish.`, ['note', 'margin-left']);
				}
			}
		}

		return frag;

		/**
		 * @typedef Link
		 *
		 * @property {FC.SexualFlaw|FC.BehavioralFlaw} flaw
		 * @property {FC.SexualQuirk|FC.BehavioralQuirk} [quirk]
		 * @property {FC.Fetish} [fetish]
		 * @property {string} type
		 * @property {string} link
		 */

		/**
		 *
		 * @param {App.Entity.SlaveState} slave
		 * @param {string} regimen
		 * @param {Array<HTMLAnchorElement|HTMLSpanElement>} links
		 * @param {number} index
		 * @param {Link[]} args
		 */
		function addLinks(slave, regimen, links, index, ...args) {
			args.forEach(link => {
				if (slave.sexualFlaw !== link.flaw &&
					slave.behavioralFlaw !== link.flaw &&
					(!link.quirk || slave.sexualQuirk !== link.quirk &&
						slave.behavioralQuirk !== link.quirk) &&
					(!link.fetish || slave.fetish === link.fetish)) {
					if (regimen === link.type) {
						links.push(App.UI.DOM.disabledLink(link.link, [
							`Currently selected.`,
						]));
					} else {
						links.push(App.UI.DOM.link(link.link, () => {
							V.personalAttention.slaves[index].objective = link.type;

							refresh();
						}, null, '', `Inducing flaws is difficult and bad for slaves' obedience.`));
					}
				}
			});
		}
	}

	function slaves() {
		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
		App.UI.DOM.appendNewElement("h3", div, `Select a slave to train`);
		if (V.PC.skill.slaving >= 100) {
			App.Events.addNode(div, [
				`Your <span class="skill player">slaving experience</span> allows you to divide your attention between more than one slave each week, with slightly reduced efficiency.`
			], "div", ['note', 'margin-left']);
		}

		div.append(App.UI.SlaveList.slaveSelectionList(
			s => (assignmentVisible(s) || App.Entity.facilities.masterSuite.isHosted(s)) && s.fuckdoll === 0,
			s => App.UI.DOM.link(SlaveFullName(s),
				(id) => { selectSlave(id); }, [s.ID]
			),
		));

		return div;
	}

	function refresh() {
		App.UI.DOM.replace(refreshDiv, content());
	}

	function selectSlave(id) {
		if (!V.personalAttention.slaves) { // first PA target
			V.personalAttention = {
				task: PersonalAttention.TRAINING,
				slaves: [{
					ID: id,
					objective: getRegimen(getSlave(id)),
				}]
			};
		} else {
			const paIndex = V.personalAttention.slaves.findIndex(s => s.ID === id);
			if (paIndex === -1) { // not already a PA target; add
				V.personalAttention.task = PersonalAttention.TRAINING; // make sure
				V.personalAttention.slaves.push({
					ID: id,
					objective: getRegimen(getSlave(id)),
				});
			} else { // already a PA target; remove
				V.personalAttention.slaves.deleteAt(paIndex);
				if (V.personalAttention.slaves.length === 0) {
					V.personalAttention = {task: PersonalAttention.SEX};
				}
			}
		}

		refresh();

		if (V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.includes(id)) {
			document.getElementById(`attention-${id}`).scrollIntoView();
		}
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {DocumentFragment}
	 */
	 function devotionText(slave) {
		const frag = new DocumentFragment();

		App.UI.SlaveSummaryImpl.helpers.makeRatedStyledSpan(frag, App.Data.SlaveSummary.long.mental.devotion, slave.devotion, 100, true);

		return frag;
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {DocumentFragment}
	 */
	function healthText(slave) {
		const frag = new DocumentFragment();

		App.UI.SlaveSummaryImpl.helpers.makeRatedStyledSpan(frag, App.Data.SlaveSummary.long.health.health, slave.health.condition, 100, true);

		return frag;
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string}
	 */
	function getRegimen(slave) {
		if (slave.health.condition < -20) {
			return `health`;
		} else if (slave.behavioralFlaw !== "none") {
			if (slave.devotion < -20) {
				return `fix behavioral flaw`;
			} else {
				return `soften behavioral flaw`;
			}
		} else if (slave.sexualFlaw !== "none") {
			if (slave.devotion < -20 || App.Data.misc.paraphiliaList.includes(slave.sexualFlaw)) {
				return `fix sexual flaw`;
			} else {
				return `soften sexual flaw`;
			}
		} else if (!slave.fetishKnown) {
			return `explore sexuality`;
		} else if (slave.devotion <= 20 && slave.trust >= -20) {
			return `break will`;
		}
		return `build devotion`;
	}
};

repo_name: Fanatey/fc

license: mit