code:
App.Facilities.Dairy.industrialAssignmentScene = function(slave) {
	const node = new DocumentFragment();

	V.nextButton = "Continue";
	V.nextLink = V.returnTo;
	let r = [];
	const {
		He, His,
		he, him, his, himself
	} = getPronouns(slave);
	const {
		say:say, title: Master
	} = getEnunciation(slave);

	App.Events.drawEventArt(node, slave);

	r.push(`When ${slave.slaveName} reports to the dairy, it's to the`);
	if (canSee(slave)) {
		r.push(`sight of an unoccupied milking machine waiting for ${him},`);
	} else {
		r.push(`cold embrace of an unoccupied milking machine,`);
	}
	r.push(`its straps ready to immure ${him} in what is to be ${his} new home.`);

	if (slave.sexualFlaw === "self hating") { /* GETTING IN */
		r.push(`As ${he} realizes ${his} fate, a kind of peace comes over the self hating slut.`);
		if (!canTalk(slave)) {
			r.push(`${He}`);
			if (!hasAnyArms(slave)) {
				r.push(`mouths`);
			} else {
				r.push(`gestures`);
			}
			r.push(`${his} thanks dreamily.`);
		} else {
			r.push(
				Spoken(slave, `"Thank you, ${Master},"`),
				`${he} ${say}s simply.`,
				Spoken(slave, `"I deserve this,"`),
				`${he} adds quietly, half to ${himself}.`
			);
		}
		r.push(`Then ${he} falls silent and`);
		if (canSee(slave)) {
			r.push(`stares at`);
		} else {
			r.push(`faces`);
		}
		r.push(`the machine. Though ${he} hates ${himself} and looks forward to the release of being unable to do anything but get fucked, that doesn't mean ${he} isn't afraid.`);
		if (hasAnyArms(slave)) {
			if (V.dairyStimulatorsSetting > 1) {
				r.push(`${He} gauges the size of the sodomizer with ${his} hand, finding that it's wider than ${his} fist, and then presses the fist against ${his} own anus. Realizing what's about to happen, ${he} gives a little shudder.`);
				if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
					r.push(`${He} does the same with the dildo that will keep ${him} pregnant and ${his} pussy, and ${his} lower lip starts to quiver.`);
				}
			} else {
				if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
					r.push(`${He} gauges the size of the dildo that will keep ${him} pregnant with ${his} hand, finding that it's wider than ${his} fist, and then presses the fist against ${his} pussy. Realizing what's about to happen, ${he} gives a little shudder.`);
				}
			}
			if (V.dairyFeedersSetting > 1) {
				if (canSee(slave)) {
					r.push(`Looking at`);
				} else {
					r.push(`As ${he} wraps ${his} lips around`);
				}
				r.push(`the phallus that will feed ${him}, ${he} begins to cry softly.`);
			}
		}
		App.Events.addParagraph(node, r);
		r = [];
		if (hasAnyArms(slave)) {
			r.push(`${He} strips and climbs into the machine's embrace,`);
		} else {
			r.push(`Another slave helps ${him} strip and lays ${him} in the machine,`);
		}
		r.push(`${his} tears pattering onto the uncaring metal. When ${he}'s in place, ${his} shoulders slump as ${he} gives up completely.`);
		if (!canTalk(slave)) {
			r.push(`${He} mouths 'Goodbye.'`);
		} else if (SlaveStatsChecker.checkForLisp(slave)) {
			r.push(
				Spoken(slave, `"'Bye,"`),
				`${he} lisps.`
			);
		} else {
			r.push(
				Spoken(slave, `"'Bye,"`),
				`${he} whispers.`
			);
		}
	} else if ((slave.sexualFlaw === "breeder") && isFertile(slave) && slave.mpreg !== 1) {
		r.push(`As ${he} realizes what's about to happen, ${he} begins to cry openly. A curious mix of arousal, joy, and abject horror is obvious on ${his} face, and ${he} deals with the conflicting feelings by sobbing.`);
		if (!canTalk(slave)) {
			r.push(`${He}`);
			if (!hasAnyArms(slave)) {
				r.push(`mouths`);
			} else {
				r.push(`gestures`);
			}
			r.push(`${his} thanks shakily.`);
		} else {
			r.push(
				Spoken(slave, `"Th-thank you, ${Master},"`),
				`${he} ${say}s through ${his} tears.`,
				Spoken(slave, `"I love you."`)
			);
		}
		r.push(`Then ${he} falls silent and`);
		if (canSee(slave)) {
			r.push(`stares at`);
		} else if (hasAnyArms(slave)) {
			r.push(`reaches out to touch`);
		} else {
			r.push(`faces`);
		}
		r.push(`the machine. ${He}'s probably imagined this a thousand times, but the prospect is still frightening.`);
		if (hasAnyArms(slave)) {
			if (V.dairyStimulatorsSetting > 1) {
				r.push(`${He} gauges the size of the sodomizer with ${his} hand, finding that it's wider than ${his} fist, and then presses the fist against ${his} own anus. Realizing that ${his} anus is about to be permanently gaped, ${he} looks doubtful, but then visibly reassures ${himself}. ${He}'ll need both ${his} mouth and ${his} ass to eat enough.`);
			}
			if (V.dairyFeedersSetting > 1) {
				if (canSee(slave)) {
					r.push(`Looking at`);
				} else {
					r.push(`Turning to`);
				}
				r.push(`the phallus that will feed ${him}, ${he} inserts a finger into its faux urethra, measuring how fast it can pour nutrition in ${him}.`);
			}
			r.push(`${He} strokes the dildo that will keep ${him} pregnant like a lover, which, of course, it's about to be.`);
		}
		App.Events.addParagraph(node, r);
		r = [];
		if (hasAnyArms(slave)) {
			r.push(`${He} strips and climbs into the machine's embrace, shaking with nerves.`);
		} else {
			r.push(`Another slave helps ${him} strip and lays ${him} in the machine. ${He} shakes with nerves.`);
		}
		if (slave.pregKnown === 1) {
			r.push(`${He}`);
			if (canSee(slave)) {
				r.push(`cranes around to look at`);
			} else {
				r.push(`runs a hand down`);
			}
			r.push(`${his} already-pregnant belly, and looks impatient.`);
			if (canTalk(slave)) {
				r.push(
					Spoken(slave, `"Hurry up, I need the room,"`),
					`${he} whispers.`
				);
			} else {
				r.push(`${He} mouths 'hurry up, I need room.'`);
			}
		} else {
			r.push(`${He}`);
			if (canSee(slave)) {
				r.push(`cranes around to look at`);
			} else {
				r.push(`runs a hand down`);
			}
			r.push(`${his} belly, and looks impatient.`);
			if (!canTalk(slave)) {
				r.push(`${He} mouths 'come on, I'm ready.'`);
			} else {
				r.push(
					Spoken(slave, `"Come on, I'm ready,"`),
					`${he} whispers.`
				);
			}
		}
	} else if (slave.devotion > 95) { /* GETTING IN */
		r.push(`As ${he} realizes ${his} fate, the worshipful slave squares ${his} shoulders, steeling ${himself}.`);
		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"${Master},"`),
				`${he} ${say}s,`,
				Spoken(slave, `"I will do my best to serve you."`)
			);
		} else {
			r.push(`${He} gestures that ${he}'ll do ${his} best for you.`);
		}
		if (canWalk(slave)) {
			r.push(`${He} steps over to the machine.`);
		}
		if (canSee(slave)) {
			r.push(`${He} looks it over clinically,`);
		} else if (hasAnyArms(slave)) {
			r.push(`${He} runs a hand over it exploratively,`);
		} else {
			r.push(`${He} takes a deep breath,`);
		}
		r.push(`getting ${himself} into the right mindset.`);
		if (hasAnyArms(slave)) {
			if (V.dairyStimulatorsSetting > 1) {
				r.push(`${He} gauges the size of the massive phallus that will soon penetrate ${his} anus. It's broader than ${his} fist.`);
				if (canTalk(slave)) {
					r.push(Spoken(slave, `"I think I can take this. It'll be tough, but I'll need all the hydration I can get."`));
				} else {
					r.push(`${He} nods ${his} head, understanding that it will need to fit to keep ${him} hydrated.`);
				}
			}
			if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
				r.push(`${He} considers the enormous dildo that will fill ${him} with cum when ${he}'s fertile, and switch to ejaculating drugs when ${he} conceives.`);
				if (canTalk(slave)) {
					r.push(
						Spoken(slave, `"I'll be a mother to a whole generation of slaves,"`),
						`${he} ${say}s proudly, taking strength from it.`
					);
				} else {
					r.push(`${He} takes strength in knowing that ${he}'ll birth a whole generation of new slaves.`);
				}
			}
			if (V.dairyFeedersSetting > 1) {
				r.push(`${He} moves ${his} hand to the dildo that will occupy ${his} throat, feeding ${him}.`);
				if (canTalk(slave)) {
					r.push(
						Spoken(slave, `"I will need my mouth to take in as much food as I can,"`),
						`${he} ${say}s.`,
						Spoken(slave, `"I won't be able to talk. So, I'll say it one last time, ${Master}: I love you."`)
					);
				} else {
					r.push(`${He} focuses on just how much time ${he}'ll need to spend with ${his} mouth full, so ${he} blows you one final kiss to show ${his} love.`);
				}
			}
		}
		App.Events.addParagraph(node, r);
		r = [];
		if (hasAnyArms(slave)) {
			r.push(`${He} strips and climbs into the machine's embrace.`);
		} else {
			r.push(`Another slave helps ${him} strip and lays ${him} in the machine.`);
		}
		r.push(`${He} does not hesitate or`);
		if (canSee(slave)) {
			r.push(`glance back at`);
		} else {
			r.push(`show any resistance to`);
		}
		r.push(`you. You stand by as the straps automatically tighten, robbing ${him} of the ability to move.`);
		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"${Master},"`),
				`${he} ${say}s quietly,`,
				Spoken(slave, `"I will try to be strong enough to stand up to this. But if I'm not, and I forget too much, please leave me in here so I can be useful."`)
			);
		} else {
			r.push(`${He} swears to you that ${he} will try ${his} best, but implores you to leave ${him} to the machine should ${his} mind fade.`);
		}
	} else if (slave.devotion > 60) {
		r.push(`As ${he} realizes ${his} fate, the tears come quickly.`);
		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"${Master},"`),
				`${he} ${say}s quietly, "is this for me?"`
			);
		} else {
			r.push(`${He} shakily gestures if this is where ${he} will be staying.`);
		}
		if (canSee(slave)) {
			r.push(`You nod, and ${he}`);
			if (canWalk(slave)) {
				r.push(`steps over to the machine.`);
			} else {
				r.push(`accepts ${his} fate.`);
			}
		} else if (canHear(slave)) {
			r.push(`You tell ${him} it is as ${he}`);
			if (canWalk(slave)) {
				r.push(`steps over to the machine.`);
			} else {
				r.push(`accepts ${his} fate.`);
			}
		} else {
			r.push(`place a hand on ${his} shoulder in confirmation and guide ${him} to the machine.`);
		}
		if (hasAnyArms(slave)) {
			r.push(`${He} lightly traces its gleaming metal, looking wistful.`);
			if (V.dairyStimulatorsSetting > 1) {
				r.push(`${He} gently touches the head of the massive phallus that will soon penetrate ${his} anus. It's broader than ${his} fist.`);
				if (canTalk(slave)) {
					r.push(Spoken(slave, `"M-my butthole isn't going to be any good for anal after this."`));
				} else {
					r.push(`${He} gestures jokingly that nothing will fit ${his} rear hole after this.`);
				}
			}
			if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
				r.push(`${He} considers the enormous dildo that will fill ${him} with cum when ${he}'s fertile, and switch to ejaculating drugs when ${he} conceives.`);
				if (canTalk(slave)) {
					r.push(Spoken(slave, `"I guess that thing won't have any trouble reaching my cervix."`));
				} else {
					r.push(`${He} knows it won't have any trouble getting ${him} pregnant.`);
				}
			}
			if (V.dairyFeedersSetting > 1) {
				r.push(`${He} moves ${his} hand to the dildo that will occupy ${his} throat, feeding ${him}.`);
				if (canTalk(slave)) {
					r.push(
						Spoken(slave, `"I-I won't be able to t-talk m-much,"`),
						`${he} ${say}s sadly.`,
						Spoken(slave, `"S-so, I'll say it one last time, ${Master}: I love you."`)
					);
				} else {
					r.push(`${He} knows ${he} won't have another chance at this, so ${he} gives you one last tearful 'I love you'.`);
				}
			}
		}
		App.Events.addParagraph(node, r);
		r = [];
		if (hasAnyArms(slave)) {
			r.push(`${He}`);
			if (slave.clothes !== "no clothing") {
				r.push(`strips and`);
			}
			r.push(`climbs into the machine's embrace.`);
		} else {
			r.push(`Another slave helps ${him}`);
			if (slave.clothes !== "no clothing") {
				r.push(`strip and lays ${him} in`);
			} else {
				r.push(`into`);
			}
			r.push(`the machine.`);
		}
		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"${Master},"`),
				`${he} gasps out, the tears coming fast now.`,
				Spoken(slave, `"C-can you`)
			);
			if (hasAnyArms(slave)) {
				r.push(
					Spoken(slave, `h-hold my h-hand while it a-activates? Please?"`),
					`You take ${his} hand as the straps automatically tighten, robbing ${him} of the ability to move. ${He} grips your hand tightly.`
				);
			} else {
				r.push(
					Spoken(slave, `S-stay with me while it activates? Please?"`),
					`You stand by as the straps automatically tighten, robbing ${him} of the ability to move.`
				);
			}
		} else {
			r.push(`You can tell by the tears streaming down ${his} face that ${he} doesn't want to leave you so soon.`);
			if (hasAnyArms(slave)) {
				r.push(`You take ${his} hand as the straps automatically tighten, robbing ${him} of the ability to move. ${He} grips your hand tightly.`);
			} else {
				r.push(`You stand by as the straps automatically tighten, robbing ${him} of the ability to move.`);
			}
		}
	} else if (slave.devotion > 20) {
		r.push(`${He} desperately tries to be brave and obey, but as ${his} fate dawns on ${him}, ${his} courage and conditioning fail ${him}.`);
		if (!hasAnyLegs(slave)) {
			r.push(`${He} tries to wriggle away from the machine, so`);
		} else {
			r.push(`${He} turns and tries to run, so`);
		}
		if (V.MilkmaidID !== 0) {
			r.push(`${S.Milkmaid.slaveName} is`);
		} else {
			r.push(`you are`);
		}
		r.push(`obliged to`);
		if (!isAmputee(slave)) {
			r.push(`subdue ${him} and strap ${him},`);
		} else {
			r.push(`place ${him},`);
		}
		r.push(`begging and sobbing, into the machine's embrace.`);
		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"Please, ${Master}!"`),
				`${he} begs.`,
				Spoken(slave, `"Please no!`)
			);
			if (V.dairyStimulatorsSetting > 1) {
				r.push(Spoken(slave, `I-it'll fuck my b-butthole so wide I'll be useless for anal!`));
			}
			if (V.dairyPregSetting > 2 && isFertile(slave) && slave.mpreg !== 1) {
				r.push(Spoken(slave, `My w-womb c-c-can't take it! I'll b-burst! And m-my c-c-cunt will be ruined from the dildo and birthing!`));
			} else if ((V.dairyPregSetting > 1) && isFertile(slave) && slave.mpreg !== 1) {
				r.push(Spoken(slave, `M-my c-c-cunt will be s-so stretched from the dildo and birthing!`));
			}
			r.push(Spoken(slave, `I'll d-do anything!"`));
		} else {
			r.push(`${He} pitifully begs for anything but this, even going as far as trying to convey what the machine will do to ${him}, but it will do ${him} no good.`);
		}
	} else {
		r.push(`${He} starts to weep as soon as ${he} realizes ${his} fate.`);
		if (slave.trust >= -20) {
			r.push(`${He} is afraid of you, but not afraid enough that ${he} will not resist this.`);
		}
		if (hasAnyLegs(slave)) {
			r.push(`${He} tries to wriggle away from the machine, so`);
		} else {
			r.push(`${He} turns and tries to run, so`);
		}
		if (V.MilkmaidID !== 0) {
			r.push(`${S.Milkmaid.slaveName} is`);
		} else {
			r.push(`you are`);
		}
		r.push(`obliged to`);
		if (!isAmputee(slave)) {
			r.push(`subdue ${him} and strap ${him},`);
		} else {
			r.push(`place ${him},`);
		}
		r.push(`begging and sobbing, into the machine's embrace.`);

		if (canTalk(slave)) {
			r.push(
				Spoken(slave, `"Please, ${Master}!"`),
				`${he} begs.`,
				Spoken(slave, `"Please no!`)
			);
			if (V.dairyStimulatorsSetting > 1) {
				r.push(Spoken(slave, `I-it'll fuck my b-butthole so loose I'll be useless for anal! I p-promise I'll be a good little bitch from now on!`));
			}
			if (V.dairyPregSetting > 2 && isFertile(slave) && slave.mpreg !== 1) {
				r.push(Spoken(slave, `My w-womb c-c-can't take that many babies>>! I'll b-burst! M-my c-c-cunt can't t-take that dildo either! I d-don't want to g-get p-pregnant over and over...`));
			} else if ((V.dairyPregSetting > 1) && isFertile(slave) && slave.mpreg !== 1) {
				r.push(Spoken(slave, `M-my c-c-cunt can't t-take that dildo! I d-don't want to g-get p-pregnant over and over...`));
			}
			r.push(Spoken(slave, `I'll d-do anything!"`));
		} else {
			r.push(`${He} pitifully begs for to have mercy on ${him} and not subject ${him} to the machines 'features', but it will do ${him} no good.`);
		}
	}

	if (slave.lactation > 0) {
		r.push(`A big soft cup attaches itself`);
		if (slave.nipples === "fuckable" || slave.nipples === "flat") {
			r.push(`over`);
		} else {
			r.push(`to`);
		}
		r.push(`each of ${his} nipples.`);
		if (slave.nipples === "inverted") {
			r.push(`${He} gasps with pain as suction unceremoniously hauls ${his} inverted nipples down into the cups.`);
		} else if (slave.nipples === "fuckable") {
			r.push(`${He} gasps with surprise as a phallic rods unceremoniously slip into ${his} nipples to better harvest ${his} milk.`);
		}
	}
	if (slave.balls > 0) {
		if (slave.dick > 0) {
			r.push(`The first drugs hiss into ${him},`);
			if (slave.dick > 8) {
				r.push(`and ${his} eyes roll back as much of ${his} blood volume rushes into ${his} dick, though it remains soft.`);
			} else if (slave.dick > 6) {
				r.push(`and ${he} goes limp as much of ${his} blood volume rushes to bring ${him} to half mast.`);
			} else {
				r.push(`bringing ${him} to a full erection.`);
			}
			r.push(`${He} gasps as the warm, wet receptacle surrounds ${his} cock.`);
		} else {
			if (slave.lactation > 0) {
				r.push(`Another`);
			} else {
				r.push(`A big soft`);
			}
			r.push(`cup is placed against ${his} little front cumhole.`);
		}
	}
	r.push(`A visor lowers onto ${his} face to keep ${his} mind at least minimally stimulated.`);
	if (canHear(slave) && !canSee(slave)) {
		r.push(`It will play audio from`);
	} else {
		r.push(`It will display garish`);
	}
	r.push(`hardcore pornography featuring`);
	if (V.dairyFeedersSetting > 1) {
		r.push(`throatfucking, cum swallowing,`);
	}
	if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
		r.push(`bareback vaginal sex, pregnancy, childbirth,`);
	}
	if (slave.balls > 0) {
		r.push(`cumming cocks, anal stimulation,`);
	}
	if (slave.lactation > 0) {
		r.push(`breast expansion, women being milked,`);
	}
	r.push(`and brutal sodomy.`);
	if (!canHear(slave) && !canSee(slave)) {
		r.push(`Of course, ${he} won't enjoy any of that and will be left entirely at the mercy of the sensations running through ${his} flesh.`);
	}
	App.Events.addParagraph(node, r);
	r = [];

	if (slave.anus < 3 || (slave.vagina < 3 && slave.vagina > -1)) {
		slave.anus = 3;
		if (slave.vagina > -1) {
			slave.vagina = 3;
		}
		r.push(`The machine detects that ${he} requires the attention of the preparatory raper before it can penetrate ${him} successfully, and holds ${him} in place while the raper slides along its track in the ceiling. It comes to rest above the slave's defenseless body and extends its implements towards ${him}. ${He} can't see or hear it, but ${he} senses that something's happening and shivers.`);
		if (V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) {
			r.push(`${His} pussy is nowhere near ready to accept the passage of drugs and cum in and new slaves out. The new machine lubes ${him} thoroughly and then`);
			if (slave.vagina === 0) {
				r.push(`takes ${his} virginity`);
			} else {
				r.push(`starts to fuck ${him}`);
			}
			r.push(`with a reasonably sized dildo.`);
		}
		if (V.dairyStimulatorsSetting > 1 && slave.anus < 3) {
			r.push(`${He}'ll be drinking through ${his} mouth almost constantly, but that won't be enough. ${He}'ll have to absorb hydration and nutrition from both ends to keep up with the outflow ${he}'ll produce.`);
			if (V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) {
				r.push(`It`);
			} else {
				r.push(`The new machine`);
			}
			r.push(`fills ${his} ass with lube and then penetrates ${his}`);
			if (slave.anus === 0) {
				r.push(`virgin anus`);
			} else {
				r.push(`rectum`);
			}
			r.push(`gently.`);
		}
		r.push(`${He}'s worked in gradually, but every time ${he}'s loosened just slightly, the now-inadequate dildo is replaced by a larger one, and eventually more than one.`);
		if (V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) {
			if (V.dairyStimulatorsSetting > 1 && slave.anus < 3) {
				r.push(`${He} goes from a dildo in the pussy and a dildo in the ass, through numerous interesting combinations of double penetration, until ${he}'s got two porn star sized dildos sliding in and out of ${his} pussy and two more fucking ${his} ass.`);
			} else {
				r.push(`${His} womanhood goes from a normal dildo to a big dildo to two dildos, and so on, until ${he}'s taking the equivalent of two porn star cocks.`);
			}
		} else {
			r.push(`${His} asshole goes from a normal dildo to a big dildo to two dildos, and so on, until ${he}'s taking the equivalent of two porn star cocks up the butt.`);
		}
		r.push(`This is a long process, and though`);
		if (slave.devotion > 95) {
			r.push(`${he} started out getting off on it,`);
		} else if (slave.devotion > 60) {
			r.push(`${he} did ${his} best to enjoy ${himself} for a while,`);
		} else if (slave.devotion > 20) {
			r.push(`${he} tried to relax and make it easier on ${himself} at the start,`);
		} else {
			r.push(`${he} cried and tried to break loose for a while,`);
		}
		r.push(`${he}'s slumped against the machine from sheer exhaustion by the end. Its work completed, the preparatory raper withdraws and lets the milking machine begin its work. It's only been a few hours since ${slave.slaveName}'s ordeal began, but now ${he}'s ready to begin giving back. The machine revives ${him} with a hit of pharmaceuticals.`);

		App.Events.addParagraph(node, r);
		r = [];
	}

	if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
		r.push(`${His} vagina goes first. ${He} relaxes ${his} loose cunt for the elephantine dildo, but despite ${his} best efforts, it forces a gasp out of ${him} as it slides in. It remains stationary for now, but ${slave.slaveName} know it's just the beginning, and ${he} already feels full to bursting.`);
		if (slave.devotion > 95) {
			r.push(`${He} takes more deep breaths, doing ${his} best to remain calm.`);
		} else if (slave.devotion > 60) {
			r.push(`Terrified, ${he} cries harder.`);
		} else if (slave.devotion > 20) {
			r.push(`Terrified, ${he} cries harder.`);
		} else {
			r.push(`Terrified, ${he} starts to`);
			if (!canTalk(slave)) {
				r.push(`soundlessly`);
			}
			r.push(`scream and cry.`);
		}
	} else if (V.dairyPregSetting > 0 && isFertile(slave) && slave.mpreg !== 1) {
		if (slave.devotion > 95) {
			r.push(`${He} moans with pleasure`);
		} else if (slave.devotion > 60) {
			r.push(`${He} gasps`);
		} else if (slave.devotion > 20) {
			r.push(`${He} moans with fear`);
		} else {
			r.push(`${He} moans with anguish`);
		}
		r.push(`as the machine inserts a warm, lubricated dildo into ${his} vagina.`);
	}
	if (V.dairyStimulatorsSetting > 1) {
		r.push(`${His} anus is next. An auxiliary dildo the size of the largest human cocks goes first, assraping ${him} so hard ${he}'d probably be injured if ${he} wasn't already very loose.`);
		if (slave.devotion > 95) {
			r.push(`${He} relaxes and does ${his} best to enjoy ${himself}, ${his} cheeks flushing with arousal. Once ${his} sphincter is well stretched, the machine withdraws the dildo, and before ${his} anus can begin to close, the machine replaces it with the main instrument. Despite the preparation, it's so huge that ${he} moans with fear ${he} feels the head touch ${his} buttocks. The moan becomes a long low groan as ${his} butthole accommodates the enormous thing. When it's all the way in, the dildo begins to withdraw for its first stroke, and ${he}`);
			if (canTalk(slave)) {
				r.push(`whispers, "${Master}, it's s-so b-big." ${He} relaxes and recollects ${himself}, and then adds, "I can do this."`);
			} else {
				r.push(`begins distressing over its size before relaxing and recollecting ${himself}. ${He} smiles to show you ${he} can do this.`);
			}
		} else if (slave.devotion > 60) {
			r.push(`${He} tries to`);
			if (slave.skill.anal > 10) {
				r.push(`apply ${his} anal training,`);
			} else {
				r.push(`relax,`);
			}
			r.push(`but it fucks ${his} butt so mercilessly that ${he} eventually gives up and relaxes completely. This is what the machine was aiming for; it withdraws the dildo, and before ${his} sphincter can close, it replaces it with the main instrument. Despite the preparation, it's so huge that ${he} begins to`);
			if (!canTalk(slave)) {
				r.push(`silently`);
			}
			r.push(`scream in terror as ${he} feels the head touch ${his} buttocks. ${His}`);
			if (canTalk(slave)) {
				r.push(`yelling becomes a drawn-out shriek`);
			} else {
				r.push(`pointless yelling turns to struggling`);
			}
			r.push(`as ${his} butthole accommodates the enormous thing. When ${he} finally runs out of breath and slumps within ${his} restraints, the dildo begins to withdraw for its first stroke, and ${he}`);
			if (canTalk(slave)) {
				r.push(`whispers, "${Master}, it's too b-big. It hu-hurts."`);
			} else {
				r.push(`attempts to tell you that it is too big for ${his} hole.`);
			}
		} else if (slave.devotion > 20) {
			r.push(`Crying, ${he} tries to`);
			if (slave.skill.anal > 10) {
				r.push(`apply ${his} anal training,`);
			} else {
				r.push(`relax,`);
			}
			r.push(`but it fucks ${his} butt so mercilessly that ${he} eventually gives up and relaxes completely. This is what the machine was aiming for; it withdraws the dildo, and before ${his} sphincter can close, it replaces it with the main instrument. Despite the preparation, it's so huge that ${he} begins to beg desperately as ${he} feels the head touch ${his} buttocks. ${His}`);
			if (canTalk(slave)) {
				r.push(`whining becomes a drawn-out shriek`);
			} else {
				r.push(`soundless whining turns to struggling`);
			}
			r.push(`as ${his} butthole accommodates the enormous thing. When ${he} finally runs out of breath and slumps within ${his} restraints, the dildo begins to withdraw for its first stroke, and ${he} is racked with sobs.`);
		} else {
			r.push(`${He} obviously thinks this is what ${his} butt will suffer, and doesn't like it. ${He}'s tragically wrong. When ${he} finally relaxes, the machine withdraws the dildo, and before ${his} sphincter can close, it replaces it with the main instrument.`);
			if (canTalk(slave)) {
				r.push(`${He} screams with the horror of realization and begins to beg desperately as ${he} feels its head touch ${his} buttocks. ${His} cries become a drawn-out shriek as ${his} butthole accommodates the enormous thing.`);
			} else {
				r.push(`${He} attempts to fling ${himself} from the machine with the horror of realization begins to flail desperately as ${he} feels its head touch ${his} buttocks. ${His} efforts double as ${his} butthole accommodates the enormous thing.`);
			}
			r.push(`When ${he} finally runs out of breath and slumps within ${his} restraints, the dildo begins to withdraw for its first stroke, and ${he} is racked with weeping.`);
		}
		if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
			r.push(`The dildo in ${his} vagina begins to fuck ${him} as well. Between ${his} terribly broadened holes, ${his} stretched perineum is barely visible at all.`);
		}
	} else if (V.dairyStimulatorsSetting > 0) {
		if (slave.devotion > 95) {
			r.push(`${He} groans as the machine pushes a big dildo up ${his} butt and begins to sodomize ${him} powerfully.`);
		} else if (slave.devotion > 60) {
			r.push(`${He} sobs as the machine pushes a big dildo up ${his} butt and begins to sodomize ${him} powerfully.`);
		} else if (slave.devotion > 20) {
			r.push(`${He} sobs as the machine pushes a big dildo up ${his} butt and begins to sodomize ${him} powerfully.`);
		} else {
			r.push(`${He} cries as the machine pushes a big dildo up ${his} butt and begins to sodomize ${him} powerfully.`);
		}
	}
	if (V.dairyFeedersSetting > 1) {
		if (slave.devotion > 95) {
			r.push(`A manipulator prods ${his} jaw open and a phallus slides into ${his} throat, working around for a while to find the optimal position for maximum penetration where ${he} can still breathe through ${his} nose. There is a hiss as the food begins rushing through the phallus and down ${his} throat.`);
		} else if (slave.devotion > 60) {
			if (canTalk(slave)) {
				r.push(`${He} tries to say something, but ${he} left it too late.`);
			}
			r.push(`A manipulator forces ${his} jaw open and a phallus slides into ${his} throat, working around for a while to find the optimal position for maximum penetration where ${he} can still breathe through ${his} nose. There is a hiss as the food begins rushing through the phallus and down ${his} throat.`);
		} else if (slave.devotion > 20) {
			r.push(`${His} crying is abruptly cut off as a manipulator forces ${his} jaw open and a phallus slides into ${his} throat, working around for a while to find the optimal position for maximum penetration where ${he} can still breathe through ${his} nose.`);
		} else {
			r.push(`${He} cries hopelessly,`);
			if (canTalk(slave)) {
				r.push(
					Spoken(slave, `"I'm n-never going t-to leave h-here, am I, —"`),
					`${His} noise`
				);
			} else {
				r.push(`until ${his} sobbing`);
			}
			r.push(`is abruptly cut off as a manipulator forces ${his} jaw open and a phallus slides into ${his} throat, working around for a while to find the optimal position for maximum penetration where ${he} can still breathe through ${his} nose.`);
		}
	} else if (V.dairyFeedersSetting > 0) {
		if (slave.devotion > 95) {
			r.push(`The machine gives ${him} a phallus to suck on.`);
		} else if (slave.devotion > 60) {
			if (canTalk(slave)) {
				r.push(`${He} tries to say something, but ${he} left it too late.`);
			}
			r.push(`The machine gives ${him} a phallus to suck on.`);
		} else if (slave.devotion > 20) {
			r.push(`${His} crying is abruptly cut off as the machine gives ${him} a phallus to suck on.`);
		} else {
			r.push(`${He} cries hopelessly,`);
			if (canTalk(slave)) {
				r.push(
					Spoken(slave, `"I'm n-never going t-to leave h-here, am I, —"`),
					`${His} noise`
				);
			} else {
				r.push(`until ${his} sobbing`);
			}
			r.push(`is abruptly cut off as the machine forces a phallus into ${his} mouth.`);
		}
	}

	App.Events.addParagraph(node, r);
	r = [];
	r.push(`With its various applicators inserted and working, the machine begins to ejaculate necessary fluids into ${his} body. You cannot see much direct evidence, but the inrush of fluids is clear from the draining reservoirs scattered around the machine.`);
	if (V.dairyStimulatorsSetting > 1) {
		r.push(`The gargantuan phallus fucking ${his} butthole ejaculates industrial lubricant, hydration, nutrition, and medication, to be absorbed by ${his} lower intestines.`);
	} else if (V.dairyStimulatorsSetting > 0) {
		r.push(`The phallus fucking ${his} ass ejaculates hydration, nutrition, and medication, to be absorbed by ${his} colon.`);
	}
	if (V.dairyPregSetting > 1 && isFertile(slave) && slave.mpreg !== 1) {
		r.push(`The dildo in ${his} vagina ejaculates cum, fertility drugs, and medication designed to cause uncontrollable natural lubrication, so it will not damage ${him} too severely.`);
	} else if (V.dairyPregSetting > 0 && isFertile(slave) && slave.mpreg !== 1) {
		r.push(`The dildo in ${his} vagina ejaculates cum and fertility drugs.`);
	}
	if (V.dairyFeedersSetting > 0) {
		r.push(`There is a hiss as still more fluid containing hydration, nutrition, and medication begins rushing through the phallus in ${his} mouth and down ${his} throat.`);
	}
	r.push(`Finally, multiple drug injectors attach themselves to ${him} and begin to use hypersonic jets to drive pharmaceuticals into ${him} without needles.`);
	if (slave.devotion > 95) {
		r.push(`${His} eyes fly wide as ${he}`);
		if (canHear(slave)) {
			r.push(`hears and`);
		}
		r.push(`feels the number of injections. ${He} knows these drugs are not without side effects, and ${he}'s being injected with a normal day's dose every minute. ${He} musters ${his} resolve and relaxes again, relying on ${his} knowledge that you want ${him} to accept this fate.`);
	} else if (slave.devotion > 60) {
		r.push(`${His} eyes fly wide and ${he} stiffens with fear as ${he}`);
		if (canHear(slave)) {
			r.push(`hears and`);
		}
		r.push(`feels the number of injections. ${He} knows these drugs are not without side effects, and ${he}'s being injected with a normal day's dose every minute. ${He} visibly tries to accept it, knowing that you want ${him} to submit to this fate.`);
	} else if (slave.devotion > 20) {
		r.push(`The tears streaming out of ${his} eyes come faster as ${he}`);
		if (canHear(slave)) {
			r.push(`hears and`);
		}
		r.push(`feels the number of injections. ${He} knows these drugs are not without side effects, and ${he}'s being injected with a normal day's dose every minute.`);
	} else {
		r.push(`${He} begins to struggle desperately as ${he}`);
		if (canHear(slave)) {
			r.push(`hears and`);
		}
		r.push(`feels the number of injections. ${He} knows these drugs are not without side effects, and ${he}'s being injected with a normal day's dose every minute.`);
	}
	App.Events.addParagraph(node, r);
	r = [];
	r.push(`Fluids begin to come out of ${him}. The drugs are strong, and despite everything ${he} experiences an orgasm so powerful that it's clear why the straps that bind ${him} are reinforced.`);
	if (slave.balls > 0) {
		if (slave.dick > 0) {
			r.push(`The anal dildo fucks ${him} even harder,`);
		} else {
			r.push(`If ${he} had a dick, it would be caressed by a nice warm receptacle, but ${he} doesn't. The milker is forced to rape ${his} ass without mercy to force ${him} to cum,`);
		}
		r.push(`and ${he} tries to scream around the dildo in ${his} mouth.`);
		if (slave.scrotum > 0) {
			r.push(`${His} balls tighten as ${he}`);
		} else {
			r.push(`${He}`);
		}
		r.push(`shoots rope after rope of semen into the machine.`);
	}
	if (slave.vagina > -1) {
		r.push(`${He} gives the machine a nice gush of femcum.`);
	}
	if (slave.lactation > 0) {
		r.push(`The cups sucking ${his} nipples work away ceaselessly, ${his} milk whitening the clear piping running into the machine.`);
		slave.lactationDuration = 2;
		slave.boobs -= slave.boobsMilk;
		slave.boobsMilk = 0;
	}
	r.push(`The machine continues fucking ${him} despite ${his} climax.`);
	if (slave.devotion > 95) {
		r.push(`Though it's difficult to tell, it's possible ${he}'s smiling around the dildo in ${his} mouth. ${He} may be such a well-broken sex slave that ${he} can stand up to a life of nothing but drugs, milking, and an endless string of orgasms. To ease ${his} acclimation to ${his} new life, the drug cocktail is adjusted as ${his} orgasm fades,`);
	} else if (slave.devotion > 60) {
		r.push(`Despite ${his} attempt to be brave, tears begin to leak out from behind ${his} visor as ${he} realizes that there will be no respite from the penetration. The drug cocktail is adjusted as ${his} orgasm fades,`);
	} else if (slave.devotion > 20) {
		r.push(`To ease ${his} acclimation to ${his} new life, the drug cocktail is adjusted as ${his} orgasm fades,`);
	} else {
		r.push(`To allow ${him} some rest despite ${his} terror, the drug cocktail is adjusted as ${his} orgasm fades,`);
	}
	r.push(`to put ${him} to sleep. ${He} slumps against the machine as ${he} drops off.`);
	if (hasAnyArms(slave)) {
		r.push(`${His} painfully tight grip on your hand finally loosens.`);
	}
	if (V.dairyStimulatorsSetting > 1) {
		r.push(`${His} anus has not yet stretched to take the necessary full power setting, so ${he} is gently sodomized as ${he} sleeps to get ${his} sphincter used to its permanent occupier.`);
	}
	if (slave.belly < 1500) {
		r.push(`${His} belly has already begun to distend from the mass of fluid ejaculated down ${his} throat and into ${his} stomach,`);
		if (slave.ovaries === 1) {
			r.push(`inside ${his} womanhood and into ${his} womb, and`);
		}
		r.push(`up ${his} butt and into ${his} lower intestine.`);
	}

	r.push(`Silence returns to the dairy.`);
	App.Events.addParagraph(node, r);
	return node;
};


