code:
App.Intro.summary = function() {
	const el = new DocumentFragment();

	V.neighboringArcologies = variableAsNumber(V.neighboringArcologies, 0, 8, 3);
	V.FSCreditCount = variableAsNumber(V.FSCreditCount, 4, 7, 5);
	V.PC.actualAge = variableAsNumber(V.PC.actualAge, 10, 80, 35);
	V.PC.birthWeek = variableAsNumber(V.PC.birthWeek, 0, 51, 0);

	el.append(introContent());

	V.minimumSlaveAge = variableAsNumber(V.minimumSlaveAge, 3, 18, 18);
	V.retirementAge = variableAsNumber(V.retirementAge, 25, 120, 45);
	V.fertilityAge = variableAsNumber(V.fertilityAge, 3, 18, 13);
	V.potencyAge = variableAsNumber(V.potencyAge, 3, 18, 13);
	V.PC.mother = Number(V.PC.mother);
	V.PC.father = Number(V.PC.father);
	if (V.freshPC === 1 || V.saveImported === 0) {
		V.PC.origRace = V.PC.race;
		V.PC.origSkin = V.PC.skin;
		V.PC.origHColor = V.PC.hColor;
	}

	const tabBar = new App.UI.Tabs.TabBar("IntroSummary");
	tabBar.addTab("World", "world", worldContent());
	tabBar.addTab("Display", "display", App.Intro.display(true));
	tabBar.addTab("Content & Flavor", "content-and-flavor", App.Intro.contentAndFlavor(true));
	tabBar.addTab("Slaves", "slaves", slavesContent());
	tabBar.addTab("Player Character", "player", App.UI.Player.design());
	tabBar.addTab("Mods", "mods", modContent());
	el.append(tabBar.render());

	return el;

	function introContent() {
		const el = new DocumentFragment();
		App.UI.DOM.appendNewElement("div", el, `You may review your settings before clicking "Continue" to begin.`);

		const linkArray = [];
		linkArray.push(
			App.UI.DOM.link(
				"Continue",
				() => {
					if (V.freshPC === 1 || V.saveImported === 0) {
						switch (V.PC.career) {
							case "arcology owner":
								V.PC.skill.trading = 100;
								V.PC.skill.warfare = 100;
								V.PC.skill.hacking = 100;
								V.PC.skill.slaving = 100;
								V.PC.skill.engineering = 100;
								V.PC.skill.medicine = 100;
								break;
							case "wealth":
								if (V.PC.vagina === 1) {
									V.PC.vagina = 2;
								}
								V.PC.weight = 60;
								V.PC.muscles = 0;
								break;
							case "trust fund":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.warfare = -50;
								V.PC.skill.slaving = -50;
								V.PC.skill.engineering = -50;
								V.PC.skill.medicine = -50;
								V.PC.weight = 60;
								V.PC.muscles = 0;
								break;
							case "rich kid":
								V.PC.intelligenceImplant = 5;
								V.PC.skill.trading = -25;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -25;
								V.PC.weight = 60;
								V.PC.muscles = 0;
								break;
							case "capitalist":
								V.PC.skill.trading = 100;
								V.PC.muscles = 0;
								break;
							case "entrepreneur":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = 50;
								V.PC.skill.warfare = -25;
								V.PC.skill.slaving = -25;
								V.PC.skill.engineering = -25;
								V.PC.skill.medicine = -25;
								V.PC.muscles = 0;
								break;
							case "business kid":
								V.PC.intelligenceImplant = 5;
								V.PC.skill.warfare = -80;
								V.PC.skill.slaving = -80;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 0;
								break;
							case "mercenary":
								V.PC.skill.warfare = 100;
								V.PC.muscles = 50;
								break;
							case "recruit":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -25;
								V.PC.skill.warfare = 50;
								V.PC.skill.slaving = -25;
								V.PC.skill.engineering = -25;
								V.PC.skill.medicine = -25;
								V.PC.muscles = 40;
								break;
							case "child soldier":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -100;
								V.PC.skill.slaving = -80;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -80;
								break;
							case "slaver":
								V.PC.skill.slaving = 100;
								V.PC.muscles = 50;
								break;
							case "slave overseer":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -20;
								V.PC.skill.warfare = -20;
								V.PC.skill.slaving = 50;
								V.PC.skill.engineering = -25;
								V.PC.skill.medicine = -20;
								V.PC.muscles = 50;
								break;
							case "slave tender":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -60;
								V.PC.skill.hacking = -100;
								V.PC.muscles = 10;
								break;
							case "engineer":
								V.PC.skill.engineering = 100;
								break;
							case "construction":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -25;
								V.PC.skill.warfare = -50;
								V.PC.skill.slaving = -25;
								V.PC.skill.engineering = 50;
								V.PC.skill.medicine = -25;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 50;
								break;
							case "worksite helper":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -80;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = 0;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -100;
								break;
							case "medicine":
								V.PC.skill.medicine = 100;
								V.PC.muscles = 0;
								break;
							case "medical assistant":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -25;
								V.PC.skill.warfare = -50;
								V.PC.skill.slaving = -25;
								V.PC.skill.engineering = 50;
								V.PC.skill.medicine = -25;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 0;
								break;
							case "nurse":
								V.PC.intelligenceImplant = 5;
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 0;
								break;
							case "celebrity":
								if (V.PC.vagina === 1) {
									V.PC.vagina = 2;
								}
								V.PC.muscles = -20;
								break;
							case "rising star":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -50;
								V.PC.skill.warfare = -50;
								V.PC.skill.slaving = -50;
								V.PC.skill.engineering = -50;
								V.PC.skill.medicine = -50;
								V.PC.muscles = -20;
								break;
							case "child star":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 0;
								break;
							case "BlackHat":
								V.PC.skill.hacking = 100;
								V.PC.muscles = -20;
								break;
							case "hacker":
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = -50;
								V.PC.skill.warfare = -50;
								V.PC.skill.slaving = -50;
								V.PC.skill.engineering = -50;
								V.PC.skill.medicine = -50;
								V.PC.skill.hacking = 50;
								V.PC.muscles = -20;
								break;
							case "script kiddy":
								V.PC.intelligenceImplant = 5;
								V.PC.skill.trading = -80;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -80;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = 20;
								V.PC.muscles = -20;
								break;
							case "escort":
								if (V.PC.vagina >= 0) {
									V.PC.vagina = 4;
								}
								V.PC.anus = 1;
								V.PC.clothes = "a slutty outfit";
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = 50;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = 10;
								V.PC.skill.hacking = 10;
								V.PC.muscles = 0;
								break;
							case "prostitute":
								if (V.PC.vagina >= 0) {
									V.PC.vagina = 3;
								}
								V.PC.anus = 1;
								V.PC.clothes = "a slutty outfit";
								V.PC.intelligenceImplant = 0;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -50;
								V.PC.skill.hacking = -20;
								V.PC.muscles = 0;
								break;
							case "child prostitute":
								if (V.PC.vagina >= 0) {
									V.PC.vagina = 2;
								}
								V.PC.anus = 1;
								V.PC.clothes = "a slutty outfit";
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -50;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -80;
								V.PC.muscles = -20;
								break;
							case "servant":
								V.PC.clothes = "a nice maid outfit";
								V.PC.intelligenceImplant = 0;
								if (V.PC.vagina >= 1) {
									V.PC.vagina = 3;
								}
								if (V.PC.vagina >= 0) {
									V.PC.geneticQuirks.fertility = 2;
								}
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -100;
								V.PC.muscles = 0;
								V.PC.geneticQuirks.fertility = 1;
								break;
							case "handmaiden":
								V.PC.clothes = "a nice maid outfit";
								V.PC.intelligenceImplant = 0;
								if (V.PC.vagina >= 1) {
									V.PC.vagina = 3;
								}
								if (V.PC.vagina >= 0) {
									V.PC.geneticQuirks.fertility = 2;
								}
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -100;
								V.PC.muscles = 0;
								V.PC.geneticQuirks.fertility = 1;
								break;
							case "child servant":
								V.PC.clothes = "a nice maid outfit";
								V.PC.intelligenceImplant = 0;
								if (V.PC.vagina >= 1) {
									V.PC.vagina = 2;
								}
								if (V.PC.vagina >= 0) {
									V.PC.geneticQuirks.fertility = 2;
								}
								V.PC.skill.trading = -100;
								V.PC.skill.warfare = -100;
								V.PC.skill.slaving = -100;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -100;
								V.PC.muscles = 0;
								V.PC.geneticQuirks.fertility = 1;
								break;
							case "gang":
								if (V.PC.vagina === 1) {
									V.PC.vagina = 2;
								}
								V.PC.intelligenceImplant = 15;
								V.PC.skill.trading = 50;
								V.PC.skill.warfare = 50;
								V.PC.skill.slaving = 50;
								V.PC.skill.engineering = -100;
								V.PC.skill.hacking = 50;
								V.PC.muscles = 60;
								break;
							case "hoodlum":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.warfare = -20;
								V.PC.skill.slaving = -20;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -50;
								V.PC.skill.hacking = 0;
								break;
							case "street urchin":
								V.PC.intelligenceImplant = 0;
								V.PC.skill.trading = -20;
								V.PC.skill.warfare = -40;
								V.PC.skill.slaving = -80;
								V.PC.skill.engineering = -100;
								V.PC.skill.medicine = -100;
								V.PC.skill.hacking = -100;
								break;
						}
						if (V.PC.rumor === "diligence") {
							V.PC.weight = 0;
							if (V.PC.muscles < 30) {
								V.PC.muscles += 20;
							}
						} else if (V.PC.rumor === "force") {
							V.PC.muscles += 20;
						}
						// I hope this works
						PCDatatypeCleanup(V.PC);

						if (V.PC.dick >= 3) {
							V.PC.geneticQuirks.wellHung = 2;
						}
						if (V.PC.title === 0) {
							V.PC.hLength = 15;
							V.PC.waist = -20;
							V.PC.voice = 2;
						}
						if (V.PC.eye.right.vision === 1 || V.PC.eye.left.vision === 1) {
							V.PC.eyewear = "corrective glasses";
						}
						if (V.PC.physicalAge >= 14) {
							if (V.PC.balls > 0) {
								V.PC.pubertyXY = 1;
							}
							if (V.PC.ovaries > 0) {
								V.PC.pubertyXX = 1;
							}
						}
						if (V.PC.pubertyXX === 0 && V.PC.pubertyXY === 0) {
							if (V.PC.actualAge < 11) {
								V.PC.energy = 20;
							} else if (V.PC.actualAge < 12) {
								V.PC.energy = 30;
							} else if (V.PC.actualAge < 13) {
								V.PC.energy = 40;
							}
						}
						if (V.PC.preg > 0 && V.PC.preg > V.PC.pregData.normalBirth / 2) {
							V.PC.lactation = 1;
						}
					}

					V.PC.birthName = V.PC.slaveName;
					V.PC.birthSurname = V.PC.slaveSurname;

					if (V.saveImported === 1 && V.freshPC === 0 && V.PC.rules.living !== "luxurious") {
						if (V.PC.rules.living === "spare") {
							V.PC.rules.living = "normal";
						} else {
							V.PC.rules.living = "luxurious";
						}
					} else if (["celebrity", "child star", "rich kid", "rising star", "trust fund", "wealth"].includes(V.PC.career)) {
						V.PC.rules.living = "normal";
					} else {
						V.PC.rules.living = "spare";
					}
					App.Intro.initNationalities();
					SectorCounts(); // Update AProsperityCap
				},
				[],
				"Starting Girls"
			)
		);

		if ((V.economy !== 100) || (V.seeDicks !== 25) || (V.continent !== "North America") || (V.internationalTrade !== 1) || (V.internationalVariety !== 1) || (V.seeRace !== 1) || (V.seeNationality !== 1) || (V.seeExtreme !== 0) || (V.seeCircumcision !== 1) || (V.seeAge !== 1) || (V.plot !== 1)) {
			linkArray.push(
				App.UI.DOM.link(
					"restore defaults",
					App.Intro.arcDefault,
					[],
					"Intro Summary"
				)
			);
		}
		linkArray.push(
			App.UI.DOM.link(
				"Cheat Start",
				() => {
					cashX(1000000, "cheating");
					V.PC.rules.living = "luxurious";
					repX(20000, "cheating");
					V.dojo += 1;
					V.cheatMode = 1;
					V.seeDesk = 0;
					V.seeFCNN = 0;
					V.sortSlavesBy = "devotion";
					V.sortSlavesOrder = "descending";
					V.sortSlavesMain = 0;
					V.rulesAssistantMain = 1;
					Object.assign(
						V.UI.slaveSummary.abbreviation,
						{
							devotion: 1,
							rules: 1,
							clothes: 2,
							health: 1,
							diet: 1,
							drugs: 1,
							race: 1,
							nationality: 1,
							genitalia: 1,
							physicals: 1,
							skills: 1,
							mental: 2
						}
					);
					V.PC.skill.trading = 100;
					V.PC.skill.warfare = 100;
					V.PC.skill.slaving = 100;
					V.PC.skill.engineering = 100;
					V.PC.skill.medicine = 100;
					V.PC.skill.hacking = 100;
					App.Intro.initNationalities();
				},
				[],
				"Starting Girls",
				"Intended for debugging: may have unexpected effects"
			)
		);
		App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray));

		return el;
	}

	function worldContent() {
		const el = new DocumentFragment();
		el.append(App.Intro.economy(true));

		App.UI.DOM.appendNewElement("h2", el, "The Free City");
		let options = new App.UI.OptionsGroup();

		options.addOption(`The Free City features <strong>${V.neighboringArcologies}</strong> arcologies in addition to your own.`, "neighboringArcologies")
			.showTextBox().addComment("Setting this to 0 will disable most content involving the rest of the Free City.");

		if (V.targetArcology.fs === "New") {
			options.addOption(`The Free City is located on <strong>${V.terrain}</strong> terrain.`, "terrain")
				.addValueList([
					["Urban", "urban"],
					["Rural", "rural"],
					["Ravine", "ravine"],
					["Marine", "marine"],
					["Oceanic", "oceanic"]
				]);

			if (V.terrain !== "oceanic") {
				options.addOption(`The Free City is located in <strong>${V.continent}</strong>.`, "continent")
					.addValue("North America").addCallback(() => V.language = "English")
					.addValue("South America").addCallback(() => V.language = "Spanish")
					.addValue("Brazil").addCallback(() => V.language = "Portuguese")
					.addValue("Western Europe").addCallback(() => V.language = "English")
					.addValue("Central Europe").addCallback(() => V.language = "German")
					.addValue("Eastern Europe").addCallback(() => V.language = "Russian")
					.addValue("Southern Europe").addCallback(() => V.language = "Italian")
					.addValue("Scandinavia").addCallback(() => V.language = "Norwegian")
					.addValue("the Middle East").addCallback(() => V.language = "Arabic")
					.addValue("Africa").addCallback(() => V.language = "Arabic")
					.addValue("Asia").addCallback(() => V.language = "Chinese")
					.addValue("Australia").addCallback(() => V.language = "English")
					.addValue("Japan").addCallback(() => V.language = "Japanese")
					.pulldown();
			}
		}

		const fsRecord = App.Data.FutureSociety.records[V.targetArcology.fs];
		if (fsRecord && fsRecord.language) {
			options.addCustom(App.UI.DOM.combineNodes(`The lingua franca of your arcology is `, App.UI.DOM.makeElement("strong", fsRecord.language), ` due to its advanced ${fsRecord.adj} society.`));
		} else {
			options.addOption("The lingua franca of your arcology is", "language")
				.addValueList(["English", "Spanish", "Arabic"]).showTextBox();
		}

		options.addOption(`The Free City could develop as many as <strong>${V.FSCreditCount}</strong> future societies.`, "FSCreditCount")
			.showTextBox().addComment("5 is default, 4 behaves the same as pre-patch 0.9.9.0, max is 7. This option cannot be changed during the game.");

		el.append(options.render());
		return el;
	}

	function modContent() {
		const el = new DocumentFragment();
		let options = new App.UI.OptionsGroup();

		options = new App.UI.OptionsGroup();

		options.addOption("The Special Force Mod is", "Toggle", V.SF)
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		options.addComment(`This mod is initially from anon1888 but expanded by SFanon offers a lategame special (started out as security but changed to special in order to try and reduce confusion with CrimeAnon's separate Security Expansion (SecExp) mod) force, that is triggered after week 72.
		It is non-canon where it conflicts with canonical updates to the base game.`);

		options.addOption("The Security Expansion Mod is", "secExpEnabled")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		options.addComment(`This mod introduces security and crime in the arcology, as well as attacks and battles.
		The mod can be activated in any moment, but it may result in unbalanced gameplay if activated very late in the game.`);

		options.addOption("Catmod is", "seeCats")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		options.addComment(`This mod allows you to start your own lategame bioengineering project, focused around creating functional catgirls for recreational purposes. The ultimate dream of any anime-addicted billionaire. After enabling, bioengineering must be manually activated from the genelab through expensive upgrades to see any of the mod's content.`);

		el.append(options.render());
		return el;
	}

	function slavesContent() {
		const el = new DocumentFragment();
		let options = new App.UI.OptionsGroup();

		options.addOption("Dynasties of enslaved royalties are", "realRoyalties")
			.addValueList([
				["Historical", 1],
				["Random", 0]
			]);

		options.addOption("Schema for ordering slave names is", "surnameOrder")
			.addValueList([
				["Country of origin", 0],
				["Name Surname", 1],
				["Surname Name", 2]
			]);

		options.addOption("Successive breeding resulting in sub-average slaves is", "inbreeding")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		el.append(options.render());

		App.UI.DOM.appendNewElement("h2", el, "Age");
		options = new App.UI.OptionsGroup();

		options.addOption("Slave aging", "seeAge")
			.addValue("Enabled", 1).on().addValue("Celebrate birthdays, but don't age.", 2).addValue("Disabled", 0).off();

		options.addOption("Slave age distribution", "pedo_mode").addComment("In loli mode most new slaves are under the age of 18. May not apply to custom slaves and slaves from specific events.")
			.addValue("Loli mode", 1, () => V.minimumSlaveAge = 5).addValue("Normal mode", 0);

		V.minimumSlaveAge = Math.clamp(V.minimumSlaveAge, 3, 18);
		options.addOption("Girls appearing in the game will be no younger than", "minimumSlaveAge").showTextBox();

		options.addOption(`Molestation of slaves younger than ${V.minimumSlaveAge} is`, "extremeUnderage")
			.addValue("Permitted", 1).on().addValue("Forbidden", 0).off();

		V.retirementAge = Math.clamp(V.retirementAge, V.minimumSlaveAge + 1, 120);
		options.addOption("Initial retirement age will be at", "retirementAge")
			.addComment("May cause issues with New Game and initial slaves if set below 45.").showTextBox();

		V.fertilityAge = Math.clamp(V.fertilityAge, 3, 18);
		options.addOption("Girls will not be able to become pregnant if their age is under", "fertilityAge").showTextBox();

		V.potencyAge = Math.clamp(V.potencyAge, 3, 18);
		options.addOption("Girls will not be able to impregnate others if their age is under", "potencyAge").showTextBox();

		options.addOption("Age penalties are", "AgePenalty").addComment("Job and career penalties due to age.")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		options.addOption("Children growing as they age is", "loliGrow")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		el.append(options.render());

		return el;
	}
};
/**
 * @param {boolean} isIntro
 * @returns {DocumentFragment}
 */
