code:
App.Medicine.Surgery.Reactions.AddOvaries = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but lacks the mental faculties to realize that ${he} now has a chance to get pregnant. As with all surgery ${his} health has been slightly affected.`);
		} else if (this._strongKnownFetish(slave, Fetish.PREGNANCY) || slave.origin === "$He sold $himself to you in the hope of someday bearing children.") {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} now has a chance to get pregnant. ${He} is filled with joy whenever ${he} thinks about the fact that feeling a life growing within ${him} is now, at last, a possibility. ${He} now places total faith in your plans for ${his} body and adores you for giving ${him} a gift ${he} once thought impossible. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 10;
			reaction.devotion += 10;
		} else if (slave.devotion > 50) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman. ${He} is tremendously impressed that you would devote such immense resources to altering ${his} body, and is more willing than ever to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 5;
			reaction.devotion += 5;
		} else if (slave.devotion >= -20) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman. ${He} is terrified of your apparently untrammeled power over ${his} body, so much so that ${he} is now more willing to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion += 5;
		} else {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman. ${He} is terrified of your apparently untrammeled power over ${his} body, and furious at ${his} lack of control over ${his} own person. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};
App.Medicine.Surgery.Reactions.AddAnimalOvaries = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but lacks the mental faculties to realize that ${he} now has a chance of carrying an animal baby to term. As with all surgery ${his} health has been slightly affected.`);
		} else if (this._strongKnownFetish(slave, Fetish.PREGNANCY) || slave.origin === "$He sold $himself to you in the hope of someday bearing children.") {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} now has a chance to get pregnant. ${He} is filled with joy whenever ${he} thinks about the fact that feeling a life growing within ${him} is now, at last, a possibility. ${He} now places total faith in your plans for ${his} body and adores you for giving ${him} a gift ${he} once thought impossible. ${He} doesn't realize exactly what the surgery entailed, however — the happiness ${he} felt at first will most likely be replaced with horror once ${he} realizes the babies in ${his} womb are not human. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 10;
			reaction.devotion += 10;
		} else if (slave.devotion > 50) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman — at least, that's what ${he} believes. Little does ${he} know that ${he} is now capable of carrying animal babies in ${his} womb. ${He} is tremendously impressed that you would devote such immense resources to altering ${his} body, and is more willing than ever to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 5;
			reaction.devotion += 5;
		} else if (slave.devotion >= -20) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman — at least, that's what ${he} believes. Little does ${he} know that ${he} is now capable of carrying animal babies in ${his} womb. ${He} is terrified of your apparently untrammeled power over ${his} body, so much so that ${he} is now more willing to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion += 5;
		} else {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to know that it means ${he} is now internally indistinguishable from a natural, unaltered woman — at least, that's what ${he} believes. Little does ${he} know that ${he} is now capable of carrying animal babies in ${his} womb. ${He} is terrified of your apparently untrammeled power over ${his} body, and furious at ${his} lack of control over ${his} own person. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAddOvaries = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.AnimalType} eggType
	 * @param {string} pregDataKey
	 */
	constructor(slave, eggType, pregDataKey) {
		super(slave);
		this.eggType = eggType;
		this.pregDataKey = pregDataKey;
	}

	get name() {
		return "Implant";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.ovaries = 1;
		this._slave.eggType = this.eggType;
		this._slave.preg = 0;
		/**
		 * @type {FC.PregnancyData}
		 */
		// @ts-ignore
		const data = {};
		deepAssign(data, App.Data.misc.pregData[this.pregDataKey]);
		this._slave.pregData = data;
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		if (V.menstruation === 1) {
			this._slave.fertPeak = 1;
		}

		if (this.eggType === "human") {
			return this._assemble(new App.Medicine.Surgery.Reactions.AddOvaries());
		} else {
			return this._assemble(new App.Medicine.Surgery.Reactions.AddAnimalOvaries());
		}
	}
};

App.Medicine.Surgery.Procedures.OFReplaceOvaries = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.AnimalType} eggType
	 * @param {string} pregDataKey
	 */
	constructor(slave, eggType, pregDataKey) {
		super(slave);
		this.eggType = eggType;
		this.pregDataKey = pregDataKey;
	}

	get name() {
		return "Replace";
	}

	get description() {
		return "you can replace the existing ovaries with a new pair";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.eggType = this.eggType;
		this._slave.preg = 0;
		/**
		 * @type {FC.PregnancyData}
		 */
		// @ts-ignore
		const data = {};
		deepAssign(data, App.Data.misc.pregData[this.pregDataKey]);
		this._slave.pregData = data;
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		if (V.menstruation === 1) {
			this._slave.fertPeak = 1;
		}

		if (this.eggType === "human") {
			return this._assemble(new App.Medicine.Surgery.Reactions.AddOvaries());
		} else {
			return this._assemble(new App.Medicine.Surgery.Reactions.AddAnimalOvaries());
		}
	}
};


code:
App.Medicine.Surgery.Reactions.AddProstate = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, His, his, him, himself} = getPronouns(slave);
		const r = [];

		r.push(`It's not immediately apparent to ${him} what kind of surgery ${he} received, since all ${he}'s left with is a terrible nonspecific ache in ${his} lower parts. As with all surgery ${his} health has been slightly affected.`);
		if (this._hasEmotion(slave)) {
			if (slave.devotion > 50) {
				if (slave.anus === 0) {
					r.push(`Since ${he}'s still an anal virgin, ${he}'s denied the most obvious way of discovering what's been added to ${him}. The revelation is deferred until the next time ${he} orgasms:`);
				} else if (canDoAnal(slave) || canDoVaginal(slave)) {
					r.push(`The next time ${he}'s penetrated, though, it's obvious:`);
				} else if (canPenetrate(slave)) {
					r.push(`The next time ${he} uses ${his} cock, though, it's obvious:`);
				} else {
					r.push(`The next time ${he} climaxes, though, it's obvious:`);
				}
				r.push(`${he}'s shocked by the astounding volume of ${his}`);
				if (slave.dick === 0) {
					r.push(`squirting female`);
				}
				r.push(`ejaculation, since ${his} new organ is of course hooked into ${his} urethra and does its duty whenever ${he} climaxes${(slave.balls === 0) ? ` despite ${his} lack of testicles to add actual semen to ${his} copious emissions` : ``}.`);
				if (slave.fetishKnown === 1 && slave.fetish === Fetish.BUTTSLUT) {
					r.push(`${He} was already an anal slut, but ${he} can now experience anal pleasure along an entirely new dimension. ${He}'s extremely grateful, and a more eager buttslut than ever.`);
					reaction.devotion += 5;
					slave.fetishStrength = Math.clamp(slave.fetishStrength + 20, 0, 100);
				} else {
					r.push(`As a sex slave, ${he}`);
					if (canHear(slave)) {
						r.push(`has of course heard of`);
					} else {
						r.push(`is of course familiar with`);
					}
					r.push(`the pleasure of prostate stimulation,`);
					if (slave.genes === GenderGenes.MALE) {
						r.push(`not to mention having once had one ${himself},`);
					}
					r.push(`and ${he}'s <span class="devotion inc">duly grateful</span> that you've altered ${him} in a way that will make sexual duties more enjoyable.`);
				}
				reaction.devotion += 5;
			} else if (slave.devotion > 20) {
				r.push(`The next time ${he} orgasms, ${he}'s shocked by the astounding volume of ${his}`);
				if (slave.dick === 0) {
					r.push(`squirting female`);
				}
				r.push(`ejaculation, since ${his} new organ is of course hooked into ${his} urethra and does its duty whenever ${he} climaxes${(slave.balls === 0) ? ` despite ${his} lack of testicles to add actual semen to ${his} copious emissions` : ``}. ${His} main reaction is confusion; this alteration is pretty far outside any of the more conventional surgeries slaves might expect to receive, and ${his} mixed feeling tend to cancel each other out.`);
			} else {
				r.push(`${He} doesn't have to know exactly what you did, though, to be mortified and infuriated by your messing around inside ${his} body. ${He} hasn't yet learned to accept that you control ${him} completely, down to the arrangement and even presence of ${his} internal organs.`);
				reaction.trust -= 10;
				reaction.devotion -= 10;
			}
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAddProstate = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Prostate";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.prostate = 1;
		return this._assemble(new App.Medicine.Surgery.Reactions.AddProstate());
	}
};

repo_name: Nithhogg/fc

license: mit