code:
/**
 * Currently setup for the Incubator and Nursery
 * @param {string} facility
 * @returns {DocumentFragment}
 */
App.UI.facilityRetrievalWorkaround = function(facility) {
	const isIncubator = facility === "Incubator";
	const facilityName = isIncubator ? V.incubator.name : V.nurseryName;
	if (isIncubator) {
		V.incubator.readySlaves = 0;
	}

	const node = new DocumentFragment();
	if (V.readySlave) {
		const {he, his, him} = getPronouns(V.readySlave);
		animalBabyWarning(V.readySlave);
		App.UI.DOM.appendNewElement("p", node, `${V.readySlave.slaveName} has been discharged from ${facilityName} and is ready for ${his} first ever inspection.`);
		if (isIncubator) {
			App.UI.DOM.appendNewElement("div", node, App.Desc.longSlave(V.readySlave));
			if (V.readySlave.tankBaby !== 3) {
				checkOrgans(V.readySlave);
				App.UI.DOM.appendNewElement("div", node, App.UI.newChildIntro(V.readySlave));
			} else {
				const price = Math.trunc(slaveCost(V.readySlave)/3);
				V.activeSlave = V.readySlave; // V.activeSlave is used by Husk Slave Swap Workaround
				node.append(`A husk is ready to be used.`);
				App.UI.DOM.appendNewElement("div", node, `As expected, ${he} is a complete vegetable, but that is what you wanted after all. You lack the facilities to care for ${him} in this state, so you should do what you are planning quickly. Or you could sell ${him} to the Flesh Heap.`, "note");
				if (V.cash >= V.surgeryCost) {
					App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink("Contact the bodyswap surgeon.", "Husk Slave Swap Workaround", null, "Will significantly increase the selected slave's upkeep."));
					App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink("Sell the husk to Flesh Heap.", "Main", () => { cashX(price, "slaveTransfer"); }, `This body can be bought by the Flesh Heap for ${cashFormat(price)}.`));
				} else {
					cashX(price, "slaveTransfer");
					App.UI.DOM.appendNewElement("span", node, `You can't sustain ${him} and thus must sell ${him} for ${cashFormat(price)}.`, "note");
				}
			}
		}
	} else if (V.newSlavePool) {
		App.UI.DOM.appendNewElement("p", node, `The following slaves were discharged from ${facilityName}:`);
		for (const slave of V.newSlavePool) {
			App.UI.DOM.appendNewElement("div", node, `Name: ${SlaveFullName(slave)}`);
			App.UI.DOM.appendNewElement("div", node, parent(slave, "mother"));
			App.UI.DOM.appendNewElement("div", node, parent(slave, "father"));
			newSlave(slave);
			checkOrgans(slave);
		}
		delete V.newSlavePool;
	}

	return node;

	function animalBabyWarning(slave) {
		if (slave.father === -8) {
			Dialog.setup("Attention");
			const frag = new DocumentFragment();
			frag.append(`As the Farmyard is currently WIP, animal-fathered children shouldn't be here! Affected slave: ${slave.slaveName}.`);
			App.UI.DOM.appendNewElement("div", frag, "Please either close this dialog, load a previous save and abort the pregnancy, or sell/discard this slave.");
			App.UI.DOM.appendNewElement("div", frag,
				App.UI.DOM.link("Alternatively, remove this slave and try again.", () => {
					if (V.readySlave) {
						V.readySlave = 0;
					} else if (V.newSlavePool) {
						V.newSlavePool.deleteAt(slave);
					}
					if (Dialog.isOpen()) {
						Dialog.close();
					}
				}, [], (V.readySlave ? facility : `${facility} Retrieval Workaround`))
			);
			$(Dialog.body()).empty().append(frag);
			Dialog.open();
		}
	}

	/**
	 * @param {FC.SlaveState} slave
	 * @param {"father"|"mother"} type
	 */
	function parent(slave, type) {
		const r = new DocumentFragment();
		const missingTableEntry = V.missingTable[slave[type]];
		const missingSlave = missingTableEntry ? `Your former slave, ${missingTableEntry.slaveName}.` : `Unknown.`;
		animalBabyWarning(slave);
		r.append(`${capFirstChar(type)}: `);
		if (slave[type] > 0) {
			const tempParent = getSlave(slave[type]);
			if (!tempParent) {
				r.append(`Unknown.`);
			} else {
				r.append(SlaveFullName(tempParent));
			}
		} else if (slave[type] === -1) {
			r.append(PlayerName());
		} else if (type === "father") {
			if (slave.father === -2) {
				r.append(`Unknown citizen.`);
			} else if (slave.father === -3) {
				r.append(`Your former Master.`);
			} else if (slave.father === -4) {
				r.append(`Another arcology's owner.`);
			} else if (slave.father === -5) {
				r.append(`One of your clients.`);
			} else if (slave.father === -6) {
				r.append(`Societal Elite.`);
			} else if (slave.father === -7) {
				r.append(`Lab crafted.`);
			} else if (slave.father === -9) {
				r.append(`Futanari Sister.`);
			} else {
				r.append(missingSlave);
			}
		} else {
			r.append(missingSlave);
		}
		return r;
	}

	function checkOrgans(slave) {
		if (V.incubator.organs.length > 0) {
			for (const organ of V.incubator.organs.filter(o => o.ID === slave.ID)) {
				const newOrgan = {type: organ.type, weeksToCompletion: organ.weeksToCompletion, ID: slave.ID};
				if (newOrgan.weeksToCompletion <= 0) {
					V.completedOrgans.push(organ);
				} else {
					V.organs.push(newOrgan);
				}
				V.incubator.organs.deleteAt(organ);
			}
		}
	}
};