App.Intro.economy = function(isIntro) {
	const el = new DocumentFragment();
	App.UI.DOM.appendNewElement("h2", el, "Economy");

	let options = new App.UI.OptionsGroup();

	V.localEcon = V.economy;
	options.addOption("Economic climate", "baseDifficulty")
		.addValue("Very Easy", 1, () => V.economy = 200)
		.addValue("Easy", 2, () => V.economy = 125)
		.addValue("Default Difficulty", 3, () => V.economy = 100)
		.addValue("Hard", 4, () => V.economy = 80)
		.addValue("Very Hard", 5, () => V.economy = 67);

	if (V.difficultySwitch === 1) {
		V.econAdvantage = -2;
	}
	if (V.difficultySwitch === 0) {
		V.econRate = 0;
	}
	options.addOption("Economic forecast", "econRate").addComment("Some economic content requires this to be set to harder than vanilla")
		.addValue("Vanilla", 0, () => V.difficultySwitch = 0)
		.addValue("Easy", 1, () => V.difficultySwitch = 1)
		.addValue("Default", 2, () => V.difficultySwitch = 1)
		.addValue("Hard", 3, () => V.difficultySwitch = 1);

	/* Not functional yet
	All the things you need to run your arcology are getting more expensive
	if (V.incomeMod === 0) {
		while all forms of income <strong>remain static</strong>.
			[[Easier|Intro Summary][V.incomeMod = 1]]
	} else if (V.incomeMod === 1) {
		while all forms of income <strong>rise but cannot keep pace</strong>.
		[[Harder|Intro Summary][V.incomeMod = 0]] | [[Easier|Intro Summary][V.incomeMod = 2]]
	} else {
		but luckily all forms of income <strong>rise in lockstep</strong>.
		[[Harder|Intro Summary][V.incomeMod = 1]]
	}
	*/

	if (isIntro) {
		setup();
	}

	if (!V.customVariety) {
		if (isIntro) {
			options.addCustomOption("You are using standardized slave trading channels.")
				.addButton("Customize the slave trade", () => { V.customVariety = 1; V.customWA = 0; }, "Customize Slave Trade");
		}

		options.addOption("", "internationalTrade")
			.addValue("Allow intercontinental trade", 1).on().customDescription("The slave trade is <strong>international,</strong> so a wider variety of slaves will be available.")
			.addValue("Restrict the trade to continental", 0).off().customDescription("The slave trade is <strong>continental,</strong> so a narrower variety of slaves will be available.");

		if (V.internationalTrade === 1) {
			options.addOption("International slave variety is", "internationalVariety")
				.addValue("Normalized national variety", 1).customDescription("<strong>normalized,</strong> so small nations will appear nearly as much as large ones.")
				.addValue("Semi-realistic national variety", 0).customDescription("<strong>semi-realistic,</strong> so more populous nations will be more common.");
		}
	} else if (isIntro) {
		options.addCustomOption("Nationality distributions are customized.")
			.addButton("Adjust the slave trade", () => { V.customWA = 0; V.customVariety = 1; }, "Customize Slave Trade")
			.addButton("Stop customizing", () => { delete V.customVariety; });
	}
	/* closes V.customVariety is defined */

	if (V.customVariety) {
		options.addCustom(App.UI.nationalitiesDisplay());
	}

	options.addOption("", "plot")
		.addValue("Enable non-erotic events", 1).on().customDescription("Game mode: <strong>two-handed</strong>. Includes non-erotic events concerning the changing world.")
		.addValue("Disable non-erotic events", 0).off().customDescription("Game mode: <strong>one-handed</strong>. No non-erotic events concerning the changing world.");

	el.append(options.render());
	return el;

	function setup() {
		V.mods.food.cost = Math.trunc(2500 / V.economy);
		V.drugsCost = Math.trunc(10000 / V.economy);
		V.rulesCost = Math.trunc(10000 / V.economy);
		V.modCost = Math.trunc(5000 / V.economy);
		V.surgeryCost = Math.trunc(30000 / V.economy);
	}
};

App.Intro.arcDefault = function() {
	V.seeDicks = 25;
	V.economy = 100;
	V.continent = "North America";
	V.internationalTrade = 1;
	V.internationalVariety = 1;
	V.seeRace = 1;
	V.seeNationality = 1;
	V.seeExtreme = 0;
	V.seeCircumcision = 1;
	V.seeAge = 1;
	V.plot = 1;
};


code:
App.Intro.locationIntro = function() {
	const node = new DocumentFragment();

	App.Events.addParagraph(node, [
		`As the old countries crumble and technology stagnates, the gap between rich and poor increases. In order to continue living a good life without having their property taken by the mob, many of the wealthy and powerful come together to form 'Free Cities.' These are new cities on undeveloped land, in remote areas, or even afloat, fully free of any allegiance or law. These new cities are built on new ideas, with most buildings designed as futuristic, self-contained 'arcologies.' An arcology and everything in it is usually owned by a single person. And you're determined that you will soon be one of those single people.`,
		App.UI.DOM.makeElement("span", `In what part of the world is your new arcology going to be located?`, ["intro", "question"])
	]);

	const continents = new Map([
		["North America", "English"],
		["South America", "Spanish"],
		["Brazil", "Portuguese"],
		["Central Europe", "German"],
		["Western Europe", "English"],
		["Eastern Europe", "Russian"],
		["Southern Europe", "Italian"],
		["Scandinavia", "Norwegian"],
		["the Middle East", "Arabic"],
		["Africa", "Arabic"],
		["Asia", "Chinese"],
		["Japan", "Japanese"],
		["Australia", "English"],
	]);

	const linkArray = [];
	for (const [name, language] of continents) {
		linkArray.push(App.UI.DOM.passageLink(
			name,
			"Intro Summary",
			() => {
				V.continent = name;
				V.language = language;
			}
		));
	}
	node.append(App.UI.DOM.generateLinksStrip(linkArray));

	return node;
};

repo_name: Banyanael/fc

license: mit


