code:
App.UI.SlaveInteract.huskSlaveSwap = function() {
	const node = new DocumentFragment();

	const oldSlave = clone(V.swappingSlave);
	const m = V.slaveIndices[V.swappingSlave.ID];
	const {
		he
	} = getPronouns(V.swappingSlave);

	App.UI.DOM.appendNewElement("p", node, `You strap ${V.slaves[m].slaveName}, and the body to which ${he} will be transferred, into the remote surgery and stand back as it goes to work.`);
	bodySwap(V.slaves[m], V.activeSlave, false);
	const gps = V.genePool.findIndex(function(s) { return s.ID === V.slaves[m].ID; });
	// special exception to swap genePool since the temporary body lacks an entry. Otherwise we could just call the widget using the genePool entries
	V.genePool[gps].race = V.slaves[m].race;
	V.genePool[gps].origRace = V.slaves[m].origRace;
	V.genePool[gps].skin = V.slaves[m].skin;
	V.genePool[gps].markings = V.slaves[m].markings;
	V.genePool[gps].eye.origColor = V.slaves[m].eye.origColor;
	V.genePool[gps].origHColor = V.slaves[m].origHColor;
	V.genePool[gps].origSkin = V.slaves[m].origSkin;
	V.genePool[gps].face = V.slaves[m].face;
	V.genePool[gps].pubicHStyle = V.slaves[m].pubicHStyle;
	V.genePool[gps].underArmHStyle = V.slaves[m].underArmHStyle;
	V.genePool[gps].eyebrowHStyle = V.slaves[m].eyebrowHStyle;

	App.Events.addParagraph(node, [
		`After an honestly impressive procedure, ${V.slaves[m].slaveName} is recovering nicely.`,
		bodySwapReaction(V.slaves[m], oldSlave)
	]);

	const cost = slaveCost(oldSlave);
	const payout = Math.trunc(cost/3);
	let r = [];
	r.push(`${V.slaves[m].slaveName}'s old body was bought by the Flesh Heap for ${cashFormat(payout)}.`);
	if (V.slaves[m].bodySwap > 0) {
		const myBody = V.slaves.findIndex(function(s) { return s.origBodyOwnerID === V.slaves[m].ID; });
		if (myBody !== -1) {
			V.slaves[myBody].origBodyOwnerID = 0;
			const {
				he2, him2, his2
			} = getPronouns(V.slaves[myBody]).appendSuffix("2");
			if (V.slaves[myBody].fetish !== "mindbroken" && V.slaves[myBody].fuckdoll === 0) {
				if (V.slaves[myBody].devotion > 20) {
					r.push(`${V.slaves[myBody].slaveName} is somewhat saddened to see ${his2} body leave forever.`);
				} else if (V.slaves[myBody].devotion >= -50) {
					r.push(`${V.slaves[myBody].slaveName} is <span class="mediumorchid">disturbed</span> to find ${his2} body is gone for good, damaging ${his2} <span class="gold">ability to trust you.</span>`);
					V.slaves[myBody].devotion -= 30;
					V.slaves[myBody].trust -= 30;
				} else {
					r.push(`${V.slaves[myBody].slaveName} is deeply upset that ${he2}'ll never see ${his2} body again. With so little left, ${he2} finds it easy to take vengeance by completely rejecting your ownership of ${him2}.`);
					V.slaves[myBody].devotion -= 50;
					V.slaves[myBody].trust = 100;
				}
			}
		}
	}
	App.Events.addParagraph(node, r);
	V.slaves[m].bodySwap++;
	cashX(payout, "slaveTransfer");
	V.activeSlave = 0;
	V.swappingSlave = 0;
	return node;
};


code:
App.UI.SlaveInteract.slaveSlaveSwap = function() {
	const node = new DocumentFragment();

	const ss1 = V.slaveIndices[V.AS];
	const ss1Clone = clone(getSlave(V.AS));

	const ss2 = V.slaveIndices[V.swappingSlave.ID];
	const ss2Clone = clone(V.swappingSlave);

	const gps1 = V.genePool.findIndex(s => s.ID === V.slaves[ss1].ID);
	const gps1Clone = clone(V.genePool[gps1]);

	const gps2 = V.genePool.findIndex(s => s.ID === V.slaves[ss2].ID);
	const gps2Clone = clone(V.genePool[gps2]);

	App.UI.DOM.appendNewElement("p", node, `You strap ${getSlave(V.AS).slaveName} and ${V.swappingSlave.slaveName} into the remote surgery and stand back as it goes to work.`);

	bodySwap(V.slaves[ss1], ss2Clone, false);
	bodySwap(V.genePool[gps1], gps2Clone, true);

	bodySwap(V.slaves[ss2], ss1Clone, false);
	bodySwap(V.genePool[gps2], gps1Clone, true);

	App.Events.addParagraph(node, [
		`After an honestly impressive procedure, ${V.slaves[ss1].slaveName} is recovering nicely.`,
		bodySwapReaction(V.slaves[ss1], ss1Clone)
	]);

	App.UI.DOM.appendNewElement("hr", node);

	App.Events.addParagraph(node, [
		`In the neighboring bed, ${V.slaves[ss2].slaveName} rests peacefully.`,
		bodySwapReaction(V.slaves[ss2], ss2Clone)
	]);

	// figuring out whom has whose body now
	whoHasWho(ss1, ss2Clone);
	whoHasWho(ss2, ss1Clone);

	// now to handle whose body it is, name-wise
	bodySwapName(V.slaves[ss1], V.slaves[ss2]);
	bodySwapName(V.slaves[ss2], V.slaves[ss1]);

	for (const ss of [ss1, ss2]) {
		if (ss1Clone.bodySwap > 0) {
			if (V.slaves[ss].origBodyOwnerID === V.slaves[ss].ID) {
				V.slaves[ss].bodySwap = 0;
				V.slaves[ss].origBodyOwnerID = 0;
				V.slaves[ss].origBodyOwner = "";
			} else {
				V.slaves[ss].bodySwap++;
			}
		} else {
			V.slaves[ss].bodySwap++;
		}
	}

	V.activeSlave = 0;
	V.swappingSlave = 0;
	return node;

	function whoHasWho(index, opposingClone) {
		if (V.slaves[index].bodySwap === 0) {
			V.slaves[index].origBodyOwnerID = opposingClone.ID;
		} else if (V.slaves[ss2].origBodyOwner !== "") { // now who's going to be looking for you?
			const myBody = V.slaves.findIndex(function(s) { return s.origBodyOwnerID === V.slaves[ss2].ID; });
			if (myBody !== -1) {
				V.slaves[myBody].origBodyOwnerID = V.slaves[index].ID;
			}
		}
	}
};

repo_name: Elohiem/fc

license: mit


code:
App.UI.cloningWorkaround = function() {
	const node = new DocumentFragment();

	let eligibility = 0;
	const donatrix = V.donatrix;
	const receptrix = V.receptrix;

	let impreg;
	if (donatrix !== "undecided" && donatrix.ID === -1) {
		impreg = PlayerName();
	} else if (donatrix !== "undecided") {
		impreg = SlaveFullName(donatrix);
	} else {
		impreg = donatrix;
	}

	let receive;
	if (receptrix !== "undecided" && receptrix.ID === -1) {
		receive = PlayerName();
	} else if (receptrix !== "undecided") {
		receive = SlaveFullName(receptrix);
	} else {
		receive = receptrix;
	}

	App.UI.DOM.appendNewElement("h2", node, `Genetic Source`);
	App.UI.DOM.appendNewElement("div", node, "Blank ovum prepared, please select genetic source and surrogate.", "note");
	App.UI.DOM.appendNewElement("div", node, `Chosen source: ${impreg}`);

	App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
		"Yourself",
		() => {
			V.donatrix = V.PC;
			App.UI.reload();
		}
	));
	for (const slave of V.slaves) {
		if (donatrix !== "undecided" && donatrix.ID === slave.ID) {
			App.UI.DOM.appendNewElement("div", node, SlaveFullName(slave), "note");
		} else {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				SlaveFullName(slave),
				() => {
					V.donatrix = slave;
					App.UI.reload();
				}
			));
		}
	}
	App.UI.DOM.appendNewElement("h2", node, `Surrogate`);
	App.UI.DOM.appendNewElement("div", node, `Chosen surrogate: ${receive}`);

	for (const slave of V.slaves) {
		if (canBeReceptrix(slave)) {
			const name = SlaveFullName(slave);
			if (receptrix !== "undecided" && receptrix.ID === slave.ID) {
				App.UI.DOM.appendNewElement("div", node, name, "note");
			} else {
				App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
					name,
					() => {
						V.receptrix = slave;
						App.UI.reload();
					}, [], "",
					(slave.pregType >= 4) ? `Using a slave carrying multiples is inadvisable` : ``
				));
			}
			eligibility = 1;
		}
	}
	if (eligibility === 0) {
		App.UI.DOM.appendNewElement("div", node, `You have no slaves capable of acting as a surrogate.`, "note");
	}

	if (V.PC.vagina !== -1 && V.PC.preg >= 0 && V.PC.preg < 4 && V.PC.pregType < 8 && V.PC.physicalAge < 70) {
		if (receptrix !== "undecided" && receptrix.ID === V.PC.ID) {
			App.UI.DOM.appendNewElement("div", node, `Yourself`, "note");
		} else {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				"Use your own womb",
				() => {
					V.receptrix = V.PC;
					App.UI.reload();
				}
			));
		}
	}
	App.UI.DOM.appendNewElement("h2", node, `Implantation`);

	if (impreg !== "undecided" && receive !== "undecided") {
		App.UI.DOM.appendNewElement("div", node, `${impreg} will be cloned and ${receive} shall act as the incubator.`);
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Implant clone ovum",
			() => {
				cashX(forceNeg(V.surgeryCost * 2), "slaveSurgery");
				V.surgeryType = "clone";
			}, [], "Surrogacy",
		));
	} else if (impreg !== "undecided") {
		App.Events.addNode(node, [
			`${impreg} will be cloned.`,
			App.UI.DOM.makeElement("span", "Please select a surrogate", "note")
		]);
	} else if (receive !== "undecided") {
		App.Events.addNode(node, [
			`${receive} shall act as the incubator.`,
			App.UI.DOM.makeElement("span", "Please select a genetic source", "note")
		]);
	} else {
		App.UI.DOM.appendNewElement("div", node, `Please select a genetic source and surrogate`, "note");
	}

	return node;
};


code:
/**
 *
 * @param {App.Entity.SlaveState} slave
 * @returns {DocumentFragment}
 */