repo_name: Banyanael/fc

license: mit


code:
App.Facilities.FarmerSelect = function() {
	const f = document.createDocumentFragment();

	if (S.Farmer) {
		f.append(`Farmer: ${SlaveFullName(S.Farmer)}, tends to your crops and animals. `);
		f.append(App.UI.DOM.link("Remove Farmer", () => {
			removeJob(S.Farmer, Job.FARMER);
		},
		[], "Farmyard"
		));
	} else {
		f.append(`No Farmer assigned, appoint one from your devoted slaves.`);
	}

	f.append(App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.farmyard, "Farmyard"));
	return f;
};


code:
/** The base animal class. */
App.Entity.Animal = class Animal {
	/**
	 * @param {string} name
	 * @param {string} species
	 * @param {'canine'|'hooved'|'feline'} type
	 * @param {'domestic'|'exotic'} rarity
	 */
	constructor(name, species, type, rarity) {
		this.name = name;
		this.species = species;
		this.type = type;
		this.rarity = rarity;
		this.articleAn = 'a';
		this.dick = {
			/** Corresponds directly to the sizes in SlaveState. */
			size: this.species === 'cat' ? 2 : 4,
			desc: this.species === 'cat' ? 'little' : 'large',
		};
		this.deadliness = this.type === 'feline' ? this.species === 'cat' ? 1 : 4 : 3;
	}

	/** @returns {boolean} */
	get purchased() {
		return V.animals[this.type].includes(this);
	}

	/** @returns {boolean} */
	get isActive() {
		return V.active[this.type] === this.name;
	}

	/** @returns {string} */
	get ballType() {
		return this.species;
	}

	/** @returns {this} */
	purchase() {
		V.animals[this.type].push(this);

		if (V.pit && !V.pit.animal) {
			V.pit.animal = this.name;
		}

		return this;
	}

	/** @param {string} name */
	setName(name) {
		this.name = name;

		return this;
	}

	/** @param {string} species */
	setSpecies(species) {
		this.species = species;

		return this;
	}

	/** @param {'canine'|'hooved'|'feline'} type */
	setType(type) {
		this.type = type;

		return this;
	}

	/** @param {'domestic'|'exotic'} rarity */
	setRarity(rarity) {
		this.rarity = rarity;

		return this;
	}

	/** @returns {this} */
	setActive() {
		V.active[this.type] = this.name;

		return this;
	}

	/** @param {'a'|'an'} setter */
	setArticle(setter) {
		this.articleAn = setter;

		return this;
	}

	/**
	 * @param {number} size
	 * @param {string} desc
	 */
	setDick(size = 2, desc = null) {
		this.dick.size = size;
		this.dick.desc = desc;

		return this;
	}

	/** @param {number} setter */
	setDeadliness(setter) {
		this.deadliness = setter;

		return this;
	}
};