code:
App.Intro.newGamePlus = function() {
	const node = new DocumentFragment();
	V.ui = "start";
	if (!V.hasOwnProperty("slavesToImportMax")) {
		V.slavesToImportMax = 5;
	}

	const fee = 50000 + (V.slavesToImportMax * 10000);
	setupLastWeeksCash();
	setupLastWeeksRep();

	App.UI.DOM.appendNewElement("p", node, `You have decided to start over and will be able to take a few things with you: a few slaves, a small fraction of your current reserves of money, and possibly even your experience as an arcology owner, which will give you a very powerful career background. Many of your other customizations and settings will be carried over as the defaults for your new game, but can be revised freely.`);

	if (V.cash >= fee) {
		App.Events.addNode(node, [`You have allocated funds to bring up to ${V.slavesToImportMax} slaves with you (or your equivalent) to a new arcology. It will cost ${cashFormat(fee)} to insure another slave's safe transfer. You have ${cashFormat(V.cash)} to spend.`], "div");
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Increase slave import capacity by 1.",
			() => {
				cashX(forceNeg(fee), "capEx");
				V.slavesToImportMax++;
				App.UI.reload();
			}
		));
	} else {
		App.Events.addNode(node, [`You lack the <span class="yellowgreen">${cashFormat(fee)}</span> needed to bring any more than ${V.slavesToImportMax} slaves with you (or your equivalent) to a new arcology.`], "div");
	}

	V.ngpParams = {nationality: getRevivalistNationality(), prosperity: (250 * V.arcologies[0].prosperity * V.arcologies[0].ownership)};
	if (V.freshPC === 0) {
		if (V.retainCareer === 1 && V.PC.career !== "arcology owner") {
			if (V.week > 52 || (V.PC.skill.slaving >= 100 && V.PC.skill.trading >= 100 && V.PC.skill.warfare >= 100 && V.PC.skill.engineering >= 100 && V.PC.skill.medicine >= 100 && V.PC.skill.hacking >= 100)) {
				App.Events.addNode(node, [`You have acquired a fair amount of knowledge regarding arcologies and their day-to-day management in your time spent as one's owner qualifying you as an "arcology owner"! Benefits include:`], "div");
				for (const text of [
					`20% reduced cost of construction.`,
					`Free additional starting rep along with easy rep maintenance.`,
					`Reduced mercenary costs.`,
					`An eye for gingered slaves.`,
					`An edge in all things data.`
				]) {
					App.UI.DOM.appendNewElement("div", node, text, "lime");
				}
				V.oldCareer = V.PC.career;
				if (V.retainCareer === 1) {
					App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
						"Change career.",
						() => {
							V.retainCareer = 0;
							V.PC.career = "arcology owner";
							App.UI.reload();
						}
					));
				}
			} else {
				App.UI.DOM.appendNewElement("div", node, `You lack the experience needed to qualify for a career change to "arcology owner".`);
			}
		}
		if (V.retainCareer === 0 && V.PC.career === "arcology owner") {
			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
				"Don't change career.",
				() => {
					V.retainCareer = 1;
					V.PC.career = V.oldCareer;
					App.UI.reload();
				}
			));
		}
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Start over with a new player character.",
			() => {
				V.freshPC = 1;
				V.retainCareer = 1;
				App.UI.reload();
			}
		));
	} else {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"Use existing player character.",
			() => {
				V.freshPC = 0;
				App.UI.reload();
			}
		));
	}

	if (V.cheatMode === 1) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
			"DEBUG: Add all slaves to import list",
			() => {
				V.slaves.forEach(s => assignJob(s, Job.IMPORTED));
				App.UI.reload();
			}
		));
	}
	App.UI.DOM.appendNewElement("div", node, App.Events.makeNode([
		`Select up to ${V.slavesToImportMax} slaves to be imported into a new game and then click`,
		App.UI.DOM.link(
			"here.",
			() => {
				V.saveImported = 1;
				V.oldCareer = "undefined";
			}, [], "Alpha disclaimer",
		)
	]));
	node.append(App.UI.SlaveList.listNGPSlaves());

	return node;
};


code:
App.UI.Player = {};

App.UI.Player.appearance = function(options, summary = false) {
	let option;

	options.addOption("Your nationality is", "nationality", V.PC).showTextBox()
		.addValueList(App.Data.misc.baseNationalities)
		.addComment("For best result capitalize it.").pulldown();

	options.addOption("Your race is", "race", V.PC).showTextBox()
		.addValueList(Array.from(App.Data.misc.filterRaces, (k => [k[1], k[0]])));

	if (V.cheatMode) {
		options.addOption("Your race is", "origRace", V.PC).showTextBox()
			.addValueList(Array.from(App.Data.misc.filterRaces, (k => [k[1], k[0]])));
	}

	options.addOption("You are genetically", "genes", V.PC)
		.addValue("XY").addValue("XX");

	options.addOption(`You are`, "height", V.PC).showTextBox({unit: "cm"})
		.addRange(145, 150, "<", "Petite")
		.addRange(155, 160, "<", "Short")
		.addRange(165, 170, "<", "Average")
		.addRange(180, 185, "<", "Tall")
		.addRange(190, 185, ">=", "Very tall")
		.addComment(`Average height for a ${V.PC.physicalAge} year old is ${heightToEitherUnit(Height.mean(V.PC))}`);
	option = options.addCustomOption()
		.addButton(
			"Make average",
			() => resyncSlaveHight(V.PC),
			""
		);

	options.addOption("Your skin tone is", "skin", V.PC).showTextBox()
		.addValueList(makeAList(App.Medicine.Modification.naturalSkins));

	if (V.cheatMode) {
		options.addOption("Your genetic skin tone is", "origSkin", V.PC).showTextBox()
			.addValueList(makeAList(App.Medicine.Modification.naturalSkins));
	}

	if (V.cheatMode) {
		options.addOption("Your original hair is", "origHColor", V.PC).showTextBox()
			.addValueList(makeAList(App.Medicine.Modification.Color.Primary.map(color => color.value)));
	} else {
		options.addOption("Your hair is", "hColor", V.PC).showTextBox()
			.addValueList(makeAList(App.Medicine.Modification.Color.Primary.map(color => color.value)));
	}

	options.addOption("Your genetic eye color is", "origColor", V.PC.eye).showTextBox()
		.addValueList(makeAList(App.Medicine.Modification.eyeColor.map(color => color.value)));

	options.addOption("You", "vision", V.PC.eye.right)
		.addValueList([
			["Need glasses to see properly", 1, () => { V.PC.eye.right.vision = 1; V.PC.eye.left.vision = 1; }],
			["have normal vision", 2, () => { V.PC.eye.right.vision = 2; V.PC.eye.left.vision = 2; }]
		]);

	options.addOption("Your face is", "faceShape", V.PC)
		.addValueList([
			["Normal", "normal"],
			["Androgynous", "androgynous"],
			["Masculine", "masculine"],
			["Cute", "cute"],
			["Sensual", "sensual"],
			["Exotic", "exotic"]
		]);

	options.addOption("Your body", "markings", V.PC)
		.addValueList([["Is clear of blemishes", "none"], ["Has light freckling", "freckles"], ["Has heavy freckling", "heavily freckled"]]);

	options.addOption("You have", "lips", V.PC).addValue("Thin lips", 5)
		.addValueList([
			["Normal lips", 15],
			["Kissable lips", 25],
			["Plush lips", 45],
		]);

	/* Handled by career currently
	options.addOption("You are", "weight", V.PC).addValue("Very thin", -50);
	options.addValueList([
		["Thin", -20],
		["Healthy", 0],
		["Curvy", 20],
		["Chubby", 60],
		["Fat", 100],
	])
	.showTextBox();
	*/

	option = options.addOption("Your shoulders are", "shoulders", V.PC).addValue("Very narrow", -2);
	option.addValueList([
		["Narrow", -1],
		["Average", 0],
	]);
	if (V.PC.physicalAge > 13) {
		option.addValue("Broad", 1);
	}
	if (V.PC.physicalAge > 18) {
		option.addValue("Very broad", 2);
	}

	if (V.PC.boobs >= 200 || summary) {
		if (V.PC.title === 1 && V.PC.boobs <= 200) {
			option = options.addOption("Your chest is", "boobs", V.PC).addValue("Manly", 200, () => { V.PC.boobsImplant = 0; V.PC.boobsImplantType = "none"; });
		} else {
			option = options.addOption("Your breasts are", "boobs", V.PC).addValue("Non-existent", 200, () => { V.PC.boobsImplant = 0; V.PC.boobsImplantType = "none"; });
		}
		option.addValueList([
			["A-cups", 300],
			["B-cups", 400],
			["C-cups", 500],
		]);
		if (V.PC.physicalAge <= 13) {
			option.addValueList([
				["hefty D-cups", 650],
				["heavy DD-cups", 900],
			]);
		} else {
			option.addValueList([
				["D-cups", 650],
				["DD-cups", 900],
				["F-cups", 1100],
				["G-cups", 1300]
			]);
		}
		option.showTextBox({unit: "CCs"});
		if (V.PC.boobs >= 500) {
			options.addOption("Your breasts are", "boobsImplant", V.PC)
				.addValueList([
					["All natural", 0, () => { V.PC.boobsImplant = 0; V.PC.boobsImplantType = "none"; }],
					["Fake", V.PC.boobs / 2, () => V.PC.boobsImplantType = "normal"]
				]);
		}
		if (V.PC.boobsImplant > 0) {
			option = options.addOption("You have", "boobsImplantType", V.PC).addValue("Regular implants", "normal");
			if (V.PC.boobsImplant > 400) {
				option.addValue("string implants", "string");
			}
			if (V.PC.boobsImplant > 600) {
				option.addValue("Fillable implants", "fillable");
			}
		}
		if (V.PC.boobs >= 300) {
			option = options.addOption("Your nipples are", "nipples", V.PC).addValue("Tiny", "tiny");
			option.addValue("Cute", "cute");
			if (V.PC.boobs >= 500) {
				option.addValue("Puffy", "puffy");
				option.addValue("Partially inverted", "partially inverted");
			}
			if (V.PC.boobs >= 1000) {
				option.addValue("Inverted", "inverted");
				option.addValue("Huge", "huge");
			}
		}
	}

	option = options.addOption("Your hips are", "hips", V.PC).addValue("Very narrow", -2);
	option.addValueList([
		["Narrow", -1],
		["Average", 0],
	]);
	if (V.PC.physicalAge > 13) {
		option.addValue("Wide", 1);
	}
	if (V.PC.physicalAge > 18) {
		option.addValue("Very Wide", 2);
	}

	option = options.addOption("Your butt is", "butt", V.PC).addValue("Flat", 0, () => { V.PC.buttImplant = 0; V.PC.buttImplantType = "none"; });
	option.addValueList([
		["Small", 1],
		["Plump", 2],
		["Big", 3],
	]);
	if (V.PC.physicalAge > 13) {
		option.addValue("Huge", 4);
	}
	if (V.PC.physicalAge > 18) {
		option.addValueList([
			["Enormous", 5],
			["Gigantic", 6],
		]);
	}
	if (V.PC.butt >= 3) {
		options.addOption("Your ass is", "buttImplant", V.PC)
			.addValueList([
				["All natural", 0, () => V.PC.buttImplantType = "none"],
				["Fake", Math.round(V.PC.butt / 2), () => V.PC.buttImplantType = "normal"]
			]);
	}
	if (V.PC.buttImplant > 0) {
		option = options.addOption("You have", "buttImplantType", V.PC).addValue("Regular implants", "normal");
		if (V.PC.buttImplant > 1) {
			option.addValue("string implants", "string");
			option.addValue("Fillable implants", "fillable");
		}
	}

	if (V.PC.dick !== 0) {
		option = options.addOption("Your dick is", "dick", V.PC).addValue("Tiny", 1, () => V.PC.foreskin = 2);
		option.addValueList([
			["Small", 2, () => V.PC.foreskin = 3],
			["Average", 3, () => V.PC.foreskin = 3],
			["Big", 4, () => V.PC.foreskin = 4],
		]);
		if (V.PC.physicalAge > 13) {
			option.addValue("Huge", 5, () => V.PC.foreskin = 5);
		}
		if (V.PC.physicalAge > 18) {
			option.addValue("Gigantic", 6, () => V.PC.foreskin = 5);
		}
		options.addOption("You are", "foreskin", V.PC)
			.addValueList([
				["Cut", 0],
				["Uncut", V.PC.dick]
			])
			.showTextBox()
			.addComment("Any value above 0 is uncircumcised. For comfort, keep equal or one greater than dick size.");
	}

	if (V.PC.balls !== 0) {
		option = options.addOption("Your balls are", "balls", V.PC).addValue("Small", 2, () => V.PC.scrotum = 2);
		option.addValueList([
			["Average", 3, () => V.PC.scrotum = 4],
			["Large", 4, () => V.PC.scrotum = 5],
		]);
		if (V.PC.physicalAge > 13) {
			option.addValue("Huge", 5, () => V.PC.scrotum = 5);
		}
		if (V.PC.physicalAge > 18) {
			option.addValue("Massive", 6, () => V.PC.scrotum = 6);
		}
		option.addComment("Small balls may be located internally.");
		if (V.PC.balls <= 2) {
			options.addOption("Your balls are", "scrotum", V.PC)
				.addValueList([
					["Internal", 0],
					["External", V.PC.balls]
				])
				.showTextBox()
				.addComment("Any value above 0 is external. For comfort, keep equal or one greater than ball size.");
		}
		if (V.PC.physicalAge < 14) {
			options.addOption("You are", "pubertyXY", V.PC)
				.addValueList([["Not producing potent sperm yet", 0], ["Producing potent sperm", 1]]);
		}
	}

	if (V.PC.vagina !== -1) {
		if (V.PC.dick === 0 && V.PC.physicalAge > 13) {
			options.addOption("Your clit is", "clit", V.PC)
				.addValueList([["Normal", 0], ["Large", 1], ["Huge", 2]]);
		}
		if (V.PC.physicalAge <= 18) {
			options.addOption("You are", "vagina", V.PC)
				.addValueList([["A virgin", 0], ["Not a virgin", 1]]);
			if (V.PC.physicalAge < 14 && V.PC.preg <= 0) {
				options.addOption("You have", "pubertyXX", V.PC)
					.addValueList([["Not had your first period", 0], ["Had your first period", 1]]);
			}
		}
	}

	options.addOption("You are", "anus", V.PC)
		.addValueList([["An anal virgin", 0], ["Not an anal virgin", 1]]);

	function makeAList(iterable) {
		return Array.from(iterable, (k => [capFirstChar(k), k]));
	}
};