App.UI.SlaveInteract.fatGraft = function(slave) {
	const frag = new DocumentFragment();
	let availableFat = Math.round(slave.weight / 10);
	let boobFat = 0;
	let buttFat = 0;

	const passage = App.UI.DOM.appendNewElement("span", frag, content());

	return frag;

	function content() {
		const el = new DocumentFragment();
		let r = [];
		const {his} = getPronouns(slave);
		let p;
		let linkArray = [];
		const buttCost = (slave.butt > 10) ? 5 : 2;  // Buttsizes are apparently not linear, so it takes a lot more fat to increase the largest booties.
		r.push(`All surplus body fat was harvested, and enough is graftable for an additional ${availableFat * 100}ccs per breast or an additional ${num(Math.trunc(availableFat / buttCost))} sizes to ${his} rear.`);
		if (availableFat === 0) {
			r.push(`All fat marked for use.`);
		} else {
			r.push(`A total of ${availableFat} ${(availableFat === 1) ? `unit remains` : `units remain`}.`);
		}
		App.Events.addNode(el, r, "p", "scene-intro");

		// Boobs
		p = App.UI.DOM.appendNewElement("p", el);
		App.UI.DOM.appendNewElement("div", p, `${boobFat} units of fat will be added to ${his} breasts for a size gain of ${boobFat * 100}ccs.`);
		if (availableFat > 0) {
			linkArray.push(
				App.UI.DOM.link(
					"Increase",
					() => {
						boobFat++;
						availableFat--;
						refresh();
					}
				)
			);
		} else {
			linkArray.push(App.UI.DOM.disabledLink(`No more fat available.`, []));
		}
		if (boobFat > 0) {
			linkArray.push(
				App.UI.DOM.link(
					"Decrease",
					() => {
						boobFat--;
						availableFat++;
						refresh();
					}
				)
			);
		} else {
			linkArray.push(App.UI.DOM.disabledLink(`No fat marked for breast use.`, []));
		}
		App.UI.DOM.appendNewElement("div", p, App.UI.DOM.generateLinksStrip(linkArray));

		// Ass
		p = App.UI.DOM.appendNewElement("p", el);
		linkArray = [];
		App.UI.DOM.appendNewElement("div", p, `${num(buttFat * buttCost)} units of fat will be added to ${his} ass for a size gain of ${buttFat}.`);
		if (availableFat / buttCost > 1) {
			linkArray.push(
				App.UI.DOM.link(
					"Increase",
					() => {
						buttFat++;
						availableFat -= buttCost;
						refresh();
					}
				)
			);
		} else if (availableFat) {
			linkArray.push(App.UI.DOM.disabledLink(`Not enough fat remains to increase ${his} butt an entire size.`, []));
		} else {
			linkArray.push(App.UI.DOM.disabledLink(`No more fat available.`, []));
		}
		if (buttFat > 0) {
			linkArray.push(
				App.UI.DOM.link(
					"Decrease",
					() => {
						buttFat--;
						availableFat += buttCost;
						refresh();
					}
				)
			);
		} else {
			linkArray.push(App.UI.DOM.disabledLink(`No fat marked for ass use.`, []));
		}
		App.UI.DOM.appendNewElement("div", p, App.UI.DOM.generateLinksStrip(linkArray));
		App.UI.DOM.appendNewElement("p", el, App.UI.DOM.passageLink("Finalize fat transfer", "Surgery Degradation", () => {
			slave.boobs += boobFat * 100;
			slave.butt += buttFat;
			slave.boobs = Math.clamp(slave.boobs, 0, 50000);
			slave.butt = Math.clamp(slave.butt, 0, 20);

			V.boobFat = boobFat;
			V.buttFat = buttFat;

			surgeryDamage(slave, 40);
			cashX(forceNeg(V.surgeryCost * 2), "slaveSurgery", slave);
			V.surgeryType = "fat graft";
		}));
		return el;
	}

	function refresh() {
		jQuery(passage).empty().append(content());
	}
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {DocumentFragment}
 */
App.Medicine.OrganFarm.growActions = function(slave) {
	const O = App.Medicine.OrganFarm.Organs;

	// find already being grown/ready to implant organs
	const slaveOrgans = {};
	O.forEach((organ, key) => slaveOrgans[key] = 0);
	V.completedOrgans.forEach(organ => {
		if (organ.ID === slave.ID) {
			slaveOrgans[organ.type] = -1;
		}
	});
	V.organs.forEach(organ => {
		if (organ.ID === slave.ID) {
			slaveOrgans[organ.type] = organ.weeksToCompletion;
		}
	});

	function weeksLeft(time) {
		if (V.organFarmUpgrade === 1) {
			return time;
		} else if (V.organFarmUpgrade === 2) {
			return Math.ceil(time / 2);
		} else {
			return Math.ceil(time / 4);
		}
	}

	// create entries for each organ
	const canImplant = [];
	const cantImplant = [];
	const growing = [];
	let any = false;
	O.forEach((organ, key) => {
		if (slaveOrgans[key] === 0) {
			if (organ.canGrow(slave)) {
				const array = [];
				array.push(App.UI.DOM.makeElement("div", App.UI.DOM.passageLink(organ.name, "Remote Surgery", () => {
					App.Medicine.OrganFarm.growOrgan(slave, key);
				})));

				const tooltip = typeof organ.tooltip === "string" ? organ.tooltip : organ.tooltip(slave);
				array.push(App.UI.DOM.makeElement("div", `Costs ${cashFormat(organ.cost)}${tooltip !== "" ? ` and ${tooltip}` : ""}.`, "detail"));

				if (organ.implantActions.some((o) => { return o.canImplant(slave); })) {
					canImplant.push(...array);
				} else {
					cantImplant.push(...array);
				}
			}
			any = true;
		} else if (slaveOrgans[key] > 0) {
			// in growth organs at the end of the list
			growing.push({
				time: slaveOrgans[key],
				organ: organ.name,
				text: `Ready for implantation in ${weeksLeft(slaveOrgans[key])} weeks.`
			});
			any = true;
		}
	});

	const fragment = new DocumentFragment();

	if (growing.length > 0) {
		App.UI.DOM.appendNewElement("h4", fragment, "Growing");
		const div = App.UI.DOM.appendNewElement("div", fragment);
		div.classList.add("grid-2columns-auto", "choices");
		// nearer to completion => higher up
		growing.sort((a, b) => a.time - b.time);
		for (let i = 0; i < growing.length; i++) {
			App.UI.DOM.appendNewElement("div", div, growing[i].organ);
			App.UI.DOM.appendNewElement("div", div, growing[i].text);
		}
	}
	if (canImplant.length > 0) {
		App.UI.DOM.appendNewElement("h4", fragment, "Can be implanted immediately");
		const div = App.UI.DOM.appendNewElement("div", fragment);
		div.classList.add("grid-2columns-auto", "choices");
		div.append(...canImplant);
	}
	if (cantImplant.length > 0) {
		App.UI.DOM.appendNewElement("h4", fragment, "Cannot be implanted immediately");
		const div = App.UI.DOM.appendNewElement("div", fragment);
		div.classList.add("grid-2columns-auto", "choices");
		div.append(...cantImplant);
	}

	if (any) {
		return fragment;
	} else {
		return null;
	}
};

/**
 * @param {App.Entity.SlaveState} slave
 * @param {string} organType
 */
App.Medicine.OrganFarm.growOrgan = function(slave, organType) {
	const organ = App.Medicine.OrganFarm.Organs.get(organType);

	V.organs.push({type: organType, weeksToCompletion: organ.time, ID: slave.ID});

	cashX(-organ.cost, "slaveSurgery", slave);
};

/**
 * @param {App.Entity.SlaveState} slave
 * @param {string} organType
 */
App.Medicine.OrganFarm.growIncubatorOrgan = function(slave, organType) {
	const organ = App.Medicine.OrganFarm.Organs.get(organType);

	V.incubator.organs.push({type: organType, weeksToCompletion: organ.time, ID: slave.ID});

	cashX(-organ.cost, "slaveSurgery", slave);
};

/**
 * @param {App.Entity.SlaveState} slave
 * @returns {DocumentFragment}
 */
App.Medicine.OrganFarm.implantActions = function(slave) {
	let slaveOrgans = V.completedOrgans.filter(o => o.ID === slave.ID);
	if (slaveOrgans.length === 0) { return null; }

	const F = App.Medicine.OrganFarm;
	const grid = document.createElement("div");
	grid.classList.add("grid-2columns-auto");

	for (const organ of slaveOrgans) {
		App.UI.DOM.appendNewElement("div", grid, F.Organs.get(organ.type).name);

		let links = [];
		for (let i = 0; i < F.Organs.get(organ.type).implantActions.length; i++) {
			const action = F.Organs.get(organ.type).implantActions[i];
			if (action.canImplant(slave)) {
				const link = App.UI.DOM.link(
					action.name,
					() => {
						App.Medicine.OrganFarm.implant(slave, organ.type, i);
						V.AS = slave.ID;
					},
					[],
					"Surgery Degradation"
				);
				if (action.tooltip !== "") {
					link.classList.add("has-tooltip");
					tippy(link, {content: `${capFirstChar(action.tooltip)}.`});
				}
				links.push(link);
				if (!F.Organs.get(organ.type).displayMultipleActions) {
					break; // there can only be one implant action
				}
			} else {
				const error = action.implantError(slave);
				if (error !== "") {
					links.push(App.UI.DOM.spanWithTooltip(action.name, error));
				}
			}
		}

		// all links in a row
		const div = document.createElement("div");
		for (let i = 0; i < links.length; i++) {
			div.append(links[i], " | ");
		}

		// last error or implant action has "Discard" after them.
		div.append(App.UI.DOM.link("Discard", App.Medicine.OrganFarm.removeOrgan, [slave, organ.type], "Remote Surgery"));
		grid.append(div);
	}

	return App.UI.DOM.combineNodes(`The fabricator has completed ${slaveOrgans.length} organ(s):`, grid);
};

/**
 * @param {App.Entity.SlaveState} slave
 * @param {string} type
 * @param {number} actionIndex
 */
App.Medicine.OrganFarm.implant = function(slave, type, actionIndex) {
	const A = App.Medicine.OrganFarm.Organs.get(type).implantActions[actionIndex];

	A.implant(slave);
	surgeryDamage(slave, A.healthImpact);
	if (V.organFarmUpgrade >= 2) {
		slave.chem += 20;
	}

	App.Medicine.OrganFarm.removeOrgan(slave, type);
	V.surgeryType = A.surgeryType;
};

/**
 * @param {App.Entity.SlaveState} slave
 * @param {string} type
 */
App.Medicine.OrganFarm.removeOrgan = function(slave, type) {
	let organIndex = V.completedOrgans.findIndex(o => (o.ID === slave.ID && o.type === type));

	if (organIndex !== -1) {
		V.completedOrgans.deleteAt(organIndex);
	}
};

/**
 * Organs the that can be implanted on the slave, sorted by dependencies first
 *
 * @param {App.Entity.SlaveState} slave
 * @returns {string[]}
 */
App.Medicine.OrganFarm.getSortedOrgans = function(slave) {
	const F = App.Medicine.OrganFarm;
	/** @type {string[]} */
	const organs = [];
	const dependencies = [];
	V.completedOrgans.forEach(organ => {
		if (organ.ID === slave.ID) {
			organs.push(organ.type);
		}
	});
	organs.forEach(organKey => {
		F.Organs.get(organKey).dependencies.forEach(dependencyKey => {
			if (organs.includes(dependencyKey)) { /* inefficient, is there a better way? */
				dependencies.push([dependencyKey, organKey]);
			}
		});
	});
	try {
		return App.Utils.topologicalSort(organs, dependencies);
	} catch (e) { // closed loop
		console.log(e.message);
		return [];
	}
};

/**
 * Returns the full organ farm menu, hiding empty parts
 *
 * @param {App.Entity.SlaveState} slave
 * @returns {DocumentFragment}
 */
App.Medicine.OrganFarm.fullMenu = function(slave) {
	const fragment = document.createDocumentFragment();
	if (!(V.organFarmUpgrade >= 1 && slave.indentureRestrictions < 2)) {
		return fragment;
	}

	const growActions = App.Medicine.OrganFarm.growActions(slave);
	let anyAction = false;
	if (growActions != null) {
		const {him} = getPronouns(slave);
		App.UI.DOM.appendNewElement("h3", fragment, "Grow new organs");
		App.UI.DOM.appendNewElement("div", fragment, `The fabricator is ready to grow an organ for ${him}. Extract tissue to begin growing.`);
		App.UI.DOM.appendNewElement("div", fragment, growActions);
		anyAction = true;
	}

	const implantActions = App.Medicine.OrganFarm.implantActions(slave);
	if (implantActions !== null) {
		App.UI.DOM.appendNewElement("h3", fragment, "Implant Organs");
		App.UI.DOM.appendNewElement("div", fragment, implantActions, "indent");
		anyAction = true;
	}

	if (!anyAction) {
		return fragment;
	}

	fragment.prepend(App.UI.DOM.makeElement("h2", "Organ Farm"));
	return fragment;
};

/**
 * Returns a list of currently growing and finished organs.
 *
 * @returns {DocumentFragment}
 */
App.Medicine.OrganFarm.currentlyGrowing = function() {
	function weeksToCompletion(weeks) {
		if (V.organFarmUpgrade === 1) {
			return weeks;
		} else if (V.organFarmUpgrade === 2) {
			return Math.ceil(weeks / 2);
		} else {
			return Math.ceil(weeks / 4);
		}
	}

	/**
	 * @type {Array<string|HTMLSpanElement>}
	 */
	let growLines = [];
	/**
	 * @type {Array<string|HTMLSpanElement>}
	 */
	let finishLines = [];

	V.organs.forEach(o => {
		const slave = getSlave(o.ID);
		if (slave !== undefined) {
			const weeks = weeksToCompletion(o.weeksToCompletion);
			growLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}, ${weeks} ${weeks > 1 ? "weeks" : "week"} left.`);
		} else {
			growLines.push(App.UI.DOM.makeElement("span", `ERROR: No slave with ID ${o.ID} found.`, "error"));
		}
	});
	if (V.incubator.capacity > 0) {
		V.incubator.organs.forEach(o => {
			const tank = V.incubator.tanks.find((t) => t.ID === o.ID);
			if (tank !== undefined) {
				if (o.weeksToCompletion <= 0) {
					finishLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}.`);
				} else {
					growLines.push(`${tank.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}, ${
						weeksToCompletion(o.weeksToCompletion)} week(s) left.`);
				}
			} else {
				growLines.push(App.UI.DOM.makeElement("span", `ERROR: No tank with ID ${o.ID} found.`, "error"));
			}
		});
	}

	V.completedOrgans.forEach(o => {
		const slave = getSlave(o.ID);
		if (slave !== undefined) {
			finishLines.push(`${slave.slaveName}'s ${App.Medicine.OrganFarm.Organs.get(o.type).name}.`);
		} else {
			growLines.push(App.UI.DOM.makeElement("span", `ERROR: No slave with ID ${o.ID} found.`, "error"));
		}
	});

	const frag = document.createDocumentFragment();

	if (growLines.length > 0) {
		App.UI.DOM.appendNewElement("h3", frag, "Growing Organs");

		growLines.forEach(l => {
			App.UI.DOM.appendNewElement("div", frag, l);
		});
	}

	if (finishLines.length > 0) {
		App.UI.DOM.appendNewElement("h3", frag, "Finished Organs");

		finishLines.forEach(l => {
			App.UI.DOM.appendNewElement("div", frag, l);
		});
	}

	if (growLines.length === 0 && finishLines.length === 0) {
		App.UI.DOM.appendNewElement("div", frag, "Organs must be genetically matched to their host slave. To begin growing organs for a slave, take them to the Remote Surgery.", "detail");
	}

	return frag;
};