code:
App.Medicine.Surgery.Reactions.AddScrotum = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		r.push(`${He} leaves the surgery gingerly, knowing ${he}'s had surgery on ${his} junk. Taking the first opportunity to`);
		if (canSee(slave)) {
			r.push(`look at ${his} crotch in a mirror,`);
		} else {
			r.push(`feel ${his} crotch,`);
		}
		r.push(`${he}'s`);
		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`confused to find something new dangling there.`);
		} else if (slave.devotion > 50) {
			r.push(`overjoyed to find that ${he} has a ballsack. ${He} very obviously starts to think about how it will affect ${his} various functions as a sex slave. First, ${he} flexes ${his} Kegel muscles,`);
			if (canSee(slave)) {
				r.push(`watching raptly as`);
			} else {
				r.push(`giggling as ${he} feels`);
			}
			r.push(`${his} testicles move within the new pouch of soft skin beneath ${his} cock. Then ${he} starts to bounce and hump a little, this way and that, experimenting with how they move as ${he} performs fucking motions. ${He}'s looking forward to having fun with this latest alteration of ${his} body, and is more willing than ever to submit to your plans for ${his} future.`);
			reaction.trust += 5;
			reaction.devotion += 5;
		} else if (slave.devotion >= -20) {
			r.push(`shocked to find that ${he} has a ballsack. ${He} flexes ${his} Kegel muscles, mostly for lack of anything better to try,`);
			if (canSee(slave)) {
				r.push(`watching raptly as`);
			} else {
				r.push(`thinking deeply as`);
			}
			r.push(`${his} testicles move within the new pouch of soft skin beneath ${his} cock.`);
			if (canSee(slave)) {
				r.push(`Staring at the sight`);
			} else {
				r.push(`Transfixed on the motion`);
			}
			r.push(`with obviously mixed feelings, ${he} struggles for a while before bursting into girlish tears from the sheer ambivalence. ${He}'s frightened of your ability to modify ${him}, and is more willing than ever to submit to your plans for ${his} future.`);
			reaction.trust -= 5;
			reaction.devotion += 5;
		} else {
			r.push(`shocked and appalled to find that ${he} has a ballsack. ${He}`);
			if (canSee(slave)) {
				r.push(`stares at ${his} newly visible`);
			} else {
				r.push(`feels ${his} new`);
			}
			r.push(`balls in horror; it's obvious ${he} thought they were out of sight, and out of mind. ${He} checks ${himself} over carefully, and then bursts into tears, seemingly feeling that even if ${he} has a ballsack, ${his} cock is still a slave's bitchclit, and ${his} asshole is still a slut's asspussy. ${He}'s frightened of your ability to modify ${him}, and resentful of how you use it.`);
			reaction.trust -= 5;
			reaction.devotion -= 5;
		}
		r.push(`As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAddScrotum = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Graft on";
	}

	get healthCost() {
		return 10;
	}

	apply(cheat) {
		this._slave.scrotum = this._slave.balls;
		return this._assemble(new App.Medicine.Surgery.Reactions.AddScrotum());
	}
};


code:
App.Medicine.Surgery.Reactions.AddTesticles = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`It's not immediately apparent to ${him} what kind of surgery ${he} received, since all ${he}'s left with is a nonspecific ache in ${his} abdomen. As with all surgery ${his} health has been slightly affected.`);
		} else if (slave.devotion > 50) {
			r.push(`${He} lies back in the surgical chair${(canSee(slave)) ? `, gazing at ${himself} in the ceiling mirror` : ``} as the fog of anesthetics lifts and feeling returns to ${his} lower half. As a devoted slave, ${he} knew the essentials of the surgery before it was performed, so ${he}'s excited to`);
			if (canSee(slave)) {
				r.push(`see`);
			} else {
				r.push(`feel`);
			}
			r.push(`the results. ${He} is tremendously impressed that you would devote such immense resources to altering ${his} body, and is more willing than ever to submit to your plans for ${his} future.`);
			reaction.trust += 5;
			reaction.devotion += 5;
		} else if (slave.devotion >= -20) {
			r.push(`It's not immediately apparent to ${him} what kind of surgery ${he} received, since all ${he}'s left with is a nonspecific ache in ${his} abdomen. As with all surgery ${his} health has been slightly affected.`);
		} else {
			r.push(`It's not immediately apparent to ${him} what kind of surgery ${he} received, since all ${he}'s left with is a nonspecific ache in ${his} abdomen. As with all surgery ${his} health has been slightly affected. ${He} doesn't have to know exactly what you did, though, to be mortified and infuriated by your messing around inside ${his} body. ${He} hasn't yet learned to accept that you control ${him} completely, down to the arrangement and even presence of ${his} internal organs.`);
			reaction.trust -= 10;
			reaction.devotion -= 10;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAddTesticles = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.AnimalType} ballType
	 */
	constructor(slave, ballType) {
		super(slave);
		this.ballType = ballType;
	}

	get name() {
		return "Implant";
	}

	get description() {
		return "you can forgo standard procedure and implant testicles directly into their abdomen";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		if (this._slave.prostate === 0) {
			this._slave.prostate = 1;
		}
		this._slave.balls = 2;
		this._slave.ballType = this.ballType;
		if (this._slave.pubertyAgeXY === 0) {
			if (V.precociousPuberty === 1) {
				if (this._slave.physicalAge >= V.potencyAge) {
					this._slave.pubertyAgeXY = this._slave.physicalAge + 1;
				}
			} else {
				if (this._slave.physicalAge >= V.potencyAge) {
					this._slave.pubertyXY = 1;
				}
			}
		}
		return this._assemble(new App.Medicine.Surgery.Reactions.AddTesticles());
	}
};

App.Medicine.Surgery.Procedures.OFReplaceTesticles = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.AnimalType} ballType
	 */
	constructor(slave, ballType) {
		super(slave);
		this.ballType = ballType;
	}

	get name() {
		return "Replace";
	}

	get description() {
		return "you can replace the existing testicles with a new pair";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.balls = 2;
		this._slave.ballType = this.ballType;
		if (this._slave.pubertyAgeXY === 0) {
			if (V.precociousPuberty === 1) {
				if (this._slave.physicalAge >= V.potencyAge) {
					this._slave.pubertyAgeXY = this._slave.physicalAge + 1;
				}
			} else {
				if (this._slave.physicalAge >= V.potencyAge) {
					this._slave.pubertyXY = 1;
				}
			}
		}
		return this._assemble(new App.Medicine.Surgery.Reactions.AddTesticles());
	}
};


code:
App.Medicine.Surgery.Reactions.AsexualReproOvaries = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, girl} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but lacks the mental faculties to realize that ${he} is now self-impregnating. As with all surgery ${his} health has been slightly affected.`);
		} else if (slave.devotion > 50) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to suspect that something has critically changed about ${his} reproductive system. ${He} is pleased that you would go out of your way to alter ${his} body, and is more willing than ever to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 5;
			reaction.devotion += 5;
		} else if (slave.devotion >= -20) {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to shudder at the thought of just what could have possibly been put into ${him}. ${He} is terrified of your apparently untrammeled power over ${his} body, so much so that ${he} is now more willing to submit to your plans for ${his} future. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion += 5;
		} else {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen, but ${he} has managed to catch enough slave rumors about what the organ farm can do to dread the discovery of what now resides inside ${him}. ${He} is terrified of your apparently untrammeled power over ${his} body, and furious at ${his} lack of control over ${his} own person. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust -= 5;
			reaction.devotion -= 5;
		}
		if (isFertile(slave) && slave.preg === 0) {
			knockMeUp(slave, 100, 2, slave.ID);
			r.push(`${He} doesn't even have the chance to reach the slave quarters before ${his} new reproductive system detects ${his} unprotected fertility and begins to internally cum.`);
			if (canWalk(slave)) {
				r.push(`${He} struggles to stand as wave after wave of pleasure radiates from inside ${his} self-fertilizing womb.`);
			} else {
				r.push(`The slave carrying ${him} struggles to keep their grip on the orgasm wracked ${girl}.`);
			}
			r.push(`By the time ${he} is finished, ${he} is a sweat-soaked, panting mess with a womb <span class="pregnant">`);
			if (slave.pregType > 50) {
				r.push(`stuffed full of fertilized eggs.`);
			} else if (slave.pregType > 20) {
				r.push(`filled with new life.`);
			} else if (slave.pregType > 1) {
				r.push(`housing several new lives.`);
			} else {
				r.push(`filled with seed and a new life.`);
			}
			r.push(`</span>`);
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAsexualReproOvaries = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Implant";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		if (this._slave.preg < -1) {
			this._slave.preg = 0;
			if (V.menstruation === 1) {
				this._slave.fertPeak = 1;
			}
		}
		this._slave.eggType = "human";
		this._slave.pregData = _.cloneDeep(App.Data.misc.pregData.human);
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		this._slave.ovaImplant = OvaryImplantType.ASEXUAL;
		return this._assemble(new App.Medicine.Surgery.Reactions.AsexualReproOvaries());
	}
};