App.UI.Player.syncAgeBasedParameters = function() {
	V.PC.actualAge = Math.clamp(V.PC.actualAge, 10, 80);
	V.PC.physicalAge = V.PC.actualAge;
	V.PC.visualAge = V.PC.actualAge;
	V.PC.ovaryAge = V.PC.actualAge;
	V.PC.height = Height.random(V.PC, {limitMult: [1, 2]});
	if (V.PC.genes === "XY") {
		if (V.PC.physicalAge <= 13) {
			V.PC.hips = -2;
			V.PC.shoulders = -1;
			V.PC.butt = 0;
			V.PC.boobs = 100;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 0;
				V.PC.vaginaLube = 0;
				if (V.PC.preg <= 0) {
					V.PC.pubertyXX = 0;
				}
			}
			V.PC.pregAdaptation = 10;
			if (V.PC.dick !== 0) {
				V.PC.dick = 2;
				V.PC.balls = 2;
				V.PC.scrotum = V.PC.balls + 1;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 0;
			}
		} else if (V.PC.physicalAge <= 18) {
			V.PC.hips = -2;
			V.PC.shoulders = 0;
			V.PC.butt = 1;
			V.PC.boobs = 200;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 1;
				V.PC.vaginaLube = 0;
				V.PC.pubertyXX = 1;
			}
			V.PC.pregAdaptation = 15;
			if (V.PC.dick !== 0) {
				V.PC.dick = 3;
				V.PC.balls = 3;
				V.PC.scrotum = V.PC.balls;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 1;
			}
		} else {
			V.PC.hips = -1;
			V.PC.shoulders = 1;
			V.PC.butt = 2;
			V.PC.boobs = 200;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 1;
				V.PC.vaginaLube = 1;
				V.PC.pubertyXX = 1;
			}
			V.PC.pregAdaptation = 20;
			if (V.PC.dick !== 0) {
				V.PC.dick = 4;
				V.PC.balls = 3;
				V.PC.scrotum = V.PC.balls + 1;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 1;
			}
		}
	} else {
		if (V.PC.physicalAge <= 13) {
			V.PC.hips = -2;
			V.PC.shoulders = -2;
			V.PC.butt = 0;
			V.PC.boobs = 350;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 0;
				V.PC.vaginaLube = 0;
				if (V.PC.preg <= 0) {
					V.PC.pubertyXX = 0;
				}
			}
			V.PC.pregAdaptation = 30;
			if (V.PC.dick !== 0) {
				V.PC.dick = 2;
				V.PC.balls = 2;
				V.PC.scrotum = V.PC.balls + 1;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 0;
			}
		} else if (V.PC.physicalAge <= 18) {
			V.PC.hips = 0;
			V.PC.shoulders = -1;
			V.PC.butt = 1;
			V.PC.boobs = 600;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 1;
				V.PC.vaginaLube = 1;
				V.PC.pubertyXX = 1;
			}
			V.PC.pregAdaptation = 50;
			if (V.PC.dick !== 0) {
				V.PC.dick = 3;
				V.PC.balls = 3;
				V.PC.scrotum = V.PC.balls;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 1;
			}
		} else {
			V.PC.hips = 1;
			V.PC.shoulders = 0;
			V.PC.butt = 2;
			V.PC.boobs = 900;
			if (V.PC.vagina !== -1) {
				V.PC.vagina = 1;
				V.PC.vaginaLube = 1;
				V.PC.pubertyXX = 1;
			}
			V.PC.pregAdaptation = 50;
			if (V.PC.dick !== 0) {
				V.PC.dick = 4;
				V.PC.balls = 3;
				V.PC.scrotum = V.PC.balls + 1;
				V.PC.foreskin = V.PC.dick;
				V.PC.pubertyXY = 1;
			}
		}
		if (V.PC.boobs < 250) {
			V.PC.nipples = "tiny";
		} else if (V.PC.boobs < 1000) {
			V.PC.nipples = "cute";
		} else {
			V.PC.nipples = "puffy";
		}
	}
};

App.UI.Player.assignCareerByAge = function(selection) {
	let career;

	if (V.disableForcedCareers) {
		career = selection;
	} else {
		for (const data of App.Data.player.career.values()) {
			if (Object.values(data).includes(V.PC.career)) {
				if (V.PC.actualAge <= 13) {
					career = data.child;
				} else if (V.PC.actualAge <= 21) {
					career = data.apprentice;
				}
				career = career || data.master;
			}
		}
	}

	V.disableForcedCareers = null;

	return career;
};

App.UI.Player.refreshmentChoice = function(options) {
	let option = options.addOption("Your preferred refreshment is", "refreshmentType", V.PC);
	for (const [key, value] of App.Data.player.refreshmentType) {
		option.addValue(value.name, key, () => { V.PC.refreshment = value.suggestions.values().next().value; } );
	}
	let comment = `Flavor only; no mechanical effect. If entering a custom refreshment, please assign proper usage.`;
	if (V.PC.refreshmentType === 0) {
		comment += ` "Smoked" must fit into the following sentence: "I smoked a ${V.PC.refreshment}" to fit events properly.`;
	} else if (V.PC.refreshmentType === 5) {
		comment += ` "Popped" must fit into the following sentence: "I shook the bottle of ${V.PC.refreshment}" to fit events properly.`;
	} else if (V.PC.refreshmentType === 6) {
		comment += ` "Orally Dissolved" must fit into the following sentence: "I placed a tab of ${V.PC.refreshment} under my tongue" to fit events properly.`;
	}
	option.addComment(comment);

	option = options.addOption("Specifically", "refreshment", V.PC).showTextBox().pulldown();
	for (const refreshment of App.Data.player.refreshmentType.get(V.PC.refreshmentType).suggestions) {
		option.addValue(capFirstChar(refreshment), refreshment);
	}
};

App.UI.Player.names = function(options) {
	options.addCustomOption(`Everyone calls you <b>${PlayerName()}.</b>`);
	options.addOption("Your given name is", "slaveName", V.PC).showTextBox();

	if (V.cheatMode) {
		options.addOption("Birth Name", "birthName", V.PC).showTextBox();
	}

	if (V.PC.slaveSurname === 0) {
		options.addOption("And no surname", "slaveSurname", V.PC)
			.addValue("Add a surname", "Anon")
			.addComment("Surnames cannot be changed during the game outside of special circumstances.");
	} else {
		options.addOption("And your surname is", "slaveSurname", V.PC).showTextBox()
			.addValue("Go by a single name", 0)
			.addComment("Surnames cannot be changed during the game outside of special circumstances.");
		if (V.cheatMode) {
			options.addOption("Birth Surname", "birthSurname", V.PC).showTextBox();
		}
	}
};