code:
App.UI.ovaTransplantWorkaround = function() {
	const node = new DocumentFragment();
	V.receptrix = 0;
	let eligibility = 0;

	App.UI.DOM.appendNewElement("p", node, "You've decided which fertilized ovum is to be transplanted; now you must select whose womb will be its new home.", "scene-intro");

	App.UI.DOM.appendNewElement("h2", node, "Select a slave to serve as the host");

	for (const slave of V.slaves) {
		if ((V.donatrix.ID !== slave.ID && slave.ovaries > 0 || slave.mpreg > 0) && isSlaveAvailable(slave) && slave.preg >= 0 && slave.preg < slave.pregData.normalBirth / 10 && slave.pregWeek >= 0 && slave.pubertyXX === 1 && slave.pregType < 12 && slave.bellyImplant === -1 && slave.broodmother === 0 && slave.inflation <= 2 && slave.physicalAge < 70) {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				SlaveFullName(slave),
				() => {
					V.receptrix = slave;
					cashX(forceNeg(V.surgeryCost * 2), "slaveSurgery");
					V.surgeryType = "transplant";
				}, [], "Surrogacy",
				(slave.pregType >= 4) ? `Using a slave carrying multiples is inadvisable` : ``
			));
			eligibility = 1;
		}
	}
	if (eligibility === 0) {
		App.UI.DOM.appendNewElement("div", node, "You have no slaves capable of acting as a surrogate.");
	}

	if (V.PC.vagina !== -1 && V.donatrix.ID !== -1 && V.PC.preg >= 0 && V.PC.preg < 4 && V.PC.pregType < 8 && V.PC.physicalAge < 70) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			`Use your own womb`,
			() => {
				V.receptrix = V.PC;
				cashX(forceNeg(V.surgeryCost * 2), "slaveSurgery");
				V.surgeryType = "transplant";
			},
			[],
			"Surrogacy"
		));
	}
	return node;
};


code:
/**
 * Composes the Procedure object from its parts
 *
 * This function has the only purpose to ensure the result object has all required properties
 * @param {string} typeId
 * @param {string} label
 * @param {number} effect
 * @param {string} desc
 * @param {slaveOperation} [action]
 * @param {number} [costs] money costs
 * @param {number} [hCosts] health costs
 * @param {string} [surgeryType]
 * @param {boolean} [cheat]
 * @returns {FC.Medicine.Surgery.Procedure}
 */
App.Medicine.Surgery.makeOption = function(typeId, label, effect, desc, action, costs, hCosts, surgeryType, cheat = false) {
	return {
		typeId: typeId,
		label: label,
		targetEffect: effect,
		description: desc,
		costs: (cheat) ? 0 : costs,
		healthCosts: (cheat) ? 0 : hCosts,
		action: action,
		surgeryType: surgeryType
	};
};

/**
 * Composes the procedure option with empty .action, i.e. a procedure that can't be applied
 * @param {string} typeId
 * @param {string} label
 * @param {string} desc
 * @returns {FC.Medicine.Surgery.Procedure}
 */
App.Medicine.Surgery.makeImpossibleOption = function(typeId, label, desc) {
	return this.makeOption(typeId, label, 0, desc);
};

/**
 * Various constants for procedures
 */
App.Medicine.Keys = {
	Surgery: {
		Target: {
			/**
			 * Type id's for breast-related procedures
			 */
			breast: {
				installImplant: "breast.implant.install",
				removeImplant: "breast.implant.remove",
				fillUp: "breast.implant.fill",
				drain: "breast.implant.drain",
				changeImplant: "breast.implant.replace",
				reduction: "breast.tissue.reduce",
			},
			/**
			 * Type id's for butt-related procedures
			 */
			butt: {
				installImplant: "butt.implant.install",
				removeImplant: "butt.implant.remove",
				fillUp: "butt.implant.fill",
				drain: "butt.implant.drain",
				changeImplant: "but.implant.replace",
				reduction: "butt.tissue.reduce",
			}
		}
	}
};

/**
 * Commit procedure, executing its action and subtracting its costs
 * @param {FC.Medicine.Surgery.Procedure} surgery
 * @param {App.Entity.SlaveState} slave
 * @param {boolean} [cheat]
 */
App.Medicine.Surgery.commit = function(surgery, slave, cheat = false) {
	V.surgeryType = surgery.surgeryType;
	surgery.action(slave);
	if (!cheat) {
		cashX(forceNeg(surgery.costs), "slaveSurgery", slave);
		surgeryDamage(slave, surgery.healthCosts, cheat);
	}
};

/**
 * @param {App.Medicine.Surgery.Procedure} procedure
 * @param {function():void} refresh
 * @param {boolean} cheat
 * @returns {HTMLAnchorElement|HTMLSpanElement}
 */
App.Medicine.Surgery.makeLink = function(procedure, refresh, cheat) {
	if (procedure.disabledReasons.length > 0) {
		return App.UI.DOM.disabledLink(procedure.name, procedure.disabledReasons);
	}

	const slave = procedure.originalSlave;
	return App.UI.DOM.link(procedure.name, apply, [], "", tooltip());

	function healthCosts() {
		const hc = (V.PC.skill.medicine >= 100) ? Math.round(procedure.healthCost / 2) : procedure.healthCost;
		if (hc > 30) {
			return 'substantial';
		} else if (hc > 20) {
			return 'significant';
		} else if (hc > 10) {
			return 'moderate';
		} else if (hc > 5) {
			return 'light';
		}
		return 'insignificant';
	}

	function tooltip() {
		const tooltip = new DocumentFragment();
		if (procedure.description !== "") {
			App.UI.DOM.appendNewElement("div", tooltip, `${capFirstChar(procedure.description)}.`);
		}
		if (!cheat) {
			App.UI.DOM.appendNewElement("div", tooltip, `Surgery costs: ${cashFormat(procedure.cost)}.`);
			App.UI.DOM.appendNewElement("div", tooltip, `Projected health damage: ${healthCosts()}.`);
		}
		return tooltip;
	}

	function apply() {
		const result = App.Medicine.Surgery.apply(procedure, cheat);
		if (result === null) {
			Engine.play("Surgery Death");
			return;
		}

		const [diff, reaction] = result;

		const f = makeSlaveReaction(diff, reaction);

		App.Utils.Diff.applyDiff(slave, diff);

		// Refresh the surgery options or wherever the surgery originated
		refresh();

		// Finally show the slaves reaction
		Dialog.setup(procedure.name);
		Dialog.append(f);
		Dialog.open();
	}

	/**
	 * @param {Partial<App.Entity.SlaveState>} diff
	 * @param {App.Medicine.Surgery.SimpleReaction} reaction
	 * @returns {DocumentFragment}
	 */
	function makeSlaveReaction(diff, reaction) {
		const f = new DocumentFragment();
		let r = [];

		r.push(...reaction.intro(slave, diff));

		const resultMain = reaction.reaction(slave, diff);
		for (const p of resultMain.longReaction) {
			r.push(...p);
			App.Events.addParagraph(f, r);
			r = [];
		}
		slave.devotion += resultMain.devotion;
		slave.trust += resultMain.trust;

		const resultOutro = reaction.outro(slave, diff, resultMain);
		for (const p of resultOutro.longReaction) {
			r.push(...p);
			App.Events.addParagraph(f, r);
			r = [];
		}
		slave.devotion += resultOutro.devotion;
		slave.trust += resultOutro.trust;

		return f;
	}
};