code:
App.Facilities.Farmyard.animals = function() {
	App.Facilities.Farmyard.animals.init();

	const frag = new DocumentFragment();

	App.UI.DOM.appendNewElement("h1", frag, 'Animals');
	const activeDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);
	const domesticDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);
	const exoticDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);

	const hrMargin = '0';

	const canine = 'canine';
	const hooved = 'hooved';
	const feline = 'feline';
	const exotic = 'exotic';
	const domestic = 'domestic';

	V.nextButton = "Back";
	V.nextLink = "Farmyard";
	V.returnTo = "Farmyard Animals";
	V.encyclopedia = "Farmyard";

	if (V.active.canine || V.active.hooved || V.active.feline) {
		App.UI.DOM.appendNewElement("h2", activeDiv, 'Active Animals');
	}

	App.UI.DOM.appendNewElement("h2", domesticDiv, 'Domestic Animals');

	if (V.farmyardKennels > 1 || V.farmyardStables > 1 || V.farmyardCages > 1) {
		App.UI.DOM.appendNewElement("h2", exoticDiv, 'Exotic Animals');
	}

	activeDiv.append(activeAnimals());

	domesticDiv.append(
		domesticCanines(),
		domesticHooved(),
		domesticFelines(),
	);

	exoticDiv.append(
		exoticCanines(),
		exoticHooved(),
		exoticFelines(),
	);

	if (V.debugMode || V.cheatMode) {
		frag.append(addAnimal());
	}

	return frag;

	// Active Animals

	function activeAnimals() {
		if (V.active.canine || V.active.hooved || V.active.feline) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Canine', ['bold']);

			div.append(hr);

			if (V.active.canine) {
				div.append(canine());
			}
			if (V.active.hooved) {
				div.append(hooved());
			}
			if (V.active.feline) {
				div.append(feline());
			}

			return div;
		}

		return document.createElement("div");

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

			const option = options.addOption(null, "canine", V.active);
			V.animals.canine.forEach(canine => {
				option.addValue(capFirstChar(canine.name), canine.name).pulldown();
			});

			div.append(`Your ${V.active.canine} is currently set as your active canine.`, options.render());

			return div;
		}

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

			const option = options.addOption(null, "hooved", V.active);
			V.animals.hooved.forEach(hooved => {
				option.addValue(capFirstChar(hooved.name), hooved.name).pulldown();
			});

			div.append(`Your ${V.active.hooved} is currently set as your active hooved animal.`, options.render());

			return div;
		}

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

			const option = options.addOption(null, "feline", V.active);
			V.animals.feline.forEach(feline => {
				option.addValue(capFirstChar(feline.name), feline.name).pulldown();
			});

			div.append(`Your ${V.active.feline} is currently set as your active feline.`, options.render());

			return div;
		}
	}

	// Domestic Animals

	function domesticCanines() {
		if (V.farmyardKennels) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Dogs', ['bold']);

			div.append(hr, animalList(canine, domestic, 5000, canine));

			return div;
		}

		return document.createElement("div");
	}

	function domesticHooved() {
		if (V.farmyardStables) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);

			div.append(hr, animalList(hooved, domestic, 20000, hooved));

			return div;
		}

		return document.createElement("div");
	}

	function domesticFelines() {
		if (V.farmyardCages) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Cats', ['bold']);

			div.append(hr, animalList(feline, domestic, 1000, feline));

			return div;
		}

		return document.createElement("div");
	}

	// Exotic Animals

	function exoticCanines() {
		if (V.farmyardKennels > 1) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Canines', ['bold']);

			div.append(hr, animalList(canine, exotic, 50000, canine));

			return div;
		}

		return document.createElement("div");
	}

	function exoticHooved() {
		if (V.farmyardStables > 1) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);

			div.append(hr, animalList(hooved, exotic, 75000, hooved));

			return div;
		}

		return document.createElement("div");
	}

	function exoticFelines() {
		if (V.farmyardCages > 1) {
			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
			const hr = document.createElement("hr");

			hr.style.margin = hrMargin;

			App.UI.DOM.appendNewElement("span", div, 'Felines', ['bold']);

			div.append(hr, animalList(feline, exotic, 100000, feline));

			return div;
		}

		return document.createElement("div");
	}

	// Helper Functions

	/**
	 * Creates either a link or note text depending on parameters given
	 * @param {object} param
	 * @param {App.Entity.Animal} param.animal
	 * @param {string} param.active
	 * @param {string} param.type
	 * @param {number} param.price
	 * @param {function():void} param.setActiveHandler
	 * @param {function():void} param.purchaseHandler
	 * @returns {string|HTMLElement}
	 */
	function animalLink({animal, active, type, price, setActiveHandler, purchaseHandler}) {
		if (animal.purchased || V.animals[animal.type].some(a => a.name === animal.name)) {
			if (V.active[active] && V.active[active] === animal.name) {
				return App.UI.DOM.makeElement("span", `Set as active ${type}`, ["note"]);
			} else {
				return App.UI.DOM.link(`Set as active ${type}`, setActiveHandler);
			}
		} else {
			return App.UI.DOM.link(
				`Purchase`,
				purchaseHandler,
				[], '', `Costs ${cashFormat(price)} and will incur upkeep costs.`
			);
		}
	}

	/**
	 * Creates a list of the specified animal type from the main animal array.
	 * @param {'canine'|'hooved'|'feline'} type One of 'canine', 'hooved', or 'feline', also used to determine the active animal type.
	 * @param {'domestic'|'exotic'} rarity One of 'domestic' or 'exotic'.
	 * @param {number} price
	 * @param {string} active The name of the current active animal of the given type.
	 * @returns {HTMLDivElement}
	 */
	function animalList(type, rarity, price, active) {
		const mainDiv = document.createElement("div");
		const filteredArray = App.Data.animals.filter(animal => animal.rarity === rarity && animal.type === type);

		filteredArray.forEach(animal => {
			const animalDiv = document.createElement("div");
			const optionSpan = document.createElement("span");

			const args = {
				animal: animal,
				active: active,
				type: type,
				price: price,
				setActiveHandler() {
					animal.setActive();
					App.UI.DOM.replace(mainDiv, animalList(type, rarity, price, active));
					App.UI.DOM.replace(activeDiv, activeAnimals());
				},
				purchaseHandler() {
					cashX(forceNeg(price), "farmyard");
					animal.purchase();
					if (!V.active[animal.type]) {
						animal.setActive();
					}
					App.UI.DOM.replace(activeDiv, activeAnimals());
					App.UI.DOM.replace(mainDiv, animalList(type, rarity, price, active));
				}
			};

			optionSpan.append(animalLink(args));

			animalDiv.append(capFirstChar(animal.name), ' ', optionSpan);

			mainDiv.appendChild(animalDiv);
		});

		return mainDiv;
	}

	function addAnimal() {
		const addAnimalDiv = document.createElement("div");
		const dickDiv = document.createElement("div");
		const deadlinessDiv = document.createElement("div");
		const addDiv = App.UI.DOM.makeElement("div", null, ['animal-add']);

		const animal = new App.Entity.Animal(null, null, "canine", "domestic");

		App.UI.DOM.appendNewElement("div", addAnimalDiv, `Add a New Animal`, ['uppercase', 'bold']);

		addAnimalDiv.append(
			name(),
			species(),
			type(),
			rarity(),
			article(),
			dick(),
			deadliness(),
			add(),
		);

		return addAnimalDiv;

		function name() {
			const nameDiv = document.createElement("div");

			nameDiv.append(
				`Name: `,
				App.UI.DOM.makeTextBox(animal.name || '', value => {
					animal.setName(value);

					App.UI.DOM.replace(nameDiv, name);
					App.UI.DOM.replace(dickDiv, dick);
					App.UI.DOM.replace(deadlinessDiv, deadliness);
					App.UI.DOM.replace(addDiv, add);
				}),
			);

			return nameDiv;
		}

		function species() {
			const speciesDiv = document.createElement("div");

			speciesDiv.append(
				`Species: `,
				App.UI.DOM.makeTextBox(animal.species || '', value => {
					animal.setSpecies(value);

					App.UI.DOM.replace(speciesDiv, species);
					App.UI.DOM.replace(addDiv, add);
				}),
			);

			return speciesDiv;
		}

		function type() {
			const typeDiv = document.createElement("div");

			const typeLinks = [];

			if (animal.type === "canine") {
				typeLinks.push(
					App.UI.DOM.disabledLink(`Canine`, [`Already selected.`]),
					App.UI.DOM.link(`Hooved`, () => {
						animal.setType('hooved');

						App.UI.DOM.replace(typeDiv, type);
					}),
					App.UI.DOM.link(`Feline`, () => {
						animal.setType("feline");

						App.UI.DOM.replace(typeDiv, type);
					}),
				);
			} else if (animal.type === "hooved") {
				typeLinks.push(
					App.UI.DOM.link(`Canine`, () => {
						animal.setType("canine");

						App.UI.DOM.replace(typeDiv, type);
					}),
					App.UI.DOM.disabledLink(`Hooved`, [`Already selected.`]),
					App.UI.DOM.link(`Feline`, () => {
						animal.setType("feline");

						App.UI.DOM.replace(typeDiv, type);
					}),
				);
			} else {
				typeLinks.push(
					App.UI.DOM.link(`Canine`, () => {
						animal.setType("canine");

						App.UI.DOM.replace(typeDiv, type);
					}),
					App.UI.DOM.link(`Hooved`, () => {
						animal.setType("hooved");

						App.UI.DOM.replace(typeDiv, type);
					}),
					App.UI.DOM.disabledLink(`Feline`, [`Already selected.`]),
				);
			}

			typeDiv.append(`Type: `, App.UI.DOM.generateLinksStrip(typeLinks));

			return typeDiv;
		}

		function rarity() {
			const rarityDiv = document.createElement("div");

			const rarityLinks = [];

			if (animal.rarity === "domestic") {
				rarityLinks.push(
					App.UI.DOM.disabledLink(`Domestic`, [`Already selected.`]),
					App.UI.DOM.link(`Exotic`, () => {
						animal.setRarity('exotic');

						App.UI.DOM.replace(rarityDiv, rarity);
					}),
				);
			} else {
				rarityLinks.push(
					App.UI.DOM.link(`Domestic`, () => {
						animal.setRarity('domestic');

						App.UI.DOM.replace(rarityDiv, rarity);
					}),
					App.UI.DOM.disabledLink(`Exotic`, [`Already selected.`]),
				);
			}

			rarityDiv.append(`Rarity: `, App.UI.DOM.generateLinksStrip(rarityLinks));

			return rarityDiv;
		}

		function article() {
			const articleDiv = document.createElement("div");

			const articleLinks = [];

			if (animal.articleAn === 'a') {
				articleLinks.push(
					App.UI.DOM.link("Yes", () => {
						animal.articleAn = 'an';

						App.UI.DOM.replace(articleDiv, article);
						App.UI.DOM.replace(dickDiv, dick);
						App.UI.DOM.replace(deadlinessDiv, deadliness);
					}),
					App.UI.DOM.disabledLink("No", [`Already selected.`]),
				);
			} else {
				articleLinks.push(
					App.UI.DOM.disabledLink("Yes", [`Already selected.`]),
					App.UI.DOM.link("No", () => {
						animal.articleAn = 'a';

						App.UI.DOM.replace(articleDiv, article);
						App.UI.DOM.replace(dickDiv, dick);
						App.UI.DOM.replace(deadlinessDiv, deadliness);
					}),
				);
			}

			articleDiv.append(`Is this animal's name preceded by an 'an'? `, App.UI.DOM.generateLinksStrip(articleLinks));

			return articleDiv;
		}

		function dick() {
			dickDiv.append(dickSize(), dickDesc());

			return dickDiv;

			function dickSize() {
				const dickSizeDiv = document.createElement("div");

				dickSizeDiv.append(
					`How large is ${animal.name ? `${animal.articleAn} male ${animal.name}` : `a male`}'s penis? `,
					App.UI.DOM.makeTextBox(animal.dick.size || 2, value => {
						animal.setDick(value, animal.dick.desc || null);

						App.UI.DOM.replace(dickSizeDiv, dickSize);
					}, true),
					App.UI.DOM.makeElement("span", `1 is smallest, and default is 2. `, ['note']),
				);

				return dickSizeDiv;
			}

			function dickDesc() {
				const dickDescDiv = document.createElement("div");

				dickDescDiv.append(
					`What does it look like? `,
					App.UI.DOM.makeTextBox(animal.dick.desc || '', value => {
						animal.setDick(animal.dick.size || 2, value);

						App.UI.DOM.replace(dickDescDiv, dickDesc);
					}),
					App.UI.DOM.makeElement("span", `Default is 'large'. `, ['note']),
				);

				return dickDescDiv;
			}
		}

		function deadliness() {
			deadlinessDiv.append(
				`How deadly is ${animal.name ? `${animal.articleAn} ${animal.name}` : `the animal`}? `,
				App.UI.DOM.makeTextBox(5, value => {
					animal.setDick(value);
				}, true),
				App.UI.DOM.makeElement("span", `Default is 5. `, ['note']),
			);

			return deadlinessDiv;
		}

		function add() {
			const disabledReasons = [];

			let link;

			if (!animal.name) {
				disabledReasons.push(`Animal must have a name.`);
			}

			if (!animal.species) {
				disabledReasons.push(`Animal must have a species.`);
			}

			if (disabledReasons.length > 0) {
				link = App.UI.DOM.disabledLink(`Add`, disabledReasons);
			} else {
				link = App.UI.DOM.link(`Add`, () => {
					App.Data.animals.push(animal);

					App.UI.DOM.replace(addAnimalDiv, addAnimal);
				});
			}

			addDiv.appendChild(link);

			return addDiv;
		}
	}
};