App.UI.Player.design = function() {
	const el = new DocumentFragment();
	let options = new App.UI.OptionsGroup();
	let option;
	let r;
	let linkArray;
	const allowEdits = (V.freshPC === 1 || V.saveImported === 0 || V.cheatMode);

	// Title / age
	if (allowEdits) {
		options.addOption("You are a", "title", V.PC)
			.addValue("Masculine Master", 1, () => V.PC.genes = "XY").addValue("Feminine Mistress", 0, () => V.PC.genes = "XX");

		App.UI.Player.names(options);

		V.PC.physicalAge = V.PC.actualAge;
		V.PC.visualAge = V.PC.actualAge;
		V.PC.ovaryAge = V.PC.actualAge;
		if (V.cheatMode) {
			options.addOption("Actual Age", "actualAge", V.PC).showTextBox();
			options.addOption("Physical Age", "physicalAge", V.PC).showTextBox();
			options.addOption("Visual Age", "visualAge", V.PC).showTextBox();
			options.addOption("Ovary Age", "ovaryAge", V.PC).showTextBox();
			options.addOption("Age Implant", "ageImplant", V.PC).addValue("Age altering surgery", 1).on().addValue("No surgery", 0).off();
		} else {
			options.addOption("You are", "actualAge", V.PC).showTextBox()
				.addRange(25, 35, "<", "Surprisingly young").addRange(40, 50, "<", "Entering middle age")
				.addRange(55, 65, "<", "Well into middle age").addRange(70, 65, ">=", "Old");

			options.addOption(`Your birthday was <strong>${V.PC.birthWeek}</strong> weeks ago.`, "birthWeek", V.PC).showTextBox();
			option = options.addCustomOption()
				.addButton(
					"Adjust body to match age",
					() => App.UI.Player.syncAgeBasedParameters(),
					""
				);
		}
	} else {
		r = [];
		r.push(`You are a`);
		if (V.PC.title === 1) {
			r.push(`masculine <strong>Master</strong>`);
		} else {
			r.push(`feminine ''Mistress'`);
		}
		r.push(`and everyone that matters calls you	${PlayerName()}.`);

		r.push(`You are ${V.PC.actualAge} years old, which is`);
		if (V.PC.actualAge >= 65) {
			r.push(`<strong>old</strong>.`);
		} else if (V.PC.actualAge >= 50) {
			r.push(`<strong>well into middle age</strong>.`);
		} else if (V.PC.actualAge >= 35) {
			r.push(`<strong>entering middle age</strong>.`);
		} else if (V.PC.actualAge >= 22) {
			r.push(`<strong>surprisingly young</strong>.`);
		} else if (V.PC.actualAge >= 14) {
			r.push(`<strong>exceedingly young</strong>.`);
		} else {
			r.push(`<strong>merely a child</strong>.`);
		}
		App.Events.addNode(el, r, "p");
	}

	option = options.addOption("Player aging is", "playerAging")
		.addValue("Enabled", 2).on().addValue("Celebrate birthdays, but don't age.", 1).addValue("Disabled", 0).off();
	if (!V.cheatMode) {
		option.addComment("This option cannot be changed during the game.");
	}

	if (V.PC.customTitle) {
		options.addOption("Custom title", "customTitle", V.PC).showTextBox()
			.addValue("Reset to default", "", () => {
				delete V.PC.customTitle;
				delete V.PC.customTitleLisp;
			});

		options.addOption("Lisped custom title", "customTitleLisp", V.PC).showTextBox()
			.addComment('If using a custom title, select Master or Mistress to set the gender of your title. Make sure to replace your "s"s with "th"s to have working lisps in your lisped title.');
	} else {
		options.addCustomOption("Custom title")
			.addButton("Set custom title", () => {
				V.PC.customTitle = "Master";
				V.PC.customTitleLisp = 'Mather';
			});
	}

	// Appearance
	if (allowEdits) {
		if (V.PC.vagina !== -1 && V.PC.dick !== 0) {
			State.temporary.vaginaPenis = 2;
		} else if (V.PC.vagina !== -1) {
			State.temporary.vaginaPenis = 1;
		} else {
			State.temporary.vaginaPenis = 0;
		}

		option = options.addOption("You have a", "vaginaPenis", State.temporary)
			.addValue("Penis", 0, () => {
				V.PC.preg = 0;
				V.PC.pregType = 0;
				V.PC.dick = 4;
				V.PC.balls = 3;
				V.PC.scrotum = 3;
				V.PC.prostate = 1;
				V.PC.vagina = -1;
				V.PC.ovaries = 0;
			}).addValue("Vagina", 1, () => {
				V.PC.dick = 0;
				V.PC.balls = 0;
				V.PC.scrotum = 0;
				V.PC.prostate = 0;
				V.PC.vagina = 1;
				V.PC.ovaries = 1;
			}).addValue("Penis and Vagina", 2, () => {
				V.PC.dick = 4;
				V.PC.balls = 3;
				V.PC.scrotum = 3;
				V.PC.prostate = 1;
				V.PC.vagina = 1;
				V.PC.ovaries = 1;
			});
		if (State.temporary.vaginaPenis === 0) {
			option.addComment("Standard sex scenes; easiest reputation maintenance.");
		} else if (State.temporary.vaginaPenis === 1) {
			option.addComment("Sex scene variations; most difficult reputation maintenance.");
		} else {
			option.addComment("Sex scene variations; more difficult reputation maintenance; some unique opportunities, especially with breasts.");
		}
		App.UI.Player.appearance(options, true);
	} else {
		r = [];

		r.push(`You are a ${heightToEitherUnit(V.PC.height)} tall ${V.PC.nationality} ${V.PC.race} with`);
		if (V.PC.markings === "heavily freckled") {
			r.push(`heavily freckled`);
		} else if (V.PC.markings === "freckles") {
			r.push(`lightly freckled`);
		} else {
			r.push(`clear`);
		}
		r.push(`${V.PC.skin} skin, ${V.PC.hColor} hair and ${App.Desc.eyesColor(V.PC)}. You have a ${V.PC.faceShape}`);
		if (V.PC.lips > 95) {
			r.push(`face with way too much lip; you can't shut your mouth properly anymore.`);
		} else if (V.PC.lips > 70) {
			r.push(`face with truly massive lips.`);
		} else if (V.PC.lips > 40) {
			r.push(`face with plump lips.`);
		} else if (V.PC.lips > 20) {
			r.push(`face with full lips.`);
		} else {
			r.push(`face.`);
		}
		App.Events.addNode(el, r, "p");
	}

	// Refresh
	App.UI.Player.refreshmentChoice(options);

	// History
	if (allowEdits) {
		option = options.addOption("Before you came to the Free Cities, you were a", "career", V.PC);
		if (V.PC.career === "arcology owner") {
			option.addValue("Arcology owner", "arcology owner");
		} else {
			option.addValueList([
				["Member of the idle wealthy", "wealth"],
				["Business leader", "capitalist"],
				["Mercenary", "mercenary"],
				["Slaver", "slaver"],
				["Engineer", "engineer"],
				["Doctor", "medicine"],
				["Hacker", "BlackHat"],
				["Minor celebrity", "celebrity"],
				["Escort", "escort"],
				["Servant", "servant"],
				["Gang leader", "gang"]]
			);
			option = options.addCustomOption("")
				.addButton(
					"Adjust career for age",
					() => V.PC.career = App.UI.Player.assignCareerByAge(V.PC.career),
					""
				);
			if (V.secExpEnabled > 0) {
				if (isPCCareerInCategory("capitalist")) {
					option.addComment(`<div><span class="yellowgreen">The propaganda hub's upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("mercenary")) {
					option.addComment(`<div><span class="positive">Easier to maintain security</span> and <span class="yellowgreen">the security HQ's upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("slaver")) {
					option.addComment(`<div><span class="positive">Easier to maintain authority</span> and <span class="yellowgreen">the security HQ's upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("engineer")) {
					option.addComment(`<div><span class="yellowgreen">construction and upgrade of facilities will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("medicine")) {
					option.addComment(`<div><span class="yellowgreen">Drug upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("celebrity")) {
					option.addComment(`<div><span class="yellowgreen">The propaganda hub's upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("escort")) {
					option.addComment(`<div><span class="red">Harder to maintain authority.</span></div>`);
				} else if (isPCCareerInCategory("servant")) {
					option.addComment(`<div><span class="red">Harder to maintain authority.</span></div>`);
				} else if (isPCCareerInCategory("gang")) {
					option.addComment(`<div><span class="positive">Easier to maintain authority</span> and <span class="yellowgreen">the security HQ's upgrades will be cheaper.</span></div>`);
				} else if (isPCCareerInCategory("BlackHat")) {
					option.addComment(`<div><span class="red">Harder to maintain authority.</span></div>`);
				} else {
					option.addComment(`<div><span class="red">Harder to maintain authority,</span> but <span class="yellowgreen">the propaganda hub's upgrades will be cheaper.</span></div>`);
				}
			}
		}

		options.addOption("It is rumored that you acquired your arcology through", "rumor", V.PC)
			.addValueList([
				["Wealth", "wealth"],
				["Hard work", "diligence"],
				["Force", "force"],
				["Social engineering", "social engineering"],
				["Blind luck", "luck"]
			]);

		el.append(options.render());
	} else {
		r = [];
		switch (V.PC.career) {
			case "wealth":
			case "trust fund":
			case "rich kid":
				r.push(`Prior to being an arcology owner, you were a member of the idle wealthy.`);
				break;
			case "capitalist":
				r.push(`Prior to being an arcology owner, you were a business leader.`);
				break;
			case "entrepreneur":
			case "business kid":
				r.push(`Prior to being an arcology owner, you were a cunning entrepreneur.`);
				break;
			case "mercenary":
			case "recruit":
				r.push(`Prior to being an arcology owner, you were a mercenary.`);
				break;
			case "child soldier":
				r.push(`Prior to being an arcology owner, you were a disposable conscript.`);
				break;
			case "slaver":
			case "slave overseer":
				r.push(`Prior to being an arcology owner, you were a slaver.`);
				break;
			case "slave tender":
				r.push(`Prior to being an arcology owner, you were a slaver tasked with looking after fresh captures.`);
				break;
			case "engineer":
				r.push(`Prior to being an arcology owner, you were an engineer.`);
				break;
			case "construction":
			case "worksite helper":
				r.push(`Prior to being an arcology owner, you built buildings.`);
				break;
			case "medicine":
				r.push(`Prior to being an arcology owner, you were a surgeon.`);
				break;
			case "medical assistant":
				r.push(`Prior to being an arcology owner, you assisted with surgeries.`);
				break;
			case "nurse":
				r.push(`Prior to being an arcology owner, you were a nurse.`);
				break;
			case "celebrity":
				r.push(`Prior to being an arcology owner, you were a minor celebrity.`);
				break;
			case "rising star":
				r.push(`Prior to being an arcology owner, you were an up-and-coming star.`);
				break;
			case "child star":
				r.push(`Prior to being an arcology owner, you were a child actor.`);
				break;
			case "BlackHat":
			case "hacker":
			case "script kiddy":
				r.push(`Prior to being an arcology owner, you specialized in cracking databases and making mockeries of cyber security.`);
				break;
			case "arcology owner":
				r.push(`Being an arcology owner defines your life now.`);
				break;
			case "escort":
			case "prostitute":
				r.push(`Prior to being an arcology owner, you knew how to survive off your looks and body.`);
				break;
			case "child prostitute":
				r.push(`Prior to being an arcology owner, you had no choice but to sell your body to survive.`);
				break;
			case "servant":
			case "handmaiden":
			case "child servant":
				r.push(`Prior to being an arcology owner, you served a well-off`);
				if (V.PC.counter.birthMaster >= 8) {
					r.push(`master as his breeder.`);
				} else if (V.PC.counter.birthMaster >= 2) {
					r.push(`master and bore him several children.`);
				} else if (V.PC.counter.birthMaster >= 1) {
					r.push(`master and bore him a child.`);
				} else {
					r.push(`master.`);
				}
				break;
			case "gang":
				r.push(`Prior to being an arcology owner, you were the leader of a ruthless gang.`);
				break;
			case "hoodlum":
				r.push(`Prior to being an arcology owner, you were a troublemaker in a gang.`);
				break;
			case "street urchin":
				r.push(`Prior to being an arcology owner, you lived a hard life on the streets.`);
				break;
		}

		r.push(`Word in the arcology is you acquired it through`);
		switch (V.PC.rumor) {
			case "wealth":
				r.push(`a rather ridiculous amount of money.`);
				break;
			case "diligence":
				r.push(`sheer effort.`);
				break;
			case "force":
				r.push(`brutal force.`);
				break;
			case "social engineering":
				r.push(`clever social manipulation.`);
				break;
			case "luck":
				r.push(`blind luck.`);
				break;
		}
		App.Events.addNode(el, r, "p");
	}

	// Sexuality
	App.UI.DOM.appendNewElement("h2", el, "Sexuality");

	if (allowEdits) {
		options = new App.UI.OptionsGroup();

		// obsolete?
		if (V.cheatMode) {
			options.addOption("Vagina", "vagina", V.PC).showTextBox();
			options.addOption("New vagina", "newVag", V.PC).showTextBox();
			options.addOption("Dick", "dick", V.PC).showTextBox();
			options.addOption("Balls", "balls", V.PC).addValueList([
				["Normal", 3],
				["Big", 5],
				["Huge", 9],
				["Monstrous", 30]
			])
				.showTextBox();
			options.addOption("Balls implant", "ballsImplant", V.PC).showTextBox();
		}

		if (V.PC.vagina !== -1 && V.PC.pubertyXX === 1) {
			option = options.addOption("You are", "preg", V.PC)
				.addValue("Taking contraceptives", -1, () => { V.PC.pregType = 0; V.PC.labor = 0; })
				.addValue("Not taking contraceptives", 0, () => { V.PC.pregType = 0; V.PC.labor = 0; })
				.addRange(16, 37, "<=", "Pregnant").addCallback(() => { V.PC.pregType = 1; V.PC.labor = 0; })
				.addRange(40, 42, "<=", "Ready to drop").addCallback(() => { V.PC.pregType = 1; V.PC.labor = 0; })
				.addRange(43, 42, ">", "Ready to drop with octuplets").addCallback(() => { V.PC.pregType = 8; V.PC.labor = 1; });
			const r =[];
			if (V.cheatMode) {
				option.showTextBox();
				r.push(`How far along your pregnancy is (pregMood kicks in at 24+ weeks) - -2: infertile, -1: contraceptives, 0: not pregnant, 1 - 42: pregnant, 43+: giving birth.`);
			}
			if (V.PC.preg === -1) {
				r.push("You can't get pregnant, however there will be a slight increase to living expenses.");
			}

			if (V.PC.counter.birthsTotal > 0) {
				r.push(`You have given birth to <strong>${V.PC.counter.birthsTotal}</strong> babies.`);
			}
			if (r.length >0) {
				option.addComment(r.join(" "));
			}

			option = options.addOption("Hormone effects", "pregMood", V.PC)
				.addValueList([
					["None", 0],
					["Caring and motherly", 1],
					["Aggressive and domineering", 2]
				]);
			if (V.PC.pregMood === 1) {
				option.addComment("Sex scene alterations; slaves will trust you more, but may try to take advantage of your mercy.");
			} else if (V.PC.pregMood === 2) {
				option.addComment("Sex scene alterations; slaves will fear you more, but will become more submissive to you.");
			}

			if (V.cheatMode) {
				options.addOption("Fetus Count", "pregType", V.PC).showTextBox().addComment(`how many you're having (1-8)`);
				options.addOption("Pregnancy Source", "pregSource", V.PC)
					.addValueList([
						["Unknown", 0],
						["Self-impregnation", -1],
						["Citizen", -2],
						["Former Master", -3],
						["Male arc owner", -4],
						["Client", -5],
						["Societal Elite", -6],
						["Designer baby", -7],
						["Futanari Sister", -9],
					])
					.showTextBox();
			}
		}

		el.append(options.render());
	} else {
		r = [];

		if (V.PC.boobs >= 300) {
			r.push(`You have a`);
			if (V.PC.title > 0) {
				r.push(`masculine`);
			} else {
				r.push(`feminine`);
			}
			r.push(`body with`);
			if (V.PC.shoulders > 1) {
				r.push(`very broad shoulders`);
			} else if (V.PC.shoulders > 0) {
				r.push(`broad shoulders`);
			} else if (V.PC.shoulders < -1) {
				r.push(`very narrow shoulders`);
			} else if (V.PC.shoulders < 0) {
				r.push(`narrow shoulders`);
			}
			if (V.PC.shoulders !== 0) {
				r.push(`and`);
			}
			let breastShapeDesc = "";
			if (V.PC.boobShape === "saggy") {
				breastShapeDesc = ` that sag a bit`;
			} else if (V.PC.boobShape === "spherical") {
				breastShapeDesc = ` that might just be a little too much implant now.`;
			}
			if (V.PC.boobs >= 1400) {
				r.push(`giant${(V.PC.boobsImplant !== 0) ? `, fake` : ``} cow tits${breastShapeDesc}.`);
			} else if (V.PC.boobs >= 1200) {
				r.push(`huge`);
				if (V.PC.boobsImplant !== 0) {
					r.push(`fake`);
				}
				r.push(`breasts${breastShapeDesc}.`);
			} else if (V.PC.boobs >= 1000) {
				r.push(`big`);
				if (V.PC.boobsImplant !== 0) {
					r.push(`fake`);
				}
				r.push(`breasts${breastShapeDesc}.`);
			} else if (V.PC.boobs >= 800) {
				r.push(`noticeable breasts${breastShapeDesc}.`);
			} else if (V.PC.boobs >= 650) {
				r.push(`unremarkable breasts${breastShapeDesc}.`);
			} else if (V.PC.boobs >= 500) {
				r.push(`average breasts${breastShapeDesc}.`);
			} else {
				r.push(`small breasts${breastShapeDesc}.`);
			}
		} else {
			if (V.PC.title > 0) {
				r.push(`You have a manly chest.`);
			} else {
				r.push(`You are flat as a board.`);
			}
		}
		r.push(`Around back, you have`);
		if (V.PC.butt > 10) {
			r.push(`a disproportionate swelling of flesh`);
		} else if (V.PC.butt > 7) {
			r.push(`an absurdly large butt`);
		} else if (V.PC.butt > 6) {
			r.push(`a ridiculous ass`);
		} else if (V.PC.butt > 5) {
			r.push(`a gigantic ass`);
		} else if (V.PC.butt > 4) {
			r.push(`an enormous ass`);
		} else if (V.PC.butt > 3) {
			r.push(`a huge ass`);
		} else if (V.PC.butt > 2) {
			r.push(`a big butt`);
		} else if (V.PC.butt > 1) {
			r.push(`a shapely rear`);
		} else if (V.PC.butt > 0) {
			r.push(`a trim rear`);
		} else {
			r.push(`a flat ass`);
		}
		r.push(`attached to a pair of`);
		if (V.PC.hips > 2) {
			r.push(`inhumanly wide hips.`);
		} else if (V.PC.hips > 1) {
			r.push(`very wide hips.`);
		} else if (V.PC.hips > 0) {
			r.push(`wide hips.`);
		} else if (V.PC.hips > -1) {
			r.push(`average hips.`);
		} else if (V.PC.hips > -2) {
			r.push(`narrow hips.`);
		} else {
			r.push(`very narrow hips.`);
		}

		r.push(`Between your legs, you have`);
		if (V.PC.dick !== 0) {
			if (V.PC.dick === 1) {
				r.push(`a tiny, humiliating`);
			} else if (V.PC.dick === 2) {
				r.push(`a small`);
			} else if (V.PC.dick === 3) {
				r.push(`an average`);
			} else if (V.PC.dick === 4) {
				r.push(`a big`);
			} else if (V.PC.dick === 5) {
				r.push(`a huge`);
			} else if (V.PC.dick === 6) {
				r.push(`a pussy wrecking`);
			} else if (V.PC.dick === 7) {
				r.push(`a massive, unusable`);
			} else if (V.PC.dick === 8) {
				r.push(`an imposing, if unusable,`);
			} else if (V.PC.dick === 9) {
				r.push(`a monster of a`);
			} else if (V.PC.dick === 10) {
				r.push(`an inhuman`);
			} else {
				r.push(`an unusable slab of sensitive flesh you call a`);
			}
			r.push(`dick`);
			if (V.PC.balls !== 0) {
				r.push(r.pop() + ",");
			}
			if (V.PC.balls === 1) {
				if (V.PC.scrotum === 0) {
					r.push(`a tiny pair of internal balls`);
				} else {
					r.push(`vestigial testicles`);
				}
			} else if (V.PC.balls === 2) {
				if (V.PC.scrotum === 0) {
					r.push(`a pair of internal balls`);
				} else {
					r.push(`a pair of small testicles`);
				}
			} else if (V.PC.balls === 3) {
				r.push(`a pair of average testicles`);
			} else if (V.PC.balls === 4) {
				r.push(`a dangling pair of large balls`);
			} else if (V.PC.balls === 5) {
				r.push(`a dangling pair of heavy testicles`);
			} else if (V.PC.balls === 6) {
				r.push(`a heavy pair of huge balls`);
			} else if (V.PC.balls === 7) {
				r.push(`a ponderous set of giant testicles`);
			} else if (V.PC.balls === 8) {
				r.push(`a ponderous set of enormous testicles`);
			} else if (V.PC.balls === 9) {
				r.push(`a monstrous pair of testicles`);
			} else {
				r.push(`an inhuman pair of testicles`);
			}
			if (V.PC.vagina !== -1) {
				r.push(`and`);
			} else {
				r.push(r.pop() + ".");
			}
		}
		if (V.PC.vagina !== -1) {
			if (V.PC.vagina === 0) {
				r.push(`an unsullied`);
			} else if (V.PC.vagina === 1 || V.PC.newVag === 1) {
				// nothing
			} else if (V.PC.vagina === 2) {
				r.push(`an experienced`);
			} else if (V.PC.vagina === 3) {
				r.push(`a loose`);
			} else if (V.PC.vagina === 4) {
				r.push(`a very well-traveled`);
			} else {
				r.push(`a ruined`);
			}
			r.push(`vagina.`);
		}
		if (V.PC.vagina !== -1 && V.PC.mpreg !== 0) {
			r.push(`You are`);
			if (V.PC.pregWeek < 0) {
				r.push(`currently recovering from your last pregnancy.`);
			} else if (V.PC.preg === -2) {
				r.push(`infertile and can't get pregnant.`);
			} else if (V.PC.preg === -1) {
				r.push(`taking contraceptives to avoid potential pregnancy.`);
			} else if (V.PC.preg === 0) {
				if (V.PC.pubertyXX === 0) {
					r.push(`not yet fertile.`);
				} else {
					r.push(`fertile and capable of becoming pregnant.`);
				}
			} else if (V.PC.preg > 37) {
				r.push(`extremely pregnant and likely to give birth soon.`);
			} else if (V.PC.preg > 0) {
				r.push(`currently pregnant.`);
			}

			linkArray = [];
			if (V.PC.preg > 20 || V.PC.counter.birthsTotal > 0) {
				if (V.PC.pregMood === 1) {
					r.push(`You tend to be caring and motherly when you're pregnant.`);
					linkArray.push(noChange(), aggressive());
				} else if (V.PC.pregMood === 0) {
					r.push(`Pregnancy doesn't really affect your mood.`);
					linkArray.push(motherly(), aggressive());
				} else {
					r.push(`You tend to be very demanding and aggressive when you're pregnant.`);
					linkArray.push(noChange(), motherly());
				}
			} else {
				if (V.PC.pregMood === 1) {
					r.push(`You tend to be caring and motherly when you're hormonal.`);
					linkArray.push(noChange(), aggressive());
				} else if (V.PC.pregMood === 0) {
					r.push(`Your mood isn't tied to your hormones.`);
					linkArray.push(motherly(), aggressive());
				} else {
					r.push(`You tend to be very demanding and aggressive when you're hormonal.`);
					linkArray.push(noChange(), motherly());
				}
			}

			r.push(App.UI.DOM.generateLinksStrip(linkArray));
			if (V.PC.counter.birthsTotal > 0) {
				r.push(`You have given birth to ${V.PC.counter.birthsTotal} babies.`);
			}
		}

		App.Events.addNode(el, r, "p");
	}

	if (V.cheatMode) {
		// Skills
		App.UI.DOM.appendNewElement("h2", el, "Skills");
		options = new App.UI.OptionsGroup();
		options.addOption(`Trading: ${tradingDescription()}`, "trading", V.PC.skill).addValueList([
			["Economics master", 100],
			["Economics expert", 90],
			["Skilled in economics", 70],
			["Amateur economist", 50],
			["Economics beginner", 30],
			["Basic trader", 0],
			["Haggler", -10],
			["Shopper", -30],
			["Weak saver", -50],
			["Money sieve", -70],
			["What's a trading?", -90],
		]).showTextBox();

		options.addOption(`Warfare: ${warfareDescription()}`, "warfare", V.PC.skill).addValueList([
			["Warfare master", 100],
			["Warfare expert", 90],
			["Skilled in warfare", 70],
			["Amateur combatant", 50],
			["Combat beginner", 30],
			["Basic fighter", 0],
			["Gun haver", -10],
			["Knife holder", -30],
			["Throat puncher", -50],
			["Groin kicker?", -70],
			["Most likely to be raped", -90]
		]).showTextBox();

		options.addOption(`Slaving: ${slavingDescription()}`, "slaving", V.PC.skill).addValueList([
			["Master slaver", 100],
			["Expert slaver", 90],
			["Skilled in slaving", 70],
			["Amateur slaver", 50],
			["Slaving beginner", 30],
			["Basic slaver", 0],
			["Can't make me a slave", -10],
			["Can read contracts", -30],
			["Careful now", -50],
			["Don't trust that guy", -70],
			["Potential slave", -90]
		]).showTextBox();

		options.addOption(`Engineering: ${engineeringDescription()}`, "engineering", V.PC.skill).addValueList([
			["Master engineer", 100],
			["Expert engineer", 90],
			["Skilled in engineering", 70],
			["Amateur engineer", 50],
			["Engineering beginner", 30],
			["Basic engineer", 0],
			["Gingerbread house", -10],
			["Knot tyer", -30],
			["You can use glue", -50],
			["You aren't handy", -70],
			["My hovercraft is full of eels", -90]
		]).showTextBox();

		options.addOption(`Medicine: ${medicineDescription()}`, "medicine", V.PC.skill).addValueList([
			["Master surgeon", 100],
			["Expert surgeon", 90],
			["Skilled in medicine", 70],
			["Amateur surgeon", 50],
			["Medical beginner", 30],
			["Basic medic", 0],
			["Can treat wounds", -10],
			["First-aid kit user", -30],
			["Band-aid applier", -50],
			["MEDIC!", -70],
			["Give me another beer", -90]
		]).showTextBox();

		options.addOption(`Hacking: ${hackingDescription()}`, "hacking", V.PC.skill).addValueList([
			["Master hacker", 100],
			["Expert hacker", 90],
			["Skilled hacker", 70],
			["Amateur hacker", 50],
			["Hacking beginner", 30],
			["Basic hacker", 0],
			["Mouse clicker", -10],
			["You can press Enter", -30],
			[`Where's the "any" key?`, -50],
			["Main screen turn on?", -70],
			["Ooh, cool glowy thingy!", -90]
		]).showTextBox();

		el.append(options.render());

		// Potential
		App.UI.DOM.appendNewElement("h2", el, "Misc");
		options = new App.UI.OptionsGroup();
		options.addOption(`Sexual Energy`, "sexualEnergy", V.PC).showTextBox();
		options.addOption(`Cum Tap`, "cumTap", V.PC.skill).showTextBox();
		options.addOption(`Stored Cum`, "storedCum", V.PC.counter).showTextBox();
		options.addOption(`Fertility Drugs`, "fertDrugs", V.PC)
			.addValue("Yes", 1).on()
			.addValue("No", 0).off();
		options.addOption(`Forced Fertility Drugs`, "forcedFertDrugs", V.PC).showTextBox();
		options.addOption(`Stamina Pills`, "staminaPills", V.PC)
			.addValue("Yes", 1).on()
			.addValue("No", 0).off();
		el.append(options.render());
	}

	return el;

	function noChange() {
		return App.UI.DOM.link(
			"Change to no change",
			() => { V.PC.pregMood = 0; },
			[],
			"Intro Summary"
		);
	}

	function motherly() {
		return App.UI.DOM.link(
			"Change to motherly",
			() => { V.PC.pregMood = 1; },
			[],
			"Intro Summary"
		);
	}

	function aggressive() {
		return App.UI.DOM.link(
			"Change to aggressive",
			() => { V.PC.pregMood = 2; },
			[],
			"Intro Summary"
		);
	}

	function tradingDescription() {
		if (V.PC.skill.trading >= 100) {
			return `You are a master at economics and trading.`;
		} else if (V.PC.skill.trading >= 80) {
			return `You are an expert at economics and trading.`;
		} else if (V.PC.skill.trading >= 60) {
			return `You are skilled in economics and trading.`;
		} else if (V.PC.skill.trading >= 40) {
			return `You know some things about economics and trading.`;
		} else if (V.PC.skill.trading >= 20) {
			return `You are a beginner in economics.`;
		} else if (V.PC.skill.trading >= 0) {
			return `You know only the basics of trading.`;
		} else if (V.PC.skill.trading >= -20) {
			return `You know how to haggle a little.`;
		} else if (V.PC.skill.trading >= -40) {
			return `You know how to shop around.`;
		} else if (V.PC.skill.trading >= -60) {
			return `You know not to pay sticker price.`;
		} else if (V.PC.skill.trading >= -80) {
			return 	`People always give you discounts, but you never save any money.`;
		} else {
			return `They said it was a bear market, so where are the bears?`;
		}
	}

	function warfareDescription() {
		if (V.PC.skill.warfare >= 100) {
			return `You are a master of warfare.`;
		} else if (V.PC.skill.warfare >= 80) {
			return `You are an expert at tactics and strategy.`;
		} else if (V.PC.skill.warfare >= 60) {
			return `You are skilled in combat.`;
		} else if (V.PC.skill.warfare >= 40) {
			return `You know some things about combat.`;
		} else if (V.PC.skill.warfare >= 20) {
			return `You are a beginner in tactics and strategy.`;
		} else if (V.PC.skill.warfare >= 0) {
			return `You know only the basics of fighting.`;
		} else if (V.PC.skill.warfare >= -20) {
			return `You know how to hold a gun.`;
		} else if (V.PC.skill.warfare >= -40) {
			return `You know how to stab with a knife.`;
		} else if (V.PC.skill.warfare >= -60) {
			return `Go for the throat?`;
		} else if (V.PC.skill.warfare >= -80) {
			return `Just kick them in the balls, right?`;
		} else {
			return `People like you are usually the first raped in a war.`;
		}
	}

	function slavingDescription() {
		if (V.PC.skill.slaving >= 100) {
			return `You are a master slaver.`;
		} else if (V.PC.skill.slaving >= 80) {
			return `You are an expert at enslaving.`;
		} else if (V.PC.skill.slaving >= 60) {
			return `You are skilled in slaving.`;
		} else if (V.PC.skill.slaving >= 40) {
			return `You know some things about getting slaves.`;
		} else if (V.PC.skill.slaving >= 20) {
			return `You are a beginner in slaving.`;
		} else if (V.PC.skill.slaving >= 0) {
			return `You know only the basics of slaving.`;
		} else if (V.PC.skill.slaving >= -20) {
			return `You know how to avoid becoming a slave.`;
		} else if (V.PC.skill.slaving >= -40) {
			return `You know to read contracts before you sign them.`;
		} else if (V.PC.skill.slaving >= -60) {
			return `You know to be careful.`;
		} else if (V.PC.skill.slaving >= -80) {
			return `You know better than to trust anyone.`;
		} else {
			return `It would be easy to enslave you.`;
		}
	}

	function engineeringDescription() {
		if (V.PC.skill.engineering >= 100) {
			return `You are a master engineer.`;
		} else if (V.PC.skill.engineering >= 80) {
			return `You are an expert at engineering.`;
		} else if (V.PC.skill.engineering >= 60) {
			return `You are skilled in engineering.`;
		} else if (V.PC.skill.engineering >= 40) {
			return `You know some things about engineering.`;
		} else if (V.PC.skill.engineering >= 20) {
			return `You are a beginner in engineering.`;
		} else if (V.PC.skill.engineering >= 0) {
			return `You know only the basics of engineering.`;
		} else if (V.PC.skill.engineering >= -20) {
			return `You can build a gingerbread house that doesn't collapse.`;
		} else if (V.PC.skill.engineering >= -40) {
			return `You can tie a tight knot, does that count?`;
		} else if (V.PC.skill.engineering >= -60) {
			return `Glue is your friend; lots of it.`;
		} else if (V.PC.skill.engineering >= -80) {
			return `You know better than to even try to build something.`;
		} else {
			return `You can cook; that's sort of like building something, right?`;
		}
	}

	function medicineDescription() {
		if (V.PC.skill.medicine >= 100) {
			return `You are a master surgeon.`;
		} else if (V.PC.skill.medicine >= 80) {
			return `You are an expert at medicine and surgery.`;
		} else if (V.PC.skill.medicine >= 60) {
			return `You are skilled in surgery.`;
		} else if (V.PC.skill.medicine >= 40) {
			return `You know some things about medicine.`;
		} else if (V.PC.skill.medicine >= 20) {
			return `You are a beginner in medicine.`;
		} else if (V.PC.skill.medicine >= 0) {
			return `You know the basics of treating injuries.`;
		} else if (V.PC.skill.medicine >= -20) {
			return `You can stop a wound from getting infected.`;
		} else if (V.PC.skill.medicine >= -40) {
			return `Gauze is your friend. Just keep wrapping.`;
		} else if (V.PC.skill.medicine >= -60) {
			return `You know how to apply a band-aid.`;
		} else if (V.PC.skill.medicine >= -80) {
			return `Cure-alls are wonderful. Why aren't they sold in stores, though?`;
		} else {
			return `Alcohol makes pain go away, right?`;
		}
	}

	function hackingDescription() {
		if (V.PC.skill.hacking >= 100) {
			return `You are a master of hacking.`;
		} else if (V.PC.skill.hacking >= 80) {
			return `You are an expert at hacking.`;
		} else if (V.PC.skill.hacking >= 60) {
			return `You are skilled in hacking.`;
		} else if (V.PC.skill.hacking >= 40) {
			return `You know some things about hacking.`;
		} else if (V.PC.skill.hacking >= 20) {
			return `You are a beginner in hacking.`;
		} else if (V.PC.skill.hacking >= 0) {
			return `You know only the basics of hacking.`;
		} else if (V.PC.skill.hacking >= -20) {
			return `You know how to click a mouse.`;
		} else if (V.PC.skill.hacking >= -40) {
			return `Enter does something?`;
		} else if (V.PC.skill.hacking >= -60) {
			return `Where is the "any" key?`;
		} else if (V.PC.skill.hacking >= -80) {
			return `You can push the power button, good job.`;
		} else {
			return `This black box thingy is magical.`;
		}
	}
};


code:
App.Intro.PCAppearanceIntro = function() {
	const node = new DocumentFragment();

	node.append(
		`Race and appearance are largely irrelevant in the Free Cities; there are only the free and the enslaved.`,
		App.UI.DOM.makeElement("div", `Appearance only, will mostly have a superficial effect (unless you make a big deal out of it).`, ["indent", "note"])
	);

	const options = new App.UI.OptionsGroup();
	App.UI.Player.appearance(options);
	node.append(options.render());

	if (isFertile(V.PC)) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
			"Continue player character customization",
			"PC Preg Intro",
			() => resetEyeColor(V.PC)
		));
	} else {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
			"Finish player character customization",
			"PC Experience Intro",
			() => resetEyeColor(V.PC)
		));
	}

	return node;
};