/**
 * if null is returned the slave died
 *
 * @param {App.Medicine.Surgery.Procedure} procedure
 * @param {boolean} cheat
 * @returns {[Partial<App.Entity.SlaveState>, App.Medicine.Surgery.SimpleReaction]}
 */
App.Medicine.Surgery.apply = function(procedure, cheat) {
	const slave = procedure.originalSlave;
	if (!cheat) {
		cashX(-procedure.cost, "slaveSurgery", slave);
		surgeryDamage(slave, procedure.healthCost, cheat);
		if (procedure.invasive && slave.health.condition < random(-100, -80)) {
			return null;
		}
	}

	const [diff, reaction] = procedure.apply(cheat);

	if (reaction.removeJob) {
		removeJob(slave, Job.LURCHER, true);
		removeJob(slave, Job.PIT, true);
		removeJob(slave, slave.assignment);
	}

	return [diff, reaction];
};

/**
 * Returns options to accept all possible surgeries
 * @returns {FC.Medicine.Surgery.SizingOptions}
 */
App.Medicine.Surgery.allSizingOptions = function() {
	return {
		augmentation: true,
		reduction: true,
		strings: true,
		replace: true
	};
};

App.Medicine.Surgery.sizingProcedures = function() {
	class ForbiddenDummy extends App.Medicine.Surgery.Procedure {
		/**
		 * @param {string} name
		 * @param {string} forbidden why the surgery can't be used
		 */
		constructor(name, forbidden) {
			super(null);
			this._name = name;
			this._forbidden = forbidden;
		}

		get name() { return this._name; }

		get disabledReasons() { return [this._forbidden]; }
	}

	return {
		bodyPart: bodyPart,
		boobs: boobSizingProcedures,
		butt: buttSizingProcedures
	};

	/**
	 * Returns list of available surgeries targeted at changing size of the given body part
	 * @param {string} bodyPart
	 * @param {App.Entity.SlaveState} slave
	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
	 * @returns {App.Medicine.Surgery.Procedure[]}
	 */
	function bodyPart(bodyPart, slave, options) {
		if (bodyPart === "boobs") {
			return boobSizingProcedures(slave, options);
		}
		if (bodyPart === "butt") {
			return buttSizingProcedures(slave, options);
		}
		throw Error(`No sizing procedures for ${bodyPart}`);
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
	 * @returns {App.Medicine.Surgery.Procedure[]}
	 */
	function boobSizingProcedures(slave, options = {}) {
		const thisArcology = V.arcologies[0];
		const largeImplantsAvailable = thisArcology.FSTransformationFetishistResearch === 1;
		const advancedSurgeryAvailable = V.ImplantProductionUpgrade === 1;
		const {he, His} = getPronouns(slave);

		const areStringsInstalled = slave.boobsImplantType === "string";
		const areFillablesInstalled = ["fillable", "advanced fillable", "hyper fillable"].includes(slave.boobsImplantType);
		const curSize = slave.boobsImplant;
		const implantType = slave.boobsImplantType;

		/**
		 * @type {Array<App.Medicine.Surgery.Procedure>}
		 */
		let procedures = [];
		if (options.augmentation) {
			if (slave.indentureRestrictions >= 2) {
				procedures.push(new ForbiddenDummy("Change boob size", `${His} indenture forbids elective surgery.`));
			} else if (slave.breastMesh === 1) {
				procedures.push(new ForbiddenDummy("Put implants", `${His} supportive mesh implant blocks implantation.`));
			} else if (curSize === 0) {
				if (options.strings) {
					procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "string", "string", 400));
				}
				if (advancedSurgeryAvailable) {
					procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "large", "normal", 600));
				}
				procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "standard", "normal", 400));
				procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "small", "normal", 200));
			} else if (implantType === "normal") {
				if (curSize > 400) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "fillable", "fillable", 800));
				} else if (curSize > 200) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "large", "normal", 600));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "standard", "normal", 400));
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "large", "normal", 600));
				}
			} else if (implantType === "hyper fillable") {
				if (slave.boobs >= 50000) {
					procedures.push(new ForbiddenDummy("Increase boobs", `${His} breasts are as large as ${he} can physically support.`));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 1000));
				}
			} else if (implantType === "advanced fillable") {
				if (curSize >= 10000) {
					procedures.push(new ForbiddenDummy("Increase boobs", `${His} implants are filled to capacity.`));
					if (largeImplantsAvailable) {
						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "hyper fillable", "hyper fillable", 11000));
					}
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 400));
				}
			} else if (implantType === "fillable") {
				if (curSize >= 1800) {
					procedures.push(new ForbiddenDummy("Add inert filler", `${His} implants are filled to capacity.`));
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "advanced fillable", "advanced fillable", 2200, true));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 200));
				}
			}
		}

		if (options.replace && slave.indentureRestrictions < 2 && curSize > 0) {
			if (!areStringsInstalled && curSize < 600) {
				procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "string", "string", 400));
			} else if (areStringsInstalled) {
				// we have engorged string implants, suggest replacing with normal implants of similar size
				if (curSize > 10000) {
					if (largeImplantsAvailable) {
						if (slave.boobs < 50000) {
							procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "hyper fillable", "hyper fillable", Math.round(curSize / 1000) * 1000));
						}
					}
				} else if (curSize > 2200) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "advanced fillable", "advanced fillable", Math.round(curSize / 400) * 400, true));
				} else if (curSize > 400) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "fillable", "fillable", Math.round(curSize / 200) * 200));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "standard", "normal", 400));
				}
			}
		}

		if (options.reduction && (slave.boobs > 300 || curSize > 0)) {
			if (curSize > 0) {
				if (areStringsInstalled && curSize > 400) {
					if (curSize > 8000) {
						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 1000));
					} else if (curSize > 5000) {
						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 750));
					} else if (curSize > 2000) {
						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 500));
					} else if (curSize > 1000) {
						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 250));
					} else if (curSize > 500) {
						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 100));
					}
				} else if (areFillablesInstalled) {
					if (implantType === "hyper fillable") {
						if (curSize <= 10000) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 1000));
						}
					} else if (implantType === "advanced fillable") {
						if (curSize <= 1000) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 500));
						}
					} else if (implantType === "fillable") {
						if (curSize <= 500) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 100));
						}
					}
				}
				if (slave.indentureRestrictions < 2) {
					procedures.push(new App.Medicine.Surgery.Procedures.RemoveBoobImplants(slave));
				}
			}
			if ((slave.boobs > 300) && (curSize === 0) && slave.indentureRestrictions < 2) {
				procedures.push(new App.Medicine.Surgery.Procedures.ReduceBoobs(slave, "reduce", 200));
				if (slave.boobs < 675) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReduceBoobs(slave, "slightly reduce", 25));
				}
			}
			if ((curSize === 0) && slave.indentureRestrictions < 2 && (slave.breedingMark !== 1 || V.propOutcome !== 1 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
				if (slave.boobs >= 2000) {
					procedures.push(new App.Medicine.Surgery.Procedures.Mastectomy(slave));
				}
			}
		}
		return procedures;
	}

	/**
	 * @param {App.Entity.SlaveState} slave
	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
	 * @returns {App.Medicine.Surgery.Procedure[]}
	 */
	function buttSizingProcedures(slave, options = {}) {
		const thisArcology = V.arcologies[0];
		const largeImplantsAvailable = thisArcology.FSTransformationFetishistResearch === 1;
		const advancedSurgeryAvailable = V.ImplantProductionUpgrade === 1;
		const {His} = getPronouns(slave);

		const areStringsInstalled = slave.buttImplantType === "string";
		const areFillablesInstalled = ["fillable", "advanced fillable", "hyper fillable"].includes(slave.buttImplantType);
		const curSize = slave.buttImplant;
		const implantType = slave.buttImplantType;

		/**
		 * @type {Array<App.Medicine.Surgery.Procedure>}
		 */
		let procedures = [];
		if (options.augmentation) {
			if (slave.indentureRestrictions >= 2) {
				procedures.push(new ForbiddenDummy("Change butt size", `${His} indenture forbids elective surgery.`));
			} else if (slave.butt > 19 && areFillablesInstalled) {
				procedures.push(new ForbiddenDummy("Increase butt", `${His} butt is as large as it can possibly get.`));
			} else if (curSize === 0) {
				if (options.strings) {
					procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "string", "string", 1));
				}
				if (advancedSurgeryAvailable) {
					procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "big", "normal", 2));
				}
				procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "standard", "normal", 1));
			} else if (implantType === "normal") {
				if (curSize >= 5) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", curSize, true));
				} else if (curSize >= 2) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "fillable", "fillable", 3));
				} else if (curSize === 1) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "bigger", "normal", 2));
				}
			} else if (implantType === "hyper fillable") {
				if (curSize > 19) {
					procedures.push(new ForbiddenDummy("Increase butt", `${His} butt implants are filled to capacity.`));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
				}
			} else if (implantType === "advanced fillable") {
				if (curSize > 7) {
					procedures.push(new ForbiddenDummy("Increase butt", `${His} butt implants are filled to capacity.`));
					if (largeImplantsAvailable) {
						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "hyper fillable", "hyper fillable", 9));
					}
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
				}
			} else if (implantType === "fillable") {
				if (curSize >= 4) {
					procedures.push(new ForbiddenDummy("Increase size", `${His} implants are filled to capacity.`));
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", 5, true));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
				}
			}
		}

		if (options.replace && slave.indentureRestrictions < 2 && curSize > 0) {
			if (!areStringsInstalled && curSize === 1) {
				procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "string", "string", 1));
			} else if (areStringsInstalled) {
				// we have engorged string implants, suggest replacing with normal implants of similar size
				if (curSize >= 9) {
					if (largeImplantsAvailable) {
						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "hyper fillable", "hyper fillable", curSize));
					}
				} else if (curSize >= 5) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", curSize, true));
				} else if (curSize >= 3) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "fillable", "fillable", curSize));
				} else if (curSize === 2) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "big", "normal", curSize));
				} else {
					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "standard", "normal", curSize));
				}
			}
		}

		if (options.reduction) {
			if (curSize > 0) {
				if (areStringsInstalled && curSize > 1) {
					procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
				} else if (areFillablesInstalled) {
					if (implantType === "hyper fillable") {
						if (curSize <= 5) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
						}
					} else if (implantType === "advanced fillable") {
						if (curSize <= 3) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
						}
					} else if (implantType === "fillable") {
						if (curSize <= 1) {
							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
						} else {
							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
						}
					}
				}
				if (slave.indentureRestrictions < 2) {
					procedures.push(new App.Medicine.Surgery.Procedures.RemoveButtImplants(slave));
				}
			}
			if ((slave.butt > 1) && (curSize === 0)) {
				if (slave.indentureRestrictions < 2) {
					procedures.push(new App.Medicine.Surgery.Procedures.ReduceButt(slave, "reduce", 1));
				}
			}
		}
		return procedures;
	}
}();

