code:
App.Ads = {};
App.Ads.Categories = {};

/* Ad categories can classify individual slaves into many values, but at the facility level they get reduced to positive, zero, and negative to see whether the ads were effective */

App.Ads.Categories.age = {
	varSuffix: "Old",

	classifySlave: function(slave) {
		if (isYoung(slave)) {
			if (slave.physicalAge >= 18) {
				return -1; // young adult
			} else if (slave.physicalAge >= 13) {
				return -2; // teen
			} else {
				return -3; // loli
			}
		}
		return 1; // mature
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSMaturityPreferentialist !== "unset") && (V.arcologies[0].FSMaturityPreferentialist >= 80)) {
			return 1; // mature
		} else if ((V.arcologies[0].FSYouthPreferentialist !== "unset") && (V.arcologies[0].FSYouthPreferentialist >= 80)) {
			return -1; // young
		}
		return 0;
	}
};

App.Ads.Categories.assetSize = {
	varSuffix: "Stacked",

	classifySlave: function(slave) {
		if (isStacked(slave)) {
			return 1;
		} else if (isSlim(slave)) {
			return -1;
		} else {
			return 0;
		}
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSAssetExpansionist !== "unset") && (V.arcologies[0].FSAssetExpansionist >= 80)) {
			return 1; // stacked
		} else if ((V.arcologies[0].FSSlimnessEnthusiast !== "unset") && (V.arcologies[0].FSSlimnessEnthusiast >= 80)) {
			return -1; // slim
		}
		return 0;
	}
};

App.Ads.Categories.assetOrigin = {
	varSuffix: "Implanted",

	classifySlave: function(slave) {
		if (isSurgicallyImproved(slave)) {
			return 1;
		} else if (isPure(slave)) {
			return -1;
		}
		return 0;
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSTransformationFetishist !== "unset") && (V.arcologies[0].FSTransformationFetishist >= 80)) {
			return 1; // implanted
		} else if ((V.arcologies[0].FSBodyPurist !== "unset") && (V.arcologies[0].FSBodyPurist >= 80)) {
			return -1; // natural
		}
		return 0;
	}
};

App.Ads.Categories.mods = {
	varSuffix: "Modded",

	classifySlave: function(slave) {
		if (SlaveStatsChecker.isModded(slave)) {
			return 1;
		} else if (SlaveStatsChecker.isUnmodded(slave)) {
			return -1;
		}
		return 0;
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSDegradationist !== "unset") && (V.arcologies[0].FSDegradationist >= 80)) {
			return 1; // modded
		} else if ((V.arcologies[0].FSBodyPurist !== "unset") && (V.arcologies[0].FSBodyPurist >= 80)) {
			return -1; // natural
		}
		return 0;
	}
};

App.Ads.Categories.preg = {
	varSuffix: "Preg",

	classifySlave: function(slave) {
		if (isPreg(slave)) {
			return 1;
		} else if (isNotPreg(slave)) {
			return -1;
		}
		return 0;
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSRepopulationFocus !== "unset") && (V.arcologies[0].FSRepopulationFocus >= 80)) {
			return 1; // pregnant
		} else if ((V.arcologies[0].FSRestart !== "unset") && (V.arcologies[0].FSRestart >= 80)) {
			return -1; // non-pregnant
		}
		return 0;
	}
};

App.Ads.Categories.genitalia = {
	varSuffix: "XX",

	classifySlave: function(slave) {
		if (slave.dick === 0 && slave.vagina > -1) {
			return 1; // pussies, no dicks
		} else if (slave.dick > 0) {
			return -1; // dicks, pussies optional
		}
		return 0; // null?
	},

	classifyLocalPreference: function() {
		if ((V.arcologies[0].FSGenderFundamentalist !== "unset") && (V.arcologies[0].FSGenderFundamentalist >= 80)) {
			return 1; // pussies, no dicks
		} else if ((V.arcologies[0].FSGenderRadicalist !== "unset") && (V.arcologies[0].FSGenderRadicalist >= 80)) {
			return -1; // dicks, pussies optional
		}
		return 0;
	}
};

/** Returns all the ad categories in the system. */
App.Ads.getAllCategories = function() {
	return _.values(App.Ads.Categories);
};

/** categorizes a girl in all the categories and returns the total categories in which she matches the advertisements */
App.Ads.getMatchedCategoryCount = function(slave, facility) {
	let matchedCategories = 0;

	for (const cat of App.Ads.getAllCategories()) {
		const result = cat.classifySlave(slave);
		if (result === V[`${facility}Ads${cat.varSuffix}`]) {
			++matchedCategories;
		}
	}

	return matchedCategories;
};

/** Manages the ads for a facility. Use example: adMgr = new App.Ads.AdManager("brothel") */
App.Ads.AdManager = class {
	constructor(facility) {
		this.varPrefix = `${facility}Ads`;
		this.totalSlaves = 0;
		this.missedBonuses = 0;
		for (const cat of App.Ads.getAllCategories()) {
			this[`tally${cat.varSuffix}`] = new Map();
		}
	}

	/** categorizes a girl in all the categories and adds the results to the running totals */
	tallySlave(slave) {
		++this.totalSlaves;
		for (const cat of App.Ads.getAllCategories()) {
			const result = cat.classifySlave(slave);
			this[`tally${cat.varSuffix}`].set(result, (this[`tally${cat.varSuffix}`].get(result) || 0) + 1);
		}
	}

	_coalesceTally(category) {
		const catMap = this[`tally${category.varSuffix}`];
		let neg = 0;
		let pos = 0;
		for (let [key, tally] of catMap) {
			if (key < 0) {
				neg += tally;
			} else if (key > 0) {
				pos += tally;
			} /* index == 0 is deliberately ignored */
		}
		return {neg, pos};
	}

	/** returns -1 if the majority of the girls have a negative value, +1 if the majority of the girls have a positive value, and 0 otherwise */
	slavesMajority(category) {
		const {neg, pos} = this._coalesceTally(category);
		if (neg > this.totalSlaves * 0.5) {
			return -1;
		} else if (pos > this.totalSlaves * 0.5) {
			return +1;
		} else {
			return 0;
		}
	}

	/** returns true if the majority of the girls fit the local preferences in the given category */
	slavesMatchPrefs(category) {
		const majority = this.slavesMajority(category);
		return (majority !== 0 && majority === category.classifyLocalPreference());
	}

	/** returns true if the majority of the girls fit the ad campaign in the given category */
	slavesMatchAds(category) {
		const majority = this.slavesMajority(category);
		return (majority !== 0 && majority === V[`${this.varPrefix}${category.varSuffix}`]);
	}

	/** returns true if the local preferences match the ad campaign in the given category */
	prefsMatchAds(category) {
		const prefs = category.classifyLocalPreference();
		return (prefs !== 0 && prefs === V[`${this.varPrefix}${category.varSuffix}`]);
	}

	/** returns -1 if the category qualifies for a variety bonus but the facility failed to get it, 1 if the category qualifies for a variety bonus and the facility got it, or 0 if it did not qualify */
	varietyBonus(category) {
		// qualifies for variety bonus only if the category has no preference, we are spending money on ads, and our ads show no preference
		if (category.classifyLocalPreference() !== 0 || V[`${this.varPrefix}Spending`] === 0 || V[`${this.varPrefix}${category.varSuffix}`] !== 0) {
			return 0;
		}
		// check to see if we achieved variety bonus
		const {neg, pos} = this._coalesceTally(category);
		if (neg > 0 && pos > 0 && Math.abs(pos - neg) <= (this.totalSlaves / 3)) {
			return 1; // got it
		} else {
			this.missedBonuses++;
			return -1; // qualified but failed
		}
	}

	overallVarietyBonus() {
		return (this.missedBonuses === 0);
	}
};

/**
 *
 * @param {string} building
 * @param {boolean} [preview]
 * @returns {DocumentFragment}
 */