code:
App.Intro.PCBodyIntro = function() {
	V.PC.actualAge = Math.clamp(V.PC.actualAge, 10, 80);

	const el = new DocumentFragment();
	let r = [];

	r.push(`Most slaveowners in the Free Cities are male. The preexisting power structures of the old world have mostly migrated to the new, and it can often be very hard to be a free woman in the Free Cities. Some manage to make their way, but in many arcologies, men are the owners, and women are the owned. You'll cut a striking figure as the owner and leader of your arcology, but`);
	r.push(App.UI.DOM.makeElement("span", `what's under your business attire?`, ["intro", "question"]));
	App.Events.addNode(el, r, "p");

	el.append(body());
	el.append(age());
	el.append(nameIndulgence());
	el.append(endScene());

	return el;

	function body() {
		const el = document.createElement("p");
		const options = new App.UI.OptionsGroup();
		let r = [];

		// Gender
		r.push(`You are a`);
		if (V.PC.genes === "XX") {
			r.push(`woman`);
		} else {
			r.push(`man`);
		}
		r.push(`with a`);
		if (V.PC.title > 0) {
			r.push(`masculine figure and will be referred to as <strong>Master.</strong>`);
		} else {
			r.push(`feminine figure and will be referred to as <strong>Mistress.</strong>`);
		}
		options.addOption(r.join(" "), "title", V.PC)
			.addValue("Masculine appearance", 1)
			.addValue("Feminine appearance", 0)
			.addComment("This option will affect scenes. Femininity may increase difficulty in the future, but for now only your chest and junk matter.");

		// Chest
		options.addOption("Under my suit jacket", "boobs", V.PC)
			.addValue((V.PC.title > 0) ? `Masculine muscles` : `A flat chest`, 200)
			.addValue("Feminine breasts", 900)
			.addComment("These options will affect scenes. Sporting breasts will increase difficulty");

		// Lower deck
		r = [];
		let option;
		r.push(`Behind the front of my tailored`);
		if (V.PC.dick !== 0) {
			if (V.PC.vagina !== -1) {
				r.push(`slacks, <strong>both a penis and a vagina.</strong>`);
				option = options.addCustomOption(r.join(" "))
					.addButton("Remove the penis", penisRemove)
					.addButton("Remove the vagina", vaginaRemove);
			} else {
				r.push(`slacks, a <strong>penis.</strong>`);
				option = options.addCustomOption(r.join(" "))
					.addButton(
						"Switch to vagina",
						() => {
							penisRemove();
							V.PC.genes = "XX";
							vaginaAdd();
						},
						"PC Body Intro"
					)
					.addButton("Add a vagina", vaginaAdd);
			}
		} else {
			r.push(`skirt, a <strong>vagina.</strong>`);
			option = options.addCustomOption(r.join(" "))
				.addButton(
					"Switch to penis",
					() => {
						penisAdd();
						V.PC.genes = "XY";
						vaginaRemove();
					},
					"PC Body Intro"
				)
				.addButton("Add a penis", penisAdd);
		}
		option.addComment(`These options will affect sex scenes. Feminine options will increase difficulty.`);

		el.append(options.render());

		return el;

		function penisAdd() {
			V.PC.dick = 4;
			V.PC.balls = 3;
			V.PC.scrotum = 3;
			V.PC.prostate = 1;
		}

		function penisRemove() {
			V.PC.dick = 0;
			V.PC.balls = 0;
			V.PC.scrotum = 0;
			V.PC.prostate = 0;
		}

		function vaginaAdd() {
			V.PC.vagina = 1;
			V.PC.ovaries = 1;
		}

		function vaginaRemove() {
			V.PC.vagina = -1;
			V.PC.ovaries = 0;
		}
	}

	function age() {
		const el = document.createElement("p");
		const options = new App.UI.OptionsGroup();

		App.UI.DOM.appendNewElement("div", el, `How old are you?`, ["intro", "question"]);
		const r = [];
		r.push(`You're`);
		if (V.PC.actualAge >= 65) {
			r.push(`getting up in years. You've made a legacy for myself, and not done with life just yet.`);
		} else if (V.PC.actualAge >= 50) {
			r.push(`well into middle age. You've made a name for myself, and still got your groove.`);
		} else if (V.PC.actualAge >= 35) {
			r.push(`entering middle age. You're accomplished, and retain some youthful vigor.`);
		} else if (V.PC.actualAge >= 22) {
			r.push(`surprisingly young. You'll need to prove yourself, but you've got energy to burn.`);
		} else if (V.PC.actualAge >= 14) {
			r.push(`exceedingly young. You're nobody, but you're full of youthful vigor and ready to make the world yours.`);
		} else {
			r.push(`just a child. You may be emancipated, but society won't accept you as a leader.`);
		}
		r.push(`Your age:`);
		options.addOption(r.join(" "), "actualAge", V.PC).showTextBox()
			.addComment(`Older player characters start with more reputation and maintain reputation somewhat more easily, but have slightly less sexual energy. Exceedingly young characters will not be accepted by society, even more so if underage, and will face additional hurdles and complications.`);

		el.append(options.render());

		return el;
	}

	function nameIndulgence() {
		const el = document.createElement("p");
		const options = new App.UI.OptionsGroup();

		App.UI.DOM.appendNewElement("div", el, `What is your name and alternate indulgence?`, ["intro", "question"]);

		App.UI.Player.names(options);
		App.UI.Player.refreshmentChoice(options);

		el.append(options.render());

		return el;
	}

	function endScene() {
		const el = document.createElement("p");
		el.append(
			App.UI.DOM.link(
				"Confirm player character overview",
				() => {
					App.UI.Player.syncAgeBasedParameters();
				},
				[],
				"PC Appearance Intro"
			)
		);

		return el;
	}
};