code:
App.Medicine.Surgery.Reactions.FreshOvaries = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him} = getPronouns(slave);
		const r = [];

		if (slave.ovaryAge >= 45 && this._hasEmotion(slave)) {
			if (this._strongKnownFetish(slave, Fetish.PREGNANCY) || slave.origin === "$He sold $himself to you in the hope of someday bearing children.") {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} now has a chance to get pregnant once more. ${He} is filled with joy whenever ${he} thinks about the fact that ${he}'ll have the chance to feel a life growing within ${him} again. ${He}'s so pleased that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
				reaction.trust += 4;
				reaction.devotion += 5;
			} else if (slave.devotion > 50) {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} now has the chance to get pregnant again. ${He}'s grateful that you think ${him} worthy of extending ${his} fertility, and even a little nervous about how ${he}'ll perform as a mother that has tasted menopause. As with all surgery ${his} health has been slightly affected.`);
				reaction.devotion += 4;
			} else if (slave.devotion >= -20) {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} may now be impregnated once more. ${He} understands the realities of ${his} life as a slave, but didn't expect to have ${his} waning fertility renewed. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
				reaction.trust -= 5;
			} else {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to believe you have forced fertility upon ${him} again. ${He} does not understand the realities of ${his} life as a slave at a core level, so ${he}'s terrified and angry at the potential that ${he}'ll be forced to carry children. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
				reaction.trust -= 5;
				reaction.devotion -= 5;
			}
		} else {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen; it won't be clear to ${him} that menopause is not a concern for now. As with all surgery ${his} health has been slightly affected.`);
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFFreshOvaries = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Implant";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.ovaryAge = Math.clamp(this._slave.ovaryAge - 2, 0, 45);
		if (this._slave.preg < -1) {
			this._slave.preg = 0;
		}
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		if (V.menstruation === 1) {
			this._slave.fertPeak = 1;
		}
		return this._assemble(new App.Medicine.Surgery.Reactions.FreshOvaries());
	}
};


code:
App.Medicine.Surgery.Reactions.ImmortalOvaries = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, His, he, his, him} = getPronouns(slave);
		const r = [];

		if (slave.ovaryAge >= 45 && this._hasEmotion(slave)) { // use same reactions as freshOvaries - slave doesn't know the difference
			if (this._strongKnownFetish(slave, Fetish.PREGNANCY) || slave.origin === "$He sold $himself to you in the hope of someday bearing children.") {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} now has a chance to get pregnant once more. ${He} is filled with joy whenever ${he} thinks about the fact that ${he}'ll have the chance to feel a life growing within ${him} again. ${He}'s so pleased that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
				reaction.trust += 4;
				reaction.devotion += 5;
			} else if (slave.devotion > 50) {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} now has the chance to get pregnant again. ${He}'s grateful that you think ${him} worthy of extending ${his} fertility, and even a little nervous about how ${he}'ll perform as a mother that has tasted menopause. As with all surgery ${his} health has been slightly affected.`);
				reaction.devotion += 4;
			} else if (slave.devotion >= -20) {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to know that it means ${he} may now be impregnated once more. ${He} understands the realities of ${his} life as a slave, but didn't expect to have ${his} waning fertility renewed. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
				reaction.trust -= 5;
			} else {
				r.push(`${He} leaves the surgery with nothing but a nonspecific ache, yet a familiar warmth, in ${his} lower abdomen, but ${he} knows enough about surgery and sex slaves to believe you have forced fertility upon ${him} again. ${He} does not understand the realities of ${his} life as a slave at a core level, so ${he}'s terrified and angry at the potential that ${he}'ll be forced to carry children. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
				reaction.trust -= 5;
				reaction.devotion -= 5;
			}
		} else {
			r.push(`${He} leaves the surgery with nothing but a nonspecific ache in ${his} lower abdomen; it won't be clear to ${him} that menopause will never be a concern for ${him} again. As with all surgery ${his} health has been slightly affected.`);
		}
		if (slave.geneMods.immortality === 1) {
			r.push(`${His} immortal body accepts the genetically modified organs as its own without protest.`);
		} else {
			r.push(`A temporary regimen of anti-rejection drugs is required while ${his} body integrates the extensively genetically modified organs, leaving ${him} feeling rather ill over the following week.`);
			healthDamage(slave, 10);
			slave.chem += 100;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFImmortalOvaries = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Implant";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.ovaryAge = -100;
		if (this._slave.preg < -1) {
			this._slave.preg = 0;
		}
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		if (V.menstruation === 1) {
			this._slave.fertPeak = 1;
		}
		return this._assemble(new App.Medicine.Surgery.Reactions.ImmortalOvaries());
	}
};


code:
App.Medicine.Surgery.Reactions.AddMPreg = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him} = getPronouns(slave);
		const r = [];

		r.push(`${He} leaves the surgery with a certain fullness in ${his} lower abdomen, ${he} knows that, despite lacking female reproductive organs, ${he} can now become pregnant.`);
		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (this._strongKnownFetish(slave, Fetish.PREGNANCY)) {
			r.push(`${He} is  filled with joy about the possibility of becoming pregnant and gleefully rubs ${his} softer belly. ${He}'s so pleased that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 4;
			reaction.devotion += 10;
		} else if (slave.devotion > 50) {
			r.push(`${He}'s grateful that you think ${his} offspring are valuable enough to give ${him} this gift, and a little nervous about how ${he}'ll perform as a mother. As with all surgery ${his} health has been slightly affected.`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			r.push(`${He} understands the realities of ${his} life as a slave, so it isn't much of a shock. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body and ${his} inevitable pregnancy.`);
			reaction.trust -= 10;
		} else {
			r.push(`${He} does not understand the realities of ${his} life as a slave at a core level, so ${he}'s terrified and angry that you have forced ${him} to become fertile in such an unnatural way. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body and ${his} inevitable pregnancy.`);
			reaction.trust -= 15;
			reaction.devotion -= 15;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.OFAddMPreg = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.AnimalType} eggType
	 * @param {string} pregDataKey
	 */
	constructor(slave, eggType, pregDataKey) {
		super(slave);
		this.eggType = eggType;
		this.pregDataKey = pregDataKey;
	}

	get name() {
		return "Implant";
	}

	get healthCost() {
		return 40;
	}

	apply(cheat) {
		this._slave.mpreg = 1;
		this._slave.eggType = this.eggType;
		this._slave.preg = 0;
		/**
		 * @type {FC.PregnancyData}
		 */
		// @ts-ignore
		const data = {};
		deepAssign(data, App.Data.misc.pregData[this.pregDataKey]);
		this._slave.pregData = data;
		if (this._slave.pubertyXX === 0 && this._slave.physicalAge >= V.fertilityAge) {
			if (V.precociousPuberty === 1) {
				this._slave.pubertyAgeXX = this._slave.physicalAge + 1;
			} else {
				this._slave.pubertyXX = 1;
			}
		}
		if (V.menstruation === 1) {
			this._slave.fertPeak = 1;
		}
		return this._assemble(new App.Medicine.Surgery.Reactions.AddMPreg());
	}
};