/**
 *
 * @param {string} name
 * @returns {App.Entity.Animal}
 */
globalThis.getAnimal = function(name) {
	return V.animals.canine.find(animal => animal.name === name) ||
		V.animals.hooved.find(animal => animal.name === name) ||
		V.animals.feline.find(animal => animal.name === name);
};

App.Facilities.Farmyard.animals.init = function() {
	if (!App.Data.animals || App.Data.animals.length === 0) {
		class Animal extends App.Entity.Animal {}

		const dog = 'dog';
		const cat = 'cat';
		const canine = 'canine';
		const hooved = 'hooved';
		const feline = 'feline';
		const domestic = 'domestic';
		const exotic = 'exotic';
		const an = 'an';

		/** @type {Animal[]} */
		App.Data.animals = [
			new Animal("beagle", dog, canine, domestic)
				.setDeadliness(2),
			new Animal("bulldog", dog, canine, domestic),
			new Animal("French bulldog", dog, canine, domestic)
				.setDeadliness(2),
			new Animal("German shepherd", dog, canine, domestic),
			new Animal("golden retriever", dog, canine, domestic),
			new Animal("labrador retriever", dog, canine, domestic),
			new Animal("poodle", dog, canine, domestic)
				.setDeadliness(2),
			new Animal("rottweiler", dog, canine, domestic),
			new Animal("Siberian husky", dog, canine, domestic),
			new Animal("Yorkshire terrier", dog, canine, domestic)
				.setDeadliness(2),

			new Animal("dingo", "dingo", canine, exotic),
			new Animal("fox", "fox", canine, exotic),
			new Animal("jackal", "jackal", canine, exotic),
			new Animal("wolf", "wolf", canine, exotic)
				.setDeadliness(4),

			new Animal("bull", "bull", hooved, domestic)
				.setDick(5, 'huge'),
			new Animal("horse", "horse", hooved, domestic)
				.setDick(5, 'huge'),
			new Animal("pig", "pig", hooved, domestic),

			new Animal("zebra", "zebra", hooved, exotic)
				.setDick(5, 'huge'),
			new Animal("elephant", "elephant", hooved, exotic)
				.setArticle(an)
				.setDick(6, 'enormous'),	// not exactly true to life, but more interesting

			new Animal("Abbysinian", cat, feline, domestic)
				.setArticle(an),
			new Animal("Bengal", cat, feline, domestic),
			new Animal("Birman", cat, feline, domestic),
			new Animal("Maine coon", cat, feline, domestic),
			new Animal("Oriental shorthair", cat, feline, domestic)
				.setArticle(an),
			new Animal("Persian", cat, feline, domestic),
			new Animal("Ragdoll", cat, feline, domestic),
			new Animal("Russian blue", cat, feline, domestic),
			new Animal("Siamese", cat, feline, domestic),
			new Animal("Sphynx", cat, feline, domestic),

			new Animal("cougar", "cougar", feline, exotic),
			new Animal("jaguar", "jaguar", feline, exotic),
			new Animal("leopard", "leopard", feline, exotic),
			new Animal("lion", "lion", feline, exotic),
			new Animal("lynx", "lynx", feline, exotic),
			new Animal("puma", "puma", feline, exotic),
			new Animal("tiger", "tiger", feline, exotic),
		];
	}
};