code:
App.Intro.PCExperienceIntro = function() {
	//	:: PC Experience Intro [nobr]
	const node = new DocumentFragment();

	V.showSecExp = V.showSecExp || 0;

	if (V.PC.career === "arcology owner") {
		setTimeout(() => Engine.play("PC Rumor Intro"), Engine.minDomActionDelay);
	}
	if (!V.disableForcedCareers) {
		V.disableForcedCareers = V.PC.actualAge >= 22 ? 1 : 0;
	}
	App.Events.addParagraph(node, [
		`You're a relative unknown in the Free Cities, but it's clear you're already accomplished. The meek and average cannot aspire to acquire arcologies. You've got all the necessary skills to take over an arcology and succeed as its owner, but you should be able to leverage the skills and experience you retain from your past, too.`,
		App.UI.DOM.makeElement("span", `What career brought you to the Free Cities?`, ["intro", "question"])
	]);

	makeOption(
		"Idle wealth", "wealth",
		App.Events.makeNode([`Start with <span class="cash inc">extra money.</span>${(V.showSecExp === 1) ? ` However, you will find it harder to maintain authority, but propaganda hub upgrades will be cheaper.` : ``} Your starting slaves will have two free levels of sex skills available.`])
	);

	makeOption(
		"Venture capitalism", "capitalist",
		App.Events.makeNode([`You will be more <span class="positive">effective at business pursuits.</span>${(V.showSecExp === 1) ? ` In addition, propaganda hub upgrades will be cheaper.` : ``} Your starting slaves will have a free level of prostitution skill available.`])
	);

	makeOption(
		"Private military work", "mercenary",
		App.Events.makeNode([
			`You retain mercenary contacts ${(V.showSecExp === 1) ? `and your security skills will make it easier to keep the arcology safe. Also, security HQ upgrades will be cheaper.` : `and security skills.`}`,
			`Your starting slaves will have <span class="positive">free trust available.</span>`
		])
	);

	makeOption(
		"Slaving", "slaver",
		App.Events.makeNode([
			`Your slave breaking experience will be useful. ${(V.showSecExp === 1) ? `You will find that authority will be easier to maintain and security HQ upgrades will be cheaper.` : ""}`, `Your starting slaves will have free <span class="hotpink">devotion</span> available.`
		])
	);

	makeOption(
		"Engineering", "engineer",
		App.Events.makeNode([`<span class="cash inc">Upgrading the arcology will be cheaper.</span> Also, the arcology will start with <span class="cash inc">basic economic upgrades</span> already installed.`])
	);

	makeOption(
		"Surgery", "medicine",
		App.Events.makeNode([`Surgery will be cheaper and healthier and drug upgrades will be cheaper. Your starting slaves will have free implants available.`])
	);

	makeOption(
		"Minor celebrity", "celebrity",
		App.Events.makeNode([
			`Start with <span class="positive">extra reputation.</span>${(V.showSecExp === 1) ? ` In addition, propaganda hub upgrades will be cheaper.` : ``}`,
			`Your starting slaves will have a free level of <span class="cyan">entertainment skill</span> available.`
		])
	);

	makeOption(
		"Sex industry", "escort",
		App.Events.makeNode([
			`As an ex-whore, you will find it <span class="red">hard to maintain reputation</span>${(V.showSecExp === 1) ? `, in addition to authority` : ``}.`,
			`Your starting slaves will have a free level of <span class="cyan">sex skills</span> available, along with a free level of <span class="cyan">entertainment and prostitution.</span>`])
	);

	makeOption(
		"Servant", "servant",
		App.Events.makeNode([
			`As an ex-servant, you will find it <span class="red">hard to maintain reputation</span>${(V.showSecExp === 1) ? `, in addition to authority` : ``}.`, `You know how to lower your upkeep, but not much else. Your starting slaves will have free trust and devotion.`
		])
	);

	makeOption(
		"Gang affiliation", "gang",
		App.Events.makeNode([
			`As an ex-gang member, you know how to haggle slaves.${(V.showSecExp === 1) ? `In addition, asserting your authority will be easier and security HQ upgrades will be cheaper.` : ``}`, `However, you will find reputation quite hard to maintain. Your starting slaves will be fitter and possess a free level of combat skill.`
		])
	);

	makeOption(
		"Incursion Specialist", "BlackHat",
		App.Events.makeNode([
			`As an ex-hacker, you know how to gain access computer systems and other devices. Certain upgrades will be cheaper and you may find alternative approaches to problems.${(V.showSecExp === 1) ? `However, you will <span class="red">find authority quite hard</span> to maintain.` : ""}`,
			`Your starting slaves will have a free level of <span class="cyan">intelligence.</span>`
		])
	);

	function makeOption(linkTitle, career, desc) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
			linkTitle,
			"PC Rumor Intro",
			() => V.PC.career = App.UI.Player.assignCareerByAge(career)
		));

		App.UI.DOM.appendNewElement("div", node, desc, ["indent", "note"]);
	}

	const options = new App.UI.OptionsGroup();

	options.addOption(`Security Expansion Mod effects`, "showSecExp")
		.addValueList([
			["Hide", 0],
			["Show", 1],
		]);

	const option = options.addOption(`Forced career choices`, "disableForcedCareers")
		.addValue("Disable", 0);
	let r = [];
	if (V.PC.actualAge < 14) {
		r.push(`Due to your young age, you will be given the child variant of your chosen career line.`);
	} else if (V.PC.actualAge < 22) {
		r.push(`Due to your age, you will be given the inexperienced variant of your chosen career line.`);
	}
	r.push(`Over time and with effort, you will be capable of achieving everything of importance in the adult careers.`);
	option.addComment(r.join(" "));
	if (V.PC.actualAge < 22) {
		option.addValue("Enable", 1)
			.addComment("Use age based careers.");
	}
	node.append(options.render());

	return node;
};