App.Ads.report = function(building, preview = false) {
	/** @type {App.Entity.Facilities.Facility} */
	const facility = App.Entity.facilities[building];
	const DL = facility.employeesIDs().size;

	let adMgr = new App.Ads.AdManager(building);
	facility.employees().forEach(s => {
		adMgr.tallySlave(s);
	});
	if (facility.manager.currentEmployee) {
		adMgr.tallySlave(facility.manager.currentEmployee);
	}

	let adCampaign = {
		stacked: V[building + "AdsStacked"],
		preg: V[building + "AdsPreg"],
		modded: V[building + "AdsModded"],
		implanted: V[building + "AdsImplanted"],
		XX: V[building + "AdsXX"],
		age: V[building + "AdsOld"],
		spending: V[building + "AdsSpending"]
	};

	return report();

	function report() {
		const frag = new DocumentFragment();
		if (preview) {
			App.UI.DOM.appendNewElement("h3", frag, "Asset size");
			frag.append(stacked());
			frag.append(links("stacked"));

			App.UI.DOM.appendNewElement("h3", frag, "Asset origin");
			frag.append(implanted());
			frag.append(links("implanted"));

			App.UI.DOM.appendNewElement("h3", frag, "Body mods");
			frag.append(modded());
			frag.append(links("modded"));

			if (V.seePreg !== 0) {
				App.UI.DOM.appendNewElement("h3", frag, "Pregnancy");
				frag.append(preg());
				frag.append(links("preg"));
			}

			App.UI.DOM.appendNewElement("h3", frag, "Age");
			frag.append(age());
			frag.append(links("age"));

			if (V.seeDicks !== 0) {
				App.UI.DOM.appendNewElement("h3", frag, "Genitalia");
				frag.append(XX());
				frag.append(links("XX"));
			}
			App.UI.DOM.appendNewElement("p", frag, final());
		} else {
			App.UI.DOM.appendNewElement("p", frag, intro());
			App.UI.DOM.appendNewElement("p", frag, stacked());
			App.UI.DOM.appendNewElement("p", frag, preg());
			App.UI.DOM.appendNewElement("p", frag, modded());
			App.UI.DOM.appendNewElement("p", frag, implanted());
			App.UI.DOM.appendNewElement("p", frag, XX());
			App.UI.DOM.appendNewElement("p", frag, age());
			App.UI.DOM.appendNewElement("p", frag, final());
		}
		return frag;
	}

	function intro() {
		const frag = new DocumentFragment();
		let t = [];
		if (adCampaign.spending !== 0) {
			if (building === "brothel") {
				t.push(App.UI.DOM.makeElement("div", `An ad campaign is supporting business there, and whores that match it make more ¤.`));
			} else if (building === "club") {
				t.push(App.UI.DOM.makeElement("div", `An ad campaign is getting citizens into the ${building} every night, and sluts that match it gratify patrons.`));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function payBonus() {
		if (!preview) {
			if (building === "brothel") {
				const adsIncome = DL * random(20, 30);
				V.facility[building].adsIncome += adsIncome;
				cashX(adsIncome, (building + "Ads"));
			} else if (building === "club") {
				repX(DL * random(5, 10), (building + "Ads"));
			}
		}
	}

	function stacked() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.assetSize.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.assetSize);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.stacked}`));
		}

		// Ads
		if (adCampaign.spending !== 0) {
			if (adCampaign.stacked === 1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls with plenty up top and rears to match.`));
			} else if (adCampaign.stacked === -1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature trim girls with little in the way of T&A.`));
			} else {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature a variety of girls, some that are trim and others that are curvaceous.`));
			}
		}

		// Preferences
		if (pref === 1) {
			t.push(`Most customers prefer their girls well endowed.`);
		} else if (pref === -1) {
			t.push(`Most customers prefer their girls light.`);
		} else {
			let variety = adMgr.varietyBonus(App.Ads.Categories.assetSize);
			if (variety === 1) {
				payBonus();
				t.push(
					`The ${building} offers a`,
					App.UI.DOM.makeElement("span", `wide`, (building === "brothel") ? "yellowgreen" : "green"),
					`variety of slim and stacked slaves.`
				);
			}
			t.push(`Most customers don't mind the selection of assets.`);
		}

		// Girls
		if (girls === -1) {
			t.push(`Most of the slaves in the ${building} have small tits and asses.`);
		} else if (girls === 1) {
			t.push(`Most of the slaves in the ${building} have large tits and asses.`);
		} else {
			t.push(`The slaves in the ${building} vary in asset size.`);
		}

		// Results
		if (pref === 0) { /* customers don't care*/
		} else if (adCampaign.spending > 0) {
			if ((adCampaign.stacked === pref) && (girls === adCampaign.stacked)) {
				payBonus();
				t.push(`Its advertising for`);
				if (adCampaign.stacked === 1) {
					t.push(`stacked`);
				} else if (adCampaign.stacked === -1) {
					t.push(`trim`);
				}
				t.push(`girls matched most customers' preferences and the girls in the ${building} matched its advertisements.`);
				t.push(reputation(1));
			} else if ((adCampaign.stacked === pref) && (girls !== adCampaign.stacked)) {
				t.push(`Its advertising for`);
				if (adCampaign.stacked === 1) {
					t.push(`stacked`);
				} else if (adCampaign.stacked === -1) {
					t.push(`trim`);
				}
				t.push(`girls matched most customers preferences, but most of the girls in the ${building} were not as advertised.`);
				t.push(reputation(-1));
			} else if ((girls === pref) && (girls !== adCampaign.stacked)) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`stacked`);
				} else if (girls === -1) {
					t.push(`trim`);
				}
				t.push(`girls in the ${building} did not match its advertisements, but since the girls in the ${building} matched most customers preferences for`);
				if (pref === 1) {
					t.push(`stacked`);
				} else if (pref === -1) {
					t.push(`slim`);
				}
				t.push(`girls,`);
				t.push(reputation(0));
			} else if (girls !== pref) {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`stacked`);
				} else if (girls === -1) {
					t.push(`trim`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`stacked`);
				} else if (pref === -1) {
					t.push(`slim`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		} else {
			if (girls === pref) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`stacked`);
				} else if (girls === -1) {
					t.push(`trim`);
				}
				t.push(`girls in the ${building} match most customers' preferences for`);
				if (pref === 1) {
					t.push(`stacked`);
				} else if (pref === -1) {
					t.push(`slim`);
				}
				t.push(`girls.`);
				t.push(reputation(1));
			} else {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`stacked`);
				} else if (girls === -1) {
					t.push(`trim`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`large`);
				} else if (pref === -1) {
					t.push(`slim`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function preg() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.preg.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.preg);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.preg}`));
		}
		if (V.seePreg === 1) {
			// Ads
			if (adCampaign.spending > 0) {
				if (adCampaign.preg === 1) {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that are clearly pregnant.`));
				} else if (adCampaign.preg === -1) {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that have flat, usually firm, bellies.`));
				} else {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature some girls that are pregnant.`));
				}
			}

			// Preferences
			if (pref === 1) {
				t.push(`Most customers prefer their girls rounded with child.`);
			} else if (pref === -1) {
				t.push(`Most customers prefer girls that aren't gravid.`);
			} else {
				let variety = adMgr.varietyBonus(App.Ads.Categories.preg);
				if (variety === 1) {
					payBonus();
					t.push(
						`The ${building} offers a`,
						App.UI.DOM.makeElement("span", `wide`, (building === "brothel") ? "yellowgreen" : "green"),
						`selection of slaves with a variety of middles.`
					);
				}
				t.push(`Most customers don't have preferences for either big-bellied or flat-bellied girls.`);
			}

			// Girls
			if (girls === -1) {
				t.push(`Most of the slaves in the ${building} sport flat bellies.`);
			} else if (girls === 1) {
				t.push(`Most of the slaves in the ${building} sport gravid middles.`);
			} else {
				t.push(`The slaves in the ${building} vary in belly type.`);
			}

			// Results
			if (pref === 0) { /* customers don't care*/
			} else if (adCampaign.spending > 0) {
				if ((adCampaign.preg === pref) && (girls === adCampaign.preg)) {
					payBonus();
					t.push(`Its advertising for`);
					if (adCampaign.preg === 1) {
						t.push(`pregnant`);
					} else if (adCampaign.preg === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls matched most customers' preferences and the girls in the ${building} matched its advertisements.`);
					t.push(reputation(1));
				} else if ((adCampaign.preg === pref) && (girls !== adCampaign.preg)) {
					t.push(`Its advertising for`);
					if (adCampaign.preg === 1) {
						t.push(`pregnant`);
					} else if (adCampaign.preg === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls matched most customers' preferences, but the girls in the ${building} did not.`);
					t.push(reputation(-1));
				} else if ((girls === pref) && (girls !== adCampaign.preg)) {
					t.push(`The`);
					if (girls === 1) {
						t.push(`pregnant`);
					} else if (girls === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls in the ${building} did not match its advertisements, but since the girls in the ${building} matched most customers preferences for`);
					if (pref === 1) {
						t.push(`fecund`);
					} else if (pref === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls,`);
					t.push(reputation(0));
				} else if (girls !== pref) {
					t.push(`Some customers were put off since the`);
					if (girls === 1) {
						t.push(`pregnant`);
					} else if (girls === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls there did not match their preferences for`);
					if (pref === 1) {
						t.push(`fecund`);
					} else if (pref === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls.`);
					t.push(reputation(-1));
				}
			} else {
				if (girls === pref) {
					t.push(`The`);
					if (girls === 1) {
						t.push(`pregnant`);
					} else if (girls === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls in the ${building} match most customers' preferences for`);
					if (pref === 1) {
						t.push(`fecund`);
					} else if (pref === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls.`);
					t.push(reputation(1));
				} else {
					t.push(`Some customers were put off since the`);
					if (girls === 1) {
						t.push(`pregnant`);
					} else if (girls === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls there did not match their preferences for`);
					if (pref === 1) {
						t.push(`fecund`);
					} else if (pref === -1) {
						t.push(`flat-bellied`);
					}
					t.push(`girls.`);
					t.push(reputation(-1));
				}
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function modded() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.mods.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.mods);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.modded}`));
		}

		// Ads
		if (adCampaign.spending > 0) {
			if (adCampaign.modded === 1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that are heavily pierced and tattooed.`));
			} else if (adCampaign.modded === -1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that are free from piercings and tattoos.`));
			} else {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature some girls that are tattooed and pierced, and some that aren't.`));
			}
		}

		// Preferences
		if (pref === 1) {
			t.push(`Most customers prefer heavily modified girls.`);
		} else if (pref === -1) {
			t.push(`Most customers prefer natural girls.`);
		} else {
			let variety = adMgr.varietyBonus(App.Ads.Categories.mods);
			if (variety === 1) {
				payBonus();
				t.push(
					`The ${building} offers`,
					App.UI.DOM.makeElement("span", `both`, (building === "brothel") ? "yellowgreen" : "green"),
					`a selection of heavily altered slaves and those with more natural bodies.`
				);
			}
			t.push(`Most customers don't have preferences for either modded or natural slaves.`);
		}

		// Girls
		if (girls === 1) {
			t.push(`Most of the slaves in the ${building} are heavily pierced and tattooed.`);
		} else if (girls === -1) {
			t.push(`Most of the slaves in the ${building} have natural, unmodded bodies.`);
		} else {
			t.push(`Some girls in the ${building} have piercings or tattoos, some have none and others have both.`);
		}

		// Results
		if (pref === 0) { /* customers don't care*/
		} else if (adCampaign.spending > 0) {
			if ((adCampaign.modded === pref) && (girls === adCampaign.modded)) {
				payBonus();
				t.push(`Its advertising for`);
				if (adCampaign.modded === 1) {
					t.push(`heavily modified`);
				} else if (adCampaign.modded === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls matched most customers' preferences and the girls in the ${building} matched its advertisements.`);
				t.push(reputation(1));
			} else if ((adCampaign.modded === pref) && (girls !== adCampaign.modded)) {
				t.push(`Its advertising for`);
				if (adCampaign.modded === 1) {
					t.push(`heavily modified`);
				} else if (adCampaign.modded === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls matched most customers preferences, but the girls in the ${building} did not.`);
				t.push(reputation(-1));
			} else if ((girls === pref) && (girls !== adCampaign.modded)) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`heavily modified`);
				} else if (girls === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls in the ${building} did not match its advertisements, but since the girls in the ${building} matched most customers preferences for`);
				if (pref === 1) {
					t.push(`heavily modded`);
				} else if (pref === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls,`);
				t.push(reputation(0));
			} else if (girls !== pref) {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`heavily modified`);
				} else if (girls === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`heavily modded`);
				} else if (pref === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		} else {
			if (girls === pref) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`heavily modified`);
				} else if (girls === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls in the ${building} match most customers' preferences for`);
				if (pref === 1) {
					t.push(`heavily modded`);
				} else if (pref === -1) {
					t.push(`natural unmodded`);
				}
				t.push(`girls.`);
				t.push(reputation(1));
			} else {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`heavily modified`);
				} else if (girls === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`heavily modded`);
				} else if (pref === -1) {
					t.push(`natural bodied`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function implanted() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.assetOrigin.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.assetOrigin);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.implanted}`));
		}

		// Ads
		if (adCampaign.spending > 0) {
			if (adCampaign.implanted === 1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that are augmented by implants or improved surgically.`));
			} else if (adCampaign.implanted === -1) {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls that have all natural bodies.`));
			} else {
				t.push(App.UI.DOM.makeElement("div", `Its advertisements feature some girls that are surgically improved and implanted and some that are all-natural.`));
			}
		}

		// Preferences
		if (pref === 1) {
			t.push(`Most customers prefer heavily implanted and surgically enhanced girls.`);
		} else if (pref === -1) {
			t.push(`Most customers prefer all-natural girls.`);
		} else {
			let variety = adMgr.varietyBonus(App.Ads.Categories.assetOrigin);
			if (variety === 1) {
				payBonus();
				t.push(
					`The ${building} offers`,
					App.UI.DOM.makeElement("span", `both`, (building === "brothel") ? "yellowgreen" : "green"),
					`all-natural girls, and slaves whose beauty has been improved by surgical means.`
				);
			}
			t.push(`Most customers don't have preferences for either all-natural or surgically enhanced and implanted girls.`);
		}

		// Girls
		if (girls === 1) {
			t.push(`Most of the slaves in the ${building} are heavily implanted or surgically enhanced.`);
		} else if (girls === -1) {
			t.push(`Most of the slaves in the ${building} have naturally pure bodies.`);
		} else {
			t.push(`The slaves in the ${building} vary in body modification.`);
		}

		// Results
		if (pref === 0) { /* customers don't care*/
		} else if (adCampaign.spending > 0) {
			if ((adCampaign.implanted === pref) && (girls === adCampaign.implanted)) {
				payBonus();
				t.push(`Its advertising for`);
				if (adCampaign.implanted === 1) {
					t.push(`implanted or surgically improved`);
				} else if (adCampaign.implanted === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls matched most customers' preferences and the girls in the ${building} matched its advertisements.`);
				t.push(reputation(1));
			} else if ((adCampaign.implanted === pref) && (girls !== adCampaign.implanted)) {
				t.push(`Its advertising for`);
				if (adCampaign.implanted === 1) {
					t.push(`implanted or surgically improved`);
				} else if (adCampaign.implanted === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls matched most customers preferences, but the girls in the ${building} did not.`);
				t.push(reputation(-1));
			} else if ((girls === pref) && (girls !== adCampaign.implanted)) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`implanted or surgically improved`);
				} else if (girls === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls in the ${building} did not match its advertisements, but since the girls in the ${building} matched most customers preferences for`);
				if (pref === 1) {
					t.push(`implanted or surgically improved`);
				} else if (pref === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls,`);
				t.push(reputation(0));
			} else if (girls !== pref) {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`implanted or surgically improved`);
				} else if (girls === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`implanted or surgically improved`);
				} else if (pref === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		} else {
			if (girls === pref) {
				t.push(`The`);
				if (girls === 1) {
					t.push(`implanted or surgically improved`);
				} else if (girls === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls in the ${building} match most customers' preferences for`);
				if (pref === 1) {
					t.push(`implanted or surgically improved`);
				} else if (pref === -1) {
					t.push(`natural unmodded`);
				}
				t.push(`girls.`);
				t.push(reputation(1));
			} else {
				t.push(`Some customers were put off since the`);
				if (girls === 1) {
					t.push(`implanted or surgically improved`);
				} else if (girls === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls there did not match their preferences for`);
				if (pref === 1) {
					t.push(`implanted or surgically improved`);
				} else if (pref === -1) {
					t.push(`naturally pure`);
				}
				t.push(`girls.`);
				t.push(reputation(-1));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function XX() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.genitalia.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.genitalia);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.XX}`));
		}
		if (V.seeDicks !== 0) {
			// Ads
			if (adCampaign.spending > 0) {
				if (adCampaign.XX === 1) {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls with female genitalia.`));
				} else if (adCampaign.XX === -1) {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature girls with male genitalia.`));
				} else {
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature a variety of girls with both male and female genitalia.`));
				}
			}

			// Preferences
			if (pref === 1) {
				t.push(`Most customers prefer girls with pussies.`);
			} else if (pref === -1) {
				t.push(`Most customers prefer girls with dicks.`);
			} else {
				let variety = adMgr.varietyBonus(App.Ads.Categories.genitalia);
				if (variety === 1) {
					payBonus();
					t.push(
						`The ${building} offers a`,
						App.UI.DOM.makeElement("span", `mix`, (building === "brothel") ? "yellowgreen" : "green"),
						`of`
					);
					if (building === "brothel") {
						t.push(`whores`);
					} else {
						t.push(`sluts`);
					}
					t.push(`that can appeal to varied tastes in genitalia.`);
				}
				t.push(`Most customers don't have preferences for either girls with dicks or girls with pussies.`);
			}

			// Girls
			if (girls === 1) {
				t.push(`Most of the slaves in the ${building} have female genitalia.`);
			} else if (girls === -1) {
				t.push(`Most of the slaves in the ${building} have male genitalia.`);
			} else {
				t.push(`The slaves in the ${building} vary in genitalia.`);
			}

			// Results
			if (pref === 0) { /* customers don't care*/
			} else if (adCampaign.spending > 0) {
				if ((adCampaign.XX === pref) && (girls === adCampaign.XX)) {
					payBonus();
					t.push(`Its advertising for girls`);
					if (adCampaign.XX === 1) {
						t.push(`with pussies`);
					} else if (adCampaign.XX === -1) {
						t.push(`with dicks`);
					}
					t.push(`matches most customers' preferences as advertised.`);
					t.push(reputation(1));
				} else if ((adCampaign.XX === pref) && (girls !== adCampaign.XX)) {
					t.push(`Its advertising for girls`);
					if (adCampaign.XX === 1) {
						t.push(`with pussies`);
					} else if (adCampaign.XX === -1) {
						t.push(`with dicks`);
					}
					t.push(`matched most customers preferences, but the girls in the ${building} are not as advertised.`);
					t.push(reputation(-1));
				} else if ((girls === pref) && (girls !== adCampaign.XX)) {
					t.push(`The girls`);
					if (girls === 1) {
						t.push(`with pussies`);
					} else if (girls === -1) {
						t.push(`with dicks`);
					}
					t.push(`in the ${building} did not match the advertisements, but since the girls in the ${building} matched most customers preferences for girls`);
					if (pref === 1) {
						t.push(`with pussies,`);
					} else if (pref === -1) {
						t.push(`with dicks,`);
					}
					t.push(reputation(0));
				} else if (girls !== pref) {
					t.push(`Some customers were put off since the girls`);
					if (girls === 1) {
						t.push(`with female genitalia`);
					} else if (girls === -1) {
						t.push(`with male genitalia`);
					}
					t.push(`did not match their preferences for girls`);
					if (pref === 1) {
						t.push(`with pussies.`);
					} else if (pref === -1) {
						t.push(`with dicks.`);
					}
					t.push(reputation(-1));
				}
			} else {
				if (girls === pref) {
					t.push(`The girls in the ${building} match most customers preferences for girls`);
					if (girls === 1) {
						t.push(`with female genitalia.`);
					} else if (girls === -1) {
						t.push(`with male genitalia.`);
					}
					t.push(reputation(1));
				} else {
					t.push(`Some customers were put off since the girls`);
					if (girls === 1) {
						t.push(`with female genitalia`);
					} else if (girls === -1) {
						t.push(`with male genitalia`);
					}
					t.push(`did not match their preferences for girls`);
					if (pref === 1) {
						t.push(`with pussies.`);
					} else if (pref === -1) {
						t.push(`with dicks.`);
					}
					t.push(reputation(-1));
				}
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function age() {
		const frag = new DocumentFragment();
		let t = [];
		const pref = App.Ads.Categories.age.classifyLocalPreference();
		let girls = adMgr.slavesMajority(App.Ads.Categories.age);
		if (V.debugMode === 1) {
			t.push(App.UI.DOM.makeElement("div", `Girls: ${girls}, Pref: ${pref}, Ads: ${adCampaign.age}`));
		}

		// Ads
		if (adCampaign.spending > 0) {
			switch (adCampaign.age) {
				case 1:
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature mature slaves.`));
					break;
				case -1:
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature young slaves.`));
					break;
				case -2:
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature teenagers.`));
					break;
				case -3:
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature lolis.`));
					break;
				default:
					t.push(App.UI.DOM.makeElement("div", `Its advertisements feature slaves of a variety of ages.`));
					break;
			}
		}

		// Preferences
		if (pref === 1) {
			t.push(`Most customers prefer mature girls.`);
		} else if (pref === -1) {
			t.push(`Most customers prefer young girls.`);
		} else {
			let variety = adMgr.varietyBonus(App.Ads.Categories.age);
			if (variety === 1) {
				payBonus();
				t.push(
					`The ${building} offers girls`,
					App.UI.DOM.makeElement("span", `both`, (building === "brothel") ? "yellowgreen" : "green"),
					`young and mature.`
				);
			}
			t.push(`Most customers don't have preferences for either mature or young girls.`);
		}

		// Girls
		if (girls === -1) {
			t.push(`Most of the slaves in the ${building} are young.`);
		} else if (girls === 1) {
			t.push(`Most of the slaves in the ${building} are mature.`);
		} else {
			t.push(`The slaves in the ${building} vary in age.`);
		}

		// Results
		if (pref === 0) { /* customers don't care*/
		} else if (adCampaign.spending > 0) {
			if ((adCampaign.age === pref) && (girls === adCampaign.age)) {
				payBonus();
				t.push(`Its advertising matches most customers' age preferences and the girls in the ${building} match the ages as advertised.`);
				t.push(reputation(1));
			} else if ((adCampaign.age === pref) && (girls !== adCampaign.age)) {
				t.push(`Its advertising matched most customers age preferences, but the girls in the ${building} are not as advertised.`);
				t.push(reputation(-1));
			} else if ((girls === pref) && (girls !== adCampaign.age)) {
				t.push(`The ages of girls in the ${building} did not match the ages as advertised, but since the girls in the ${building} matched most customers age preferences,`);
				t.push(reputation(0));
			} else if (girls !== pref) {
				t.push(`Some customers were put off since the ages of girls there did not match their preferences.`);
				t.push(reputation(-1));
			}
		} else {
			if (girls === pref) {
				t.push(`The girls in the ${building} match most customers' age preferences.`);
				t.push(reputation(1));
			} else {
				t.push(`Some customers were put off since the ages of girls there did not match their preferences.`);
				t.push(reputation(-1));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function final() {
		const frag = new DocumentFragment();
		let t = [];
		if (adMgr.overallVarietyBonus()) {
			if (!preview) {
				if (building === "brothel") {
					const adsIncome = DL * random(40, 60);
					V.facility[building].adsIncome += adsIncome;
					cashX(adsIncome, (building + "Ads"));
				} else if (building === "club") {
					repX(DL * random(10, 15), (building + "Ads"));
				}
			}
			t.push(
				`There is a`,
				App.UI.DOM.makeElement("span", `perfect variety`, [(building === "brothel") ? "yellowgreen" : "green", "bold"]),
				`of slave`
			);
			if (building === "brothel") {
				t.push(`whores`);
			} else if (building === "club") {
				t.push(`sluts`);
			}
			t.push(`working in the ${building}.`);
		} else {
			if (building === "club") {
				t.push(App.UI.DOM.makeElement("div", `${capFirstChar(V.clubName)} does not offer enough variety to satisfy all visitors.`));
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function reputation(change) {
		const minBonus = 50;
		const maxBonus = 150;
		const frag = new DocumentFragment();
		let t = [];
		if (change > 0) {
			if (preview) {
				t.push(`The current campaign would <span class="green">increase</span> your reputation.`);
			} else {
				repX(random(minBonus, maxBonus), building);
				t.push(`Your <span class="green">reputation</span> increased slightly as a result.`);
			}
		} else if (change < 0) {
			if (preview) {
				t.push(`The current campaign would <span class="red">lower</span> your reputation.`);
			} else {
				repX(forceNeg(random(minBonus, maxBonus)), building);
				t.push(`Your <span class="red">reputation</span> dropped slightly as a result.`);
			}
		} else if (change === 0) {
			if (preview) {
				t.push(`your reputation would not be affected.`);
			} else {
				t.push(`your reputation was not affected.`);
			}
		}
		App.Events.addNode(frag, t, "div");
		return frag;
	}

	function links(category) {
		const linkArray = [];

		function radioLink(name, variable, value) {
			if (V[variable] !== value) {
				linkArray.push(
					App.UI.DOM.link(
						name,
						() => {
							V[variable] = value;
							App.UI.reload();
						}
					)
				);
			} else {
				linkArray.push(
					App.UI.DOM.disabledLink(name, ["Selected"])
				);
			}
			return App.UI.DOM.generateLinksStrip(linkArray);
		}

		switch (category) {
			case "stacked":
				radioLink("Stacked", `${building}AdsStacked`, 1);
				radioLink("Slim", `${building}AdsStacked`, -1);
				radioLink("Variety", `${building}AdsStacked`, 0);
				break;
			case "preg":
				radioLink("Gravid", `${building}AdsPreg`, 1);
				radioLink("None", `${building}AdsPreg`, -1);
				radioLink("Variety", `${building}AdsPreg`, 0);
				break;
			case "modded":
				radioLink("Modded", `${building}AdsModded`, 1);
				radioLink("Unmodded", `${building}AdsModded`, -1);
				radioLink("Variety", `${building}AdsModded`, 0);
				break;
			case "implanted":
				radioLink("Implants", `${building}AdsImplanted`, 1);
				radioLink("All natural", `${building}AdsImplanted`, -1);
				radioLink("Variety", `${building}AdsImplanted`, 0);
				break;
			case "XX":
				radioLink("Pussies", `${building}AdsXX`, 1);
				radioLink("Dicks", `${building}AdsXX`, -1);
				radioLink("Variety", `${building}AdsXX`, 0);
				break;
			case "age":
				radioLink("MILF", `${building}AdsOld`, 1);
				radioLink("Young", `${building}AdsOld`, -1);
				if (V.minimumSlaveAge < 18) {
					radioLink("Teen", `${building}AdsOld`, -2);
				}
				if (V.minimumSlaveAge < 13) {
					radioLink("Loli", `${building}AdsOld`, -3);
				}
				radioLink("Variety", `${building}AdsOld`, 0);
				break;
			default:
				console.log("You done fucked up. Building: " + building + " Category: " + category);
		}
		return App.UI.DOM.makeElement("div", App.UI.DOM.generateLinksStrip(linkArray));
	}
};


code:
App.Facilities.Arcade.arcade = class Arcade extends App.Facilities.Facility {
	constructor() {
		const arcade = App.Entity.facilities.arcade;
		const decommissionHandler = () => {
			V.arcade = 0;
			V.arcadeDecoration = "standard";
			V.arcadePrice = 2;
			V.arcadeUpgradeCollectors = 0;
			V.arcadeUpgradeFuckdolls = 0;
			V.arcadeUpgradeHealth = -1;
			V.arcadeUpgradeInjectors = 0;

			App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Market, "Arcade", "Markets");
		};

		super(
			arcade,
			decommissionHandler,
		);

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

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

		text.push(this.facility.nameCaps, this.decorations);

		if (this.facility.hostedSlaves > 2) {
			text.push(`It's busy. Customers are entering and exiting, leaving a few ¤ behind in the charge machines and loads of semen behind in the holes.`);
		} else if (this.facility.hostedSlaves > 0) {
			text.push(`It's understaffed; there are lines here and there for the few holes available.`);
		} else {
			text.push(`It's empty and quiet.`);
		}

		return text.join(' ');
	}

	/** @returns {string} */
	get decorations() {
		/** @type {FC.Facilities.Decoration} */
		const FS = {
			"Roman Revivalist": `is built out as a Roman street restaurant, with the bar containing the inmates. Citizens can amuse themselves at either side of the bar while enjoying some wine and olives and talking over the day's events.`,
			"Neo-Imperialist": `is built out as a Neo-Imperial temple, the banners of your house and a few other prominent noble families fluttering over the writhing bodies of the inmates. There's a lively bar and tables built out to one side where citizens can drink and relax when not enjoying themselves with the captive slaves.`,
			"Aztec Revivalist": `is built out as an Aztec stone temple, with a short stone staircase to lead the people straight to the slaves waiting in front of the establishment. A small canal leads the shed blood to the back and out of the building.`,
			"Egyptian Revivalist": `is built to look like an ancient Egyptian temple, with a long altar of sacrifice serving as the wall in which the inmates are held. Incongruously, it's piled with fresh flowers.`,
			"Edo Revivalist": `is built to look like an Edo onsen, with discreet partitions allowing citizens a modicum of privacy as they use the services here. There are baths available so they can wash themselves afterward.`,
			"Arabian Revivalist": `is built to look like a fantastical Arabian dungeon, with the inmates kept in iron cages that hold their holes in place for use.`,
			"Chinese Revivalist": `is set up to look like a rough bar in an ancient Chinese city, with the inmates immured in the bar itself. Rowdy citizens can drink and fuck the holes here while shouting and boasting over the slaves' heads.`,
			"Chattel Religionist": `is well decorated with severe religious iconography, since this place is an acceptable if not respectable place for a citizen to find relief, so long as they keep the service of the slave they use here in mind.`,
			"Degradationist": `is nothing but a system of harnesses to hold slaves in the usual posture they would hold within a normal Free Cities sex arcade. This way, no iota of their degradation here is missed.`,
			"Asset Expansionist": `is constructed so that the slaves lie within the arcade facing up. The wall itself ends at waist height, so their breasts stick up to be groped while they are used from either end.`,
			"Transformation Fetishist": `reveals more of its inmates' bodies than the typical Free Cities sex arcade. There's no attempt to hide the feeding arrangements or injection lines, since transformation into a human sex toy is considered arousing here.`,
			"Repopulationist": `is constructed so that the slaves lie within the arcade facing up. A hole is situated above them, so that their belly has room to protrude upwards as they are fucked pregnant.`,
			"Eugenics": `is designed with built in dispensers for various prophylactics. Numerous reminders to not impregnate subhumans line the walls along with offers for patrons to join the ranks of the Elite.`,
			"Gender Radicalist": `is built to reveal most of its inmate's bellies, butts, groins, and thighs. Whatever a slave here has between her legs, it's available to be fucked, played with, or abused.`,
			"Gender Fundamentalist": `is built to block the lower part of its inmates' butts from view and use. The slaves within are thus limited to their anuses for service here, but any slave can be disposed of in ${V.arcadeName} without offending fundamentalist sensibilities.`,
			"Physical Idealist": `logs customers' performance for their own athletic information. It keeps track of personal bests and all-time high scores, and pays out cash prizes to customers who fuck the holes faster, harder, or for longer than the previous record holder.`,
			"Supremacist": `is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the subhumans here is one of the main attractions.`,
			"Subjugationist": `is constructed so that the inmates' entire heads stick out of the mouth wall, though they're still masked and their jaws are held apart by ring gags. After all, seeing the anguish of the ${V.arcologies[0].FSSubjugationistRace} slaves here is one of the main attractions.`,
			"Paternalist": `is constructed so that nothing at all of the slaves is visible. The arcade is just a row of holes. In this way, good, paternalistic citizens can partake of a Free Cities sex arcade without being confronted with what they're doing.`,
			"Pastoralist": `is constructed so that the slaves lie within the arcade facing up. If a slave is lactating, her breasts are kept bare and under the maximum sustainable dose of lactation drugs, so that any penetration of her holes produces amusing squirts of milk.`,
			"Maturity Preferentialist": `is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering MILFs while using ${V.arcadeName} to get value out of useless young bitches' holes.`,
			"Youth Preferentialist": `is constructed so that nothing but the slaves' holes can be seen. This makes it possible to maintain the appearance of offering nothing but young slaves while using ${V.arcadeName} to get value out of old bitches' holes.`,
			"Body Purist": `is built out in such a way that much more of the slaves' rears and faces are visible than in a standard Free Cities sex arcade. This makes it much easier to check them for purity before using their holes.`,
			"Slimness Enthusiast": `is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: since the butts sticking out of the wall are much skinnier than usual, there's no padding to get in the way of hilting oneself in the holes.`,
			"Hedonistic": `is built in such a way so that most of a slave's ass, thighs, breasts and belly are exposed for patrons to grope and fondle. Plenty of cup holders and surfaces are available to hold one's food and drink as they enjoy their hole of choice.`,
			"Intellectual Dependency": `is barely distinguishable from a standard Free Cities sex arcade. The difference is a fun one, though: ${V.arcadeName} keeps track of the total number of orgasms each stall experiences each day and displays the current leader to encourage competition.`,
			"Slave Professionalism": `is constructed so that nothing but the slaves' holes can be seen. No details are given about the slave within, nor are their minds allowed to perceive what is happening around them.`,
			"Petite Admiration": `is barely distinguishable from a standard Free Cities sex arcade. The difference is remarkable, though: since it expects clientèle of all sizes, the stalls are easily ratcheted to the perfect height.`,
			"Statuesque Glorification": `is constructed so that the slaves' holes are lined up perfectly for the taller clientèle. This makes it possible to maintain the appearance of offering nothing but tall slaves while using ${V.arcadeName} to get value out of short bitches' holes.`,
			"standard": `is a standard Free Cities sex arcade: a pair of hallways extend away from the entrance, lined with doorless stalls like those in a public restroom. One hallway offers mouths, the other ${V.seeDicks !== 100 ? `vaginas and ` : ``}anuses.`,
		};

		const res = FS[V.arcadeDecoration];

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

		return res;
	}

	/** @returns {FC.Facilities.Expand} */
	get expand() {
		return {
			desc: `It can support ${num(V.arcade)} inmates. There ${this.facility.hostedSlaves === 1 ? `is currently ${num(this.facility.hostedSlaves)} slave` : `are currently ${num(this.facility.hostedSlaves)} slaves`} incarcerated in ${V.arcadeName}.`,
			removeSlave: "work a glory hole",
		};
	}

	/** @returns {FC.IUpgrade[]} */
	get upgrades() {
		return [
			{
				property: "arcadeUpgradeInjectors",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `It is a standard arcade. It can be upgraded to either maximize the pleasure of those that visit it at the expense of the health of the inmates, or to keep them healthy (if not happy) and milk them of useful fluids.`,
						link: `Upgrade the arcade with invasive performance-enhancing systems`,
						cost: 10000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += .1;

							App.UI.reload();
						},
						notes: [
							`increases upkeep costs`,
							`is mutually exclusive with the collectors`,
						],
						prereqs: [
							V.arcadeUpgradeCollectors < 1,
						],
					},
					{
						value: 1,
						upgraded: 2,
						text: `It has been upgraded with electroshock applicators. Whether they're enjoying themselves or not is irrelevant; they are shocked to tighten their holes regardless. You may also apply aphrodisiacs to further enhance performance.`,
						link: `Apply aphrodisiacs`,
						handler: () => V.PC.skill.engineering += .1,
						prereqs: [
							V.arcadeUpgradeCollectors < 1,
						],
					},
					{
						value: 2,
						text: `It has been upgraded with aphrodisiac injection systems and electroshock applicators. If the aphrodisiacs fail to force an orgasm from an inmate, they are shocked to tighten their holes regardless.`,
					},
				],
			},
			{
				property: "arcadeUpgradeCollectors",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The fluids produced by the inmates here can be collected and sold.`,
						link: `Retrofit the arcade to collect useful fluids`,
						cost: 10000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += .1;

							App.UI.reload();
						},
						notes: [
							`increases upkeep costs`,
							`is mutually exclusive with the injectors`,
						],
						prereqs: [
							V.arcadeUpgradeInjectors < 1,
						],
					},
					{
						value: 1,
						text: `It has been retrofitted to milk lactating slaves${V.seeDicks !== 0 ? ` and cockmilk slaves capable of ejaculating` : ``}, though less efficiently than a dedicated facility.`,
					},
				],
			},
			{
				property: "arcadeUpgradeHealth",
				tiers: [
					{
						value: -1,
						upgraded: 0,
						text: `The arcade can be upgraded to include curative injectors in order to keep inmates from succumbing under the harsh treatment. You are assured the inmates won't like their time in the arcade any better; it is purely intended to keep them functional and ready for use around the clock. It comes equipped with two settings.`,
						link: `Install curative injectors`,
						cost: 10000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += .1;

							App.UI.reload();
						},
						notes: [`will increase upkeep costs`],
					},
				],
			},
			{
				property: "arcadeUpgradeFuckdolls",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `${capFirstChar(V.arcadeName)} is not equipped to convert inmates into standard Fuckdolls.`,
						link: `Upgrade the arcade to create Fuckdolls`,
						cost: 5000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += .1;

							App.UI.reload();
						},
						notes: [`will increase upkeep costs`],
					},
				],
			},
		];
	}

	/** @returns {FC.Facilities.Rule[]} */
	get rules() {
		return [
			{
				property: "arcadeUpgradeFuckdolls",
				prereqs: [
					V.arcadeUpgradeFuckdolls > 0,
					App.Entity.facilities.arcade.hostedSlaves > 0,
				],
				options: [
					{
						get text() {
							return `You have decided that the least popular inmate will be converted to a standard Fuckdoll this week.`;
						},
						link: `Activate`,
						value: 2,
					},
					{
						get text() {
							return `The arcade has automatic Fuckdollification functions, and you can decide to convert your least popular slave at the end of the week.`;
						},
						link: `Deactivate`,
						value: 1,
					},
				],
				nodes: [
					V.arcade > App.Entity.facilities.arcade.hostedSlaves && V.fuckdolls > 0
						? `There is room in the arcade for ${V.arcade - App.Entity.facilities.arcade.hostedSlaves} menial Fuckdolls. ${V.fuckdolls > 1
							? `They'll be more efficient in the arcade, so you restrain them here.`
							: `Your Fuckdoll will be more efficient serving in the arcade, so you send it here.`}`
						: ``,
				],
			},
			{
				property: "arcadeUpgradeHealth",
				prereqs: [
					V.arcadeUpgradeHealth > -1,
				],
				options: [
					{
						get text() {
							return `It has been upgraded with curative injectors, but they are currently turned off.`;
						},
						link: `Deactivate`,
						value: 0,
					},
					{
						get text() {
							return `It has been upgraded with curative injectors, which are working normally. Inmates will be kept alive and productive, so they may be held locked in place for as long as necessary and available for use.`;
						},
						link: `Normal power`,
						value: 1,
					},
					{
						get text() {
							return `It has been upgraded with curative injectors and set to maximum power. Inmates will be kept decently healthy so they can be held locked in place for as long as necessary while remaining productive throughout.`;
						},
						link: `Maximum power`,
						value: 2,
					},
				],
			},
			{
				property: "arcadeUpgradeFuckdolls",
				prereqs: [
					V.arcadeUpgradeFuckdolls > 0,
				],
				options: [
					{
						get text() {
							return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter can be put to work on your order.`;
						},
						link: `Deactivate`,
						value: 1,
					},
					{
						get text() {
							return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert the least popular girl at the end of the week.`;
						},
						link: `Single conversion`,
						value: 2,
					},
					{
						get text() {
							return `${capFirstChar(V.arcadeName)} is equipped to convert inmates into standard Fuckdolls. The converter is currently active and will convert underperforming girls at the end of the week.`;
						},
						link: `Bulk conversion`,
						value: 3,
					},
				],
			},
		];
	}

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

repo_name: Fanatey/fc

license: mit


code:
/** @type {FC.FacilityFramework} */
App.Data.Facilities.arcade = {
	baseName: "arcade",
	genericName: null,
	jobs: {
		assignee: {
			position: "inmate",
			assignment: Job.ARCADE,
			publicSexUse: true,
			fuckdollAccepted: true
		},
	},
	defaultJob: "assignee",
	manager: null,
	decorated: true
};

App.Entity.Facilities.ArcadeJob = class extends App.Entity.Facilities.FacilitySingleJob {
	/**
	 * Can slave be employed at this position
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string[]}
	 */
	checkRequirements(slave) {
		let r = super.checkRequirements(slave);
		if (slave.indentureRestrictions > 0) {
			r.push(`${slave.slaveName}'s indenture forbids arcade service.`);
		}
		return r;
	}
};