code:
App.Medicine.Surgery.Procedures.SizingImplantProcedure = class extends App.Medicine.Surgery.Procedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {FC.SizingImplantType} implantType
	 * @param {number} size
	 */
	constructor(slave, target, implantType, size) {
		super(slave);
		this._target = target;
		this._implantType = implantType;
		this._size = size;
	}

	get name() {
		return `${capFirstChar(this._resolveDynamic(this._implantData.name, this._size))} implants`;
	}

	get changeValue() {
		return this._size;
	}

	apply(cheat) {
		this._slave[this._target] += this._size;
		this._slave[`${this._target}Implant`] += this._size;
		this._setSlaveImplantType(this._implantType);

		if (this.changeValue >= 0) {
			return this._assemble(this._doTargetGain());
		} else {
			if (this._slave[`${this._target}Implant`] < 1) {
				this._slave[`${this._target}Implant`] = 0;
				this._setSlaveImplantType("none");
			}
			return this._assemble(this._doTargetLoss());
		}
	}

	_surgeryWorkPriceFactor() {
		return V.surgeryCost * V.localEcon / 3e4;
	}

	/**
	 * @param {FC.SizingImplantType} type
	 */
	_implantDataForType(type) {
		return App.Data.Medicine.sizingImplants[this._target][type];
	}

	/**
	 * @param {FC.SizingImplantType} type
	 * @param {number} size
	 */
	_installationHealthCost(type, size) {
		return this._implantDataForType(type).healthCostFactor.installation * size;
	}

	/**
	 * @param {FC.InstalledSizingImplantType} type
	 * @param {number} size
	 */
	_removalHealthCost(type, size) {
		return type === "none" ? 0
			: this._implantDataForType(type).healthCostFactor.removal * size;
	}

	/**
	 * @param {FC.InstalledSizingImplantType} type
	 * @param {number} size
	 */
	_installationWorkCost(type, size) {
		return type === "none" ? 0
			: this._implantDataForType(type).workCostFactor.installation * size * this._surgeryWorkPriceFactor();
	}

	/**
	 * @param {FC.InstalledSizingImplantType} type
	 * @param {number} size
	 */
	_removalWorkCost(type, size) {
		return type === "none" ? 0
			: this._implantDataForType(type).workCostFactor.removal * size * this._surgeryWorkPriceFactor();
	}

	get _implantData() {
		return this._implantDataForType(this._implantType);
	}

	get _implantName() {
		return this._resolveDynamic(this._implantData.name, this._size);
	}

	get _materialCost() {
		return this._resolveDynamic(this._implantData.specificMaterialCost, this._size) * this._size;
	}

	/**
	 * @param {*} amount Positive for fill, negative for drain
	 */
	_fillDrainMaterialCost(amount) {
		const id = this._implantData;
		return amount >= 0
			? (id.fill ? this._implantData.fill.materialCostFactor * amount : 0)
			: 0; // draining does not impose material cost as of now
	}

	/**
	 * @template {string | number} T
	 * @param {T | ((size: number) => T)} value
	 * @param {number} size
	 * @returns {T}
	 */
	_resolveDynamic(value, size) {
		return typeof value !== "function" ? value : value(size);
	}

	get _targetName() {
		switch (this._target) {
			case "boobs":
				return ["mammaries", "chest", "breasts"].random();
			case "butt":
				return ["buttocks", "posterior"].random();
			case "lips":
				return "lip";
			default:
				return this._target;
		}
	}

	/**
	 * Returns a string containing the name (depends on size) and possible volume of the implant
	 * @param {FC.SizingImplantType} type
	 * @param {number} volume
	 */
	_describeImplant(type, volume) {
		let r = this._resolveDynamic(this._implantDataForType(type).name, volume);
		const volumeDesc = this._volumeStr(volume);
		if (volumeDesc) {
			r += ` (${volumeDesc})`;
		}
		return r;
	}

	_setSlaveImplantType(implantType) {
		if (this.originalSlave[`${this._target}ImplantType`] !== implantType) {
			this._slave[`${this._target}ImplantType`] = implantType;
		}
	}

	/**
	 * @abstract
	 * @returns {App.Medicine.Surgery.SimpleReaction}
	 */
	_doTargetGain() {
		throw Error("Abstract method called");
	}
	/**
	 * @abstract
	 * @returns {App.Medicine.Surgery.SimpleReaction}
	 */
	_doTargetLoss() {
		throw Error("Abstract method called");
	}

	/**
	 * @abstract
	 * @param {number} volume
	 * @returns {string}
	 */
	_volumeStr(volume) {
		throw Error("Abstract method called");
	}

	/**
	 * @abstract
	 * @param {number} volume
	 * @returns {string}
	 */
	 _fleshExcessStr(volume) {
		throw Error("Abstract method called");
	}
};

App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.SizingImplantProcedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {FC.SizingImplantType} implantType
	 * @param {number} size how big is the implant
	 * @param {number} fleshExcess Excess flesh volume to remove for installing this implant
	 */
	constructor(slave, target, implantType, size, fleshExcess) {
		super(slave, target, implantType, size);
		this._fleshExcess = fleshExcess;
	}

	get description() {
		const {his} = getPronouns(this._slave);
		return `place ${this._describeImplant(this._implantType, this._size)} implants into ${his} ${this._targetName}`;
	}

	get note() {
		if (this._fleshExcess > 0) {
			const {his} = getPronouns(this._slave);
			return App.UI.DOM.makeElement('span',
				`Installation requires removing ${this._fleshExcessStr(this._fleshExcess)} of ${his} ${this._targetName} flesh.`, ["warning"]);
		}
		return null;
	}

	get healthCost() {
		return this._installationHealthCost(this._implantType, this._size);
	}

	get _workCost() {
		return super._workCost + super._installationWorkCost(this._implantType, this._size);
	}
};

App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase = class extends App.Medicine.Surgery.Procedures.SizingImplantProcedure {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {number} size
	 * @param {FC.SizingImplantType} [implantType]
	 */
	constructor(slave, target, size, implantType = null) {
		const oldImplantInfo = App.Medicine.implantInfo(slave, target);
		if (oldImplantInfo.type === "none") {
			throw Error(`Slave has no ${target} implant to work on`);
		}
		super(slave, target, implantType || oldImplantInfo.type, size);
		this._oldImplantInfo = oldImplantInfo;
	}

	/**
	 * @protected
	 */
	get _oldImplantsDescription() {
		return this._describeImplant(/** @type {FC.SizingImplantType}*/(this._oldImplantInfo.type), this._oldImplantInfo.volume);
	}
};

App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 */
	constructor(slave, target) {
		super(slave, target, -slave[`${target}Implant`]);
	}

	get name() {
		return `Remove implants`;
	}

	get description() {
		const {his} = getPronouns(this._slave);
		return `remove ${his} ${this._oldImplantsDescription} implants`;
	}

	get _materialCost() {
		return 0;
	}

	get _workCost() {
		return super._workCost + super._removalWorkCost(this._implantType, -this._size);
	}

	get healthCost() {
		return this._removalHealthCost(this._implantType, -this._size);
	}
};

App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {FC.SizingImplantType} implantType
	 * @param {number} size how big is the implant
	 * @param {number} fleshExcess Excess flesh volume to remove for installing this implant
	 */
	constructor(slave, target, implantType, size, fleshExcess) {
		super(slave, target, size, implantType);
		this._fleshExcess = fleshExcess;
	}

	get description() {
		const {his} = getPronouns(this._slave);
		return `replace ${his} ${this._oldImplantsDescription} implants with ${this._describeImplant(this._implantType, this._size)} ones`;
	}

	get note() {
		if (this._fleshExcess > 0) {
			const {his} = getPronouns(this._slave);
			return App.UI.DOM.makeElement('span',
				`Installation of the new implant requires removing ${this._fleshExcessStr(this._fleshExcess)} of ${his} ${this._targetName} flesh.`, ["warning"]);
		}
		return null;
	}

	get healthCost() {
		let removeCost = this._removalHealthCost(this._oldImplantInfo.type, this._oldImplantInfo.volume);
		let implantCost = this._installationHealthCost(this._implantType, this._size);
		return Math.max(removeCost, implantCost) + Math.min(removeCost, implantCost) * 0.2;
	}

	get _workCost() {
		const previousImplant = App.Medicine.implantInfo(this.originalSlave, this._target);
		return super._workCost + super._removalWorkCost(previousImplant.type, previousImplant.volume) +
			this._installationWorkCost(this._implantType, this._size);
	}

	get changeValue() {
		return this._size - this._oldImplantInfo.volume;
	}

	apply(cheat) {
		this._slave[this._target] -= this._oldImplantInfo.volume;
		this._slave[`${this._target}Implant`] = 0;

		return super.apply(cheat);
	}
};

App.Medicine.Surgery.Procedures.FillSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {number} amount
	 */
	constructor(slave, target, amount) {
		super(slave, target, amount);
	}

	get name() {
		return `Add inert filler`;
	}

	get description() {
		const {his} = getPronouns(this._slave);
		const volumeStr = this._volumeStr(this._size);
		return `add ${volumeStr ? `${volumeStr} of` : 'some'} inert filler to each of ${his} ${this._oldImplantsDescription} implants`;
	}

	get _materialCost() {
		return this._fillDrainMaterialCost(this._size);
	}

	get healthCost() {
		return this._implantData.fill.healthCost;
	}
};

App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {FC.SizingImplantTarget} target
	 * @param {number} amount
	 */
	constructor(slave, target, amount) {
		super(slave, target, -amount);
	}

	get name() {
		return `Drain inert filler`;
	}

	get description() {
		const {his} = getPronouns(this._slave);
		const volumeStr = this._volumeStr(this._size);
		return `drain ${volumeStr ? `${volumeStr} of` : 'some'} inert filler from ${his} ${this._oldImplantsDescription} implants`;
	}

	get _materialCost() {
		return 0;
	}

	get healthCost() {
		return this._implantData.drain.healthCost;
	}
};