/**
 * Clean up extremities on removal or piercings, tats, and brands
 * For limbs use removeLimbs()
 * @param {App.Entity.SlaveState} slave
 * @param {string} part
 * @param {boolean} [cheat]
 */
globalThis.surgeryAmp = function(slave, part, cheat = false) {
	switch (part) {
		case "left ear":
			delete slave.brand["left ear"];
			slave.earShape = "none";
			slave.earT = "none";
			slave.earPiercing = 0;
			surgeryDamage(slave, 10, cheat);
			break;
		case "right ear":
			delete slave.brand["right ear"];
			slave.earShape = "none";
			slave.earT = "none";
			slave.earPiercing = 0;
			surgeryDamage(slave, 10, cheat);
			break;
		case "dick":
			slave.dick = 0;
			slave.foreskin = 0;
			slave.skill.vaginal = 0;
			slave.dickPiercing = 0;
			slave.dickTat = 0;
			slave.dickAccessory = "none";
			slave.chastityPenis = 0;
			surgeryDamage(slave, 20, cheat);
			break;
		case "vagina":
			slave.vagina = -1;
			slave.ovaries = 0;
			slave.preg = -2;
			slave.pregSource = 0;
			slave.skill.vaginal = 0;
			slave.vaginaTat = 0;
			slave.vaginalAccessory = "none";
			slave.vaginalAttachment = "none";
			slave.chastityVagina = 0;
			if (slave.cervixImplant === 1) {
				slave.cervixImplant = 0;
			} else if (slave.cervixImplant === 3) {
				slave.cervixImplant = 2;
			}
			surgeryDamage(slave, 20, cheat);
			break;
		case "horn":
			slave.horn = "none";
			slave.hornColor = "none";
			surgeryDamage(slave, 10, cheat);
			break;
		case "voicebox":
			slave.voice = 0;
			slave.voiceImplant = 0;
			surgeryDamage(slave, 10, cheat);
			break;
		case "lips":
			slave.lips -= slave.lipsImplant;
			slave.lipsImplant = 0;
			if (slave.skill.oral > 10) {
				slave.skill.oral -= 10;
			}
			break;
		default:
			// eslint-disable-next-line no-console
			console.log(`ERROR: Unknown amputation type: ` + part);
	}
};

/**
 * @param {FC.HumanState} slave
 * @param {"both"|"left"|"right"} side
 * @param {"normal"|"glass"|"cybernetic"|"remove"|"blind"|"blur"|"fix"} action
 */
globalThis.eyeSurgery = function(slave, side, action) {
	if (side === "both") {
		eyeSurgery(slave, "left", action);
		eyeSurgery(slave, "right", action);
		return;
	}

	if (side !== "left" && side !== "right") {
		return;
	} // make sure side can be used to access the object
	const eyeExists = slave.eye[side] !== null;

	/* actions that don't need an eye */
	switch (action) {
		case "normal":
			addEye(slave); // color overwritten by genetics
			return;
		case "glass":
			if (!eyeExists) { // color stays the same if possible
				addEye(slave);
			}
			slave.eye[side].type = 2;
			slave.eye[side].vision = 0;
			return;
		case "cybernetic":
			if (!eyeExists) { // color stays the same if possible
				addEye(slave);
			}
			slave.eye[side].type = 3;
			slave.eye[side].vision = 2;
			return;
		case "remove":
			if (eyeExists) {
				slave.eye[side] = null;
			}
			return;
		case "blind":
			if (eyeExists) {
				slave.eye[side].vision = 0;
			}
			return;
		case "blur":
			if (eyeExists) {
				slave.eye[side].vision = 1;
			}
			return;
		case "fix":
			if (eyeExists) {
				slave.eye[side].vision = 2;
			}
			return;
		default:
			throw Error(`${typeof action} "${action}" not found`);
	}

	function addEye(slave) {
		slave.eye[side] = new App.Entity.SingleEyeState();
		resetEyeColor(slave, side);
	}
};

/**
 * To be used during slave generation or slave styling (auto salon)
 *
 * @param {App.Entity.SlaveState} slave
 * @param {string} color to set eye to
 * @param {string} [side] "left", "right", "both"
 */
globalThis.setEyeColor = function(slave, color, side = "both") {
	if (side === "both") {
		setEyeColor(slave, color, "left");
		setEyeColor(slave, color, "right");
		return;
	}

	if (side !== "left" && side !== "right") {
		return;
	}

	slave.eye[side].iris = color;
};

/**
 * Set all colors of the eye.
 *
 * @param {FC.HumanState} slave
 * @param {string} iris
 * @param {string} pupil
 * @param {string} sclera
 * @param {string} side
 */
globalThis.setEyeColorFull = function(slave, iris = "brown", pupil = "circular", sclera = "white", side = "both") {
	if (side === "both") {
		setEyeColorFull(slave, iris, pupil, sclera, "left");
		setEyeColorFull(slave, iris, pupil, sclera, "right");
		return;
	}

	if (side !== "left" && side !== "right") {
		return;
	}

	if (iris !== "") {
		slave.eye[side].iris = iris;
	}
	if (pupil !== "") {
		slave.eye[side].pupil = pupil;
	}
	if (sclera !== "") {
		slave.eye[side].sclera = sclera;
	}
};

/**
 * Set genetic eye color
 *
 * @param {App.Entity.SlaveState} slave
 * @param {string} color
 * @param {boolean} heterochromia
 */
globalThis.setGeneticEyeColor = function(slave, color, heterochromia = false) {
	if (heterochromia) {
		slave.geneticQuirks.heterochromia = color;
	} else {
		slave.eye.origColor = color;
	}
};

/**
 * Sets the eye color to the genetic color.
 * Takes heterochromia and albinism into account.
 *
 * @param {FC.HumanState} slave
 * @param {string} [side]
 */
globalThis.resetEyeColor = function(slave, side = "both") {
	if (side === "both") {
		resetEyeColor(slave, "left");
		resetEyeColor(slave, "right");
		return;
	}

	if (side !== "left" && side !== "right") {
		return;
	}

	slave.eye[side].iris = getGeneticEyeColor(slave, side);
	slave.eye[side].pupil = "circular";
	slave.eye[side].sclera = "white";
};

/**
 * @param {App.Entity.SlaveState} slave
 * @param {FC.GeneticQuirk} level
 */
globalThis.induceAlbinism = function(slave, level) {
	slave.geneticQuirks.albinism = level;
	if (level < 2) {
		slave.albinismOverride = null;
		return;
	}
	slave.albinismOverride = makeAlbinismOverride(slave.race);
};

/**
 * Allowed values for limb:
 * left arm, right arm, left leg, right leg, all
 *
 * @param {App.Entity.SlaveState} slave
 * @param {FC.LimbArgumentAll} limb
 */
globalThis.removeLimbs = function(slave, limb) {
	function remove(limb, side) {
		const prosthetic = findProsthetic(slave, limbToProsthetic(slave[limb][side].type));

		if (prosthetic) {
			prosthetic[limb][side] = slave[limb][side];
		}

		slave[limb][side] = null;
	}

	function cleanLegs() {
		if (!hasAnyLegs(slave)) {
			slave.legsTat = 0;
			slave.shoes = "none";
			slave.legAccessory = "none";
			slave.heels = 0;
			if (slave.heightImplant !== 0) {
				slave.height -= slave.heightImplant * 10;
			}
			slave.heightImplant = 0;
		}
	}

	switch (limb) {
		case "left arm":
			if (!hasLeftArm(slave)) {
				return;
			}
			remove("arm", "left");
			delete slave.brand["left upper arm"];
			delete slave.brand["left lower arm"];
			delete slave.brand["left wrist"];
			delete slave.brand["left hand"];
			// slave.armsTat = 0;
			if (!hasAnyArms(slave)) {
				slave.armAccessory = "none";
				// slave.nails = 0;
			}
			break;
		case "right arm":
			if (!hasRightArm(slave)) {
				return;
			}
			remove("arm", "right");
			delete slave.brand["right upper arm"];
			delete slave.brand["right lower arm"];
			delete slave.brand["right wrist"];
			delete slave.brand["right hand"];
			// slave.armsTat = 0;
			if (!hasAnyArms(slave)) {
				slave.armAccessory = "none";
				// slave.nails = 0;
			}
			break;
		case "left leg":
			if (!hasLeftLeg(slave)) {
				return;
			}
			remove("leg", "left");
			delete slave.brand["left thigh"];
			delete slave.brand["left calf"];
			delete slave.brand["left ankle"];
			delete slave.brand["left foot"];
			cleanLegs();
			break;
		case "right leg":
			if (!hasRightLeg(slave)) {
				return;
			}
			remove("leg", "right");
			delete slave.brand["right thigh"];
			delete slave.brand["right calf"];
			delete slave.brand["right ankle"];
			delete slave.brand["right foot"];
			cleanLegs();
			break;
		case "all":
			removeLimbs(slave, "left arm");
			removeLimbs(slave, "right arm");
			removeLimbs(slave, "left leg");
			removeLimbs(slave, "right leg");
			break;
	}
};

/**
 * Expects amputated limbs. Will overwrite existing limbs.
 *
 * Allowed values for limb:
 * left arm, right arm, left leg, right leg, all
 *
 * @param {App.Entity.SlaveState} slave
 * @param {FC.LimbArgumentAll} limb
 * @param {number} id
 */
globalThis.attachLimbs = function(slave, limb, id) {
	function attach(limb, side) {
		let prosthetic = findProsthetic(slave, limbToProsthetic(id));

		if (prosthetic) {
			slave[limb][side] = prosthetic[limb][side];
		} else {
			slave[limb][side] = new App.Entity.LimbState();
			slave[limb][side].type = id;
		}
	}

	switch (limb) {
		case "left arm":
			attach("arm", "left");
			break;
		case "right arm":
			attach("arm", "right");
			break;
		case "left leg":
			attach("leg", "left");
			break;
		case "right leg":
			attach("leg", "right");
			break;
		case "all":
			attachLimbs(slave, "left arm", id);
			attachLimbs(slave, "right arm", id);
			attachLimbs(slave, "left leg", id);
			attachLimbs(slave, "right leg", id);
			break;
		default:
			// eslint-disable-next-line no-console
			console.log(`ERROR: Unknown attach point: ` + limb);
	}
};