App.Entity.facilities.arcade = new App.Entity.Facilities.SingleJobFacility(
	App.Data.Facilities.arcade,
	{
		assignee: new App.Entity.Facilities.ArcadeJob()
	}
);


code:
App.Facilities.BGSelect = function() {
	let div = document.createElement("div");
	const f = document.createDocumentFragment();

	App.UI.DOM.appendNewElement("h1", f, "Bodyguard Management");

	if (S.Bodyguard) {
		f.append(`${SlaveFullName(S.Bodyguard)} is working as your Bodyguard, remaining close to you at all times and guards your person. `);
		f.append(App.UI.DOM.link("Remove Bodyguard", () => {
			removeJob(S.Bodyguard, Job.BODYGUARD);
		},
		[], "Main"
		));

		div.append(App.UI.DOM.makeCheckbox("bodyguardTrains"), " Can train potential successors.");
		f.append(div);
	} else {
		f.append(`No Bodyguard assigned, appoint one from your devoted slaves.`);
	}

	f.append(App.UI.SlaveList.facilityManagerSelection(App.Entity.facilities.armory, "BG Select"));
	return f;
};


code:
/** @type {FC.FacilityFramework} */
App.Data.Facilities.armory = {
	baseName: "dojo",
	genericName: "Armory",
	jobs: {	},
	defaultJob: null,
	manager: {
		position: "bodyguard",
		positionAbbreviation: "BG",
		assignment: Job.BODYGUARD,
		careers: App.Data.Careers.Leader.bodyguard,
		skill: "bodyguard",
		publicSexUse: false,
		fuckdollAccepted: false,
		broodmotherAccepted: false,
		shouldWalk: true,
		shouldHold: true,
		shouldSee: true,
		shouldHear: true,
		shouldTalk: false,
		shouldThink: true,
		requiredDevotion: 51
	},
	decorated: false
};