code:
App.Medicine.Surgery.Reactions.BoobsGain = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const heGlaresDaggers = canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`;
		const r = [];

		if (diff.areolae > slave.areolae) {
			r.push(`The increase in breast size <span class="lime">stretches and broadens ${his} areolae.</span>`);
		}
		if (diff.nipples === NippleShape.CUTE && slave.nipples === NippleShape.PUFFY) {
			r.push(`The breast surgery is invasive, and when ${his} nipples heal, <span class="orange">they're a bit more normal.</span>`);
		} else if (diff.nipples === NippleShape.PUFFY && slave.nipples === NippleShape.HUGE) {
			r.push(`The breast surgery is invasive, and when ${his} nipples heal, <span class="orange">they're a bit smaller.</span>`);
		} else if (diff.nipples === NippleShape.FLAT && (slave.nipples === NippleShape.CUTE || slave.nipples === NippleShape.TINY)) {
			r.push(`The sudden increase in breast size has <span class="orange">stretched ${his} already small nipples flat.</span>`);
		}
		if (slave.boobShape !== BreastShape.SPHERICAL) {
			if (diff.boobShape === BreastShape.SPHERICAL) {
				r.push(`With so little actual flesh left, the shape of ${his} breasts are now entirely dictated by the implants within, <span class="lime">rendering them comically spherical.</span>`);
			} else if (diff.boobShape === BreastShape.NORMAL && slave.boobShape !== BreastShape.NORMAL) {
				r.push(`The natural shape of ${his} breasts has been eliminated by the cosmetic surgery, <span class="lime">rendering ${his} boobs pretty and rounded.</span>`);
			}
		}

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} shows little reaction to the new weight on ${his} chest. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 20 && this._strongKnownFetish(slave, Fetish.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 deliriously happy with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
			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.`);
			}
			r.push(`<span class="devotion inc">${He}'s happy with your changes to ${his} boobs.</span> As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			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.`);
			}
			r.push(`${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 ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
			reaction.trust -= 5;
		} else {
			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 (hasAnyArms(slave)) {
				r.push(`${He}'s still sore, so ${he} doesn't touch them, but ${heGlaresDaggers}.`);
			} else {
				r.push(`${He}'s still sore, so ${he} keeps ${his} torso still, but ${heGlaresDaggers}.`);
			}
			r.push(`${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, ${he} seems to view these fake breasts as a cruel imposition. As with all surgery ${his} health has been slightly affected. ${He} is now terribly afraid of your total power over ${his} body.`);
			reaction.trust -= 10;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		if (diff.areolae < slave.areolae) {
			r.push(`The breast reduction surgery also <span class="orange">slightly reduces ${his} massive areolae.</span>`);
		}
		if (slave.nipples === NippleShape.HUGE) {
			r.push(`The breast reduction surgery also <span class="orange">slightly reduces ${his} massive nipples.</span>`);
		} else if (slave.nipples === NippleShape.FUCKABLE && diff.boobs < 500) {
			r.push(`Without the tissue needed to support their unusual shape, ${his} fuckable nipples have reverted <span class="orange">to being huge and protruding.</span>`);
		} else if (slave.nipples === NippleShape.FLAT) {
			r.push(`Without the ${his} massive implants forcing them flat, ${his} nipples have reverted <span class="lime">to being huge and protruding.</span>`);
		}
		if (slave.boobShape === BreastShape.SPHERICAL) {
			r.push(`With the removal of ${his} load bearing implants, <span class="orange">${his} breasts are left deflated and sagging.</span>`);
		}

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} shows little awareness that ${his} breasts are smaller. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 50) {
			if (hasAnyArms(slave)) {
				r.push(`${He} hefts ${his} new, sleeker breasts experimentally and turns to you with a smile to show off ${his} new, slimmer form. ${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} smaller breasts move and turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't bounce too much.`);
			}
			r.push(`<span class="devotion inc">${He}'s happy with your changes to ${his} boobs.</span> As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} new, smaller breasts skeptically.`);
			} else {
				r.push(`${He} attempts to sway ${his} big tits experimentally, only to find them substantially less bouncy.`);
			}
			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.`);
			}
			r.push(`${He}'s come to terms with the fact that ${he}'s a slave, but ${he} expected something other than this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
			reaction.trust -= 5;
		} else {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} sudden lack of ${his} former breasts with resentment.`);
			} else {
				r.push(`The sudden lack of weight on ${his} chest fills ${him} with resentment.`);
			}
			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,`);
			}
			r.push(`but ${canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`}.`);
			r.push(`${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, ${he} seems to view this surgical theft as a cruel imposition. As with all surgery ${his} health has been slightly affected. ${He} is now terribly afraid of your total power over ${his} body.`);
			reaction.trust -= 10;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

/**
 * @type {FC.Medicine.AssetSizingProcedureSet}
 */
App.Medicine.Surgery.Procedures.boobImplantsProcedure = function() {
	/**
	 * @param {FC.SlaveState} slave
	 */
	const applyBoobsGain = (slave) => {
		if (slave.areolae < 2 && Math.random() > 0.7) {
			slave.areolae += 1;
		}
		if (slave.nipples === NippleShape.PUFFY) {
			if (Math.random() > 0.7) {
				slave.nipples = NippleShape.CUTE;
			}
		} else if (slave.nipples === NippleShape.HUGE) {
			if (Math.random() > 0.9) {
				slave.nipples = NippleShape.PUFFY;
			}
		} else if ((slave.nipples === NippleShape.CUTE || slave.nipples === NippleShape.TINY) && (slave.boobsImplant / slave.boobs >= 0.75)) {
			slave.nipples = NippleShape.FLAT;
		}
		if (slave.boobShape !== BreastShape.SPHERICAL) {
			if (slave.boobsImplant / slave.boobs >= 0.90) {
				slave.boobShape = BreastShape.SPHERICAL;
			} else if (slave.boobShape !== BreastShape.NORMAL && Math.random() > 0.5) {
				slave.boobShape = BreastShape.NORMAL;
			}
		}
		if (!["fillable", "advanced fillable", "hyper fillable"].includes(slave.boobsImplantType) && ["all", "TnA", "mombod", "boobsImplant"].includes(slave.cervixImplantTarget)) {
			slave.cervixImplantTarget = "none";
		}
	};

	/**
	 * @param {FC.SlaveState} slave
	 */
	const applyBoobsLoss = (slave) => {
		if (slave.areolae > 2) {
			slave.areolae -= 1;
		}
		if (slave.nipples === NippleShape.HUGE) {
			slave.nipples = NippleShape.PUFFY;
		} else if (slave.nipples === NippleShape.FUCKABLE && slave.boobs < 500) {
			slave.nipples = NippleShape.HUGE;
		} else if (slave.nipples === NippleShape.FLAT) {
			slave.nipples = NippleShape.HUGE;
		}
		if (slave.boobShape === BreastShape.SPHERICAL) {
			slave.boobShape = BreastShape.SAGGY;
		}
		if (!["fillable", "advanced fillable", "hyper fillable"].includes(slave.boobsImplantType) && ["all", "TnA", "mombod", "boobsImplant"].includes(slave.cervixImplantTarget)) {
			slave.cervixImplantTarget = "none";
		}
	};

	/**
	 * @template {FC.Medicine.SizingImplantProcedureConstructor} T
	 * @param {T} Procedure
	 * @param {ConstructorParameters<T>} args
	 */
	function makeBoobProcedure(Procedure, args) {
		return new (class extends Procedure {
			_doTargetGain() {
				applyBoobsGain(this._slave);
				return new App.Medicine.Surgery.Reactions.BoobsGain();
			}

			_doTargetLoss() {
				applyBoobsLoss(this._slave);
				return new App.Medicine.Surgery.Reactions.BoobsLoss();
			}

			/**
			 * @param {number} volume
			 * @returns {string}
			 */
			_volumeStr(volume) {
				return V.showBoobCCs ? App.Utils.expandHTML(`${volume} cm³`) : '';
			}

			/**
			 * @param {number} volume
			 * @returns {string}
			 */
			_fleshExcessStr(volume) {
				const percentsStr = `${Math.round(100.0 * volume / App.Medicine.fleshSize(this.originalSlave, "boobs"))} %`;

				return V.showBoobCCs
					? App.Utils.expandHTML(`${volume} cm³ (${percentsStr})`)
					: App.Utils.expandHTML(percentsStr);
			}
		})(...args);
	}

	class Reduce extends App.Medicine.Surgery.Procedure {
		/**
		 * @param {FC.SlaveState} slave
		 * @param {string} procedureName
		 * @param {number} amount
		 */
		constructor(slave, procedureName, amount) {
			super(slave);
			this._procedureName = capFirstChar(procedureName);
			this._amount = amount;
		}

		get name() {
			return `${this._procedureName} boobs`;
		}

		get description() {
			const {his} = getPronouns(this._slave);
			return `${this._procedureName} ${his} boobs`;
		}

		get healthCost() { return 5; }

		get changeValue() { return -this._amount; }

		apply(cheat) {
			this._slave.boobs -= this._amount;

			applyBoobsLoss(this._slave);

			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsLoss());
		}
	}

	return {
		install: (slave, type, size, fleshExcess) =>
			makeBoobProcedure(App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure, [slave, "boobs", type, size, fleshExcess]),
		replace: (slave, type, size, fleshExcess) =>
			makeBoobProcedure(App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure, [slave, "boobs", type, size, fleshExcess]),
		remove: (slave) =>
			makeBoobProcedure(App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure, [slave, "boobs"]),

		fill: (slave, amount) =>
			makeBoobProcedure(App.Medicine.Surgery.Procedures.FillSizingImplantProcedure, [slave, "boobs", amount]),
		drain: (slave, amount) =>
			makeBoobProcedure(App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure, [slave, "boobs", amount]),

		reduce: (slave, name, amount) => new Reduce(slave, name, amount)
	};
}();


code:
App.Medicine.Surgery.Reactions.BreastLift = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`The changes to ${his} breasts are lost on ${him}. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 20 && this._strongKnownFetish(slave, Fetish.BOOBS)) {
			if (hasAnyArms(slave)) {
				r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new, perkier breasts despite the pain.`);
			} else {
				r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new, perkier breasts against anything ${he} can reach, despite the pain.`);
			}
			r.push(`${He}'s deliriously happy with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 4;
			reaction.devotion += 4;
		} else if (slave.devotion > 50) {
			if (hasAnyArms(slave)) {
				r.push(`${He} runs ${his}`);
				if (hasBothArms(slave)) {
					r.push(`hands`);
				} else {
					r.push(`hand`);
				}
				r.push(`over ${his} perkier breasts experimentally and turns to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't touch them much, 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} perkier tits move before ${he} turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't move too violently, but ${he} wiggles ${himself} a little to show off.`);
			}
			r.push(`<span class="devotion inc">${He}'s thrilled that you firmed up ${his} breasts.</span> As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} new, perkier breasts skeptically.`);
			} else {
				r.push(`The cool air flowing over the new location of ${his} nipples draws a skeptical expression to ${his} face.`);
			}
			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} body still.`);
			}
			r.push(`${He}'s come to terms with the fact that ${he}'s a slave, but ${he} is quite happy you'd take the time to make ${his} breasts prettier. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body and that this may be only the beginning of extensive breast surgery.`);
			reaction.devotion += 3;
			reaction.trust -= 5;
		} else {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} new, perkier breasts`);
			} else {
				r.push(`The feel of the air running over the new location of ${his} nipples fills ${him}`);
			}
			r.push(`with resentment.`);
			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,`);
			}
			r.push(`but ${canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`}.`);
			r.push(`${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. Oddly, ${he} seems to like that ${his} breasts are no longer saggy despite ${his} immediate reaction. As with all surgery ${his} health has been slightly affected. ${He} is now terribly afraid of your total power over ${his} body and fears that this is only the beginning of ${his} breast surgeries.`);
			reaction.trust -= 10;
			reaction.devotion += 2;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.BreastLift = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Breast lift";
	}

	get healthCost() {
		return 20;
	}

	apply(cheat) {
		this._slave.boobShape = BreastShape.NORMAL;
		return this._assemble(new App.Medicine.Surgery.Reactions.BreastLift());
	}
};


code:
App.Medicine.Surgery.Reactions.BreastReconstruction = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`The changes to ${his} breasts are lost on ${him}. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 20 && this._strongKnownFetish(slave, Fetish.BOOBS)) {
			if (hasAnyArms(slave)) {
				r.push(`${He}'s barely out of the surgery before ${he}'s playing with ${his} new, ${slave.boobShape} breasts despite the pain.`);
			} else {
				r.push(`${He}'s barely out of the surgery before ${he}'s rubbing ${his} new, ${slave.boobShape} breasts against anything ${he} can reach, despite the pain.`);
			}
			r.push(`${He}'s deliriously happy with your changes to what ${he} thinks of as ${his} primary sexual organs, so much so that ${he} now trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
			reaction.trust += 4;
			reaction.devotion += 4;
		} else if (slave.devotion > 50) {
			if (hasAnyArms(slave)) {
				r.push(`${He} runs ${his}`);
				if (hasBothArms(slave)) {
					r.push(`hands`);
				} else {
					r.push(`hand`);
				}
				r.push(`over ${his} ${slave.boobShape} breasts experimentally and turns to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't touch them much, 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} ${slave.boobShape} tits move before ${he} turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't move too violently, but ${he} wiggles ${himself} a little to show off.`);
			}
			r.push(`<span class="devotion inc">${He}'s happy with your changes to ${his} breasts.</span> As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} new, ${slave.boobShape} breasts skeptically.`);
			} else {
				r.push(`The cool air flowing over the new location of ${his} nipples draws a skeptical expression to ${his} face.`);
			}
			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} body still.`);
			}
			r.push(`${He}'s come to terms with the fact that ${he}'s a slave, so ${he} isn't much affected mentally despite the surprise of having ${his} breasts reshaped. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
			reaction.trust -= 5;
		} else {
			if (canSee(slave)) {
				r.push(`${He} eyes ${his} new, ${slave.boobShape} breasts`);
			} else {
				r.push(`The feel of the air running over the new location of ${his} nipples fills ${him}`);
			}
			r.push(`with resentment.`);
			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} body still,`);
			}
			r.push(`but ${canSee(slave) ? `${he} glares daggers` : `${his} face contorts with distaste`}.`);
			r.push(`${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, ${he} seems to view ${his} altered breasts as a cruel imposition. As with all surgery ${his} health has been slightly affected. ${He} is now terribly afraid of your total power over ${his} body.`);
			reaction.trust -= 10;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Procedures.BreastReconstruction = class extends App.Medicine.Surgery.Procedure {
	/**
	 *
	 * @param {FC.SlaveState} slave
	 * @param {FC.BreastShape} boobShape
	 */
	constructor(slave, boobShape) {
		super(slave);
		this._boobShape = boobShape;
	}

	get name() {
		switch (this._boobShape) {
			case BreastShape.TORPEDO:
				return "Make them torpedo-shaped";
			case BreastShape.PERKY:
				return "Reshape them to be perkier";
			case BreastShape.NORMAL:
				return "Reshape them to be more normal";
		}
		return "Invalid boobShape: " + this._boobShape;
	}

	get healthCost() {
		return 10;
	}

	apply(cheat) {
		this._slave.boobShape = this._boobShape;
		return this._assemble(new App.Medicine.Surgery.Reactions.BreastReconstruction());
	}
};


code:
App.Medicine.Surgery.Reactions.BreastShapePreservation = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his} = getPronouns(slave);
		const r = [];

		r.push(`${He} notices almost immediately the immense soreness in ${his} breasts. ${He} can't find anything off about them, but ${he} knows you did something to them. As with all surgery ${his} health has been slightly affected.`);

		reaction.longReaction.push(r);
		return reaction;
	}
};