code:
App.Intro.PCPregIntro = function() {
	const node = new DocumentFragment();

	App.Events.addParagraph(node, [
		`You have a working female reproductive system, and thus, a menstrual cycle. Women already face hardships as slaveowners and arcology owners, and being with child, coupled with a strong societal aversion to the dominant being penetrated, leads most pregnant owners to find themselves in dire situations. As an added precaution, since nothing stops an owner from hooking up with another owner, contraceptives are common amongst free women.`,
		App.UI.DOM.makeElement("span", `What's your stance on taking contraceptives?`, ["intro", "question"])
	]);

	// <p>
	let r = [];
	let linkArray = [];
	r.push(`You're`);
	if (V.PC.preg === -1) {
		r.push(`not interested in being a mother.`);
		linkArray.push(App.UI.DOM.passageLink(
			"Risky",
			"PC Preg Intro",
			() => V.PC.preg = 0
		));
	} else if (V.PC.preg === 0) {
		r.push(`fertile and you know the risks.`);
		linkArray.push(App.UI.DOM.passageLink(
			"Safe",
			"PC Preg Intro",
			() => V.PC.preg = -1
		));
		linkArray.push(App.UI.DOM.passageLink(
			"About that...",
			"PC Preg Intro",
			() => V.PC.preg = 10
		));
	} else if (V.PC.preg > 42) {
		r.push(`proudly pregnant with octuplets and they are coming right now.`);
		linkArray.push(App.UI.DOM.passageLink(
			"Not pregnant",
			"PC Preg Intro",
			() => {
				V.PC.preg = 0;
				V.PC.pregType = 0;
				V.PC.labor = 0;
			}
		));
	} else if (V.PC.preg > 37) {
		r.push(`${V.PC.preg} weeks pregnant and very close to being due.`);
		linkArray.push(App.UI.DOM.passageLink(
			"Not pregnant",
			"PC Preg Intro",
			() => {
				V.PC.preg = 0;
				V.PC.pregType = 0;
			}
		));
		linkArray.push(App.UI.DOM.passageLink(
			"Overdid the fertility agents",
			"PC Preg Intro",
			() => {
				V.PC.preg = 43;
				V.PC.pregType = 8;
				V.PC.labor = 1;
			}
		));
	} else {
		r.push(`already pregnant.`);
		linkArray.push(App.UI.DOM.passageLink(
			"Fertile",
			"PC Preg Intro",
			() => V.PC.preg = 0
		));
		linkArray.push(App.UI.DOM.passageLink(
			"Make that very pregnant",
			"PC Preg Intro",
			() => V.PC.preg = 40
		));
	}
	App.Events.addParagraph(node, [
		r.join(" "),
		App.UI.DOM.generateLinksStrip(linkArray),
		App.UI.DOM.makeElement("span", `Being or becoming pregnant will raise difficulty.`, "note")
	]);

	App.UI.DOM.appendNewElement("p", node, `Hormones can be an interesting thing, but how do they affect you?`, ["intro", "question"]);

	r = [];
	r.push(`You're`);
	if (V.PC.pregMood === 1) {
		r.push(`gentle and motherly when you're hormonal.`);
	} else if (V.PC.pregMood === 0) {
		r.push(`in complete control of yourself.`);
	} else {
		r.push(`aggressive and domineering when you're hormonal.`);
	}
	const options = new App.UI.OptionsGroup();
	options.addOption(r.join(" "), "pregMood", V.PC)
		.addValueMap(new Map([
			["Normal", 0],
			["Motherly", 1],
			["Aggressive", 2]
		]))
		.addComment(`Hormone induced moods may alter some sex scenes, as well as change slaves' reactions to you.`);
	node.append(options.render());

	App.UI.DOM.appendNewElement("p", node, App.UI.DOM.passageLink(
		"Confirm player character customization",
		"PC Experience Intro"
	));
	return node;
};


code:
App.Intro.PCRumorIntro = function() {
	//	:: PC Experience Intro [nobr]
	const node = new DocumentFragment();

	delete V.showSecExp;

	App.Events.addParagraph(node, [
		`Who you are is something that you will have to define for yourself through your actions. Once you own an arcology, no one will be in a position to apply moral scorekeeping to you. In the brave new world of the Free Cities, you will be free to define yourself as the sum of your actions, rather than as the product of your past. The first decision that will define who you are as an arcology owner is your choice of method in acquiring one.`,
		App.UI.DOM.makeElement("span", `What approach will you take?`, ["intro", "question"])
	]);

	makeOption(
		"A judicious application of funds", "wealth",
		App.Events.makeNode([`Start with <span class="cash inc">extra money,</span> since you were wealthy enough to buy an arcology.`])
	);

	makeOption(
		"Hard work and diligence", "diligence",
		App.Events.makeNode([`New slaves will <span class="hotpink">hate you less,</span> since it will be known that you worked hard to earn your position.`])
	);

	makeOption(
		"The remorseless use of force", "force",
		App.Events.makeNode([`New slaves <span class="gold">will fear you more,</span> since rumors about your violent takeover will inevitably circulate.`])
	);

	makeOption(
		"Clever social engineering", "social engineering",
		App.Events.makeNode([`Start with the <span class="positive">first societal option unlocked,</span> since you manipulated the arcology's citizens.`])
	);

	makeOption(
		"Blind luck", "luck",
		App.Events.makeNode([`Start with a <span class="positive">good reputation,</span> since the story of your unlikely accession will be famous.`])
	);

	return node;

	function makeOption(linkTitle, rumor, desc) {
		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
			linkTitle,
			"Takeover Target",
			() => V.PC.rumor = rumor
		));

		App.UI.DOM.appendNewElement("div", node, desc, ["indent", "note"]);
	}
};


code:
App.Intro.slaveAgeIntro = function() {
	const node = new DocumentFragment();

	App.UI.DOM.appendNewElement("p", node, `Do you want to see content involving girls younger than 18 in this game?`, ["intro", "question"]);

	makeOption([
		App.UI.DOM.passageLink("No.", "PC Body Intro", () => {
			V.minimumSlaveAge = 18;
			V.pedo_mode = 0;
		}),
		App.UI.DOM.makeElement("span", `All slaves will be at least 18 years old, and slavery of children will be illegal in the Free Cities.`, "note")
	]);

	makeOption([
		`Yes, I wish to see girls as young as`,
		App.UI.DOM.makeTextBox(V.minimumSlaveAge, (v) => V.minimumSlaveAge = v, true),
		App.UI.DOM.passageLink("Continue.", "PC Body Intro", () => {
			V.pedo_mode = 0;
		}),
	]);

	makeOption([
		`Yes, and`,
		App.UI.DOM.passageLink("I just want lots of lolis.", "PC Body Intro", () => {
			V.minimumSlaveAge = 3;
			V.pedo_mode = 1;
		}),
		App.UI.DOM.makeElement("span", `Nearly all randomly generated slaves will be under the age of 18, although custom slaves and slaves related to specific events may be older.`, "note")
	]);

	makeOption([
		`Yes,`,
		App.UI.DOM.passageLink("I wish to see them grow up and become fertile.", "PC Body Intro", () => {
			V.minimumSlaveAge = 3;
			V.pedo_mode = 0;
			V.precociousPuberty = 1;
			V.loliGrow = 1;
			V.fertilityAge = 10;
			V.potencyAge = 12;
			V.seeAge = 1;
		}),
		App.UI.DOM.makeElement("span", `Preset. Slaves' age will be random from minimal possible age. They can be made fertile younger than normal puberty age (10) in some cases, and grow up naturally.`, "note")
	]);

	return node;

	function makeOption(array) {
		App.UI.DOM.appendNewElement("div", node, App.Events.makeNode(array));
	}
};


code:
App.Intro.takeoverTarget = function() {
	//	:: Takeover Target [nobr]
	const node = new DocumentFragment();
	let r = [];
	r.push(`Before you deploy the`);
	if (V.PC.rumor === "wealth") {
		r.push(`financial reserves that`);
	} else if (V.PC.rumor === "diligence") {
		r.push(`carefully constructed plan that`);
	} else if (V.PC.rumor === "force") {
		r.push(`mercenaries and`);
		if (V.continent === "Eastern Europe") { // maskirovka//
		} else {
			r.push(`cover plan`);
		}
		r.push(`that`);
	} else if (V.PC.rumor === "social engineering") {
		r.push(`clever social manipulation that`);
	} else {
		r.push(`optimistic plan you hope`);
	}
	r.push(`will allow you to take over an arcology, you need to select a target. There are a number of vulnerable arcologies that you could`);
	if (V.PC.rumor === "wealth") {
		r.push(`attempt a hostile takeover of`);
	} else if (V.PC.rumor === "diligence") {
		r.push(`work to take over`);
	} else if (V.PC.rumor === "force") {
		r.push(`attack`);
	} else if (V.PC.rumor === "social engineering") {
		r.push(`infiltrate`);
	} else {
		r.push(`aspire to take over`);
	}
	r.push(`with a reasonable chance of success. Free Cities are volatile places, even compared to the troubled state of the rest of the world. There are always arcologies whose owners are on the brink of failure, and you could target one of them.`);
	if (V.PC.career === "arcology owner") {
		r.push(`(Since you've <span class="springgreen">owned an arcology before,</span> you identify more potential target arcologies than a novice might.)`);
	}
	r.push(`Alternatively, arcologies are being built every day, and their owners' control is often uncertain.`);

	r.push(App.UI.DOM.makeElement("div", `Which arcology will you target?`, ["intro", "question"]));
	App.Events.addParagraph(node, r);

	const card = App.UI.DOM.appendNewElement("div", node, null, "card");
	card.append(App.UI.DOM.passageLink(
		"A newly constructed arcology",
		"Terrain Intro",
		() => V.targetArcology.fs = "New"
	));
	App.UI.DOM.appendNewElement("div", card, `With many new arcologies being constructed, you will be able to select which area of the world and type of Free City you'd like your target arcology to be located in.`, ["indent", "note"]);
	App.UI.DOM.appendNewElement("div", card, `Recommended for new players.`, ["indent", "note"]);

	node.append(App.Intro.generateEstablishedArcologies());
	return node;
};