globalThis.upgradeLimbs = function(slave, newId) {
	let changed = false;

	/**
	 * @param {number} oldId
	 * @returns {number}
	 */
	function computeUpgrade(oldId) {
		if (newId < 2) {
			return oldId;
		} else if (newId === 2 && oldId === 0) {
			return 2;
		} else if (newId < 6 && oldId <= 2) {
			return newId;
		} else if (newId > oldId) {
			return newId;
		} else {
			return oldId;
		}
	}

	/**
	 * @param {FC.LimbArgumentAll} limb
	 * @param {function(App.Entity.SlaveState): number} idFunction
	 */
	function upgradeLimb(limb, idFunction) {
		let oldId = idFunction(slave);
		if (oldId === 1) {
			return;
		}
		if (oldId > 1) {
			removeLimbs(slave, limb);
		}
		if (newId > 1) {
			attachLimbs(slave, limb, computeUpgrade(oldId));
		}
		if (oldId !== idFunction(slave)) {
			changed = true;
		}
	}

	upgradeLimb("left arm", getLeftArmID);
	upgradeLimb("right arm", getRightArmID);
	upgradeLimb("left leg", getLeftLegID);
	upgradeLimb("right leg", getRightLegID);

	return changed;
};

/**
 * Changes a slaves limbs to the specified value AND sets all related variables.
 * Intended for giving prosthetics during slave generation and events.
 *
 * @param {App.Entity.SlaveState} slave
 * @param {FC.LimbArgumentAll} limb
 * @param {number} id
 * @param {boolean} clean if the slave should be cleaned of all existing
 */
globalThis.configureLimbs = function(slave, limb, id, clean = false) {
	if (limb === "all") {
		configureLimbs(slave, "left arm", id);
		configureLimbs(slave, "right arm", id);
		configureLimbs(slave, "left leg", id);
		configureLimbs(slave, "right leg", id);
		return;
	}

	if (clean) {
		slave.PLimb = 0;
		slave.readyProsthetics = [];
	}

	let p = limbToProsthetic(id);
	if (p) {
		addProsthetic(slave, p);
	}

	if (id >= 6 && slave.PLimb < 2) {
		slave.PLimb = 2;
		addProsthetic(slave, "interfaceP2");
	} else if (id >= 2 && slave.PLimb < 1) {
		slave.PLimb = 1;
		addProsthetic(slave, "interfaceP1");
	}

	switch (limb) {
		case "left arm":
			if (id !== getLeftArmID(slave)) {
				removeLimbs(slave, "left arm");
				if (id > 0) {
					attachLimbs(slave, "left arm", id);
				}
			}
			break;
		case "right arm":
			if (id !== getRightArmID(slave)) {
				removeLimbs(slave, "right arm");
				if (id > 0) {
					attachLimbs(slave, "right arm", id);
				}
			}
			break;
		case "left leg":
			if (id !== getLeftLegID(slave)) {
				removeLimbs(slave, "left leg");
				if (id > 0) {
					attachLimbs(slave, "left leg", id);
				}
			}
			break;
		case "right leg":
			if (id !== getRightLegID(slave)) {
				removeLimbs(slave, "right leg");
				if (id > 0) {
					attachLimbs(slave, "right leg", id);
				}
			}
			break;
	}
};

/**
 * Prepare and set up for new Fuckdoll
 * @param {App.Entity.SlaveState} slave
 */
globalThis.beginFuckdoll = function(slave) {
	slave.fuckdoll = 1;
	slave.toyHole = "all her holes";
	if ((slave.pubicHStyle !== "bald") && (slave.pubicHStyle !== "hairless")) {
		slave.pubicHStyle = "waxed";
	}
	slave.rules.living = "spare";
	slave.rules.speech = "restrictive";
	slave.rules.release.masturbation = 0;
	slave.rules.release.facilityLeader = 0;
	slave.rules.release.partner = 0;
	slave.rules.release.family = 0;
	slave.rules.release.slaves = 0;
	slave.rules.relationship = "restrictive";
	slave.choosesOwnClothes = 0;
	slave.clothes = "a Fuckdoll suit";
	slave.collar = "none";
	slave.faceAccessory = "none";
	slave.mouthAccessory = "none";
	if ((!hasAnyLegs(slave)) || (slave.shoes !== "none")) {
		slave.shoes = "heels";
	}
	slave.armAccessory = "none";
	slave.legAccessory = "none";
	slave.vaginalAccessory = "none";
	slave.vaginalAttachment = "none";
	slave.dickAccessory = "none";
	slave.buttplug = "none";
	slave.chastityAnus = 0;
	slave.chastityPenis = 0;
	slave.chastityVagina = 0;
	slave.attrKnown = 1;
	slave.fetishKnown = 1;
	slave.subTarget = 0;
	slave.sentence = 0;
	slave.training = 0;
	deflate(slave);
};

/**
 * Calculates the added artificiality a face surgery introduces.
 *
 * @returns {number}
 */
globalThis.faceSurgeryArtificiality = function() {
	return 25
		- (5 * Math.trunc(V.PC.skill.medicine / 50))
		- (10 * V.surgeryUpgrade);
};


code:
/**
 * @param {App.Entity.SlaveState} slave
 * @returns {HTMLElement|DocumentFragment}
 */
App.UI.SlaveInteract.surgeryDegradation = function(slave) {
	const el = new DocumentFragment();
	let r = [];
	const {his, him} = getPronouns(slave);

	/* disallow surgery for slaves on certain assignments */
	// TODO: do this before apply, this is too late
	switch (slave.assignment) {
		case "be your agent":
		case "live with your agent":
			return App.UI.DOM.makeElement("span", `You must retrieve ${slave.slaveName} from ${his} assignment before performing surgery on ${him}.`, "red");
	}

	// TODO: do this during apply
	if (slave.dick === 0) {
		if (slave.vagina === -1) {
			slave.clitPiercing = 0;
		}
		if (slave.drugs === "penis enhancement" || slave.drugs === "hyper penis enhancement" || slave.drugs === "breast redistributors") {
			slave.drugs = "no drugs";
		}
	}
	if (slave.balls === 0) {
		if (slave.drugs === "testicle enhancement" || slave.drugs === "hyper testicle enhancement" || slave.drugs === "testicle atrophiers") {
			slave.drugs = "no drugs";
		}
	}

	// Search for Reaction class and apply if there is one.
	if (App.Medicine.Surgery.ReactionsMap.has(V.surgeryType)) {
		const reaction = App.Medicine.Surgery.ReactionsMap.get(V.surgeryType);

		if (reaction.invasive && slave.health.condition < random(-100, -80)) {
			r.push(`${slave.slaveName} <span class="health dec">has died from complications of surgery.</span>`);
			App.Events.addParagraph(el, r);
			removeSlave(slave);
			V.nextLink = "Main";
			return el;
		}

		if (reaction.removeJob) {
			removeJob(slave, Job.LURCHER, true);
			removeJob(slave, Job.PIT, true);
			removeJob(slave, slave.assignment);
		}

		r.push(...reaction.intro(slave, {}));

		const resultMain = reaction.reaction(slave, {});
		for (const p of resultMain.longReaction) {
			r.push(...p);
			App.Events.addParagraph(el, r);
			r = [];
		}
		slave.devotion += resultMain.devotion;
		slave.trust += resultMain.trust;

		const resultOutro = reaction.outro(slave, {}, resultMain);
		for (const p of resultOutro.longReaction) {
			r.push(...p);
			App.Events.addParagraph(el, r);
			r = [];
		}
		slave.devotion += resultOutro.devotion;
		slave.trust += resultOutro.trust;

		return el;
	} else {
		r.push(`<span class="error">ERROR bad/missing surgery description</span>`);
		r.push(`surgeryType: ${V.surgeryType}`);
		App.Events.addParagraph(el, r);
	}

	return null;
};

// switch (V.surgeryType) {
/*
case "ampA1":
	if (slave.fetish === "mindbroken") {
		r.push(`You're there to help ${him} with the door as ${he} exits the surgery. ${He} smiles dumbly at your generosity, already seeming to forget ${he} ever had another arm. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 50) {
		r.push(`You're there to help ${him} with the door as ${he} exits the surgery. ${He} knows what a slave's life is, but ${he} did not really expect that it would ever come to this for ${him}. After a short, silent`);
		if (canSee(slave)) {
			r.push(`stare at`);
		} else {
			r.push(`consideration of`);
		}
		r.push(`the stump that was once ${his} arm, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 20) {
		r.push(`You're there to help ${him} with the door as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} shoulder occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is immensely afraid of your total power over ${his} body.`);
		slave.trust -= 8;
		slave.devotion -= 8;
	} else {
		r.push(`You're there to help ${him} with the door as ${he} exits the surgery. You had a good idea what ${his} reaction would be, so you've made sure to bind ${his} other arm`);
		if (hasAnyLegs(slave)) {
			r.push(`and ${his} ${(hasBothLegs(slave)) ? `legs` : `leg`}`);
		}
		r.push(`to prevent ${him} from trying to attack you, and`);
		if (slave.teeth === "removable") {
			r.push(`remove ${his} teeth`);
		} else {
			r.push(`muzzle ${him}`);
		}
		r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
		if (canSee(slave)) {
			r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
		} else {
			r.push(`shoulder stump twitches pathetically with ${his} desperate efforts to move ${his} missing arm, to prove there is something other than this.`);
		}
		r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is incredibly and intensely terrified of your total power over ${his} body.`);
		slave.trust -= 20;
		slave.devotion -= 20;
	}
	break;
 */
/*
case "ampA2":
	if (slave.fetish === "mindbroken") {
		r.push(`You're there to open the door for ${him} as ${he} exits the surgery. ${He} smiles dumbly at your generosity, already seeming to forget the sensation of touching. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 50) {
		r.push(`You're there to open the door for ${him} as ${he} exits the surgery. ${He} knows what a slave's life is, but ${he} did not really expect that it would ever come to this for ${him}. After a short, silent`);
		if (canSee(slave)) {
			r.push(`stare at`);
		} else {
			r.push(`consideration of`);
		}
		r.push(`the two stumps that were once ${his} arms, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 20) {
		r.push(`You're there to open the door for ${him} as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, ${his} shoulder stumps occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is extremely afraid of your total power over ${his} body.`);
		slave.trust -= 15;
		slave.devotion -= 15;
	} else {
		r.push(`You're there to open the door for ${him} as ${he} exits the surgery. You had a good idea what ${his} reaction would be, so you've made sure to bind ${his} ${(hasBothLegs(slave)) ? `legs` : `leg`} to prevent ${him} from trying to attack you, and`);
		if (slave.teeth === "removable") {
			r.push(`remove ${his} teeth`);
		} else {
			r.push(`muzzle ${him}`);
		}
		r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
		if (canSee(slave)) {
			r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
		} else {
			r.push(`shoulder stumps twitch pathetically with ${his} desperate efforts to move ${his} arms, to prove there is something other than this.`);
		}
		r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is utterly and entirely terrified of your total power over ${his} body.`);
		slave.trust -= 40;
		slave.devotion -= 40;
	}
	break;
	 */