App.Medicine.Surgery.Reactions.BreastShapePreservationFailure = class extends App.Medicine.Surgery.SimpleReaction {
	intro(slave) {
		return [];
	}

	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, His, his, him, himself} = getPronouns(slave);
		const r = [];
		const heGlaresDaggers = (canSee(slave)) ? `${he} glares daggers` : `${his} face contorts with distaste`;

		function areolaeAndNipples() {
			if (slave.areolae > 2) {
				r.push(`The emergency mastectomy also <span class="change negative">slightly reduces ${his} massive areolae.</span>`);
			}
			if (slave.nipples === NippleShape.HUGE) {
				r.push(`The emergency mastectomy also <span class="change negative">slightly reduces ${his} massive nipples.</span>`);
			} else if (slave.nipples === NippleShape.FUCKABLE) {
				r.push(`Without the tissue needed to support their unusual shape, ${his} fuckable nipples have reverted <span class="change negative">to being huge and protruding.</span>`);
			} else if (slave.nipples === NippleShape.FLAT) {
				r.push(`Without the ${his} massive implants forcing them flat, ${his} nipples have reverted <span class="change positive">to being huge and protruding.</span>`);
			}
		}

		function movement() {
			if (hasAnyArms(slave)) {
				r.push(`${His}`);
				if (!hasBothArms(slave)) {
					r.push(`hands immediately dart`);
				} else {
					r.push(`hand immediately darts`);
				}
				r.push(`to grope ${his} tits, but ${he} only ends up grabbing air. ${His} face twitches, ${his} mind unable to comprehend why this has happened to ${him}. ${His}`);
				if (!hasBothArms(slave)) {
					r.push(`hand falls to ${his} side`);
				} else {
					r.push(`hands fall to ${his} sides`);
				}
				r.push(`as ${his} will breaks.`);
			} else {
				r.push(`${He} tries to squirm, and finds ${he} is no longer pinned by ${his} tits. ${His} face twitches, ${his} mind unable to comprehend why this has happened to ${him}. ${He} sobs once as ${his} will to go on breaks apart.`);
			}
		}

		reaction.shortReaction.push(`mesh implantation <span class="health dec">has gone wrong, resulting in a mastectomy!</span>`);

		r.push(`${slave.slaveName}'s mesh implantation <span class="health dec">has gone wrong, resulting in a mastectomy!</span>`);
		if (slave.boobs >= 7000) {
			areolaeAndNipples();
			if (slave.fetish === Fetish.MINDBROKEN) {
				r.push(`As with all invasive surgery <span class="health dec">${his} health has been affected.</span>`);
			} else if (slave.sexualFlaw === SexualFlaw.BREASTEXP) {
				if (canSee(slave)) {
					r.push(`${He} can hardly believe what ${he} is seeing. The immense bust ${he} managed to grow has been all but stripped from ${him}. ${His} face fills with disbelief as ${his} flatness dawns on ${him}.`);
				} else {
					r.push(`${He} immediately notices the lack of an immense weight hanging off ${his} chest. ${His} face fills with disbelief as ${his} flatness dawns on ${him}.`);
				}
				movement();
				r.push(`${He} loved ${his} enormous breasts, and now that they are gone, ${he} has nothing to live for. Your apparent theft of ${his} obsession has broken ${his} mind. As with all invasive surgery ${his} health has been affected.`);
				applyMindbroken(slave);
				reaction.shortReaction.push(`It broke ${his} mind.`);
			} else if (this._strongKnownFetish(slave, Fetish.BOOBS) && slave.devotion <= 20) {
				if (canSee(slave)) {
					r.push(`${He} can hardly believe what ${he} is seeing. ${His} once magnificent, immense bust has been all but stripped from ${him}. ${His} face fills with resentment as ${his} flatness dawns on ${him}.`);
				} else {
					r.push(`${He} immediately notices the lack of an immense weight hanging off ${his} chest. ${His} face fills with resentment as ${his} flatness dawns on ${him}.`);
				}
				if (hasAnyArms(slave)) {
					r.push(`${He}'s still sore, so ${he} doesn't touch them, but ${heGlaresDaggers}.`);
				} else {
					r.push(`${He}'s still sore, so ${he} keeps ${his} torso still, but ${heGlaresDaggers}.`);
				}
				r.push(`${He} loved ${his} enormous breasts, and they were apparently swiped from off ${his} chest by the person ${he} was just beginning to entrust ${himself} to. ${He} sees this as a betrayal by you. As with all invasive surgery ${his} health has been affected. ${He} is now terribly afraid that you may chose to steal something else ${he} loves, even though it was your intent to preserve them.`);
				reaction.trust -= 40;
				reaction.devotion -= 20;
			} else if (slave.devotion > 50) {
				if (hasAnyArms(slave)) {
					r.push(`${He} hefts ${his} new, tiny breasts experimentally and turns to you with a smile to show off ${his} new, slimmer form, completely unaware this wasn't your intent. ${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} tiny breasts move and turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't bounce too much.`);
				}
				r.push(`${He}'s happy with your changes to ${his} boobs and thankful that you'd consider ${his} health, well-being, and ability to fuck. As with all invasive surgery ${his} health has been affected.`);
				reaction.devotion += 4;
				reaction.trust += 4;
			} else if (slave.devotion >= -20) {
				if (canSee(slave)) {
					r.push(`${He} eyes ${his} new, tiny breasts with appreciation.`);
				} else {
					r.push(`${He} attempts to sway ${his} big tits experimentally, only to find ${his} chest barely moves at all.`);
				}
				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.`);
				}
				r.push(`${He}'s come to terms with the fact that ${he}'s a slave, but both your and ${him} expected something other than this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all invasive surgery ${his} health has been affected. ${He} is thankful that you removed the literal weight off ${his} chest.`);
				reaction.trust += 5;
			} else {
				if (canSee(slave)) {
					r.push(`${He} eyes the sudden lack of ${his} former breasts with relief.`);
				} else {
					r.push(`The sudden lack of weight on ${his} chest fills ${him} with relief.`);
				}
				if (hasAnyArms(slave)) {
					r.push(`${He}'s still sore, so ${he} doesn't touch them, but ${he} breathes easier without the immense weight hanging from ${him}.`);
				} else {
					r.push(`${He}'s still sore, so ${he} keeps ${his} torso still, but ${he} breathes easier without the immense weight hanging from ${him}.`);
				}
				r.push(`${He} still thinks of ${himself} as a person, so ${he} isn't used to the idea of being surgically altered to suit your every supposed whim. For now, ${he} seems appreciative of this literal weight lifted from ${his} chest and is thankful for your consideration of ${his} health, though it may be short lived. As with all invasive surgery ${his} health has been affected.`);
				reaction.trust += 10;
				reaction.devotion += 5;
			}
		} else {
			areolaeAndNipples();
			if (slave.fetish === Fetish.MINDBROKEN) {
				r.push(`As with all invasive surgery <span class="health dec">${his} health has been affected.</span>`);
			} else if (slave.sexualFlaw === SexualFlaw.BREASTEXP) {
				if (canSee(slave)) {
					r.push(`${He} can hardly believe what ${he} is seeing. ${His} once glorious bust has been all but stripped from ${him}. ${His} face fills with disbelief as ${his} flatness dawns on ${him}.`);
				} else {
					r.push(`${He} immediately notices the lack of an immense weight hanging off ${his} chest. ${His} face fills with disbelief as ${his} flatness dawns on ${him}.`);
				}
				movement();
				r.push(`${He} loved ${his} huge breasts, and now that they are gone, ${he} has nothing to live for. Your theft of ${his} obsession has broken ${his} mind. As with all invasive surgery ${his} health has been affected.`);
				applyMindbroken(slave);
				reaction.shortReaction.push(`It broke ${his} mind.`);
			} else if (this._strongKnownFetish(slave, Fetish.BOOBS) && slave.devotion <= 20) {
				if (canSee(slave)) {
					r.push(`${He} can hardly believe what ${he} is seeing. ${His} once magnificent bust has been all but stripped from ${him}. ${His} face fills with resentment as ${his} flatness dawns on ${him}.`);
				} else {
					r.push(`${He} immediately notices the lack of an immense weight hanging off ${his} chest. ${His} face fills with resentment as ${his} flatness dawns on ${him}.`);
				}
				if (hasAnyArms(slave)) {
					r.push(`${He}'s still sore, so ${he} doesn't touch them, but ${heGlaresDaggers}.`);
				} else {
					r.push(`${He}'s still sore, so ${he} keeps ${his} torso still, but ${heGlaresDaggers}.`);
				}
				r.push(`${He} loved ${his} huge breasts, and they were apparently swiped from off ${his} chest by the person ${he} was just beginning to entrust ${himself} to. ${He} sees this as a betrayal by you. As with all invasive surgery ${his} health has been affected. ${He} is now terribly afraid that you may chose to steal something else ${he} loves, even though it was your intent to preserve them.`);
				reaction.trust -= 40;
				reaction.devotion -= 20;
			} else if (slave.devotion > 50) {
				if (hasAnyArms(slave)) {
					r.push(`${He} hefts ${his} new, tiny breasts experimentally and turns to you with a smile to show off ${his} new, slimmer form, completely unaware this wasn't your intent. ${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} tiny breasts move and turns ${his} torso to you with a smile to show them off. ${He}'s still sore, so ${he} doesn't bounce too much.`);
				}
				r.push(`<span class="devotion inc">${He}'s happy with your changes to ${his} boobs.</span> As with all invasive surgery <span class="health dec">${his} health has been affected.</span>`);
				reaction.devotion += 4;
			} else if (slave.devotion >= -20) {
				if (canSee(slave)) {
					r.push(`${He} eyes ${his} new, tiny breasts skeptically.`);
				} else {
					r.push(`${He} attempts to sway ${his} big tits experimentally, only to find ${his} chest barely moves at all.`);
				}
				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.`);
				}
				r.push(`${He}'s come to terms with the fact that ${he}'s a slave, but both your and ${him} expected something other than this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all invasive surgery ${his} health has been affected. ${He} is sensibly fearful of your total power over ${his} body.`);
				reaction.trust -= 5;
			} else {
				if (canSee(slave)) {
					r.push(`${He} eyes the sudden lack of ${his} former breasts with resentment.`);
				} else {
					r.push(`The sudden lack of weight on ${his} chest fills ${him} with resentment.`);
				}
				if (hasAnyArms(slave)) {
					r.push(`${He}'s still sore, so ${he} doesn't touch them, but ${heGlaresDaggers}.`);
				} else {
					r.push(`${He}'s still sore, so ${he} keeps ${his} torso still, but ${heGlaresDaggers}.`);
				}
				r.push(`${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, ${he} seems to view this apparent surgical theft as a cruel imposition. As with all invasive surgery ${his} health has been affected. ${He} is now terribly afraid of your total power over ${his} body.`);
				reaction.trust -= 10;
				reaction.devotion -= 5;
			}
		}
		reaction.longReaction.push(r);

		return reaction;
	}

	outro(slave, previousReaction) {
		return this._createReactionResult();
	}
};