/** @type {App.Entity.Animal[]} */
App.Data.animals = App.Data.animals || [];


code:
App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facility {
	constructor() {
		const farmyard = App.Entity.facilities.farmyard;
		const decommissionHandler = () => {
			if (V.farmMenials) {
				V.menials += V.farmMenials;
				V.farmMenials = 0;
			}

			V.farmyardName = "the Farmyard";
			V.farmyard = 0;
			V.farmyardDecoration = "standard";

			V.farmMenials = 0;
			V.farmMenialsSpace = 0;

			V.farmyardShows = 0;
			V.farmyardBreeding = 0;
			V.farmyardCrops = 0;

			V.farmyardKennels = 0;
			V.farmyardStables = 0;
			V.farmyardCages = 0;

			if (V.pit) {
				V.pit.animal = null;
			}

			V.farmyardUpgrades = {
				pump: 0,
				fertilizer: 0,
				hydroponics: 0,
				machinery: 0,
				seeds: 0
			};

			V.animals = {
				canine: [],
				hooved: [],
				feline: [],
			};

			V.active = {
				canine: null,
				hooved: null,
				feline: null,
			};

			App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Manufacturing, "Farmyard", "Manufacturing");
		};

		super(
			farmyard,
			decommissionHandler,
		);

		V.nextButton = "Back to Main";
		V.nextLink = "Main";
		V.encyclopedia = "Farmyard";
	}

	/** @returns {string} */
	get intro() {
		const text = [];

		text.push(
			`${this.facility.nameCaps} is an oasis of growth in the midst of the jungle of steel and concrete that is ${V.arcologies[0].name}. Animals are kept in pens, tended to by your slaves, while ${V.farmyardUpgrades.hydroponics
				? `rows of hydroponics equipment`
				: `makeshift fields`} grow crops.`,
			this.decorations,
		);

		if (this.facility.hostedSlaves > 2) {
			text.push(`${this.facility.nameCaps} is bustling with activity. Farmhands are hurrying about, on their way to feed animals and maintain farming equipment.`);
		} else if (this.facility.hostedSlaves) {
			text.push(`${this.facility.nameCaps} is working steadily. Farmhands are moving about, looking after the animals and crops.`);
		} else if (S.Farmer) {
			text.push(`${S.Farmer.slaveName} is alone in ${V.farmyardName}, and has nothing to do but look after the animals and crops.`);
		} else {
			text.push(`${this.facility.nameCaps} is empty and quiet.`);
		}

		return text.join(' ');
	}

	/** @returns {string} */
	get decorations() {
		/** @type {FC.Facilities.Decoration} */
		const FS = {
			"Roman Revivalist": `Its red tiles and white stone walls are the very picture of a Roman farm villa's construction, as are the marble statues and reliefs. Saturn and Ceres look over the prosperity of the fields${V.seeBestiality ? `. Mercury watches over the health of the animals, and Feronia ensures strong litters in your slaves.` : `, and Mercury watches over the health of the animals.`} The slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Neo-Imperialist": `Its high-tech, sleek black design invocates an embracement of the future, tempered by the hanging banners displaying your family crest as the rightful lord and master of these farms. Serf-like peasants work tirelessly in the fields, both to grow crops and oversee the slaves beneath them. Despite the harsh nature of the fieldwork, the slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Aztec Revivalist": `It can't completely recreate the floating farms in the ancient Aztec fashion, but it comes as close as it can, shallow pseudo-canals dividing each field into multiple sections. Smooth stone and colorful murals cover the walls, depicting bloody stories of gods and mortals alike.`,
			"Egyptian Revivalist": `It does its best to capture the wide open nature of ancient Egyptian farms, including mimicking the irrigation systems fed by the Nile. The stone walls are decorated with murals detailing its construction and your prowess in general, ${V.seeBestiality ? `with animal-bloated slaves featured prominently.` : `hieroglyphs spelling out volumes of praise.`}`,
			"Edo Revivalist": `It does its best to mimic the rice patties and thatch roofed buildings of the Edo period despite the wide variety of crops tended by various slaves. Not every crop can thrive in flooded fields, but the ones that can take advantage of your attention to detail.`,
			"Arabian Revivalist": `Large plots of olive trees and date palms line the outer edges of the main crop area, while a combination of wheat, flax, and barley occupies the interior space. Irrigation canals snake through the area, ensuring every inch of cropland is well-watered.`,
			"Chinese Revivalist": `It does its best to capture the terraces that covered the ancient Chinese hills and mountains, turning every floor into ribbons of fields following a slight incline. Slaves wade through crops that can handle flooding and splash through the irrigation of the others when they aren't tending to${V.seeBestiality ? ` or breeding with` : ``} your animals.`,
			"Chattel Religionist": `It runs like a well oiled machine, slaves bent in humble service as they tend crops grown on the Prophet's command, or see to the animals' needs. Their clothing is tucked up and out of the way as they see to their tasks, keeping them clean as they work ${V.seeBestiality ? `around animal-bloated bellies ` : ``}as divine will dictates.`,
			"Degradationist": `It is constructed less as a converted warehouse and more as something to visit, allowing guests to enjoy the spectacle of slaves ${V.seeBestiality ? `being pounded by eager animals` : `elbow deep in scrubbing animal waste`} to their satisfaction.`,
			"Repopulationist": `It teems with life, both in the belly of every animal and the belly of every slave, though the latter makes tending the fields difficult. They're ordered to take care, as they carry the future ${V.seeBestiality ? `of this farm` : `of the arcology`} in their bellies.`,
			"Eugenics": `It holds a wide variety of crops and animals, but the best of the best is easy to find. They're set apart from the others, given only the best care and supplies${V.seeBestiality ? ` and bred with only the highest quality slaves` : ``}, while the sub-par stock is neglected off to the side.`,
			"Asset Expansionist": `It is not easy to look after animals and till fields with such enormous body parts, but your slaves are diligent regardless, working hard to provide food and livestock for the arcology.`,
			"Transformation Fetishist": `The plants and animals here all look slightly unnatural, as though they were engineered in a lab to be stronger or larger – which, of course, they were.`,
			"Gender Radicalist": `The plants and animals here all look slightly unnatural, as though they were treated with hormones to be stronger or larger – which, of course, they were.`,
			"Gender Fundamentalist": `The majority of the population of ${V.farmyardName} is pregnant, and the space is outfitted with childbearing in mind.`,
			"Physical Idealist": `Its animals are in exceptional shape, their coats unable to hide how muscular they are, requiring your slaves to be equally toned to control them. There's plenty of space for their exercise as well${V.seeBestiality ? ` and an abundance of curatives for the slaves full of their fierce, kicking offspring` : ``}.`,
			"Supremacist": `It is a clean and orderly operation, stables and cages mucked by a multitude of inferior slaves, along with grooming your animals and harvesting your crops.`,
			"Subjugationist": `It is a clean and orderly operation, stables and cages mucked by a multitude of ${V.arcologies[0].FSSubjugationistRace} slaves, while the others are tasked with grooming your animals and harvesting your crops.`,
			"Paternalist": `It's full of healthy animals, crops, and slaves, the former's every need diligently looked after by the latter. The fields flourish to capacity under such care, and the animals give the distinct impression of happiness${V.seeBestiality ? ` — some more than others if the growing bellies of your slaves are anything to go by, the only indication that such rutting takes place` : ``}.`,
			"Pastoralist": `The space is outfitted with milkers every so often so that lactating farmhands don't have to travel far to relieve themselves of their milk, and the animals are milked of what they can be as well.`,
			"Maturity Preferentialist": `The majority of the population here is older and wiser, and the older animals are all treated with a bit more luxury than the younger ones.`,
			"Youth Preferentialist": `The majority of the population here is full of youth and more energetic, and the younger animals are all treated with a bit more luxury than the older ones.`,
			"Body Purist": `Organic crops and animals are the main feature here, and the animal manure is used as a natural fertilizer for the different plants.`,
			"Slimness Enthusiast": `It features trim animals and slaves alike, not a pound of excess among them. The feed for both livestock and crops are carefully maintained to ensure optimal growth without waste, letting them flourish without being weighed down.`,
			"Hedonistic": `It features wider gates and stalls, for both the humans visiting or tending the occupants, and the animals starting to mimic their handlers${V.seeBestiality ? ` and company` : ``}, with plenty of seats along the way.`,
			"Intellectual Dependency": `Large signs covered in cartoonish illustrations dot the pens, illustrating how to take care of the needs of the occupant within.${V.seeBestiality ? ` There is a strong emphasis on proper breeding positions for your slaves, with step by step instructions.` : ``}`,
			"Slave Professionalism": `Despite the surroundings, those of your slaves that are allowed to wear clothes are dressed in clean outfits.${V.seeBestiality ? ` Those bearing litters walk with practiced care, protecting their young.` : ``} They go about their tasks methodically and with care, with ${S.Farmer ? S.Farmer.slaveName : `senior farmhands`} watching carefully to correct any lax behavior.`,
			"Petite Admiration": `The buildings are squat, one story affairs that allow those of smaller stature easier access. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"Statuesque Glorification": `Those workers who are smaller and less fit have been given the worst jobs, mucking out the pens and stables. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"standard": `It is very much a converted warehouse still, sectioned off in various 'departments'${V.farmyardUpgrades.machinery ? ` with machinery placed where it can be` : V.farmyardUpgrades.hydroponics ? ` and plumbing for the hydroponics system running every which way` : ``}.`,
		};

		const res = FS[V.farmyardDecoration];

		if (!res) {
			throw new Error(`Unknown V.farmyardDecoration value of '${V.farmyardDecoration}' found in decorations().`);
		}

		return res;
	}

	/** @returns {FC.Facilities.Expand} */
	get expand() {
		const slaves = this.facility.hostedSlaves;
		const is = slaves === 1 ? `is` : `are`;

		return {
			desc: `It can support ${num(V.farmyard)} farmhands. There ${is} currently ${numberWithPluralOne(slaves, `farmhand`)} in ${V.farmyardName}.`,
		};
	}

	/** @returns {FC.IUpgrade[]} */
	get upgrades() {
		return [
			{
				property: "pump",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `${this.facility.nameCaps} is currently using the basic water pump that it came with.`,
						link: `Upgrade the water pump`,
						cost: 5000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						note: ` and slightly decreases upkeep costs`,
					},
					{
						value: 1,
						text: `The water pump in ${this.facility.name} is a more efficient model, slightly improving the amount of crops it produces.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "fertilizer",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The fertilizer being used in ${this.facility.name} is the cheap, buy-in-bulk stuff you can purchase at the local supermarket.`,
						link: `Use a higher-quality fertilizer`,
						cost: 10000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
						prereqs: [
							() => V.farmyardUpgrades.pump > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using a specialized fertilizer created to result in a higher crop yield.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "hydroponics",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `There is room enough in ${this.facility.name} to install a hydroponics system for irrigation.`,
						link: `Purchase an advanced hydroponics system`,
						cost: 20000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						note: ` and moderately decreases upkeep costs`,
						prereqs: [
							() => V.farmyardUpgrades.fertilizer > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is outfitted with an advanced hydroponics system, reducing the amount of water your crops consume and thus saving a bit on your water bill.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "seeds",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The seeds ${this.facility.name} is using are the standard seeds one could pick up at the local farmers' market.`,
						link: `Purchase genetically modified seeds`,
						cost: 25000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
						prereqs: [
							() => V.farmyardUpgrades.hydroponics > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using genetically modified seeds, designed to produce a much greater yield while remaining more resistant to pests and disease.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "machinery",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The machinery in ${this.facility.name} is equipment that was imported before the old world began to fall apart and is fairly old and outdated.`,
						link: `Upgrade the machinery`,
						cost: 50000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
						prereqs: [
							() => V.farmyardUpgrades.seeds > 0
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using the latest in farming equipment and technology.`,
					},
				],
				object: V.farmyardUpgrades,
			},
		];
	}

	/** @returns {FC.Facilities.Rule[]} */
	get rules() {
		return [
			{
				property: "farmyardShows",
				prereqs: [
					() => this.facility.hostedSlaves > 0,
					() => V.farmyardKennels > 0 || V.farmyardStables > 0 || V.farmyardCages > 0,
				],
				options: [
					{
						get text() { return `Slaves in ${V.farmyardName} are focusing their efforts on producing as much food as possible.`; },
						link: `Food only`,
						value: 0,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are both producing food and putting on shows with animals.`; },
						link: `Both food and shows`,
						value: 1,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are only putting on shows with animals.`; },
						link: `Shows only`,
						value: 2,
					},
				],
			},
			{
				property: "farmyardBreeding",
				prereqs: [
					() => !!V.seeBestiality,
					() => !!V.farmyardShows,
					() => !!V.animals.canine || !!V.animals.hooved || !!V.animals.feline,
				],
				options: [
					{
						get text() { return `Slaves in ${V.farmyardName} are not being bred with animals.`; },
						link: `End breeding`,
						value: 0,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are being bred with animals.`; },
						link: `Begin breeding`,
						value: 1,
					},
				],
			},
			{
				property: "farmyardRestraints",
				prereqs: [
					() => !!V.farmyardBreeding,
					() => V.farmyardShows !== 0,
				],
				options: [
					{
						get text() { return `Only disobedient slaves are being restrained.`; },
						link: `Restrain only disobedient slaves`,
						value: 0,
					},
					{
						get text() { return `All of the slaves are being restrained.`; },
						link: `Restrain all slaves`,
						value: 1,
					},
				],
			},
		];
	}

	/** @returns {HTMLDivElement} */
	get stats() {
		return App.UI.DOM.makeElement("div", App.Facilities.Farmyard.Stats(true));
	}

	/** @returns {HTMLDivElement} */
	get menials() {
		const div = document.createElement("div");

		const popCap = menialPopCap();
		const bulkMax = popCap.value - V.menials - V.fuckdolls - V.menialBioreactors;

		const menialPrice = Math.trunc(menialSlaveCost());
		const maxMenials = Math.trunc(Math.clamp(V.cash / menialPrice, 0, bulkMax));
		const unitCost = Math.trunc(1000 * V.upgradeMultiplierArcology);

		let links = [];

		// Transferring

		if (V.farmMenials) {
			div.append(`Assigned to ${V.farmyardName} ${V.farmMenials === 1 ? `is` : `are`} ${V.farmMenials} menial ${V.farmMenials === 1 ? `slave` : `slaves`}, working to produce as much food for your arcology as they can. `);
		}

		if (V.farmMenialsSpace) {
			div.append(`You ${V.menials ? `own ${num(V.menials)}` : `don't own any`} free menial slaves. ${capFirstChar(V.farmyardName)} can house ${num(V.farmMenialsSpace)} menial slaves total, with ${num(V.farmMenialsSpace - V.farmMenials)} free spots. `);
		}

		if (V.farmMenialsSpace && V.farmMenials < V.farmMenialsSpace) {
			if (V.menials) {
				links.push(App.UI.DOM.link("Transfer in a menial slave", () => {
					V.menials--;
					V.farmMenials++;

					this.refresh();
				}));
			}

			if (V.menials >= 10 && V.farmMenials <= V.farmMenialsSpace - 10) {
				links.push(App.UI.DOM.link(`Transfer in ${num(10)} menial slaves`, () => {
					V.menials -= 10;
					V.farmMenials += 10;

					this.refresh();
				}));
			}

			if (V.menials >= 100 && V.farmMenials <= V.farmMenialsSpace - 100) {
				links.push(App.UI.DOM.link(`Transfer in ${num(100)} menial slaves`, () => {
					V.menials -= 100;
					V.farmMenials += 100;

					this.refresh();
				}));
			}

			if (V.menials) {
				links.push(App.UI.DOM.link(`Transfer in all free menial slaves`, () => {
					if (V.menials > V.farmMenialsSpace - V.farmMenials) {
						V.menials -= V.farmMenialsSpace - V.farmMenials;
						V.farmMenials = V.farmMenialsSpace;
					} else {
						V.farmMenials += V.menials;
						V.menials = 0;
					}

					this.refresh();
				}));
			}
		} else if (!V.farmMenialsSpace) {
			div.append(`${capFirstChar(V.farmyardName)} cannot currently house any menial slaves. `);
		} else {
			div.append(`${capFirstChar(V.farmyardName)} has all the menial slaves it can currently house assigned to it. `);
		}

		if (V.farmMenials) {
			links.push(App.UI.DOM.link(`Transfer out all menial slaves`, () => {
				V.menials += V.farmMenials;
				V.farmMenials = 0;

				this.refresh();
			}));
		}

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

		// Trading

		links = [];

		if (V.farmMenialsSpace) {
			if (bulkMax > 0 || V.menials + V.fuckdolls + V.menialBioreactors === 0) {
				links.push(App.UI.DOM.link(`Buy ${num(1)}`, () => {
					V.menials++;
					V.menialSupplyFactor--;
					cashX(forceNeg(menialPrice), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy ${num(10)}`, () => {
					V.menials += 10;
					V.menialSupplyFactor -= 10;
					cashX(forceNeg(menialPrice * 10), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy ${num(100)}`, () => {
					V.menials += 100;
					V.menialSupplyFactor -= 100;
					cashX(forceNeg(menialPrice * 100), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy maximum`, () => {
					V.menials += maxMenials;
					V.menialSupplyFactor -= maxMenials;
					cashX(forceNeg(maxMenials * menialPrice), "farmyard");

					this.refresh();
				}));
			}
		}

		if (V.farmMenials) {
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
		}

		// Housing

		links = [];

		if (V.farmMenialsSpace < 2000) {
			App.UI.DOM.appendNewElement("div", div, `There is enough room in ${V.farmyardName} to build housing, enough to give ${V.farmMenialsSpace + 100} menial slaves a place to sleep and relax.`);

			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Build a new housing unit`, () => {
				cashX(forceNeg(unitCost), "farmyard");
				V.farmMenialsSpace += 100;

				this.refresh();
			},
			[], '', `Costs ${cashFormat(unitCost)} and increases housing by ${num(100)}.`), ['indent']);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get kennels() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const CL = V.animals.canine.length;
		let dogs = '';
		let canines = '';

		if (CL === 1) {
			dogs = `${V.animals.canine[0].name}s`;

			if (V.animals.canine[0].species === "dog") {
				canines = V.animals.canine[0].name;
			} else {
				canines = asPlural(V.animals.canine[0].species);
			}
		} else if (CL < 3) {
			dogs = `a couple different breeds of dogs`;

			if (V.animals.canine.every(c => c.species === "dog")) {
				canines = `a couple different breeds of dog`;
			} else {
				canines = `a couple different species of canine`;
			}
		} else {
			dogs = `all kinds of dogs`;
			canines = `all kinds of canines`;
		}

		if (V.farmyardKennels === 0) {
			div.append(`There is enough room in ${V.farmyardName} to build kennels to house canines.`);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Add kennels`, () => {
				cashX(forceNeg(cost), "farmyard");
				V.farmyardKennels = 1;
				V.PC.skill.engineering += .1;

				this.refresh();
			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic canines.`), ['indent']);
		} else if (V.farmyardKennels === 1) {
			div.append(App.UI.DOM.passageLink("Kennels", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${dogs}`}.`);

			if (V.rep > 10000) {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade kennels", () => {
					cashX(forceNeg(cost * 2), "farmyard");
					V.farmyardKennels = 2;
					V.PC.skill.engineering += .1;

					this.refresh();
				}, [], '', `Costs ${cashFormat(cost * 2)} will incur additional upkeep costs, and unlocks exotic canines.`), ['indent']);
			} else {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade kennels",
					[`You must be more reputable to be able to house exotic canines.`]),
				['indent']);
			}
		} else if (V.farmyardKennels === 2) {
			div.append(App.UI.DOM.passageLink("Large kennels", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${canines}`}.`);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get stables() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const HL = V.animals.hooved.length;

		const hooved = HL === 1
			? `${V.animals.hooved[0].name}s` : HL < 3
				? `several different types of hooved animals`
				: `all kinds of hooved animals`;

		if (V.farmyardStables === 0) {
			div.append(`There is enough room in ${V.farmyardName} to build a stables to house hooved animals.`);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Add stables", () => {
				cashX(forceNeg(cost), "farmyard");
				V.farmyardStables = 1;
				V.PC.skill.engineering += .1;

				this.refresh();
			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic hooved animals.`), ['indent']);
		} else if (V.farmyardStables === 1) {
			div.append(App.UI.DOM.passageLink("Stables", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`);

			if (V.rep > 10000) {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade stables", () => {
					cashX(forceNeg(cost * 2), "farmyard");
					V.farmyardStables = 2;
					V.PC.skill.engineering += .1;

					this.refresh();
				}, [], '', `Costs ${cashFormat(cost * 2)}, will incur additional upkeep costs, and unlocks exotic hooved animals.`), ['indent']);
			} else {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade stables",
					[`You must be more reputable to be able to house exotic hooved animals.`]),
				['indent']);
			}
		} else if (V.farmyardStables === 2) {
			div.append(App.UI.DOM.passageLink("Large stables", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get cages() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const FL = V.animals.feline.length;
		let cats = '';
		let felines = '';

		if (FL === 1) {
			cats = `${V.animals.feline[0].name}s`;

			if (V.animals.feline[0].species === "cat") {
				felines = V.animals.feline[0].name;
			} else {
				felines = asPlural(V.animals.feline[0].species);
			}
		} else if (FL < 3) {
			cats = `a couple different breeds of cats`;

			if (V.animals.feline.every(c => c.species === "cat")) {
				felines = `a couple different breeds of cat`;
			} else {
				felines = `a couple different species of feline`;
			}
		} else {
			cats = `all kinds of cats`;
			felines = `all kinds of felines`;
		}

		if (V.farmyardCages === 0) {
			div.append(`There is enough room in ${V.farmyardName} to build cages to house felines.`);
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Add cages", () => {
				cashX(forceNeg(cost), "farmyard");
				V.farmyardCages = 1;
				V.PC.skill.engineering += .1;

				this.refresh();
			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic felines.`), ['indent']);
		} else if (V.farmyardCages === 1) {
			div.append(App.UI.DOM.passageLink("Cages", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${cats}`}.`);

			if (V.rep > 10000) {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade cages", () => {
					cashX(forceNeg(cost * 2), "farmyard");
					V.farmyardCages = 2;
					V.PC.skill.engineering += .1;

					this.refresh();
				}, [], '', `Costs ${cashFormat(cost * 2)}, will increase upkeep costs, and unlocks exotic felines.`), ['indent']);
			} else {
				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade cages",
					[`You must be more reputable to be able to house exotic felines.`]),
				['indent']);
			}
		} else if (V.farmyardCages === 2) {
			div.append(App.UI.DOM.passageLink("Large cages", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${felines}`}.`);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get removeAnimalHousing() {
		const div = App.UI.DOM.makeElement("div", null, ['margin-top']);

		const cost = ((V.farmyardKennels + V.farmyardStables + V.farmyardCages) * 5000) * V.upgradeMultiplierArcology;

		if (V.farmyardKennels || V.farmyardStables || V.farmyardCages) {
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Remove the animal housing", () => {
				V.farmyardKennels = 0;
				V.farmyardStables = 0;
				V.farmyardCages = 0;

				V.animals = {
					canine: [],
					hooved: [],
					feline: [],
				};

				V.active = {
					canine: null,
					hooved: null,
					feline: null,
				};

				if (V.pit) {
					V.pit.animal = null;
				}

				V.farmyardShows = 0;
				V.farmyardBreeding = 0;
				V.farmyardRestraints = 0;

				cashX(forceNeg(cost), "farmyard");

				this.refresh();
			},
			[], '', `Will cost ${cashFormat(cost)}.`), ['indent']);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get animals() {
		const div = document.createElement("div");

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

		div.append(
			this.kennels,
			this.stables,
			this.cages,
		);

		return div;
	}

	/** @returns {HTMLDivElement[]} */
	get customNodes() {
		return [
			this.animals,
			this.removeAnimalHousing,
		];
	}
};