App.Entity.Facilities.BodyguardJob = class extends App.Entity.Facilities.ManagingJob {
	/**
	 * @param {App.Entity.SlaveState} slave
	 * @returns {string[]}
	 */
	checkRequirements(slave) {
		let r = super.checkRequirements(slave);
		if (slave.breedingMark === 1 && V.propOutcome === 1 && V.eugenicsFullControl !== 1 && V.arcologies[0].FSRestart !== "unset") {
			r.push(`${slave.slaveName} may not participate in combat.`);
		}
		if (slave.indentureRestrictions > 1) {
			r.push(`${slave.slaveName}'s indenture forbids fighting.`);
		}
		return r;
	}
};

App.Entity.facilities.armory = new App.Entity.Facilities.Facility(App.Data.Facilities.armory, {}, new App.Entity.Facilities.BodyguardJob());


code:
App.UI.barracks = function() {
	const node = new DocumentFragment();
	let r = [];

	r.push(`The mercenaries you retain to protect ${V.arcologies[0].name} are housed in this sector of the arcology, which is fitted out as a modern military facility. It's much less expensive to house them here than to let them live at free quarters in the living areas of the arcology. They live somewhat apart from the society they protect, down here, but`);
	if (V.personalArms > 0 && V.invasionVictory > 0) {
		r.push(`you're always welcome here. You're their employer, but what's more important to them is that you also fought alongside them in victorious battle.`);
	} else {
		r.push(`they don't resent an unannounced visit from their employer.`);
	}
	r.push(`As you enter the main bay of the armory, lined with modern arms and armor and a few muscular, scarred men and women looking after their gear or suiting up to stand post, you're greeted respectfully, with`);
	if (V.personalArms > 0 && V.invasionVictory > 0) {
		r.push(`jaunty salutes and`);
	}
	r.push(`formal "${properTitle()}"s${(V.personalArms > 0 && V.invasionVictory > 0) ? `, but also with smiles and nods` : ``}.`);
	if (V.mercenaries >= 3) {
		r.push(`Though few of the mercenaries are visible,`);
		if (V.mercenaries >= 5) {
			r.push(`the bay is huge. There's enough equipment for a full company here.`);
		} else {
			r.push(`there's enough equipment for a full platoon here.`);
		}
	}

	if (V.mercenariesTitle !== "mercenaries") {
		r.push(`They've taken to their role as ${V.mercenariesTitle}.`);
		switch (V.mercenariesTitle) {
			case "Knights":
				r.push(`Every set of gear has some kind of chivalric device on it, and the heavier sets of powered armor are accented with a lot of burnished steel.`);
				break;
			case "Evocati":
				r.push(`The heavier sets of powered armor have Roman standards mounted on their backs, and officers' helmets are distinguished by horsehair crests.`);
				break;
			case "Black Eagles":
				r.push(`Their ultra-heavy Imperial Plate is painted universally black and yellow, and prominently marked with the crest of your noble house. The officer's helmets have golden eagles painted over the faceplate to mark their status.`);
				break;
			case "Shorn Ones":
				r.push(`The bigger sets of power armor are adorned with multiple ornaments and painted with symbols of the gods and victory.`);
				break;
			case "Imperial Guards":
				r.push(`Their prototype armor is equipped with the latest weapons and their Imperial Chinese war banner strikes fear into the foes.`);
				break;
			case "Medjay":
				r.push(`The gear is accented with bronze and animal skins. Some of the heavier armored helmets even have faceplates styled after Pharaonic death masks.`);
				break;
			case "Samurai":
				r.push(`The gear is functional, but it has a distinctive Sengoku style to it. A ceramic wakizashi is an almost universal tertiary weapon.`);
				break;
			case "Janissaries":
				r.push(`They consider themselves a caste apart, and keep to themselves, priding themselves on relentless training and perpetual readiness.`);
				break;
			case "Knights Templar":
				r.push(`All the armor includes a modernized version of a white surcoat emblazoned with the symbol of the new faith.`);
				break;
			case "Immortals":
				r.push(`The lighting in the bay has been lowered, and the gear is styled to be menacing. There's a sense of leashed danger here.`);
				break;
			case "Vast Legions":
				r.push(`Their bulky, heavily armored prototype armor strikes terror into foes and causes the earth to shake when they walk.`);
				break;
			case "Surgical Corps":
				r.push(`Their prototype armor is equipped with the latest medical equipment.`);
				break;
			case "Inglorious Bitches":
				r.push(`Their garish neon pink prototype armor shines brightly.`);
				break;
			case "Thousand Sons":
				r.push(`Their prototype armor is designed to preserve a sample of the wearer's genetic material in the event of death.`);
				break;
			case "Guardians of the Unborn":
				r.push(`Their gear is designed to be accommodating to pregnant women and even includes a special kit in case a baby needs delivering and they're the only ones around.`);
				break;
			case "Shadowed Hand":
				r.push(`Their armor prominently displays the symbol of the Societal Elite and is designed to make it perfectly clear that they mean business.`);
				break;
			case "Asgardians":
				r.push(`Their armor has been modified to allow the wearers' muscular arms to remain visible, and the heavier armor seems to be equipped with capes.`);
				break;
			case "Tasters":
				r.push(`Their armor has been modified to handle all sorts of waistlines. They contain numerous pockets and containers; it's not unusual to see a merc offering someone a needed pick-me-up.`);
				break;
			case "Knights of the Blood":
				r.push(`Their gear is adorned with the badges and ensigns of racialist societies, and posters from the same sources are visible on the walls.`);
				break;
			case "Knights of the Purge":
				r.push(`Their prototype armor is equipped with the latest weapons.`);
				break;
			case "Wardens":
				r.push(`Their gear is designed to take their foes alive and relatively unharmed, though lethal force can be applied if need be.`);
				break;
			case "Purifiers":
				r.push(`Their prototype armor is equipped with a cleansing flamethrower. In addition to striking fear into their foes it also cooks a mean steak.`);
				break;
			case "Abstemious":
				r.push(`Their sleek prototype armor is equipped with advanced restraining weapons.`);
				break;
			case "Rangers":
				r.push(`Their gear has a heavy Western influence; everyone carries heavy revolvers everywhere, and the armor sports rope lariats for lassoing 'cattle.'`);
				break;
			case "Shepherds":
				r.push(`Their gear has a rather gaudy appearance; it makes it easier to attract wayward bimbos that way when they wander off and get lost.`);
				break;
			case "Geniuses":
				r.push(`Their prototype armor is extremely complex to control, but those who can reap the benefits.`);
				break;
			case "Caretakers":
				r.push(`Their towering prototype armor lets them stand out in a crowd and guide the way for those lost underfoot.`);
				break;
			case "Titans":
				r.push(`Their prototype armor towers over the average civilian and compacts for easy storage despite its size.`);
		}
	}
	r.push(`There are doors to magazines, armories, and training areas to all sides, and muffled gunfire can be heard from the latter.`);

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

	r.push(`You head up a deck, to the staff area, and up one more, to look into the living area. It's comfortable and very well-kept, since they have a large number of slaves here to look after them. Relaxing mercenaries are scattered around the common areas, and most are enjoying a slave or two.`);
	if (V.FSAnnounced) {
		const {
			HeU, HisU,
			heU, hisU, himU, himselfU, girlU
		} = getNonlocalPronouns(V.seeDicks).appendSuffix("U");
		r.push(`They're obviously adopting the customs of ${V.arcologies[0].name}.`);
		let vignette = 0;
		if (V.arcologies[0].FSSubjugationist !== "unset" && V.arcologies[0].FSSubjugationistRace) {
			r.push(`A mercenary is fingering ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU}'s`);
			if (V.seeDicks !== 100) {
				r.push(`pussy.`);
			} else {
				r.push(`anus.`);
			}
			r.push(`${HeU}'s wincing a little; ${heU} must be new here.`);
			vignette++;
		}

		if (V.arcologies[0].FSSupremacist !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary, a woman, is being seen to by a multicultural bunch of subhumans of different races. She has one eating her out while two more are rubbing her feet.`);
			vignette++;
		}

		if (V.arcologies[0].FSGenderRadicalist !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary, who's rather obviously earned enough money to pay for the surgeries and drugs to turn herself into an imposing futanari, is pounding a dickgirl slave.`);
			vignette++;
		} else if (V.arcologies[0].FSGenderFundamentalist !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary is fucking a slave`);
			if (V.arcologies[0].FSRestart !== "unset") {
				r.push(`lotus style. His hands are greedily following ${hisU} womanly curves as they bang.`);
			} else {
				r.push(`doggy style. He's massaging ${hisU} rounded belly as ${heU} enjoys ${hisU} first foray into motherhood.`);
			}
			vignette++;
		}

		if (V.arcologies[0].FSPaternalist !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary is making out with a pretty slave. An old romantic movie is playing on a wallscreen in front of them, forgotten.`);
			vignette++;
		} else if (V.arcologies[0].FSDegradationist !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary is using a slave as a footrest as he relaxes. ${HeU} has a huge dildo up ${hisU} ass, and whenever ${heU} moves, he uses a foot to shove it farther inside ${himU}.`);
			vignette++;
		}
		if (V.arcologies[0].FSIntellectualDependency !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary is player strip poker with a pouting bimbo. ${HeU}'s completely nude and unaware that the game is over, not that the merc minds.`);
			vignette++;
		} else if (V.arcologies[0].FSSlaveProfessionalism !== "unset") {
			r.push(`${anotherMerc(vignette)} mercenary is practicing assembling and disassembling his sidearm under the learned eyes of his assisting slave. ${HeU} is making sure ${hisU} master is well prepared for the future and stroking his dick each time he does it right.`);
			vignette++;
		}

		if (V.arcologies[0].FSBodyPurist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is idly playing with a slave's natural breasts as he watches a wallscreen. He's being gentle and ${heU} doesn't seem to mind.`);
			vignette++;
		} else if (V.arcologies[0].FSTransformationFetishist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is fucking a bimbo slave doggy style. ${HisU} fake tits are so huge that the motion is making them slap together under ${himU}.`);
			vignette++;
		}

		if (V.arcologies[0].FSYouthPreferentialist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is getting a blowjob from a young slave. He's playing with ${hisU}`);
			if (hisU === "her") {
				r.push(`fresh pussy`);
			} else {
				r.push(`tight little anus`);
			}
			r.push(`as ${heU} sucks his dick.`);
			vignette++;
		} else if (V.arcologies[0].FSMaturityPreferentialist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is getting a massage from a mature slave. ${HeU}'s wearing a towel, but he sneaks a hand back and steals it, freeing ${hisU} heavy breasts.`);
			vignette++;
		}

		if (V.arcologies[0].FSSlimnessEnthusiast !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is getting a lap dance from a lithe slave. ${HeU}'s moving ${hisU} cute butt lower and lower, getting ready to impale ${himselfU} on his raging erection.`);
			vignette++;
		} else if (V.arcologies[0].FSAssetExpansionist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is almost hidden by a slave he's got in his lap. He has his head buried between ${hisU} monstrous breasts, and it's not clear how he's breathing.`);
			vignette++;
		}

		if (V.arcologies[0].FSPetiteAdmiration !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary has a petite slave sitting on a weight bar. Each rep buries ${hisU} butt in his face.`);
			vignette++;
		} else if (V.arcologies[0].FSStatuesqueGlorification !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is having sex with a rather tall slave against the lockers. He has to stand on a nearby bench in order to properly penetrate ${himU}.`);
			vignette++;
		}

		if (V.arcologies[0].FSPastoralist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is drinking a slave's milk, straight from the nipple, while idly massaging ${hisU} other breast, bringing out a thin stream of milk.`);
			vignette++;
		}

		if (V.arcologies[0].FSPhysicalIdealist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is doing push-ups with a well-endowed slave sitting on his back to add weight. ${HeU}'s counting his reps for him.`);
			vignette++;
		} else if (V.arcologies[0].FSHedonisticDecadence !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is doing squats with a rather portly slave sitting on his shoulders to add weight. ${HeU} pops a cookie into his mouth with each completed set.`);
			vignette++;
		}

		if (V.arcologies[0].FSChattelReligionist !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is mounting a praying slave from behind. It doesn't distract ${himU}; ${hisU} quiet devotions become more fervent as he fucks ${himU}.`);
			vignette++;
		}

		if (V.arcologies[0].FSRepopulationFocus !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is being ridden by an enormously pregnant slave. He's massaging ${hisU} taut belly as she uses ${hisU} hands to support ${hisU} sore boobs.`);
			vignette++;
		} else if (V.arcologies[0].FSRestart !== "unset") {
			r.push(`${yetAnotherMerc(vignette)} mercenary is being serviced by a slave with a visibly smooth crotch. He has a dildo rammed in ${hisU} ass and moves it along with ${hisU} sucking.`);
			vignette++;
		}

		if (V.arcologies[0].FSRomanRevivalist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
			// TODO:
		} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
			// TODO:
		}
	}

	if (V.mercenariesHelpCorp > 0) {
		const {
			HeU,
			heU, hisU, himU, himselfU, girlU
		} = getNonlocalPronouns(V.seeDicks).appendSuffix("U");
		App.UI.DOM.appendNewElement("p", node, `As you leave, a squad moves thunderously into the bay, fresh from a slave raid on behalf of your corporation. Most of their captures have been dropped off with the corporate receivers, but they've been given a pretty ${girlU} who isn't a good training prospect for the corporate brand, a common reward. The squad looks after their weapons and armor first, an inviolable rule, and as they do, they leave their naked slave standing in the middle of the bay, ignored. ${HeU} isn't even bound, but ${heU}'s standing nude and alone amongst modern mercenaries, so ${heU} knows that resistance is futile. So ${heU} does the only thing left available to ${himU}: try to cover ${himselfU} with ${hisU} hands and cry.`);
	}

	App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
		"Decommission the armory and return this sector to manufacturing",
		() => {
			App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Manufacturing, "Barracks", "Manufacturing");
			V.barracks = 0;
		}, [], "Main",
	));
	App.Events.addParagraph(node, r);
	return node;

	function anotherMerc(vignette) {
		if (vignette >= 3) {
			return `Yet another`;
		} else if (vignette >= 2) {
			return `A third`;
		} else if (vignette) {
			return `Another`;
		} else {
			return `A`;
		}
	}

	function yetAnotherMerc(vignette) {
		if (vignette >= V.FSCreditCount) {
			return `Finally, a`;
		} else {
			return anotherMerc(vignette);
		}
	}
};