App.Medicine.Surgery.Procedures.BreastShapePreservation = class extends App.Medicine.Surgery.Procedure {
	get name() {
		return "Implant a supportive mesh to preserve their shape";
	}

	get _workCost() {
		return this.originalSlave.boobs / 100;
	}

	get healthCost() {
		return 10;
	}

	apply(cheat) {
		// if health - boobs/1000 < random(-100, -70)
		if (this._slave.health.condition - this._slave.boobs / 1000 < (Math.random() * 30 - 100)) {
			// failure
			this._slave.breastMesh = 0;
			// additional unexpected damage
			surgeryDamage(this._slave, 30);
			cashX(V.surgeryCost, "slaveSurgery", this._slave);
			// breasts are gone
			this._slave.boobs = 300;
			if (this._slave.areolae > 2) {
				this._slave.areolae -= 1;
			}
			if (this._slave.nipples === NippleShape.HUGE) {
				this._slave.nipples = NippleShape.PUFFY;
			} else if (this._slave.nipples === NippleShape.FUCKABLE) {
				this._slave.nipples = NippleShape.HUGE;
			} else if (this._slave.nipples === NippleShape.FLAT) {
				this._slave.nipples = NippleShape.HUGE;
			}
			return this._assemble(new App.Medicine.Surgery.Reactions.BreastShapePreservationFailure());
		} else {
			// success
			this._slave.breastMesh = 1;
			return this._assemble(new App.Medicine.Surgery.Reactions.BreastShapePreservation());
		}
	}
};


