diff --git a/js/medicine/surgery/assets/fatGraft.js b/js/medicine/surgery/assets/fatGraft.js
new file mode 100644
index 0000000000000000000000000000000000000000..f9a8bc45a38300d9b4547143fdaef06b7125664b
--- /dev/null
+++ b/js/medicine/surgery/assets/fatGraft.js
@@ -0,0 +1,218 @@
+App.Medicine.Surgery.Reactions.FatGraft = class extends App.Medicine.Surgery.SimpleReaction {
+	/**
+	 * @param {number} boobFat
+	 * @param {number} buttFat
+	 */
+	constructor(boobFat, buttFat) {
+		super();
+		this.boobFat = boobFat;
+		this.buttFat = buttFat;
+	}
+
+	reaction(slave, diff) {
+		const reaction = super.reaction(slave, diff);
+		const {He, he, his, him, himself} = getPronouns(slave);
+		const r = [];
+
+		if (slave.fetish === "mindbroken") {
+			r.push(`${He} notices that ${his} weight is slightly off, almost as if it were someplace else. As with all surgeries, <span class="health dec">${his} health has been affected.</span>`);
+		} else if (slave.behavioralFlaw === "anorexic") {
+			if (canSee(slave)) {
+				r.push(`${He} looks over ${his} new thin figure experimentally`);
+			} else {
+				r.push(`${He} shifts ${his} weight experimentally`);
+			}
+			r.push(`and turns to you with a smile to show it off. As an anorexic <span class="devotion inc">${he} thinks you have brought ${him} closer to the true ideal.</span>`);
+			if (this.boobFat > 0) {
+				if (slave.areolae < 2) {
+					if (Math.random() > 0.7) {
+						r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
+						slave.areolae += 1;
+					}
+				}
+				if (slave.devotion > 20 && this._strongKnownFetish(slave, "boobs")) {
+					if (hasAnyArms(slave)) {
+						r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new assets.`);
+					} else {
+						r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new assets against anything ${he} can reach.`);
+					}
+					r.push(`${He}'s <span class="devotion inc">deliriously happy</span> with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
+					reaction.trust += 4;
+					reaction.devotion += 4;
+				} else {
+					if (hasAnyArms(slave)) {
+						r.push(`${He} hefts ${his} new breasts experimentally and turns to you to show them off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see them from all angles.`);
+					} else {
+						r.push(`${He} bounces a little to feel ${his} new breasts move and turns ${his} torso to you to show them off. ${He}'s still sore, so ${he} doesn't move too much, but ${he} wiggles ${himself} a little to make them bounce for you.`);
+					}
+					r.push(`${He} isn't too fond of ${his} fat being moved to ${his} breasts instead of removed completely, but it's a small price to pay to not be a blimp.`);
+				}
+			}
+			if (this.buttFat > 0) {
+				if (slave.devotion > 20 && this._strongKnownFetish(slave, "buttslut")) {
+					r.push(`${He} gently flexes ${his} sore buttocks with a sigh of pleasure. ${He}'s <span class="devotion inc">deliriously happy</span> to have a bigger butt, since ${he} confidently expects that this will mean more cocks being shoved up ${his} asshole. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
+					reaction.trust += 4;
+					reaction.devotion += 4;
+				} else if (slave.devotion > 50) {
+					r.push(`${He} rubs ${his} new butt experimentally and turns to you to show it off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see it from all angles. ${He} isn't too keen on the idea of ${his} fat being moved to ${his} butt instead of removed completely, but ${he} accepts that it isn't hanging from ${his} front any longer.`);
+				}
+			}
+			r.push(`As with all surgeries, <span class="health dec">${his} health has been affected.</span>`);
+			reaction.devotion += 4;
+		} else if (slave.devotion > 50) {
+			if (canSee(slave)) {
+				r.push(`${He} looks over ${his} new thin figure experimentally`);
+			} else {
+				r.push(`${He} shifts ${his} weight experimentally`);
+			}
+			r.push(`and turns to you with a smile to show it off. ${He}'s still sore, so ${he} doesn't bend or flirt, but ${he} turns around to let you see it from all angles. <span class="devotion inc">${He}'s happy with your changes to ${his} body.</span>`);
+			if (this.boobFat > 0) {
+				if (slave.areolae < 2) {
+					if (Math.random() > 0.7) {
+						r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
+						slave.areolae += 1;
+					}
+				}
+				if (slave.devotion > 20 && this._strongKnownFetish(slave, "boobs")) {
+					if (hasAnyArms(slave)) {
+						r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new assets.`);
+					} else {
+						r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new assets against anything ${he} can reach.`);
+					}
+					r.push(`${He}'s <span class="devotion inc">deliriously happy</span> with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
+					reaction.trust += 4;
+					reaction.devotion += 4;
+				} else if (slave.devotion > 50) {
+					if (hasAnyArms(slave)) {
+						r.push(`${He} hefts ${his} new breasts experimentally and turns to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see them from all angles.`);
+					} else {
+						r.push(`${He} bounces a little to feel ${his} new breasts move and turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't move too much, but ${he} wiggles ${himself} a little to make them bounce for you.`);
+					}
+				}
+			}
+			if (this.buttFat > 0) {
+				if (slave.devotion > 20 && this._strongKnownFetish(slave, "buttslut")) {
+					r.push(`${He} gently flexes ${his} sore buttocks with a sigh of pleasure. ${He}'s <span class="devotion inc">deliriously happy</span> to have a bigger butt, since ${he} confidently expects that this will mean more cocks being shoved up ${his} asshole. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
+					reaction.trust += 4;
+					reaction.devotion += 4;
+				} else if (slave.devotion > 50) {
+					r.push(`${He} rubs ${his} new butt experimentally and turns to you with a smile to show it off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see it from all angles.`);
+				}
+			}
+			r.push(`As with all surgery <span class="health dec">${his} health has been affected.</span>`);
+			reaction.devotion += 4;
+		} else if (slave.devotion >= -20) {
+			if (this.boobFat > 0) {
+				if (slave.areolae < 2) {
+					if (Math.random() > 0.7) {
+						r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
+						slave.areolae += 1;
+					}
+				}
+				if (canSee(slave)) {
+					r.push(`${He} eyes ${his} new breasts`);
+				} else {
+					r.push(`${He} shifts them`);
+				}
+				r.push(`skeptically.`);
+				if (hasAnyArms(slave)) {
+					r.push(`${He}'s still sore, so ${he} doesn't touch them.`);
+				} else {
+					r.push(`${He}'s still sore, so ${he} keeps ${his} torso still.`);
+				}
+			}
+			if (this.buttFat > 0) {
+				if (canSee(slave)) {
+					r.push(`${He} eyes ${his} new butt`);
+				} else {
+					r.push(`${He} shifts ${his} new butt`);
+				}
+				r.push(`skeptically. ${He}'s still sore, so ${he} doesn't touch it.`);
+			}
+			r.push(`${He}`);
+			if (canSee(slave)) {
+				r.push(`eyes ${his} new thin figure`);
+			} else {
+				r.push(`shifts ${his} weight`);
+			}
+			r.push(`skeptically. ${He}'s still sore, so ${he} doesn't bend or touch ${himself}. ${He}'s come to terms with the fact that ${he}'s a slave, so ${he} expected something like this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all surgery <span class="health dec">${his} health has been affected.</span> ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body.`);
+			reaction.trust -= 5;
+		} else {
+			if (this.boobFat > 0) {
+				if (slave.areolae < 2) {
+					if (Math.random() > 0.7) {
+						r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
+						slave.areolae += 1;
+					}
+				}
+				if (canSee(slave)) {
+					r.push(`${He} eyes ${his} new breasts`);
+				} else {
+					r.push(`The new weight on ${his} chest fills ${him}`);
+				}
+				r.push(`with resentment.`);
+			}
+			if (this.buttFat > 0) {
+				if (canSee(slave)) {
+					r.push(`${He} eyes ${his} new butt`);
+				} else {
+					r.push(`The new weight in ${his} backside fills ${him}`);
+				}
+				r.push(`with resentment.`);
+			}
+			if (canSee(slave)) {
+				r.push(`${He} eyes ${his} new thin figure`);
+			} else {
+				r.push(`How light ${he} feels fills ${him}`);
+			}
+			r.push(`with resentment. ${He}'s still sore, so ${he} doesn't bend or touch ${himself}, but ${canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`}. ${He} still thinks of ${himself} as a person, so ${he} isn't used to the idea of being surgically altered to suit your every whim. For now, <span class="devotion dec">${he} seems to view this model figure as a cruel imposition.</span> As with all surgery <span class="health dec">${his} health has been affected.</span> ${He} is <span class="trust dec">terribly afraid</span> of your total power over ${his} body.`);
+			reaction.trust -= 15;
+			reaction.devotion -= 5;
+		}
+		if (slave.weight > 190 && slave.bellySag < 10) {
+			r.push(`Due to the tremendous amount of fat removed from ${his} midsection, it sags terribly after the surgery.`);
+			slave.bellySag = 10;
+		} else if (slave.weight > 130 && slave.bellySag < 5) {
+			r.push(`Due to the large amount of fat removed from ${his} midsection, it droops noticeably after the surgery.`);
+			slave.bellySag = 5;
+		}
+		slave.weight = 0;
+
+		reaction.longReaction.push(r);
+		return reaction;
+	}
+};
+
+App.Medicine.Surgery.Procedures.FatGraft = class extends App.Medicine.Surgery.Procedure {
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} boobFat
+	 * @param {number} buttFat
+	 */
+	constructor(slave, boobFat, buttFat) {
+		super(slave);
+		this.boobFat = boobFat;
+		this.buttFat = buttFat;
+	}
+
+	get name() {
+		return "Finalize fat transfer";
+	}
+
+	get cost() {
+		return super.cost * 2;
+	}
+
+	get healthCost() {
+		return 40;
+	}
+
+	apply(cheat) {
+		this._slave.boobs += this.boobFat * 100;
+		this._slave.butt += this.buttFat;
+		this._slave.boobs = Math.clamp(this._slave.boobs, 0, 50000);
+		this._slave.butt = Math.clamp(this._slave.butt, 0, 20);
+
+		return this._assemble(new App.Medicine.Surgery.Reactions.FatGraft(this.boobFat, this.buttFat));
+	}
+};
diff --git a/js/medicine/surgery/extreme/fuckdoll.js b/js/medicine/surgery/extreme/fuckdoll.js
new file mode 100644
index 0000000000000000000000000000000000000000..026265842337b99fc03ed386d9e19d505825cda8
--- /dev/null
+++ b/js/medicine/surgery/extreme/fuckdoll.js
@@ -0,0 +1,193 @@
+App.Medicine.Surgery.Reactions.Fuckdoll = class extends App.Medicine.Surgery.SimpleReaction {
+	get removeJob() {
+		return true;
+	}
+
+	intro(slave) {
+		const r = [];
+		r.push(`As the remote surgery's long recovery cycle completes, your new Fuckdoll`);
+		if (hasAnyLegs(slave)) {
+			r.push(`stumbles`);
+		} else {
+			r.push(`is carried`);
+		}
+		r.push(`out of the surgery room. The only`);
+		if (slave.vagina > -1) {
+			r.push(`areas of skin visible are those around its vulva and anus`);
+		} else {
+			r.push(`area of skin visible is that around its anus${(slave.lips > 95) ? `, though its lips are also visible as its facepussy makes the standard Fuckdoll mouth insert unnecessary` : ``}. You can see it starting to struggle against the constricting material of the Fuckdoll suit as the sedation wears off. Other than the tiny area of exposed skin and the slight movement, there's no indication that the sex doll in front of you is alive at all.`);
+		}
+		return r;
+	}
+
+	reaction(slave, diff) {
+		const reaction = super.reaction(slave, diff);
+		const {He, he, His, his, him, sister, wife} = getPronouns(slave);
+		const relations = V.slaves.filter((s) => areRelated(s, slave) && (s.ID !== slave.relationshipTarget));
+		let r = [];
+
+		let relatedCount = 0;
+		for (const relation of relations) {
+			const {he2, his2} = getPronouns(relation).appendSuffix("2");
+			if (isParentP(slave, relation) || isParentP(relation, slave)) {
+				r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} ${relativeTerm(relation, slave)} is now a Fuckdoll.`);
+				relation.devotion -= 40;
+				relation.trust -= 40;
+				relatedCount++;
+			}
+			switch (areSisters(slave, relation)) {
+				case 1:
+					r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} twin is now a Fuckdoll. Is ${he2} next?`);
+					relation.devotion -= 50;
+					relation.trust -= 50;
+					relatedCount++;
+					break;
+				case 2:
+					r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} ${sister} is now a Fuckdoll.`);
+					relation.devotion -= 40;
+					relation.trust -= 40;
+					relatedCount++;
+					break;
+				case 3:
+					r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} half-${sister} is now a Fuckdoll.`);
+					relation.devotion -= 30;
+					relation.trust -= 30;
+					relatedCount++;
+			}
+		}
+		if (relatedCount > 0) {
+			reaction.shortReaction.push(`${His} ${relatedCount > 0 ? "relatives" : "relative"} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when they find out about ${his} fate.`);
+		}
+		if (slave.relationship > 0) {
+			const rel = getSlave(slave.relationshipTarget);
+			if (rel) {
+				const {he2, his2} = getPronouns(rel).appendSuffix("2");
+				const relTerm = relativeTerm(rel, slave);
+				r.push(`${rel.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2}`);
+				if (relTerm !== null) {
+					r.push(`${relTerm} and`);
+				}
+				let name;
+				if (slave.relationship > 4) {
+					name = wife;
+				} else if (slave.relationship > 3) {
+					name = `lover`;
+				} else if (slave.relationship > 2) {
+					name = `intimate friend`;
+				} else if (slave.relationship > 1) {
+					name = `best friend`;
+				} else {
+					name = `friend`;
+				}
+				r.push(`${name} is now a Fuckdoll.`);
+				reaction.shortReaction.push(`${His} ${name} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when they find out about ${his} fate.`);
+				rel.devotion -= slave.relationship * 10;
+				rel.trust -= slave.relationship * 10;
+				rel.relationship = 0;
+				rel.relationshipTarget = 0;
+			}
+		} else if (slave.relationship < 0) {
+			r.push(`${His} <span class="relationship dec">slave relationship to you is effectively over,</span> since everyone in the world outside ${his} suit is created equal to ${him}. ${He}'ll probably forget to distinguish your`);
+			if (V.PC.dick !== 0) {
+				r.push(`dick if it's pushed inside ${his}`);
+			} else {
+				r.push(`pussy if it's pressed against ${his} face hole`);
+			}
+			r.push(`soon enough.`);
+		}
+		if (slave.rivalry !== 0) {
+			const rival = getSlave(slave.rivalryTarget);
+			if (rival) {
+				const {he2} = getPronouns(rival).appendSuffix("2");
+				r.push(`Naturally, ${his} rivalry with ${rival.slaveName} is over. ${rival.slaveName} will be pleased ${he2} doesn't have to see ${slave.slaveName} any more, though being a Fuckdoll is terrifying enough that it's not likely ${he2}'ll derive much satisfaction from it.`);
+				rival.rivalry = 0;
+				rival.rivalryTarget = 0;
+			}
+		}
+		slave.relationship = 0;
+		slave.relationshipTarget = 0;
+		slave.rivalry = 0;
+		slave.rivalryTarget = 0;
+
+		reaction.longReaction.push(r);
+		r = [];
+		r.push(`The Fuckdoll suit's systems connect to the arcology and run a full systems check. The reports waterfall down the nearest wallscreen, moving from the top of the Fuckdoll down. The simple brain activity sensor is showing elevated readings as ${slave.slaveName} desperately tries to find ${his} bearings.`);
+		if (slave.hLength > 20) {
+			r.push(`The twin tails of hair sticking out of the suit material that covers ${his} scalp are waving from side to side slightly as ${he} struggles.`);
+		}
+		if (getBestVision(slave) > 0) {
+			r.push(`The suit does not have holes for vision, worsening the disorientation.`);
+		}
+		if (slave.voice === 0) {
+			r.push(`${His} breath rushes in and`);
+		} else {
+			r.push(`Incoherent moans are coming`);
+		}
+		r.push(`out of ${his}`);
+		if (slave.lips > 95) {
+			r.push(`facepussy.`);
+		} else {
+			r.push(`mouth insert.`);
+		}
+		r.push(`The suit can stimulate every intimate area that it covers with vibration, electrostimulation, warmth, and cold, and ${slave.slaveName} must be in agony as it tests these systems.`);
+
+		reaction.longReaction.push(r);
+		r = [];
+
+		r.push(`The suit includes a network of small tubes filled with hydraulic fluid, and tiny pumps to move it around. This is necessary to keep the Fuckdoll's internal temperature stable, but it can also be used to restrict ${his} movements. The suit is doing so now; the Fuckdoll is desperately attempting to move, but the suit won't let ${him}.`);
+		if (hasAnyProstheticLimbs(slave)) {
+			r.push(`Its P-Limbs have been removed, since they aren't compatible with Fuckdoll suits.`);
+			removeLimbs(slave, "all");
+		}
+		if (isAmputee(slave)) {
+			r.push(`The Fuckdoll's limbless torso rocks back and forth slightly.`);
+		} else {
+			if (hasBothLegs(slave)) {
+				r.push(`${He}'s rocking back and forth slightly on ${his} heeled boots, which are designed for stability.`);
+			} else if (hasAnyLegs(slave)) {
+				r.push(`${He}'s rocking back and forth slightly on ${his} single heeled boot, which is designed for great stability.`);
+			} else {
+				r.push(`The Fuckdoll's legless torso rocks back and forth slightly.`);
+			}
+		}
+		r.push(`The heart rate reading is so high that the Fuckdoll is receiving drugs to calm ${him} down and prevent damage; the suit can deliver these and any other necessary pharmaceuticals by intravenous shunt. Farther down, on the Fuckdoll's side over ${his} ribcage, there are a pair of metal ports. These allow ${him} to be fed.`);
+		if (slave.belly > 1500) {
+			r.push(`The suit does not cover ${his}`);
+			if (slave.bellyPreg > 1500) {
+				r.push(`pregnant`);
+			} else {
+				r.push(`rounded`);
+			}
+			r.push(`belly, which is allowed to protrude from a hole in the material.`);
+		}
+
+		reaction.longReaction.push(r);
+		r = [];
+		r.push(`The Fuckdoll's rear hole is extremely eye-catching from behind, since it's the only area of skin visible from that angle across ${his} body, which is a featureless expanse of dull latex-like material.`);
+		if (slave.vagina > -1) {
+			r.push(`From ${his} other side, ${his} front hole stands out likewise.`);
+		}
+		if (slave.dick > 0) {
+			r.push(`${His} penis has its own pouch in the material.`);
+		}
+		r.push(`The Fuckdoll continues to struggle. Since ${he} is new, ${he} is not yet able to obey the tonal command system the suit uses to transfer orders to its inhabitant, who cannot otherwise hear. ${He} will have to learn by painful experience, and eventually, that is all ${he} will know.`);
+
+		return reaction;
+	}
+};
+
+App.Medicine.Surgery.Procedures.Fuckdoll = class extends App.Medicine.Surgery.Procedure {
+	get name() {
+		return "Encase in a Fuckdoll suit";
+	}
+
+	get cost() {
+		return 0;
+	}
+
+	apply(cheat) {
+		beginFuckdoll(this._slave);
+		SetBellySize(this._slave);
+		return this._assemble(new App.Medicine.Surgery.Reactions.Fuckdoll());
+	}
+};
diff --git a/js/medicine/surgery/extreme/fuckdollExtraction.js b/js/medicine/surgery/extreme/fuckdollExtraction.js
new file mode 100644
index 0000000000000000000000000000000000000000..dc966e070868c16cbb57b5b983caec732595e080
--- /dev/null
+++ b/js/medicine/surgery/extreme/fuckdollExtraction.js
@@ -0,0 +1,52 @@
+App.Medicine.Surgery.Reactions.FuckdollExtraction = class extends App.Medicine.Surgery.SimpleReaction {
+	intro(slave) {
+		const r = [];
+		r.push(`As the remote surgery's long recovery cycle completes, ${slave.slaveName}`);
+		if (!hasAnyLegs(slave)) {
+			r.push(`is carried`);
+		} else if (canWalk(slave)) {
+			r.push(`walks`);
+		} else {
+			r.push(`is escorted`);
+		}
+		r.push(`out of the surgery room.`);
+		return r;
+	}
+
+	reaction(slave, diff) {
+		const reaction = super.reaction(slave, diff);
+		const {He, he, His, his, him, himself} = getPronouns(slave);
+		const r = [];
+		r.push(`If you were expecting a great return to humanity after extracting ${him} from ${his} Fuckdoll suit, you're to be disappointed.`);
+		if (getBestVision(slave) > 0) {
+			r.push(`You're denied any reaction from ${him} to the sight of ${himself} in the mirror outside the recovery area, as ${he}'s wearing a pair of very dark glasses ${he}'ll have to keep on for a few hours yet. ${He}'s been denied almost all vision for a long time, and though ${his} recovery included light therapy, ${he}'s still very sensitive to it.`);
+		}
+		if (slave.fetish === "mindbroken") {
+			r.push(`${His} mind remains just as broken outside the suit as it was inside it. In many ways, ${he}'s as much of a living sex toy now as ${he} was when ${he} was a Fuckdoll; ${he}'s unresponsive to almost everything, though ${he} will probably still understand how to get fucked. ${His} personality is probably somewhere back there in the Fuckdoll maintenance areas, like the scraps of the suit that was just cut off ${him}. Just another piece of refuse.`);
+		} else if (slave.fuckdoll > 20) {
+			r.push(`Though ${he} retains possession of some of ${his} faculties, ${he}'s been severely affected by the weeks ${he}'s spent as a living sex toy. Any joy or relief at being liberated from the Fuckdoll suit is probably being suppressed by the similarity of the extraction procedure to the routine suit maintenance ${he} received weekly. If ${he} even understands that ${he}'s been freed, ${he}'s been trained so thoroughly that ${he} will struggle to adapt to life more complex than tonal commands and sexual use.`);
+		} else {
+			r.push(`Though ${he} hasn't been a Fuckdoll long enough to be permanently damaged, ${he}'s so emotionally exhausted by everything ${he}'s experienced over the past few weeks that ${he} betrays no relief or joy, or even any fear that ${he}'ll be turned into a Fuckdoll again. ${His} posture bespeaks something like apathy. ${He} should reawaken gradually, but for now ${he}'s still actively remembering how to live as a human, rather than as a living sex toy.`);
+		}
+		reaction.longReaction.push(r);
+		return reaction;
+	}
+};
+
+App.Medicine.Surgery.Procedures.FuckdollExtraction = class extends App.Medicine.Surgery.Procedure {
+	get name() {
+		const {him} = getPronouns(this.originalSlave);
+		return `Extract ${him}`;
+	}
+
+	get cost() {
+		return 0;
+	}
+
+	apply(cheat) {
+		this._slave.fuckdoll = 0;
+		this._slave.clothes = "no clothing";
+		this._slave.shoes = "none";
+		return this._assemble(new App.Medicine.Surgery.Reactions.FuckdollExtraction());
+	}
+};
diff --git a/js/medicine/surgery/extreme/mindbreak.js b/js/medicine/surgery/extreme/mindbreak.js
new file mode 100644
index 0000000000000000000000000000000000000000..900a84c5ec3d02a49c8f525c60fe1084f7142343
--- /dev/null
+++ b/js/medicine/surgery/extreme/mindbreak.js
@@ -0,0 +1,46 @@
+App.Medicine.Surgery.Reactions.Mindbreak = class extends App.Medicine.Surgery.SimpleReaction {
+	get removeJob() {
+		return true;
+	}
+
+	reaction(slave, diff) {
+		const reaction = super.reaction(slave, diff);
+		const {He, His, his, him} = getPronouns(slave);
+		const r = [];
+
+		r.push(`${His} gaze is placid and empty.`);
+		if (canSee(slave)) {
+			r.push(`${He} looks at`);
+		} else if (canHear(slave)) {
+			r.push(`You cough, causing ${him} to turn to face`);
+		} else {
+			r.push(`${He} does not respond to your touch, so you turn ${his} head to face`);
+		}
+		r.push(`you, and there is nothing there: no recognition, no fear, no love. Nothing. <span class="mindbreak">${He} will forget this in a few hours. ${He} will forget everything in a few hours.</span>`);
+
+		reaction.shortReaction.push(`${His} mind is broken, any defining characteristics <span class="mindbreak">are gone.</span>`);
+
+		reaction.longReaction.push(r);
+		return reaction;
+	}
+};
+
+App.Medicine.Surgery.Procedures.Mindbreak = class extends App.Medicine.Surgery.Procedure {
+	get name() {
+		return "Chemically lobotomize";
+	}
+
+	get description() {
+		const {his} = getPronouns(this.originalSlave);
+		return `Warning: this is permanent and irreversible. It will destroy ${his} will and ${his} ability to remember anything but the simplest skills.`;
+	}
+
+	get healthCost() {
+		return 20;
+	}
+
+	apply(cheat) {
+		applyMindbroken(this._slave);
+		return this._assemble(new App.Medicine.Surgery.Reactions.Mindbreak());
+	}
+};
diff --git a/js/medicine/surgery/genitials/sterilize.js b/js/medicine/surgery/genitials/sterilize.js
index 8f886afaa4a85006b6b88584f6127eadb474d7da..549f5a8e89359b993db3838983122f1498c380e1 100644
--- a/js/medicine/surgery/genitials/sterilize.js
+++ b/js/medicine/surgery/genitials/sterilize.js
@@ -47,7 +47,7 @@ App.Medicine.Surgery.Procedures.Sterilize = class extends App.Medicine.Surgery.P
 
 App.Medicine.Surgery.Procedures.Oophorectomy = class extends App.Medicine.Surgery.Procedure {
 	get name() {
-		return "Sterilize";
+		return "Oophorectomy";
 	}
 
 	get healthCost() {
diff --git a/js/medicine/surgery/reaction/fatGraft.js b/js/medicine/surgery/reaction/fatGraft.js
deleted file mode 100644
index cd13de6977dd1e59f3869ae6a76b079164f3c905..0000000000000000000000000000000000000000
--- a/js/medicine/surgery/reaction/fatGraft.js
+++ /dev/null
@@ -1,183 +0,0 @@
-{
-	class FatGraft extends App.Medicine.Surgery.Reaction {
-		get key() { return "fat graft"; }
-
-		reaction(slave, diff) {
-			const reaction = super.reaction(slave, diff);
-			const {He, he, his, him, himself} = getPronouns(slave);
-			const r = [];
-
-			const boobFat = Math.max(V.boobFat, 0) || 0;	// FIXME: Property 'boobFat' does not exist on type 'GameVariables'.
-			const buttFat = Math.max(V.buttFat, 0) || 0;	// FIXME: Property 'buttFat' does not exist on type 'GameVariables'.
-
-			if (slave.fetish === "mindbroken") {
-				r.push(`${He} notices that ${his} weight is slightly off, almost as if it were someplace else. As with all surgeries, <span class="health dec">${his} health has been affected.</span>`);
-			} else if (slave.behavioralFlaw === "anorexic") {
-				if (canSee(slave)) {
-					r.push(`${He} looks over ${his} new thin figure experimentally`);
-				} else {
-					r.push(`${He} shifts ${his} weight experimentally`);
-				}
-				r.push(`and turns to you with a smile to show it off. As an anorexic <span class="devotion inc">${he} thinks you have brought ${him} closer to the true ideal.</span>`);
-				if (boobFat > 0) {
-					if (slave.areolae < 2) {
-						if (Math.random() > 0.7) {
-							r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
-							slave.areolae += 1;
-						}
-					}
-					if (slave.devotion > 20 && this._strongKnownFetish(slave, "boobs")) {
-						if (hasAnyArms(slave)) {
-							r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new assets.`);
-						} else {
-							r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new assets against anything ${he} can reach.`);
-						}
-						r.push(`${He}'s <span class="devotion inc">deliriously happy</span> with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
-						reaction.trust += 4;
-						reaction.devotion += 4;
-					} else {
-						if (hasAnyArms(slave)) {
-							r.push(`${He} hefts ${his} new breasts experimentally and turns to you to show them off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see them from all angles.`);
-						} else {
-							r.push(`${He} bounces a little to feel ${his} new breasts move and turns ${his} torso to you to show them off. ${He}'s still sore, so ${he} doesn't move too much, but ${he} wiggles ${himself} a little to make them bounce for you.`);
-						}
-						r.push(`${He} isn't too fond of ${his} fat being moved to ${his} breasts instead of removed completely, but it's a small price to pay to not be a blimp.`);
-					}
-				}
-				if (buttFat > 0) {
-					if (slave.devotion > 20 && this._strongKnownFetish(slave, "buttslut")) {
-						r.push(`${He} gently flexes ${his} sore buttocks with a sigh of pleasure. ${He}'s <span class="devotion inc">deliriously happy</span> to have a bigger butt, since ${he} confidently expects that this will mean more cocks being shoved up ${his} asshole. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
-						reaction.trust += 4;
-						reaction.devotion += 4;
-					} else if (slave.devotion > 50) {
-						r.push(`${He} rubs ${his} new butt experimentally and turns to you to show it off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see it from all angles. ${He} isn't too keen on the idea of ${his} fat being moved to ${his} butt instead of removed completely, but ${he} accepts that it isn't hanging from ${his} front any longer.`);
-					}
-				}
-				r.push(`As with all surgeries, <span class="health dec">${his} health has been affected.</span>`);
-				reaction.devotion += 4;
-			} else if (slave.devotion > 50) {
-				if (canSee(slave)) {
-					r.push(`${He} looks over ${his} new thin figure experimentally`);
-				} else {
-					r.push(`${He} shifts ${his} weight experimentally`);
-				}
-				r.push(`and turns to you with a smile to show it off. ${He}'s still sore, so ${he} doesn't bend or flirt, but ${he} turns around to let you see it from all angles. <span class="devotion inc">${He}'s happy with your changes to ${his} body.</span>`);
-				if (boobFat > 0) {
-					if (slave.areolae < 2) {
-						if (Math.random() > 0.7) {
-							r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
-							slave.areolae += 1;
-						}
-					}
-					if (slave.devotion > 20 && this._strongKnownFetish(slave, "boobs")) {
-						if (hasAnyArms(slave)) {
-							r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new assets.`);
-						} else {
-							r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new assets against anything ${he} can reach.`);
-						}
-						r.push(`${He}'s <span class="devotion inc">deliriously happy</span> with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
-						reaction.trust += 4;
-						reaction.devotion += 4;
-					} else if (slave.devotion > 50) {
-						if (hasAnyArms(slave)) {
-							r.push(`${He} hefts ${his} new breasts experimentally and turns to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see them from all angles.`);
-						} else {
-							r.push(`${He} bounces a little to feel ${his} new breasts move and turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't move too much, but ${he} wiggles ${himself} a little to make them bounce for you.`);
-						}
-					}
-				}
-				if (buttFat > 0) {
-					if (slave.devotion > 20 && this._strongKnownFetish(slave, "buttslut")) {
-						r.push(`${He} gently flexes ${his} sore buttocks with a sigh of pleasure. ${He}'s <span class="devotion inc">deliriously happy</span> to have a bigger butt, since ${he} confidently expects that this will mean more cocks being shoved up ${his} asshole. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
-						reaction.trust += 4;
-						reaction.devotion += 4;
-					} else if (slave.devotion > 50) {
-						r.push(`${He} rubs ${his} new butt experimentally and turns to you with a smile to show it off. ${He}'s still sore, so ${he} doesn't bounce or squeeze, but ${he} turns from side to side to let you see it from all angles.`);
-					}
-				}
-				r.push(`As with all surgery <span class="health dec">${his} health has been affected.</span>`);
-				reaction.devotion += 4;
-			} else if (slave.devotion >= -20) {
-				if (boobFat > 0) {
-					if (slave.areolae < 2) {
-						if (Math.random() > 0.7) {
-							r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
-							slave.areolae += 1;
-						}
-					}
-					if (canSee(slave)) {
-						r.push(`${He} eyes ${his} new breasts`);
-					} else {
-						r.push(`${He} shifts them`);
-					}
-					r.push(`skeptically.`);
-					if (hasAnyArms(slave)) {
-						r.push(`${He}'s still sore, so ${he} doesn't touch them.`);
-					} else {
-						r.push(`${He}'s still sore, so ${he} keeps ${his} torso still.`);
-					}
-				}
-				if (buttFat > 0) {
-					if (canSee(slave)) {
-						r.push(`${He} eyes ${his} new butt`);
-					} else {
-						r.push(`${He} shifts ${his} new butt`);
-					}
-					r.push(`skeptically. ${He}'s still sore, so ${he} doesn't touch it.`);
-				}
-				r.push(`${He}`);
-				if (canSee(slave)) {
-					r.push(`eyes ${his} new thin figure`);
-				} else {
-					r.push(`shifts ${his} weight`);
-				}
-				r.push(`skeptically. ${He}'s still sore, so ${he} doesn't bend or touch ${himself}. ${He}'s come to terms with the fact that ${he}'s a slave, so ${he} expected something like this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all surgery <span class="health dec">${his} health has been affected.</span> ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body.`);
-				reaction.trust -= 5;
-			} else {
-				if (boobFat > 0) {
-					if (slave.areolae < 2) {
-						if (Math.random() > 0.7) {
-							r.push(`The increase in breast size <span class="change positive">stretches and broadens ${his} areolae.</span>`);
-							slave.areolae += 1;
-						}
-					}
-					if (canSee(slave)) {
-						r.push(`${He} eyes ${his} new breasts`);
-					} else {
-						r.push(`The new weight on ${his} chest fills ${him}`);
-					}
-					r.push(`with resentment.`);
-				}
-				if (buttFat > 0) {
-					if (canSee(slave)) {
-						r.push(`${He} eyes ${his} new butt`);
-					} else {
-						r.push(`The new weight in ${his} backside fills ${him}`);
-					}
-					r.push(`with resentment.`);
-				}
-				if (canSee(slave)) {
-					r.push(`${He} eyes ${his} new thin figure`);
-				} else {
-					r.push(`How light ${he} feels fills ${him}`);
-				}
-				r.push(`with resentment. ${He}'s still sore, so ${he} doesn't bend or touch ${himself}, but ${canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`}. ${He} still thinks of ${himself} as a person, so ${he} isn't used to the idea of being surgically altered to suit your every whim. For now, <span class="devotion dec">${he} seems to view this model figure as a cruel imposition.</span> As with all surgery <span class="health dec">${his} health has been affected.</span> ${He} is <span class="trust dec">terribly afraid</span> of your total power over ${his} body.`);
-				reaction.trust -= 15;
-				reaction.devotion -= 5;
-			}
-			if (slave.weight > 190 && slave.bellySag < 10) {
-				r.push(`Due to the tremendous amount of fat removed from ${his} midsection, it sags terribly after the surgery.`);
-				slave.bellySag = 10;
-			} else if (slave.weight > 130 && slave.bellySag < 5) {
-				r.push(`Due to the large amount of fat removed from ${his} midsection, it droops noticeably after the surgery.`);
-				slave.bellySag = 5;
-			}
-			slave.weight = 0;
-
-			reaction.longReaction.push(r);
-			return reaction;
-		}
-	}
-
-	new FatGraft();
-}
diff --git a/js/medicine/surgery/reaction/fuckdoll.js b/js/medicine/surgery/reaction/fuckdoll.js
deleted file mode 100644
index 6ca648de6577395cd66605550def96fac61138e5..0000000000000000000000000000000000000000
--- a/js/medicine/surgery/reaction/fuckdoll.js
+++ /dev/null
@@ -1,181 +0,0 @@
-{
-	class Fuckdoll extends App.Medicine.Surgery.Reaction {
-		get key() { return "fuckdoll"; }
-
-		get removeJob() { return true; }
-
-		intro(slave) {
-			const r = [];
-			r.push(`As the remote surgery's long recovery cycle completes, your new Fuckdoll`);
-			if (hasAnyLegs(slave)) {
-				r.push(`stumbles`);
-			} else {
-				r.push(`is carried`);
-			}
-			r.push(`out of the surgery room. The only`);
-			if (slave.vagina > -1) {
-				r.push(`areas of skin visible are those around its vulva and anus`);
-			} else {
-				r.push(`area of skin visible is that around its anus${(slave.lips > 95) ? `, though its lips are also visible as its facepussy makes the standard Fuckdoll mouth insert unnecessary` : ``}. You can see it starting to struggle against the constricting material of the Fuckdoll suit as the sedation wears off. Other than the tiny area of exposed skin and the slight movement, there's no indication that the sex doll in front of you is alive at all.`);
-			}
-			return r;
-		}
-
-		reaction(slave, diff) {
-			const reaction = super.reaction(slave, diff);
-			const {He, he, His, his, him, sister, wife} = getPronouns(slave);
-			const relations = V.slaves.filter((s) => areRelated(s, slave) && (s.ID !== slave.relationshipTarget));
-			let r = [];
-
-			let relatedCount = 0;
-			for (const relation of relations) {
-				const {he2, his2} = getPronouns(relation).appendSuffix("2");
-				if (isParentP(slave, relation) || isParentP(relation, slave)) {
-					r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} ${relativeTerm(relation, slave)} is now a Fuckdoll.`);
-					relation.devotion -= 40;
-					relation.trust -= 40;
-					relatedCount++;
-				}
-				switch (areSisters(slave, relation)) {
-					case 1:
-						r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} twin is now a Fuckdoll. Is ${he2} next?`);
-						relation.devotion -= 50;
-						relation.trust -= 50;
-						relatedCount++;
-						break;
-					case 2:
-						r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} ${sister} is now a Fuckdoll.`);
-						relation.devotion -= 40;
-						relation.trust -= 40;
-						relatedCount++;
-						break;
-					case 3:
-						r.push(`${relation.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2} half-${sister} is now a Fuckdoll.`);
-						relation.devotion -= 30;
-						relation.trust -= 30;
-						relatedCount++;
-				}
-			}
-			if (relatedCount > 0) {
-				reaction.shortReaction.push(`${His} ${relatedCount > 0 ? "relatives" : "relative"} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when they find out about ${his} fate.`);
-			}
-			if (slave.relationship > 0) {
-				const rel = getSlave(slave.relationshipTarget);
-				if (rel) {
-					const {he2, his2} = getPronouns(rel).appendSuffix("2");
-					const relTerm = relativeTerm(rel, slave);
-					r.push(`${rel.slaveName} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when ${he2} finds out that ${his2}`);
-					if (relTerm !== null) {
-						r.push(`${relTerm} and`);
-					}
-					let name;
-					if (slave.relationship > 4) {
-						name = wife;
-					} else if (slave.relationship > 3) {
-						name = `lover`;
-					} else if (slave.relationship > 2) {
-						name = `intimate friend`;
-					} else if (slave.relationship > 1) {
-						name = `best friend`;
-					} else {
-						name = `friend`;
-					}
-					r.push(`${name} is now a Fuckdoll.`);
-					reaction.shortReaction.push(`${His} ${name} will be <span class="devotion dec">horrified</span> and <span class="trust dec">afraid</span> when they find out about ${his} fate.`);
-					rel.devotion -= slave.relationship * 10;
-					rel.trust -= slave.relationship * 10;
-					rel.relationship = 0;
-					rel.relationshipTarget = 0;
-				}
-			} else if (slave.relationship < 0) {
-				r.push(`${His} <span class="relationship dec">slave relationship to you is effectively over,</span> since everyone in the world outside ${his} suit is created equal to ${him}. ${He}'ll probably forget to distinguish your`);
-				if (V.PC.dick !== 0) {
-					r.push(`dick if it's pushed inside ${his}`);
-				} else {
-					r.push(`pussy if it's pressed against ${his} face hole`);
-				}
-				r.push(`soon enough.`);
-			}
-			if (slave.rivalry !== 0) {
-				const rival = getSlave(slave.rivalryTarget);
-				if (rival) {
-					const {he2} = getPronouns(rival).appendSuffix("2");
-					r.push(`Naturally, ${his} rivalry with ${rival.slaveName} is over. ${rival.slaveName} will be pleased ${he2} doesn't have to see ${slave.slaveName} any more, though being a Fuckdoll is terrifying enough that it's not likely ${he2}'ll derive much satisfaction from it.`);
-					rival.rivalry = 0;
-					rival.rivalryTarget = 0;
-				}
-			}
-			slave.relationship = 0;
-			slave.relationshipTarget = 0;
-			slave.rivalry = 0;
-			slave.rivalryTarget = 0;
-
-			reaction.longReaction.push(r);
-			r = [];
-			r.push(`The Fuckdoll suit's systems connect to the arcology and run a full systems check. The reports waterfall down the nearest wallscreen, moving from the top of the Fuckdoll down. The simple brain activity sensor is showing elevated readings as ${slave.slaveName} desperately tries to find ${his} bearings.`);
-			if (slave.hLength > 20) {
-				r.push(`The twin tails of hair sticking out of the suit material that covers ${his} scalp are waving from side to side slightly as ${he} struggles.`);
-			}
-			if (getBestVision(slave) > 0) {
-				r.push(`The suit does not have holes for vision, worsening the disorientation.`);
-			}
-			if (slave.voice === 0) {
-				r.push(`${His} breath rushes in and`);
-			} else {
-				r.push(`Incoherent moans are coming`);
-			}
-			r.push(`out of ${his}`);
-			if (slave.lips > 95) {
-				r.push(`facepussy.`);
-			} else {
-				r.push(`mouth insert.`);
-			}
-			r.push(`The suit can stimulate every intimate area that it covers with vibration, electrostimulation, warmth, and cold, and ${slave.slaveName} must be in agony as it tests these systems.`);
-
-			reaction.longReaction.push(r);
-			r = [];
-
-			r.push(`The suit includes a network of small tubes filled with hydraulic fluid, and tiny pumps to move it around. This is necessary to keep the Fuckdoll's internal temperature stable, but it can also be used to restrict ${his} movements. The suit is doing so now; the Fuckdoll is desperately attempting to move, but the suit won't let ${him}.`);
-			if (hasAnyProstheticLimbs(slave)) {
-				r.push(`Its P-Limbs have been removed, since they aren't compatible with Fuckdoll suits.`);
-				removeLimbs(slave, "all");
-			}
-			if (isAmputee(slave)) {
-				r.push(`The Fuckdoll's limbless torso rocks back and forth slightly.`);
-			} else {
-				if (hasBothLegs(slave)) {
-					r.push(`${He}'s rocking back and forth slightly on ${his} heeled boots, which are designed for stability.`);
-				} else if (hasAnyLegs(slave)) {
-					r.push(`${He}'s rocking back and forth slightly on ${his} single heeled boot, which is designed for great stability.`);
-				} else {
-					r.push(`The Fuckdoll's legless torso rocks back and forth slightly.`);
-				}
-			}
-			r.push(`The heart rate reading is so high that the Fuckdoll is receiving drugs to calm ${him} down and prevent damage; the suit can deliver these and any other necessary pharmaceuticals by intravenous shunt. Farther down, on the Fuckdoll's side over ${his} ribcage, there are a pair of metal ports. These allow ${him} to be fed.`);
-			if (slave.belly > 1500) {
-				r.push(`The suit does not cover ${his}`);
-				if (slave.bellyPreg > 1500) {
-					r.push(`pregnant`);
-				} else {
-					r.push(`rounded`);
-				}
-				r.push(`belly, which is allowed to protrude from a hole in the material.`);
-			}
-
-			reaction.longReaction.push(r);
-			r = [];
-			r.push(`The Fuckdoll's rear hole is extremely eye-catching from behind, since it's the only area of skin visible from that angle across ${his} body, which is a featureless expanse of dull latex-like material.`);
-			if (slave.vagina > -1) {
-				r.push(`From ${his} other side, ${his} front hole stands out likewise.`);
-			}
-			if (slave.dick > 0) {
-				r.push(`${His} penis has its own pouch in the material.`);
-			}
-			r.push(`The Fuckdoll continues to struggle. Since ${he} is new, ${he} is not yet able to obey the tonal command system the suit uses to transfer orders to its inhabitant, who cannot otherwise hear. ${He} will have to learn by painful experience, and eventually, that is all ${he} will know.`);
-
-			return reaction;
-		}
-	}
-
-	new Fuckdoll();
-}
diff --git a/js/medicine/surgery/reaction/fuckdollExtraction.js b/js/medicine/surgery/reaction/fuckdollExtraction.js
deleted file mode 100644
index f782591a350680e82f7bb364a2b9c67de6360a08..0000000000000000000000000000000000000000
--- a/js/medicine/surgery/reaction/fuckdollExtraction.js
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-	class FuckdollExtraction extends App.Medicine.Surgery.Reaction {
-		get key() { return "fuckdollExtraction"; }
-
-		intro(slave) {
-			const r = [];
-			r.push(`As the remote surgery's long recovery cycle completes, ${slave.slaveName}`);
-			if (!hasAnyLegs(slave)) {
-				r.push(`is carried`);
-			} else if (canWalk(slave)) {
-				r.push(`walks`);
-			} else {
-				r.push(`is escorted`);
-			}
-			r.push(`out of the surgery room.`);
-			return r;
-		}
-
-		reaction(slave, diff) {
-			const reaction = super.reaction(slave, diff);
-			const {He, he, His, his, him, himself} = getPronouns(slave);
-			const r = [];
-			r.push(`If you were expecting a great return to humanity after extracting ${him} from ${his} Fuckdoll suit, you're to be disappointed.`);
-			if (getBestVision(slave) > 0) {
-				r.push(`You're denied any reaction from ${him} to the sight of ${himself} in the mirror outside the recovery area, as ${he}'s wearing a pair of very dark glasses ${he}'ll have to keep on for a few hours yet. ${He}'s been denied almost all vision for a long time, and though ${his} recovery included light therapy, ${he}'s still very sensitive to it.`);
-			}
-			if (slave.fetish === "mindbroken") {
-				r.push(`${His} mind remains just as broken outside the suit as it was inside it. In many ways, ${he}'s as much of a living sex toy now as ${he} was when ${he} was a Fuckdoll; ${he}'s unresponsive to almost everything, though ${he} will probably still understand how to get fucked. ${His} personality is probably somewhere back there in the Fuckdoll maintenance areas, like the scraps of the suit that was just cut off ${him}. Just another piece of refuse.`);
-			} else if (slave.fuckdoll > 20) {
-				r.push(`Though ${he} retains possession of some of ${his} faculties, ${he}'s been severely affected by the weeks ${he}'s spent as a living sex toy. Any joy or relief at being liberated from the Fuckdoll suit is probably being suppressed by the similarity of the extraction procedure to the routine suit maintenance ${he} received weekly. If ${he} even understands that ${he}'s been freed, ${he}'s been trained so thoroughly that ${he} will struggle to adapt to life more complex than tonal commands and sexual use.`);
-			} else {
-				r.push(`Though ${he} hasn't been a Fuckdoll long enough to be permanently damaged, ${he}'s so emotionally exhausted by everything ${he}'s experienced over the past few weeks that ${he} betrays no relief or joy, or even any fear that ${he}'ll be turned into a Fuckdoll again. ${His} posture bespeaks something like apathy. ${He} should reawaken gradually, but for now ${he}'s still actively remembering how to live as a human, rather than as a living sex toy.`);
-			}
-			reaction.longReaction.push(r);
-			return reaction;
-		}
-	}
-
-	new FuckdollExtraction();
-}
diff --git a/js/medicine/surgery/reaction/insemination.js b/js/medicine/surgery/reaction/insemination.js
index 08a47443a4fe7691ec65f9c207e87d9887eef654..d76415d99f5969b856cc81cd156465a588abd80c 100644
--- a/js/medicine/surgery/reaction/insemination.js
+++ b/js/medicine/surgery/reaction/insemination.js
@@ -1,64 +1,104 @@
-{
-	class Insemination extends App.Medicine.Surgery.Reaction {
-		get key() { return "insemination"; }
+App.Medicine.Surgery.Reactions.Insemination = class extends App.Medicine.Surgery.SimpleReaction {
+	/**
+	 * @param {App.Entity.SlaveState} seedSource
+	 */
+	constructor(seedSource) {
+		super();
+		this.seedSource = seedSource;
+	}
 
-		get invasive() { return false; }
+	get invasive() {
+		return false;
+	}
 
-		get permanentChanges() { return false; }
+	get permanentChanges() {
+		return false;
+	}
 
-		reaction(slave, diff) {
-			const reaction = super.reaction(slave, diff);
-			const {He, he, his, him} = getPronouns(slave);
-			const r = [];
+	reaction(slave, diff) {
+		const reaction = super.reaction(slave, diff);
+		const {He, he, his, him} = getPronouns(slave);
+		const r = [];
 
-			if (slave.fetish === "mindbroken") {
+		if (slave.fetish === "mindbroken") {
+			r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
+		} else if (this._strongKnownFetish(slave, "pregnancy")) {
+			if (canSee(slave)) {
+				r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its introduction to ${his} waiting ${(slave.pregType > 1) ? `eggs` : `egg`}, ${he} was eagerly watching.`);
+			} else {
+				r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
+			}
+			r.push(`${He} is <span class="devotion inc">filled with joy</span> over the life settling into ${his} womb and can't wait to see the result. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
+			reaction.trust += 4;
+			reaction.devotion += 10;
+		} else if (slave.devotion > 50) {
+			if (canSee(slave)) {
+				r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its delivery into ${his} womb, ${he} was watching with rapt attention.`);
+			} else {
 				r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
-			} else if (this._strongKnownFetish(slave, "pregnancy")) {
-				if (canSee(slave)) {
-					r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its introduction to ${his} waiting ${(slave.pregType > 1) ? `eggs` : `egg`}, ${he} was eagerly watching.`);
-				} else {
-					r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
-				}
-				r.push(`${He} is <span class="devotion inc">filled with joy</span> over the life settling into ${his} womb and can't wait to see the result. ${He}'s so pleased that ${he} now <span class="trust inc">trusts</span> your plans for ${his} body.`);
-				reaction.trust += 4;
-				reaction.devotion += 10;
-			} else if (slave.devotion > 50) {
-				if (canSee(slave)) {
-					r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its delivery into ${his} womb, ${he} was watching with rapt attention.`);
-				} else {
-					r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
-				}
-				r.push(`${He}'s <span class="devotion inc">grateful</span> that you think ${him} worthy of carrying`);
-				if (slave.pregSource === -1) {
-					r.push(`your`);
-				} else {
-					r.push(`${V.impregnatrix.slaveName}'s`);	// FIXME: Property 'impregnatrix' does not exist on type 'GameVariables'.
-				}
-				r.push(`${(slave.pregType > 1) ? `children` : `child`}, and a little nervous about how ${he}'ll perform as a mother.`);
-				reaction.devotion += 4;
-			} else if (slave.devotion >= -20) {
-				if (canSee(slave)) {
-					r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its delivery into ${his} womb and ${his} subsequent impregnation, ${he} couldn't look away.`);
-				} else {
-					r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
-				}
-				r.push(`${He} understands the realities of ${his} life as a slave, so it isn't much of a shock. ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body.`);
-				reaction.trust -= 10;
+			}
+			r.push(`${He}'s <span class="devotion inc">grateful</span> that you think ${him} worthy of carrying`);
+			if (slave.pregSource === -1) {
+				r.push(`your`);
 			} else {
-				if (canSee(slave)) {
-					r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. The moment ${he} realized what was happening, ${he} shut ${his} eyes tight, only opening them again as ${he} feels the slight tingle of the injector exiting ${his} lower abdomen.`);
-				} else {
-					r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
-				}
-				r.push(`${He} does not understand the realities of ${his} life as a slave at a core level, so ${he}'s <span class="devotion dec">terrified and angry</span> that you have forced ${him} to become a mother, even more so as ${he} realizes ${he} doesn't know who the father is. ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body and the future of the life ${he} now harbors within ${him}.`);
-				reaction.trust -= 15;
-				reaction.devotion -= 15;
+				r.push(`${this.seedSource.slaveName}'s`);
 			}
-
-			reaction.longReaction.push(r);
-			return reaction;
+			r.push(`${(slave.pregType > 1) ? `children` : `child`}, and a little nervous about how ${he}'ll perform as a mother.`);
+			reaction.devotion += 4;
+		} else if (slave.devotion >= -20) {
+			if (canSee(slave)) {
+				r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. From the selection of the sperm, to its delivery into ${his} womb and ${his} subsequent impregnation, ${he} couldn't look away.`);
+			} else {
+				r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
+			}
+			r.push(`${He} understands the realities of ${his} life as a slave, so it isn't much of a shock. ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body.`);
+			reaction.trust -= 10;
+		} else {
+			if (canSee(slave)) {
+				r.push(`Since the surgery required only a local anesthetic, ${he} remained fully aware throughout the procedure. The moment ${he} realized what was happening, ${he} shut ${his} eyes tight, only opening them again as ${he} feels the slight tingle of the injector exiting ${his} lower abdomen.`);
+			} else {
+				r.push(`${He} leaves the surgery with a certain warmth in ${his} lower abdomen, ${he} knows that ${he} has been impregnated.`);
+			}
+			r.push(`${He} does not understand the realities of ${his} life as a slave at a core level, so ${he}'s <span class="devotion dec">terrified and angry</span> that you have forced ${him} to become a mother, even more so as ${he} realizes ${he} doesn't know who the father is. ${He} is <span class="trust dec">sensibly fearful</span> of your total power over ${his} body and the future of the life ${he} now harbors within ${him}.`);
+			reaction.trust -= 15;
+			reaction.devotion -= 15;
 		}
+
+		reaction.longReaction.push(r);
+		return reaction;
+	}
+};
+
+App.Medicine.Surgery.Procedures.Insemination = class extends App.Medicine.Surgery.Procedure {
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {string} name
+	 * @param {App.Entity.SlaveState} seedSource
+	 */
+	constructor(slave, name, seedSource) {
+		super(slave);
+		this._name = name;
+		this.seedSource = seedSource;
 	}
 
-	new Insemination();
-}
+	get name() {
+		return this._name;
+	}
+
+	apply(cheat) {
+		this._slave.preg = 1;
+		this._slave.pregType = setPregType(this._slave);
+		this._slave.pregWeek = 1;
+		this._slave.pregKnown = 1;
+		this._slave.pregSource = this.seedSource.ID;
+		WombImpregnate(this._slave, this._slave.pregType, this._slave.pregSource, 1);
+		return this._assemble(new App.Medicine.Surgery.Reactions.Insemination(this.seedSource));
+	}
+};
+
+App.Medicine.Surgery.Procedures.InseminationFromStored = class extends App.Medicine.Surgery.Procedures.Insemination {
+	apply(cheat) {
+		V.PC.counter.storedCum--;
+		return super.apply(cheat);
+	}
+};
diff --git a/js/medicine/surgery/reaction/mindbreak.js b/js/medicine/surgery/reaction/mindbreak.js
deleted file mode 100644
index c3a63cc8d3610f88ce62350d6a0921c27120127b..0000000000000000000000000000000000000000
--- a/js/medicine/surgery/reaction/mindbreak.js
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-	class Mindbreak extends App.Medicine.Surgery.Reaction {
-		get key() { return "mindbreak"; }
-
-		get removeJob() { return true; }
-
-		reaction(slave, diff) {
-			const reaction = super.reaction(slave, diff);
-			const {He, His, his, him} = getPronouns(slave);
-			const r = [];
-
-			r.push(`${His} gaze is placid and empty.`);
-			if (canSee(slave)) {
-				r.push(`${He} looks at`);
-			} else if (canHear(slave)) {
-				r.push(`You cough, causing ${him} to turn to face`);
-			} else {
-				r.push(`${He} does not respond to your touch, so you turn ${his} head to face`);
-			}
-			r.push(`you, and there is nothing there: no recognition, no fear, no love. Nothing. <span class="mindbreak">${He} will forget this in a few hours. ${He} will forget everything in a few hours.</span>`);
-
-			reaction.shortReaction.push(`${His} mind is broken, any defining characteristics <span class="mindbreak">are gone.</span>`);
-
-			reaction.longReaction.push(r);
-			return reaction;
-		}
-	}
-
-	new Mindbreak();
-}
diff --git a/src/005-passages/interactPassages.js b/src/005-passages/interactPassages.js
index b32fd68d30320d62311e64470d79afac1da9d6de..9f1c9dd26839d4b68c851fadbbc815aa8b60d4d4 100644
--- a/src/005-passages/interactPassages.js
+++ b/src/005-passages/interactPassages.js
@@ -20,15 +20,6 @@ new App.DomPassage("SlaveOnSlaveFeeding",
 
 new App.DomPassage("KillSlave", () => App.UI.SlaveInteract.killSlave(getSlave(V.AS)));
 
-new App.DomPassage("Fat Grafting",
-	() => {
-		V.nextButton = "Back";
-		V.nextLink = "Remote Surgery";
-
-		return App.UI.SlaveInteract.fatGraft(getSlave(V.AS));
-	}
-);
-
 new App.DomPassage(
 	"Slave Slave Swap Workaround",
 	() => {
diff --git a/src/facilities/surgery/remoteSurgery.js b/src/facilities/surgery/remoteSurgery.js
index fb11a8f992b838bc17740ff0d1e290247186c3b0..a6b6cde22d1fcb3eb289ec9468022a0d7ee39656 100644
--- a/src/facilities/surgery/remoteSurgery.js
+++ b/src/facilities/surgery/remoteSurgery.js
@@ -40,7 +40,7 @@ App.UI.SlaveInteract.remoteSurgery = function(slave) {
 	tabBar.addTab("Structural", "structural", App.UI.surgeryPassageStructural(slave, refresh));
 	tabBar.addTab("Exotic", "exotic", App.UI.surgeryPassageExotic(slave, refresh));
 	if (V.seeExtreme) {
-		tabBar.addTab("Extreme", "extreme", App.UI.surgeryPassageExtreme(slave));
+		tabBar.addTab("Extreme", "extreme", App.UI.surgeryPassageExtreme(slave, refresh));
 	}
 	el.append(tabBar.render());
 
diff --git a/src/facilities/surgery/surgeryPassageExtreme.js b/src/facilities/surgery/surgeryPassageExtreme.js
index 3620ede5f9ee25346de7b4a932765ce6eb19e0c6..899c19869bf118d3c0f9ded6b0c4e74da6c53a79 100644
--- a/src/facilities/surgery/surgeryPassageExtreme.js
+++ b/src/facilities/surgery/surgeryPassageExtreme.js
@@ -1,11 +1,11 @@
 /**
  * UI for performing surgery. Refreshes without refreshing the passage.
  * @param {App.Entity.SlaveState} slave
+ * @param {()=>void} refreshParent
  * @param {boolean} [cheat=false]
  * @returns {HTMLElement}
  */
-
-App.UI.surgeryPassageExtreme = function(slave, cheat = false) {
+App.UI.surgeryPassageExtreme = function(slave, refreshParent, cheat = false) {
 	const container = document.createElement("span");
 	container.append(content());
 	return container;
@@ -14,7 +14,7 @@ App.UI.surgeryPassageExtreme = function(slave, cheat = false) {
 		const frag = new DocumentFragment();
 		const {
 			His, He,
-			his, he, him
+			his, he
 		} = getPronouns(slave);
 
 		if (V.seeExtreme === 1) {
@@ -30,29 +30,15 @@ App.UI.surgeryPassageExtreme = function(slave, cheat = false) {
 			if (slave.fuckdoll === 0) {
 				r.push(`${He} is a normal sex slave, not a living sex toy.`);
 				if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
-					linkArray.push(makeLink(
-						"Encase in a Fuckdoll suit",
-						"fuckdoll",
-						() => {
-							beginFuckdoll(slave);
-							SetBellySize(slave);
-						},
-						0,
-						`This will greatly restrict ${him}`
-					));
+					linkArray.push(App.Medicine.Surgery.makeLink(
+						new App.Medicine.Surgery.Procedures.Fuckdoll(slave),
+						refresh, cheat));
 				}
 			} else {
 				r.push(`${He} is encased in a Fuckdoll suit.`);
-				linkArray.push(makeLink(
-					`Extract ${him}`,
-					"fuckdollExtraction",
-					() => {
-						slave.fuckdoll = 0;
-						slave.clothes = "no clothing";
-						slave.shoes = "none";
-					},
-					0
-				));
+				linkArray.push(App.Medicine.Surgery.makeLink(
+					new App.Medicine.Surgery.Procedures.FuckdollExtraction(slave),
+					refresh, cheat));
 			}
 			App.Events.addNode(el, r, "div");
 			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
@@ -70,59 +56,20 @@ App.UI.surgeryPassageExtreme = function(slave, cheat = false) {
 			}
 			if (slave.indentureRestrictions < 1 && (slave.breedingMark !== 1 || V.propOutcome === 0 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
 				if (slave.fetish !== "mindbroken") {
-					linkArray.push(makeLink(
-						"Chemically lobotomize",
-						"mindbreak",
-						() => {
-							applyMindbroken(slave);
-							surgeryDamage(slave, 20);
-						},
-						1,
-						`Warning: this is permanent and irreversible. It will destroy ${his} will and ${his} ability to remember anything but the simplest skills.`
-					));
+					linkArray.push(App.Medicine.Surgery.makeLink(
+						new App.Medicine.Surgery.Procedures.Mindbreak(slave),
+						refresh, cheat));
 				}
 			}
 			App.Events.addNode(el, r, "div");
 			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
 			return el;
 		}
+	}
 
-		/**
-		 *
-		 * @param {string} title
-		 * @param {string} surgeryType
-		 * @param {function(void):void} [func]
-		 * @param {number} [costMult=1]
-		 * @param {string} [note]
-		 * @returns {HTMLAnchorElement}
-		 */
-		function makeLink(title, surgeryType, func, costMult = 1, note = "") {
-			const cost = Math.trunc(V.surgeryCost * costMult);
-			const tooltip = new DocumentFragment();
-			App.UI.DOM.appendNewElement("div", tooltip, cost !== 0 ? `Costs ${cashFormat(cost)}` : `Free`);
-			if (note) {
-				App.UI.DOM.appendNewElement("div", tooltip, note);
-			}
-			return App.UI.DOM.link(
-				title,
-				() => {
-					if (typeof func === "function") {
-						func();
-					}
-					if (cheat) {
-						jQuery(container).empty().append(content());
-						App.Events.refreshEventArt(slave);
-					} else {
-						V.surgeryType = surgeryType;
-						// TODO: pass if it affected health or not?
-						cashX(forceNeg(cost), "slaveSurgery", slave);
-						Engine.play("Surgery Degradation");
-					}
-				},
-				[],
-				"",
-				tooltip
-			);
-		}
+	function refresh() {
+		jQuery(container).empty().append(content());
+		App.Events.refreshEventArt(slave);
+		refreshParent();
 	}
 };
diff --git a/src/facilities/surgery/surgeryPassageUpper.js b/src/facilities/surgery/surgeryPassageUpper.js
index aba313373192ac49d9ce6f8dd683d605b589259b..c3412a38df1ed4c4e50f90223aef64791314fb9a 100644
--- a/src/facilities/surgery/surgeryPassageUpper.js
+++ b/src/facilities/surgery/surgeryPassageUpper.js
@@ -345,7 +345,8 @@ App.UI.surgeryPassageUpper = function(slave, refreshParent, cheat = false) {
 					new App.Medicine.Surgery.Procedures.Liposuction(slave),
 					refresh, cheat));
 				if (V.surgeryUpgrade === 1) {
-					linkArray.push(App.UI.DOM.passageLink("Fat grafting", "Fat Grafting"));
+					linkArray.push(App.UI.DOM.link("Fat grafting",
+						() => App.UI.SlaveInteract.fatGraft(slave, refresh)));
 				}
 			}
 			App.Events.addNode(el, r, "div");
diff --git a/src/interaction/artificialInsemination.js b/src/interaction/artificialInsemination.js
index 0d6f5e880946e3df1489e955a3f83018b2d80ebc..9b5d83e556143fe853f7537ddd28b2b5c660ff4c 100644
--- a/src/interaction/artificialInsemination.js
+++ b/src/interaction/artificialInsemination.js
@@ -5,8 +5,6 @@ App.UI.SlaveInteract.artificialInsemination = function() {
 	const f = new DocumentFragment();
 	let r;
 
-	V.impregnatrix = 0;
-
 	App.UI.DOM.appendNewElement("p", f, `${getSlave(V.AS).slaveName} is prepped for fertilization; now you must select a target to harvest sperm from.`, "scene-intro");
 
 	App.UI.DOM.appendNewElement("h2", f, "Select an eligible slave to serve as the semen donatrix");
@@ -25,9 +23,9 @@ App.UI.SlaveInteract.artificialInsemination = function() {
 			r.push(App.UI.DOM.makeElement("div", name));
 
 			r.push(App.UI.DOM.makeElement("div",
-				App.UI.DOM.passageLink(`Use ${his} sperm.`, "Surgery Degradation", () => {
-					inseminate(getSlave(V.AS), slave);
-				})
+				App.Medicine.Surgery.makeLink(
+					new App.Medicine.Surgery.Procedures.Insemination(getSlave(V.AS), `Use ${his} sperm.`, slave),
+					exit, false)
 			));
 
 			any = true;
@@ -47,9 +45,9 @@ App.UI.SlaveInteract.artificialInsemination = function() {
 		for (const tank of V.incubator.tanks) {
 			if (tank.balls > 0 && tank.dick > 0 && canBreed(getSlave(V.AS), tank)) {
 				r.push(App.UI.DOM.makeElement("div",
-					App.UI.DOM.passageLink(tank.slaveName, "Surgery Degradation", () => {
-						inseminate(getSlave(V.AS), tank);
-					})
+					App.Medicine.Surgery.makeLink(
+						new App.Medicine.Surgery.Procedures.Insemination(getSlave(V.AS), `Use ${tank.slaveName}'s sperm.`, tank),
+						exit, false)
 				));
 				any = true;
 			}
@@ -64,30 +62,21 @@ App.UI.SlaveInteract.artificialInsemination = function() {
 
 	if (V.PC.balls !== 0) {
 		App.UI.DOM.appendNewElement("p", f,
-			App.UI.DOM.passageLink("Use your own", "Surgery Degradation", () => {
-				inseminate(getSlave(V.AS), V.PC);
-			})
+			App.Medicine.Surgery.makeLink(
+				new App.Medicine.Surgery.Procedures.Insemination(getSlave(V.AS), "Use your own", V.PC),
+				exit, false)
 		);
 	} else if (V.PC.counter.storedCum > 0) {
 		r = [];
-		r.push(App.UI.DOM.passageLink("Use a vial of your own", "Surgery Degradation", () => {
-			inseminate(getSlave(V.AS), V.PC);
-			V.PC.counter.storedCum--;
-		}));
+		r.push(App.Medicine.Surgery.makeLink(
+			new App.Medicine.Surgery.Procedures.InseminationFromStored(getSlave(V.AS), "Use a vial of your own", V.PC),
+			exit, false));
 		r.push(`<span class="detail">You have enough sperm stored away to inseminate ${V.PC.counter.storedCum} more ${V.PC.counter.storedCum > 1 ? "slaves" : "slave"}.</span>`);
 		App.Events.addParagraph(f, r);
 	}
 
-	function inseminate(slave, source) {
-		V.impregnatrix = source;
-		slave.preg = 1;
-		slave.pregType = setPregType(slave);
-		slave.pregWeek = 1;
-		slave.pregKnown = 1;
-		slave.pregSource = source.ID;
-		WombImpregnate(slave, slave.pregType, slave.pregSource, 1);
-		V.surgeryType = "insemination";
-		cashX(forceNeg(V.surgeryCost), "slaveSurgery", getSlave(V.AS));
+	function exit() {
+		Engine.play("Remote Surgery");
 	}
 
 	return f;
diff --git a/src/npc/surgery/fatGraft.js b/src/npc/surgery/fatGraft.js
index 85ea1572173aa4942e655818990acac095d46351..c63f7c44b0e60da256ed800cea3b5bcebda16b80 100644
--- a/src/npc/surgery/fatGraft.js
+++ b/src/npc/surgery/fatGraft.js
@@ -1,17 +1,22 @@
 /**
- *
  * @param {App.Entity.SlaveState} slave
- * @returns {DocumentFragment}
+ * @param {()=>void} refreshPage
  */
-App.UI.SlaveInteract.fatGraft = function(slave) {
-	const frag = new DocumentFragment();
+App.UI.SlaveInteract.fatGraft = function(slave, refreshPage) {
 	let availableFat = Math.round(slave.weight / 10);
 	let boobFat = 0;
 	let buttFat = 0;
 
-	const passage = App.UI.DOM.appendNewElement("span", frag, content());
+	const container = document.createElement("div");
+	container.append(content());
+
+	if (Dialog.isOpen()) {
+		Dialog.close();
+	}
+	Dialog.setup("Fat Grafting");
+	Dialog.append(container);
+	Dialog.open();
 
-	return frag;
 
 	function content() {
 		const el = new DocumentFragment();
@@ -96,23 +101,13 @@ App.UI.SlaveInteract.fatGraft = function(slave) {
 			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";
-		}));
+		App.UI.DOM.appendNewElement("p", el, App.Medicine.Surgery.makeLink(
+			new App.Medicine.Surgery.Procedures.FatGraft(slave, boobFat, buttFat),
+			refreshPage, false));
 		return el;
 	}
 
 	function refresh() {
-		jQuery(passage).empty().append(content());
+		App.UI.DOM.replace(container, content());
 	}
 };
diff --git a/src/npc/surgery/surgery.js b/src/npc/surgery/surgery.js
index 2efc9f0abd297c3a8856925fac16e6451e96b141..cf8d53b2014ab39900ca9b2a1f75b2846eda819c 100644
--- a/src/npc/surgery/surgery.js
+++ b/src/npc/surgery/surgery.js
@@ -195,17 +195,13 @@ App.Medicine.Surgery.makeSlaveReaction = function(slave, diff, reaction) {
  */
 App.Medicine.Surgery.apply = function(procedure, cheat) {
 	const slave = procedure.originalSlave;
-	console.log("1");
 	if (!cheat) {
-		console.log("1");
 		cashX(-procedure.cost, "slaveSurgery", slave);
 		surgeryDamage(slave, procedure.healthCost, cheat);
 		if (procedure.invasive && slave.health.health < random(-100, -80)) {
-			console.log("1");
 			return null;
 		}
 	}
-	console.log("1");
 
 	const [diff, reaction] = procedure.apply(cheat);