code:
// @ts-nocheck
App.Facilities.Farmyard.BC = function() {
	if (typeof V.farmyardUpgrades !== "object") {
		V.farmyardUpgrades = {
			pump: 0, fertilizer: 0, hydroponics: 0, machinery: 0, seeds: 0
		};
	}

	if (!App.Data.animals || App.Data.animals.length === 0) {
		App.Facilities.Farmyard.animals.init();
	}

	if (V.foodStored) {
		V.mods.food.amount += V.foodStored;

		delete V.foodStored;
	}

	if (V.canine) {
		V.animals.canine = Array.from(V.canine);

		delete V.canine;
	}
	if (V.hooved) {
		V.animals.hooved = Array.from(V.hooved);

		delete V.hooved;
	}
	if (V.feline) {
		V.animals.feline = Array.from(V.feline);

		delete V.feline;
	}

	if (V.active.canine && typeof V.active.canine !== "string") {
		V.active.canine = V.active.canine.name;
	}

	if (V.active.hooved && typeof V.active.hooved !== "string") {
		V.active.hooved = V.active.hooved.name;
	}

	if (V.active.feline && typeof V.active.feline !== "string") {
		V.active.feline = V.active.feline.name;
	}

	if (V.farmyardShowgirls) {
		delete V.farmyardShowgirls;
	}

	if (V.farmyardFarmers) {
		delete V.farmyardFarmers;
	}
};