code:
App.Medicine.Surgery.Reactions.ButtGain = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, him, himself} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} doesn't notice that ${his} butt has gotten larger. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 20 && this._strongKnownFetish(slave, Fetish.BUTTSLUT)) {
			r.push(`${He} gently flexes ${his} sore buttocks with a sigh of pleasure. ${He}'s deliriously happy 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 trusts your plans for ${his} body. As with all surgery ${his} health has been slightly affected.`);
			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. ${He}'s happy with your changes to ${his} ass. As with all surgery ${his} health has been slightly affected.`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			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. ${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 ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
			reaction.trust -= 5;
		} else {
			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. ${He}'s still sore, so ${he} doesn't touch them, but ${he} glares daggers. ${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, ${he} seems to view this fake ass as a cruel imposition. As with all surgery ${his} health has been slightly affected. ${He} is terribly afraid of your total power over ${his} body.`);
			reaction.trust -= 10;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};
App.Medicine.Surgery.Reactions.ButtLoss = class extends App.Medicine.Surgery.SimpleReaction {
	/**
	 * @param {FC.SlaveState} slave
	 * @param {Partial<FC.SlaveState>} diff
	 * @returns {reactionResult}
	 */
	reaction(slave, diff) {
		const reaction = super.reaction(slave, diff);
		const {He, he, his, himself} = getPronouns(slave);
		const r = [];

		if (slave.fetish === Fetish.MINDBROKEN) {
			r.push(`${He} doesn't notice that ${his} butt has gotten smaller. As with all surgery <span class="health dec">${his} health has been slightly affected.</span>`);
		} else if (slave.devotion > 50) {
			r.push(`${He}`);
			if (canSee(slave)) {
				r.push(`twists to view`);
			} else {
				r.push(`${He} jiggles`);
			}
			r.push(`${his} new, sleeker derrière and turns to you with a smile and a flirty little roll of ${his} hips. ${He}'s still sore, so ${he} doesn't bounce ${his} tighter buttocks for you, but ${he} seems happy all the same. ${He}'s happy with your changes to ${his} buttocks. As with all surgery ${his} health has been slightly affected.`);
			reaction.devotion += 4;
		} else if (slave.devotion >= -20) {
			r.push(`${He}`);
			if (canSee(slave)) {
				r.push(`twists to view`);
			} else {
				r.push(`jiggles`);
			}
			r.push(`${his} new, sleeker derrière skeptically.`);
			if (hasAnyArms(slave)) {
				r.push(`${He}'s still sore, so ${he} doesn't touch it.`);
			} else {
				r.push(`${He}'s still sore, so ${he} keeps ${his} torso still.`);
			}
			r.push(`${He}'s come to terms with the fact that ${he}'s a slave, but ${he} expected something other than this when ${he} was sent to the surgery. ${He} isn't much affected mentally. As with all surgery ${his} health has been slightly affected. ${He} is sensibly fearful of your total power over ${his} body.`);
			reaction.trust -= 5;
		} else {
			r.push(`${He} shifts ${his} diminished ass with resentment.`);
			if (hasAnyArms(slave)) {
				r.push(`${He}'s still sore, so ${he} doesn't touch it,`);
			} else {
				r.push(`${He}'s still sore, so ${he} keeps ${his} torso still,`);
			}
			r.push(`but ${(canSee(slave)) ? `${he} glares daggers` : `${his} face contorts with distaste`}.`);
			r.push(`${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, ${he} seems to view this surgical ass theft as a cruel imposition. As with all surgery ${his} health has been slightly affected. ${He} is terribly afraid of your total power over ${his} body.`);
			reaction.trust -= 10;
			reaction.devotion -= 5;
		}

		reaction.longReaction.push(r);
		return reaction;
	}
};

/**
 * @type {FC.Medicine.AssetSizingProcedureSet}
 */
App.Medicine.Surgery.Procedures.buttImplantsProcedure = function() {
	/**
	 * @param {FC.SlaveState} slave
	 */
	const applyButtChange = (slave) => {
		if (!["fillable", "advanced fillable", "hyper fillable"].includes(slave.buttImplantType) && ["all", "TnA", "bottomHeavy", "buttImplant"].includes(slave.cervixImplantTarget)) {
			slave.cervixImplantTarget = "none";
		}
	};

	/**
	 * @template {FC.Medicine.SizingImplantProcedureConstructor} T
	 * @param {T} Procedure
	 * @param {ConstructorParameters<T>} args
	 */
	 function makeButtProcedure(Procedure, args) {
		return new (class extends Procedure {
			_doTargetGain() {
				applyButtChange(this._slave);
				return new App.Medicine.Surgery.Reactions.ButtGain();
			}

			_doTargetLoss() {
				applyButtChange(this._slave);
				return new App.Medicine.Surgery.Reactions.ButtLoss();
			}

			/**
			 * @param {number} volume
			 * @returns {string}
			 */
			_volumeStr(volume) {
				return '';
			}

			/**
			 * @param {number} volume
			 * @returns {string}
			 */
			_fleshExcessStr(volume) {
				return App.Utils.expandHTML(`${Math.round(100.0 * volume / App.Medicine.fleshSize(this.originalSlave, "butt"))} %`);
			}
		})(...args);
	}

	class Reduce extends App.Medicine.Surgery.Procedure {
		/**
		 * @param {FC.SlaveState} slave
		 * @param {string} procedureName
		 * @param {number} amount
		 */
		constructor(slave, procedureName, amount) {
			super(slave);
			this._procedureName = capFirstChar(procedureName);
			this._amount = amount;
		}

		get name() {
			return `${this._procedureName} butt`;
		}

		get description() {
			const {his} = getPronouns(this._slave);
			return `${this._procedureName} ${his} butt`;
		}

		get healthCost() { return 5; }

		get changeValue() { return -this._amount; }

		apply(cheat) {
			this._slave.butt -= this._amount;
			return this._assemble(new App.Medicine.Surgery.Reactions.ButtLoss());
		}
	}

	return {
		install: (slave, type, size, fleshExcess) =>
			makeButtProcedure(App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure, [slave, "butt", type, size, fleshExcess]),
		replace: (slave, type, size, fleshExcess) =>
			makeButtProcedure(App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure, [slave, "butt", type, size, fleshExcess]),
		remove: (slave) =>
			makeButtProcedure(App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure, [slave, "butt"]),

		fill: (slave, amount) =>
			makeButtProcedure(App.Medicine.Surgery.Procedures.FillSizingImplantProcedure, [slave, "butt", amount]),
		drain: (slave, amount) =>
			makeButtProcedure(App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure, [slave, "butt", amount]),

		reduce: (slave, name, amount) => new Reduce(slave, name, amount)
	};
}();