/*
case "ampL1":
	if (slave.fetish === "mindbroken") {
		r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to walk alongside ${him}. ${He} leans into you the entire time, already seeming to forget ${he} ever had another leg. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 50) {
		r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to walk alongside ${him}. ${He} knows what a slave's life is, but ${he} did not really expect that it would involve this. After a brief, silent`);
		if (canSee(slave)) {
			r.push(`stare at`);
		} else {
			r.push(`consideration of`);
		}
		r.push(`the stump that was once ${his} leg, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 20) {
		r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to walk alongside ${him}. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} hip occasionally moving as ${he} reflexively tries to use it somehow. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is immensely afraid of your total power over ${his} body.`);
		slave.trust -= 5;
		slave.devotion -= 5;
	} else {
		r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to carry ${him}. You had a good idea what ${his} reaction would be, so you've made sure to bind ${his} other leg`);
		if (hasAnyArms(slave)) {
			r.push(`and ${his} ${(hasBothArms(slave)) ? `arms` : `arm`}`);
		}
		r.push(`to prevent ${him} from trying to attack you, and`);
		if (slave.teeth === "removable") {
			r.push(`remove ${his} teeth`);
		} else {
			r.push(`muzzle ${him}`);
		}
		r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
		if (canSee(slave)) {
			r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
		} else {
			r.push(`leg stump twitches pathetically with ${his} desperate efforts to move ${his} missing leg, to prove there is something other than this.`);
		}
		r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is incredibly and intensely terrified of your total power over ${his} body.`);
		slave.trust -= 15;
		slave.devotion -= 15;
	}
	break;
	 */
/*
case "ampL2":
	if (slave.fetish === "mindbroken") {
		r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} holds onto you the entire time, already seeming to forget the sensation of walking. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 50) {
		r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect that it would involve this. After a brief, silent`);
		if (canSee(slave)) {
			r.push(`stare at`);
		} else {
			r.push(`consideration of`);
		}
		r.push(`the two stumps that were once ${his} legs, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
	} else if (slave.devotion > 20) {
		r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, ${his} hip stumps occasionally moving as ${he} reflexively tries to stand up and walk around. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is extremely afraid of your total power over ${his} body.`);
		slave.trust -= 10;
		slave.devotion -= 10;
	} else {
		r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. You had a good idea what ${his} reaction would be, so you've made sure to bind ${his} ${(hasBothArms(slave)) ? `arms` : `arm`} to prevent ${him} from trying to attack you, and`);
		if (slave.teeth === "removable") {
			r.push(`remove ${his} teeth`);
		} else {
			r.push(`muzzle ${him}`);
		}
		r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
		if (canSee(slave)) {
			r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
		} else {
			r.push(`hip stumps twitch pathetically with ${his} desperate efforts to move ${his} legs, to prove there is something other than this.`);
		}
		r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is utterly and entirely terrified of your total power over ${his} body.`);
		slave.trust -= 30;
		slave.devotion -= 30;
	}
	break;
 */
/*
case "amp":
if (slave.fetish === "mindbroken") {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} squirms the entire time, trying to move the arms and legs ${he} now lacks. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 50) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect that it would ever come to this for ${him}. After a long, silent`);
if (canSee(slave)) {
r.push(`stare at`);
} else {
r.push(`consideration of`);
}
r.push(`${his} limbless torso, ${he} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 20) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} will never do again. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is cripplingly afraid of your total power over ${his} body.`);
slave.trust -= 20;
slave.devotion -= 20;
} else {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. You had a good idea what ${his} reaction would be, so`);
if (slave.teeth === "removable") {
r.push(`you removed ${his} teeth`);
} else {
r.push(`${he}'s muzzled`);
}
r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
if (canSee(slave)) {
r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
} else {
r.push(`stumps twitch pathetically with ${his} desperate efforts to move ${his} limbs, to prove there is something other than this.`);
}
r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is terrified to the point of insanity of your total power over ${his} body.`);
slave.trust -= 50;
slave.devotion -= 50;
}

break;
case "amp1":
V.nextLink = "Surgery Degradation", V.surgeryType = "amp";
r.push(`Since you have already have a prosthetic interface prepared for this slave, you can install it during the operation.<br>`);
r.push(`The procedure will put additional strain on ${his} health but less so than if you were to perform the procedures separately.`);
if (isProstheticAvailable(slave, "interfaceP1")) {

[[Install basic interface|Surgery Degradation][slave.PLimb = 1, slave.health.condition -= 10, V.surgeryType = "amp2", V.nextLink = "Surgery Degradation"]]
}
if (isProstheticAvailable(slave, "interfaceP2")) {

[[Install advanced interface|Surgery Degradation][slave.PLimb = 2, slave.health.condition -= 10, V.surgeryType = "amp2", V.nextLink = "Surgery Degradation"]]
}

break;
case "amp2":
if (slave.fetish === "mindbroken") {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} squirms the entire time trying to move the arms and legs ${he} now lacks, never noticing the ports in ${his} stumps. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 50) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect that it would ever come to this for ${him}. Anesthesia has yet to completely wear off so it takes ${him} a while to notice ports in ${his} stumps. When ${he} does, ${he} visibly relaxes, realizing ${he} may yet walk again. ${He} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 20) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} will never do again. ${He} slightly calms down when ${he}`);
if (canSee(slave)) {
r.push(`sees`);
} else {
r.push(`feels`);
}
r.push(`ports installed in ${his} stumps and realizes ${his} immobility is not permanent. Even so, ${he} is still terrified of your total power over ${his} body. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected.`);
slave.trust -= 10;
slave.devotion -= 10;
} else {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. You had a good idea what ${his} reaction would be, so`);
if (slave.teeth === "removable") {
r.push(`you removed ${his} teeth`);
} else {
r.push(`${he}'s muzzled`);
}
r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
if (canSee(slave)) {
r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
} else {
r.push(`stumps twitch pathetically with ${his} desperate efforts to move ${his} limbs, to prove there is something other than this.`);
}
r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is terrified to the point of insanity of your total power over ${his} body.`);
slave.trust -= 50;
slave.devotion -= 50;
}

V.prostheticsConfig = "interface";
<<include "Prosthetics Configuration">>
V.nextLink = "Remote Surgery";
break;
*/
/* This was moved to prostheticsConfig.tw
case "basicPLimbs":
r.push(`${He} exits the surgery hesitantly, the software of ${his} prosthetic limbs and the wetware of ${his} brain working together to figure out how to walk together under the tutelage of a prescribed tutorial. Recovery will be significant, since the surgical implantation of anchor points for the limbs themselves and the installation of nerve impulse detectors constituted major surgery.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion > 20) {
		r.push(`Nevertheless, ${he}'s overwhelmed with gratitude, and thanks you profusely the first chance ${he} gets. ${He} follows the acclimation program diligently, doing ${his} best to learn how to be a good slave despite, or sometimes even because of, ${his} artificial arms and legs. ${He} places more trust in you, too, since you obviously have ${his} best interests at heart.`);
		slave.devotion += 5;
slave.trust += 5;
	} else if (slave.devotion >= -20) {
		r.push(`${He}'s overwhelmed with gratitude, in part because ${he} didn't think you'd do something like this for ${him}. ${He} thanks you profusely the first chance ${he} gets, and follows the acclimation program diligently, trying to deserve the expense you went to. ${He} places more trust in you, too, since you seem to have a plan for ${him}.`);
		slave.devotion += 5;
slave.trust += 5;
	} else {
		r.push(`Despite ${his} hatred of you, ${he} can't help but trust you a bit more, since you clearly have a plan that involves putting a good deal of value into ${him}. Your goals might not be ${hers}, but at least ${he} has an indication that you're not toying with ${him}.`);
		slave.trust += 5;
	}
}

break;
case "sexPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery experimenting with ${his} new arms and legs.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He} rapidly discovers that ${his} fingertips are now vibrators, and then makes a mess when ${he} figures out that ${his} hands can dispense lube without figuring out how to make them stop dispensing lube. ${He}'s frustrated and frightened, realizing that even ${his} prosthetics are now customized to suit ${his} purpose as a human sex toy. ${He} knew ${he} was a toy before, but somehow, being a literal vibrator is a bit much for ${him}.`);
		slave.trust -= 5;
	} else if (slave.energy > 95) {
		r.push(`Since ${he}'s a nympho, ${he} discovers ${his} new sexual functions in a hurry. They trigger in part is based on arousal, and ${he}'s never not aroused, so they activate one by one as ${he} leaves the surgery. The vibration, lube, and other dirty functions surprise ${him}, and it takes ${him} a moment to realize what's going on, but ${he} begins to breathe hard when ${he} understands. ${He} runs off to try them out, and thanks you profusely, if tiredly, the next time ${he} sees you.`);
		slave.devotion += 5;
	} else {
		r.push(`${He} discovers ${his} sexy new functions one by one. The vibration, lube, and other dirty functions surprise ${him}, and it takes ${him} a moment to realize what's going on, but ${he} begins to shake with amusement when ${he} understands. ${He} heads off to try them out, and thanks you politely the next time ${he} sees you.`);
		slave.devotion += 3;
	}
}

break;
case "beautyPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery`);
if (canSee(slave)) {
r.push(`marveling at the beautiful, natural appearance of ${his} new arms and legs.`);
} else {
r.push(`thanking you for ${his} new arms and legs, unaware of how natural they look.`);
}
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s <span class="mediumaquamarine">more willing to trust you</span> after this. If ${he} doubts that you have some sort of long term plan for ${him}, all ${he} has to do is`);
if (canSee(slave)) {
r.push(`look down and examine`);
} else {
r.push(`feel`);
}
r.push(`${his} elegant, natural prosthetics, which are often mistaken for the genuine article. Even ${he} makes the mistake at times as ${he} gets used to them.`);
		slave.trust += 5;
	} else if (slave.skill.entertainment >= 100) {
		r.push(`Since ${he}'s a masterful entertainer, ${he} knows multiple styles of dance, though ${his} straightforward modern prosthetics never allowed ${him} to be anything more than a mechanically competent dancer. ${He} finds that ${he} has far better balance now, in addition to looking more natural. Before long, ${he} goes //en pointe// and holds the position, before collapsing in a heap. It soon becomes apparent that this wasn't due to clumsiness: ${he}'s sobbing so hard ${he} can barely breathe. ${He} thanks you profusely the next time ${he} sees you, eyes still puffy with tears of joy.`);
		slave.devotion += 5;
	} else {
		r.push(`When ${he} first`);
if (canSee(slave)) {
r.push(`catches sight of ${himself} in a mirror,`);
} else {
r.push(`runs a new finger over ${his} natural feeling skin,`);
}
r.push(`${he} begins to cry. Terribly complex emotions war across ${his} face: gratitude, joy, regret, and something undefinable. Blinking, ${he} uses newly elegant fingertips to trace the scarcely visible seams where ${his} artificial and natural skin meet. ${He} thanks you profusely the next time ${he} sees you, eyes still puffy with tears.`);
		slave.devotion += 3;
	}
}

break;
case "combatPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery wondering at the bulky`);
if (canSee(slave)) {
r.push(`appearance`);
} else {
r.push(`weight`);
}
r.push(`of ${his} reinforced arms and legs.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s frightened, once ${he} discovers what ${he} can do, and what ${he} is. ${His} integral weapons are locked out by the arcology systems, for now, but ${he} quickly realizes what they are. ${He} is not, to say the least, thrilled by the revelation that ${he} is now a living weapon, and is kept awake by thoughts of what you might be planning for ${him}.`);
		slave.trust -= 5;
	} else if (slave.skill.combat === 1) && (slave.devotion > 75) {
		r.push(`${He} leaves the surgery with a purpose, ${his} footsteps a bit heavier than before. ${He} heads down to the armory's range, still naked, and when ${he} gets there, ${he} places ${his} dominant hand over ${his} thigh on that side. It folds open, revealing a handgun, which ${he} draws and empties into a`);
if (canSee(slave)) {
r.push(`target`);
} else {
r.push(`beeping target`);
}; as ${he} fires the last rounds, ${he} uses ${his} off hand to reach down to that thigh, which folds open and reveals spare magazines. ${He} thanks you profusely the next time ${he} sees you. ${He} knows that ${his} prosthetics are a wash, at best, in terms of actual combat effectiveness; they'll never match the reliability and dexterity of the genuine article. But ${he} thinks they are //cool.//
		slave.devotion += 5;
	} else {
		r.push(`${He} has mixed feelings about what ${he} soon discovers. ${He}'s a living weapon now, and has to live with the constant knowledge that ${he} can incapacitate or kill with nothing more than what's contained within ${his} arms and legs. ${He}'s touched, though, by the tremendous trust this shows. ${He} knows that the arcology would instantly lock out ${his} weapons if ${he} were to misbehave, but ${he}'s still affected.`);
		slave.devotion += 3;
	}
}

break;
case "cyberPLimbs":
r.push(`${His} Limb upgrades were performed in the surgery, since its manipulators are well suited to delicate work on their circuitry as well as on flesh. ${He} exits the surgery marveling`);
if (canSee(slave)) {
r.push(`at the shiny artificial skin of ${his} new arms and legs.`);
} else {
r.push(`at the feel of the artificial skin of ${his} new arms and legs under ${his} new fingers.`);
}
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s frightened, once ${he} discovers what ${he} can do, and what ${he} is. ${His} cybernetic limbs are restricted by the arcology systems, for now, but ${he} quickly realizes what they are. ${He} is not, to say the least, thrilled by the revelation that ${he} is now a living weapon, and is kept awake by thoughts of what you might be planning for ${him}.`);
		slave.trust -= 5;
	} else if (slave.skill.combat === 1) && (slave.devotion > 75) {
		r.push(`${He} leaves the surgery with a purpose, ${his} footsteps a bit heavier than before. ${He} heads down to the armory's range, still naked, and when ${he} gets there, ${he} places ${his} dominant hand over ${his} thigh on that side. It folds open, revealing a handgun, which ${he} draws and empties into a`);
if (canSee(slave)) {
r.push(`target`);
} else {
r.push(`beeping target`);
}; as ${he} fires the last rounds, ${he} uses ${his} off hand to reach down to that thigh, which folds open and reveals spare magazines. ${He} thanks you profusely the next time ${he} sees you. ${He} knows that ${his} prosthetics will enhance ${his} combat effectiveness and ${he} thinks they are //cool.//
		slave.devotion += 5;
	} else {
		r.push(`${He} has mixed feelings about what ${he} soon discovers. ${He}'s a living weapon now, and has to live with the constant knowledge that ${he} can incapacitate or kill with nothing more than ${his} arms and legs themselves. ${He}'s touched, though, by the tremendous trust this shows. ${He} knows that the arcology would instantly lock out ${his} limbs if ${he} were to misbehave, but ${he}'s still affected.`);
		slave.devotion += 3;
	}
}

break;
case "removeLimbs":
if (slave.fetish === "mindbroken") {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} squirms the entire time trying to move the arms and legs that ${he} used to have. As with all surgery ${his} health has been slightly affected.`);
} else if (slave.devotion > 50) {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect ${his} artificial limbs would be removed again so suddenly. After a long, silent`);
if (canSee(slave)) {
r.push(`stare at`);
} else {
r.push(`consideration of`);
}
r.push(`${his} limbless torso, ${he} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. As ${he} was already amputated, there was no lasting effect. As with all surgery ${his} health has been slightly affected.`);
} else if (slave.devotion > 20) {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} had to learn to do again. Your removal of ${his} prosthetic limbs has caused ${his} devotion to drop and ${his} trust to drop. As with all surgery ${his} health has been slightly affected.`);
	slave.trust -= 5;
slave.devotion -= 5;
} else {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. It seems that ${his} mistrust of you was well founded and this removal of ${his} artificial limbs has caused ${his} devotion to drop and ${his} trust to drop. As with all surgery ${his} health has been slightly affected.`);
	slave.trust -= 5;
slave.devotion -= 5;
}
break;
*/
//	default:
//		r.push(`ERROR bad/missing surgery description`);
//		r.push(`surgeryType: ${V.surgeryType}`);
//		r.push(`Devotion: ${slave.devotion}`);
//