code:
App.Data.Facilities.farmyard = {
	baseName: "farmyard",
	genericName: null,
	jobs: {
		farmhand: {
			position: "farmhand",
			assignment: Job.FARMYARD,
			publicSexUse: false,
			fuckdollAccepted: false
		}
	},
	defaultJob: "farmhand",
	manager: {
		position: "farmer",
		assignment: Job.FARMER,
		careers: App.Data.Careers.Leader.farmer,
		skill: "farmer",
		publicSexUse: false,
		fuckdollAccepted: false,
		broodmotherAccepted: false,
		shouldWalk: true,
		shouldHold: true,
		shouldSee: true,
		shouldHear: true,
		shouldTalk: false,
		shouldThink: true,
		requiredDevotion: 51
	},
	decorated: true
};

App.Entity.Facilities.FarmHandJob = class extends App.Entity.Facilities.FacilitySingleJob {
	/**
	 * @override
	 */
	get assignment() {
		return `work in ${this.facility.name}`;
	}
};

App.Entity.facilities.farmyard = new App.Entity.Facilities.SingleJobFacility(
	App.Data.Facilities.farmyard, {
		farmhand: new App.Entity.Facilities.FarmHandJob()
	}
);


code:
/**
 * The amount of food a given slave produces in a week.
 *
 * Defaults to a menial slave if one is not provided.
 * @param {App.Entity.SlaveState} [slave]
 * @returns {number}
 */
App.Facilities.Farmyard.foodAmount = function(slave) {
	let food = 100;

	if (V.farmyardUpgrades.pump) {
		food += 25;
	}

	if (V.farmyardUpgrades.fertilizer) {
		food += 50;
	}

	if (V.farmyardUpgrades.seeds) {
		food += 75;
	}

	if (V.farmyardUpgrades.machinery) {
		food += 100;
	}

	if (S.Farmer) {
		food *= 1.1;

		if (S.Farmer.skill.farmer >= V.masteredXP) {
			food *= 1.3;
		}

		if (App.Data.Careers.Leader.farmer.includes(S.Farmer.career)) {
			food *= 1.2;
		}
	}

	if (slave) {
		food += slaveProduction(slave);

		if (V.farmyardShows === 1) {
			food *= 0.5;
		} else if (V.farmyardShows === 2) {
			return 0;
		}
	} else {
		food += menialProduction();
	}

	food = Math.trunc(Math.max(food, 0));

	return food;

	function slaveProduction(slave) {
		let food = 100;

		if (slave.devotion > 50) {
			food *= 1.1;
		} else if (slave.devotion < -50) {
			food *= 0.8;
		}

		if (slaveResting(slave)) {
			food *= 0.9;
		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
			slave.devotion -= 10;
			slave.trust -= 5;
			food *= 0.5;
		}

		if (slave.muscles > 30) {
			food *= 1.1;
		} else if (slave.muscles <= -6) {
			food *= 0.8;
		}

		if (slave.weight > 95) {
			food *= 0.9;
		} else if (slave.weight > 130) {
			food *= 0.8;
		} else if (slave.weight > 160) {
			food *= 0.7;
		} else if (slave.weight > 190) {
			food *= 0.6;
		}

		if (!canSee(slave)) {
			food *= 0.6;
		} else if (!canSeePerfectly(slave)) {
			food *= 0.8;
		}

		if (slave.hears === -1) {
			food *= 0.8;
		} else if (slave.hears < -1) {
			food *= 0.6;
		}

		food *= restEffects(slave, 20);

		return food;
	}

	function menialProduction() {
		return food * 0.85;
	}
};

/** The total amount of food produced in a given week. */
App.Facilities.Farmyard.foodProduction = function() {
	function menialProduction() {
		return V.farmMenials * App.Facilities.Farmyard.foodAmount();
	}

	function slaveProduction() {
		return App.Entity.facilities.farmyard.employees().reduce((acc, cur) => acc + App.Facilities.Farmyard.foodAmount(cur), 0);
	}

	return menialProduction() + slaveProduction();
};

/** The total amount of food consumed in a given week. */
App.Facilities.Farmyard.foodConsumption = function() {
	function citizenConsumption() {
		return (
			(V.lowerClass * V.mods.food.rate.lower) +
			(V.middleClass * V.mods.food.rate.middle) +
			(V.upperClass * V.mods.food.rate.upper) +
			(V.topClass * V.mods.food.rate.top)
		);
	}

	function slaveConsumption() {
		let total = 0;

		for (const slave of V.slaves) {
			let amount = 8;

			if (slave.diet === "restricted") {
				amount = 6;
			} else if (slave.diet === "slimming") {
				amount = 7;
			} else if (slave.diet === "muscle building") {
				amount = 9;
			} else if (slave.diet === "fattening") {
				amount = 10;
			}

			total += amount;
		}

		return total;
	}

	return citizenConsumption() + slaveConsumption();
};


code:
App.UI.foodMarket = function() {
	const frag = new DocumentFragment();
	const quantities = new Set([1, 10, 100, 1000, 10000, 100000]);

	const maxFood = Math.trunc(V.cash / V.mods.food.cost);

	frag.append(
		overview(),
		buy(),
		sell(),
		remove(),
	);

	return frag;

	function overview() {
		const div = document.createElement("div");
		const text = new SpacedTextAccumulator(div);

		const consumption = App.Facilities.Farmyard.foodConsumption();
		const foodValue = Math.trunc(V.mods.food.amount * V.mods.food.cost);
		const citizens = V.lowerClass + V.middleClass + V.upperClass + V.topClass;

		if (V.useTabs === 0) {
			App.UI.DOM.appendNewElement("h2", div, "The Food Market");
		}

		text.push(`The food market has <span class="food">${massFormat(V.mods.food.amount)}</span> in storage, valued at a total of ${cashFormat(foodValue)}.`);

		if (V.mods.food.amount > consumption) {
			text.push(`This is enough to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${numberWithPluralOne(Math.trunc(V.mods.food.amount / consumption), `week`)}.`);
		} else if (V.mods.food.amount < consumption) {
			text.push(`You will need an additional ${massFormat(consumption - V.mods.food.amount)} to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} during the upcoming week.`);
		}

		text.toChildren();

		return div;
	}

	function buy() {
		const div = document.createElement("div");
		const links = [];

		div.append(`Buy `);

		for (const q of quantities) {
			links.push(App.UI.DOM.link(
				massFormat(q),
				() => {
					cashX(forceNeg(V.mods.food.cost * q), "farmyard");
					V.mods.food.amount += q;
					App.UI.reload();
				}
			));
		}
		links.push(App.UI.DOM.link(
			"max",
			() => {
				cashX(forceNeg(maxFood * V.mods.food.cost), "farmyard");
				V.mods.food.amount += maxFood;
				App.UI.reload();
			}
		));

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

		return div;
	}

	function sell() {
		const div = document.createElement("div");
		const links = [];

		div.append(`Sell `);

		if (V.mods.food.amount > 0) {
			for (const q of quantities) {
				links.push(App.UI.DOM.link(
					massFormat(q),
					() => {
						cashX(V.mods.food.cost * q, "farmyard");
						V.mods.food.amount -= q;
						App.UI.reload();
					}
				));
			}
			links.push(App.UI.DOM.link(
				"max",
				() => {
					cashX((V.mods.food.cost * V.mods.food.amount), "farmyard");
					V.mods.food.amount = 0;
					App.UI.reload();
				}
			));
		}

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

		return div;
	}

	function remove() {
		const div = document.createElement("div");

		div.append(
			`You can remove the food market entirely and let your citizens fend for themselves, if you wish.`,
			App.UI.DOM.makeElement("div", App.UI.DOM.link(`Dismantle`, () => {
				V.mods.food.market = false;
				repX(forceNeg(8500), "food");
				App.UI.reload();
			}, [], '', `Your citizens WILL hate you for this.`), ['indent']),
		);

		return div;
	}
};


code:
App.UI.foodReport = function() {
	const text = [];
	const farmhands = App.Entity.facilities.farmyard.hostedSlaves;
	const slaveAmount = App.Entity.facilities.farmyard.employees().reduce((acc, cur) => acc + App.Facilities.Farmyard.foodAmount(cur), 0);
	const menialAmount = V.farmMenials * App.Facilities.Farmyard.foodAmount();
	const total = slaveAmount + menialAmount;

	text.push(`${V.arcologies[0].name} produced ${massFormat(total)} of food this week.`);

	if (slaveAmount > 0) {
		text.push(`${V.farmMenials ? capFirstChar(massFormat(slaveAmount)) : `All of it`} was produced by your ${num(farmhands)} farmhands`);
	}
	if (menialAmount > 0) {
		text.push(`${slaveAmount > 0 ? text.pop() + `, and ${massFormat(total - slaveAmount)}` : `All of it`} was produced by ${num(V.farmMenials)} menial slaves`);
	}

	text.push(text.pop() + `.`);

	return text.join(' ');
};