code:
App.UI.surrogacyWorkaround = function() {
	const node = new DocumentFragment();

	const donatrix = V.donatrix;
	const impregnatrix = V.impregnatrix;
	const receptrix = V.receptrix;

	let eligibility = 0;
	let eligibilityI = 0;
	let eligibility2 = 0;
	const donatrixID = (donatrix.ID === V.PC.ID) ? -1 : 0;

	let impreg;
	if (impregnatrix !== "undecided" && impregnatrix.ID === -1) {
		impreg = PlayerName();
	} else if (impregnatrix !== "undecided") {
		impreg = SlaveFullName(impregnatrix);
	} else {
		impreg = impregnatrix;
	}

	let receive;
	if (receptrix !== "undecided" && receptrix.ID === -1) {
		receive = PlayerName();
	} else if (receptrix !== "undecided") {
		receive = SlaveFullName(receptrix);
	} else {
		receive = receptrix;
	}

	App.UI.DOM.appendNewElement("p", node, `${(donatrixID === -1) ? `You've prepared yourself to have an egg taken from your ovaries;` : `${getSlave(V.AS).slaveName} is prepped to have an egg harvested from ${getPronouns(getSlave(V.AS)).possessive} ovaries;`} now you must select a target to fertilize it and who will carry it to term.`, "scene-intro");

	if (impreg !== "undecided" || receive !== "undecided") {
		const bearers = [];
		if (impreg !== "undecided") {
			bearers.push(`${impreg} will provide the seed`);
		}
		if (receive !== "undecided") {
			bearers.push(`${receive} shall carry it`);
		}
		App.UI.DOM.appendNewElement("div", node, `${toSentence(bearers)}.`);

		if (impreg !== "undecided" && receive !== "undecided") {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				"Implant fertilized ovum",
				() => {
					cashX(forceNeg(V.surgeryCost * 2), "slaveSurgery");
					V.surgeryType = "surrogacy";
					App.UI.reload();
				}, [], "Surrogacy",
			));
		}
	}

	App.UI.DOM.appendNewElement("h2", node, `Semen donatrix: ${impreg}`);

	for (const slave of V.slaves) {
		if (slave.balls > 0 && slave.pubertyXY === 1 && isSlaveAvailable(slave) && canBreed(donatrix, slave)) {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				SlaveFullName(slave),
				() => {
					V.impregnatrix = slave;
					App.UI.reload();
				}
			));
			eligibility = 1;
		}
	}
	if (eligibility === 0) {
		App.UI.DOM.appendNewElement("div", node, "You have no slaves with potent sperm.");
	}

	if (V.incubator.tanks.length > 0 && V.incubator.setting.reproduction === 2) {
		App.UI.DOM.appendNewElement("h2", node, `Incubator settings are resulting in large-scale fluid secretion. Select an eligible incubatee to milk for semen:`);

		for (const tank of V.incubator.tanks) {
			if (tank.balls > 0 && tank.dick > 0 && canBreed(donatrix, tank)) {
				App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
					tank.slaveName,
					() => {
						V.impregnatrix = tank;
						App.UI.reload();
					}
				));
				eligibilityI = 1;
			}
		}
		if (eligibilityI === 0) {
			App.UI.DOM.appendNewElement("div", node, "You have no growing slaves producing sperm.");
		}
	}

	if (V.PC.balls !== 0) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Use your own",
			() => {
				V.impregnatrix = V.PC;
				App.UI.reload();
			}
		));
	}

	App.UI.DOM.appendNewElement("h2", node, `Chosen surrogate: ${receive}`);

	for (const slave of V.slaves) {
		if (canBeReceptrix(slave)) {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				SlaveFullName(slave),
				() => {
					V.receptrix = slave;
					App.UI.reload();
				}, [], "",
				(slave.pregType >= 4) ? `Using a slave carrying multiples is inadvisable` : ``
			));
			eligibility2 = 1;
		}
	}
	if (eligibility2 === 0) {
		App.UI.DOM.appendNewElement("div", node, "You have no slaves capable of acting as a surrogate.");
	}

	if (V.PC.vagina !== -1 && V.PC.preg >= 0 && V.PC.preg < 4 && V.PC.pregType < 8 && V.PC.physicalAge < 70) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Use your own womb",
			() => {
				V.receptrix = V.PC;
				App.UI.reload();
			}
		));
	}

	return node;
};


code:
globalThis.assistant = (function() {
	return {
		BC: BC,
		object: manage,
		pronouns: pronouns,
	};

	function BC() {
		App.Update.assistantBC();
	}

	function pronouns() {
		let o = {};
		if (V.assistant.personality <= 0 || V.assistant.appearance === "normal") {
			o.main = o.market = {pronoun: App.Data.Pronouns.Kind.ai};
		} else {
			if (V.assistant.appearance === "incubus" && V.diversePronouns > 0) {
				o.main = {pronoun: App.Data.Pronouns.Kind.male};
				o.market = {pronoun: App.Data.Pronouns.Kind.female};
			} else if (V.assistant.appearance === "succubus" && V.diversePronouns > 0) {
				o.main = {pronoun: App.Data.Pronouns.Kind.female};
				o.market = {pronoun: App.Data.Pronouns.Kind.male};
			} else {
				o.main = o.market = {pronoun: App.Data.Pronouns.Kind.female};
			}
		}
		return o;
	}

	function manage() {
		V.assistant = V.assistant || {};
		Object.assign(V.assistant, {
			personality: V.assistant.personality || 0,
			name: V.assistant.name || "your personal assistant",
			power: V.assistant.power || 0,
			appearance: V.assistant.appearance || "normal",
		});

		if (V.assistant.market) {
			Object.assign(V.assistant.market, {
				relationship: V.assistant.market.relationship || "cute",
				limit: V.assistant.market.limit || 0,
				aggressiveness: V.assistant.market.aggressiveness || 0,
			});
		}
		if (V.week < 18) {
			delete V.assistant.options;
		}
	}
})();