code:
declare namespace FC {
	interface FutureSocietyIdMap {
		FSSupremacist: {noun: "Racial Supremacism", adj: "Supremacist"};
		FSSubjugationist: {noun: "Racial Subjugationism", adj: "Subjugationist"};
		FSGenderRadicalist: {noun: "Gender Radicalism", adj: "Gender Radicalist"};
		FSGenderFundamentalist: {noun: "Gender Fundamentalism", adj: "Gender Fundamentalist"};
		FSDegradationist: {noun: "Degradationism", adj: "Degradationist"};
		FSPaternalist: {noun: "Paternalism", adj: "Paternalist"};
		FSBodyPurist: {noun: "Body Purism", adj: "Body Purist"};
		FSTransformationFetishist: {noun: "Transformation Fetishism", adj: "Transformation Fetishist"};
		FSYouthPreferentialist: {noun: "Youth Preferentialism", adj: "Youth Preferentialist"};
		FSMaturityPreferentialist: {noun: "Maturity Preferentialism", adj: "Maturity Preferentialist"};
		FSSlimnessEnthusiast: {noun: "Slimness Enthusiasm", adj: "Slimness Enthusiast"};
		FSAssetExpansionist: {noun: "Asset Expansionism", adj: "Asset Expansionist"};
		FSPastoralist: {noun: "Pastoralism", adj: "Pastoralist"};
		FSCummunism: {noun: "Cummunism", adj: "Cummunist"};
		FSPhysicalIdealist: {noun: "Physical Idealism", adj: "Physical Idealist"};
		FSHedonisticDecadence: {noun: "Decadent Hedonism", adj: "Decadent Hedonist"};
		FSChattelReligionist: {noun: "Chattel Religionism", adj: "Chattel Religionist"};
		FSNull: {noun: "Multiculturalism", adj: "Multiculturalist"};
		FSIncestFetishist: {noun: "Incest Fetishism", adj: "Incest Fetishist"};
		FSRomanRevivalist: {noun: "Roman Revivalism", adj: "Roman Revivalist"};
		FSNeoImperialist: {noun: "Neo-Imperialism", adj: "Neo-Imperialist"};
		FSEgyptianRevivalist: {noun: "Egyptian Revivalism", adj: "Egyptian Revivalist"};
		FSEdoRevivalist: {noun: "Edo Revivalism", adj: "Edo Revivalist"};
		FSArabianRevivalist: {noun: "Arabian Revivalism", adj: "Arabian Revivalist"};
		FSChineseRevivalist: {noun: "Chinese Revivalism", adj: "Chinese Revivalist"};
		FSAztecRevivalist: {noun: "Aztec Revivalism", adj: "Aztec Revivalist"};
		FSRepopulationFocus: {noun: "Repopulation Focus", adj: "Repopulationist"};
		FSRestart: {noun: "Eugenics", adj: "Eugenics"};
		FSIntellectualDependency: {noun: "Intellectual Dependency", adj: "Intellectual Dependency"};
		FSSlaveProfessionalism: {noun: "Slave Professionalism", adj: "Slave Professional"};
		FSPetiteAdmiration: {noun: "Petite Admiration", adj: "Petite Admiration"};
		FSStatuesqueGlorification: {noun: "Statuesque Glorification", adj: "Statuesque Glorification"};
	}

	type FutureSociety = keyof FutureSocietyIdMap;
	type FutureSocietyNoun = FutureSocietyIdMap[keyof FutureSocietyIdMap]["noun"];
	type FutureSocietyAdj = FutureSocietyIdMap[keyof FutureSocietyIdMap]["adj"];

	type FSPolicyValue = number | "unset";

	// direction with respect to the player's arcology
	type ArcologyDirection = "east" | "north" | "northeast" | "northwest" | "south" | "southeast" | "southwest" | "west";

	interface ArcologyState extends Record<FutureSociety, FSPolicyValue> {
		name: string;
		direction: Zeroable<ArcologyDirection>;
		government: string;
		leaderID: number;
		honeymoon: number;
		prosperity: number;
		ownership: number;
		minority: number;
		PCminority: number;
		demandFactor: number;
		FSSupremacistRace: Zeroable<Race>;
		FSSubjugationistRace: Zeroable<Race>;
		embargo: number;
		embargoTarget: Zeroable<ArcologyDirection>;
		influenceTarget: Zeroable<ArcologyDirection>;
		influenceBonus: number;
		CyberEconomic: number;
		CyberEconomicTarget: Zeroable<ArcologyDirection>;
		CyberReputation: number;
		CyberReputationTarget: Zeroable<ArcologyDirection>;
		rival: number;
		FSGenderRadicalistResearch: Bool;
		FSGenderFundamentalistResearch: Bool;
		FSPaternalistResearch: Bool;
		FSDegradationistResearch: Bool;
		FSBodyPuristResearch: Bool;
		FSTransformationFetishistResearch: Bool;
		FSYouthPreferentialistResearch: Bool;
		FSMaturityPreferentialistResearch: Bool;
		FSSlimnessEnthusiastResearch: Bool;
		FSAssetExpansionistResearch: Bool;
		FSPastoralistResearch: Bool;
		FSPhysicalIdealistResearch: Bool;
		FSRepopulationFocusResearch: Bool;
		FSRestartResearch: Bool;
		FSHedonisticDecadenceResearch: Bool;
		FSHedonisticDecadenceDietResearch: Bool;
		FSIntellectualDependencyResearch: Bool;
		FSSlaveProfessionalismResearch: Bool;
		FSPetiteAdmirationResearch: Bool;
		FSStatuesqueGlorificationResearch: Bool;
		FSCummunismResearch: Bool;
		FSIncestFetishistResearch: Bool;
		FSSupremacistDecoration: number;
		FSSubjugationistDecoration: number;
		FSGenderRadicalistDecoration: number;
		FSGenderFundamentalistDecoration: number;
		FSPaternalistDecoration: number;
		FSDegradationistDecoration: number;
		FSBodyPuristDecoration: number;
		FSTransformationFetishistDecoration: number;
		FSYouthPreferentialistDecoration: number;
		FSMaturityPreferentialistDecoration: number;
		FSSlimnessEnthusiastDecoration: number;
		FSAssetExpansionistDecoration: number;
		FSPastoralistDecoration: number;
		FSPhysicalIdealistDecoration: number;
		FSChattelReligionistDecoration: number;
		FSRomanRevivalistDecoration: number;
		FSNeoImperialistDecoration: number;
		FSAztecRevivalistDecoration: number;
		FSEgyptianRevivalistDecoration: number;
		FSEdoRevivalistDecoration: number;
		FSArabianRevivalistDecoration: number;
		FSChineseRevivalistDecoration: number;
		FSRepopulationFocusDecoration: number;
		FSRestartDecoration: number;
		FSHedonisticDecadenceDecoration: number;
		FSIntellectualDependencyDecoration: number;
		FSSlaveProfessionalismDecoration: number;
		FSPetiteAdmirationDecoration: number;
		FSStatuesqueGlorificationDecoration: number;
		FSCummunismDecoration: number;
		FSIncestFetishistDecoration: number;
		FSSupremacistLawME: number;
		FSSupremacistSMR: number;
		FSSubjugationistLawME: number;
		FSSubjugationistSMR: number;
		FSGenderRadicalistLawFuta: number;
		FSGenderRadicalistLawBeauty: number;
		FSGenderFundamentalistLawBimbo: number;
		FSGenderFundamentalistSMR: number;
		FSGenderFundamentalistLawBeauty: number;
		FSPaternalistLaw: number;
		FSPaternalistSMR: Bool;
		FSDegradationistLaw: number;
		FSDegradationistSMR: Bool;
		FSBodyPuristLaw: number;
		FSBodyPuristSMR: Bool;
		FSTransformationFetishistSMR: Bool;
		FSYouthPreferentialistLaw: number;
		FSYouthPreferentialistSMR: Bool;
		FSMaturityPreferentialistLaw: number;
		FSMaturityPreferentialistSMR: Bool;
		FSSlimnessEnthusiastSMR: Bool;
		FSSlimnessEnthusiastLaw: number;
		FSAssetExpansionistSMR: Bool;
		FSPastoralistLaw: number;
		FSPastoralistSMR: Bool;
		FSPhysicalIdealistSMR: number;
		FSPhysicalIdealistLaw: number;
		FSPhysicalIdealistStrongFat: number;
		FSChattelReligionistLaw: number;
		FSChattelReligionistSMR: Bool;
		FSChattelReligionistCreed: number;
		FSRomanRevivalistLaw: number;
		FSRomanRevivalistSMR: Bool;
		FSNeoImperialistLaw1: number;
		FSNeoImperialistLaw2: number;
		FSNeoImperialistSMR: number;
		FSAztecRevivalistLaw: number;
		FSAztecRevivalistSMR: Bool;
		FSEgyptianRevivalistLaw: number;
		FSEgyptianRevivalistSMR: Bool;
		FSEdoRevivalistLaw: number;
		FSEdoRevivalistSMR: Bool;
		FSArabianRevivalistLaw: number;
		FSArabianRevivalistSMR: Bool;
		FSChineseRevivalistLaw: number;
		FSChineseRevivalistSMR: Bool;
		FSRepopulationFocusLaw: number;
		FSRepopulationFocusSMR: Bool;
		FSRestartLaw: number;
		FSRestartSMR: Bool;
		FSHedonisticDecadenceLaw: number;
		FSHedonisticDecadenceLaw2: number;
		FSHedonisticDecadenceStrongFat: number;
		FSHedonisticDecadenceSMR: Bool;
		FSIntellectualDependencyLaw: number;
		FSIntellectualDependencyLawBeauty: number;
		FSIntellectualDependencySMR: Bool;
		FSSlaveProfessionalismLaw: number;
		FSSlaveProfessionalismSMR: Bool;
		FSPetiteAdmirationLaw: number;
		FSPetiteAdmirationLaw2: number;
		FSPetiteAdmirationSMR: Bool;
		FSStatuesqueGlorificationLaw: number;
		FSStatuesqueGlorificationLaw2: number;
		FSStatuesqueGlorificationSMR: Bool;
		FSEgyptianRevivalistIncestPolicy: number;
		FSEgyptianRevivalistInterest: number;
		FSRepopulationFocusPregPolicy: number;
		FSRepopulationFocusMilfPolicy: number;
		FSRepopulationFocusInterest: number;
		FSEugenicsChastityPolicy: number;
		FSEugenicsSterilizationPolicy: number;
		FSEugenicsInterest: number;
		childhoodFertilityInducedNCSResearch: Bool;
		hackingEconomic: number;
		hackingEconomicTarget: number;
		hackingReputationTarget: number;
		hackingReputation: number;
	}
}


code:
declare namespace FC {
	type WithNone<T> = T | "none";

	const enum Bool {
		False = 0,
		True = 1
	}

	const enum NoObject {
		Value = 0
	}

	type Zeroable<T> = T | NoObject;
}

type WidenLiterals<T> =
  T extends boolean ? boolean :
  T extends string ? string :
  T extends number ? number :
  T;

repo_name: Welptard/fc

license: mit


code:
declare namespace FC {
	namespace Data {

		namespace Wardrobe {
			interface ClothingOptionBase {
				name: string;
				fs?: string; // FSPolicy;
			}
			interface ClothingOption extends ClothingOptionBase {
				value: string;
			}

			interface UpdatingClothingOption extends ClothingOptionBase {
				updateSlave: DeepPartialSlaveState;
			}
		}
		namespace Pronouns {
			interface Definition {
				pronoun: string;
				possessive: string;
				possessivePronoun: string;
				object: string;
				objectReflexive: string;
				noun: string;
			}
		}

		interface JobDesc {
			position: string;
			assignment: Assignment;
			publicSexUse: boolean;
			fuckdollAccepted: boolean;
			broodmotherAccepted?: boolean;
			/** workers can take part time jobs in addition to their main (full-time) one */
			partTime?: boolean;
		}

		interface ManagerJobDesc extends JobDesc {
			shouldWalk: boolean;
			shouldHold: boolean;
			shouldSee: boolean;
			shouldHear: boolean;
			shouldTalk: boolean;
			shouldThink: boolean;
			requiredDevotion: number;
			/** Applicable careers */
			careers: string[];
			/** Applicable skill name */
			skill: string;
			positionAbbreviation?: string;
		}

		interface FacilityDesc {
			/** Base name for state variables */
			baseName: string;
			/** Generic name for UI (Brothel, Club, etc.)
			 * If null, baseName is used instead
			 */
			genericName: string | null;
			jobs: Record<string, JobDesc>;
			defaultJob: string;
			manager: ManagerJobDesc | null;
		}

		interface ProstheticDefinition {
			name: string;
			adjust: number;
			craft: number;
			research: number;
			level: number;
			costs: number;
		}

		namespace SlaveSummary {
			interface SmartPiercing {
				setting: {
					off: string,
					submissive: string,
					lesbian: string,
					oral: string,
					humiliation: string,
					anal: string,
					boobs: string,
					sadist: string,
					masochist: string,
					dom: string,
					pregnancy: string,
					vanilla: string,
					all: string,
					none: string,
					monitoring: string,
					men: string,
					women: string,
					"anti-men": string,
					"anti-women": string,
				}
			}
		}
	}
}


code:
declare namespace FC {
	namespace Desc {
		interface LongSlaveOptions {
			/**
			 * 0 if the slave is not for sale.  Otherwise a string with the name of the market,
			 * partially to determine if laws apply to the market or not.
			 */
			market?: Zeroable<SlaveMarketName>;
			eventDescription?: boolean;
			prisonCrime?: string;
			noArt?: boolean;
		}
	}
}


code:
declare namespace FC {
	namespace Facilities {
		interface Pit {
			/** Defaults to "the Pit" if not otherwise set. */
			name: string;

			/** Has a slave fight an animal if not null. */
			animal: Animal;
			/** The type of audience the Pit has. */
			audience: "none" | "free" | "paid";
			/** Whether or not the bodyguard is fighting this week. */
			bodyguardFights: boolean;
			/** An array of the IDs of slaves assigned to the Pit. */
			fighterIDs: number[];
			/** Whether or not a fight has taken place during the week. */
			fought: boolean;
			/** Whether or not the fights in the Pit are lethal. */
			lethal: boolean;
			/** The ID of the slave fighting the bodyguard for their life. */
			slaveFightingBodyguard: number;
			/** The virginities of the loser not allowed to be taken. */
			virginities: "neither" | "vaginal" | "anal" | "all"
		}

		class Animal {
			name: string;
			species: string;
			type: string;
			articleAn: boolean;
		}
	}
}


code:
declare namespace FC {
	/**@deprecated */
	type SlaveStateOrZero = Zeroable<SlaveState>;
	/**@deprecated */
	type HumanStateOrZero = Zeroable<HumanState>;

	type DefaultGameStateVariables = typeof App.Data.defaultGameStateVariables;
	type ResetOnNGPVariables = typeof App.Data.resetOnNGPlus;

	interface Enunciation {
		title: string;
		say: string;
		s: string;
		S: string;
		ss: string;
		c: string;
		C: string;
		cc: string;
		z: string;
		Z: string;
		zz: string;
		ch: string;
		Ch: string;
		ps: string;
		Ps: string;
		sh: string;
		Sh: string;
		sc: string;
		Sc: string;
		sch: string;
		Sch: string;
		x: string;
		X: string;
	}

	interface PeacekeepersState {
		generalName: string;
		strength: number;
		attitude: number;
		independent: number;
		undermining: number;
		influenceAnnounced: number;
		tastes: number;
	}

	interface DeprecatedGameVariables {
		/** @deprecated */
		events: string[];
		/** @deprecated */
		RESSevent: string[];
		/** @deprecated */
		RESSTRevent: string[];
		/** @deprecated */
		RETSevent: string[];
		/** @deprecated */
		RECIevent: string[];
		/** @deprecated */
		RecETSevent: string[];
		/** @deprecated */
		REFIevent: string[];
		/** @deprecated */
		REFSevent: string[];
		/** @deprecated */
		PESSevent: string[];
		/** @deprecated */
		PETSevent: string[];
		/** @deprecated */
		FSAcquisitionEvents: string[];
		/** @deprecated */
		FSNonconformistEvents: string[];
		/** @deprecated */
		REAnalCowgirlSubIDs: number[];
		/** @deprecated */
		RETasteTestSubIDs: number[];
		/** @deprecated */
		rebelSlaves: string[];
		/** @deprecated */
		REBoobCollisionSubIDs: string[];
		/** @deprecated */
		REIfYouEnjoyItSubIDs: string[];
		/** @deprecated */
		RESadisticDescriptionSubIDs: string[];
		/** @deprecated */
		REShowerForceSubIDs: string[];
		/** @deprecated */
		RESimpleAssaultIDs: string[];
		/** @deprecated */
		RECockmilkInterceptionIDs: number[];
		/** @deprecated */
		REInterslaveBeggingIDs: number[];
		/** @deprecated */
		bedSlaves: SlaveState[];
		/** @deprecated */
		eligibleSlaves: SlaveState[];
		/** @deprecated */
		RERepressedAnalVirginSubIDs: number[];

		/** @deprecated */
		surgeryType: string;

		/** @deprecated */
		i: number;

		relationLinks?: Record<number, {father: number, mother: number}>;

		spire: number;
		customPronouns?: Record<number, Data.Pronouns.Definition>;
	}

	export type HeadGirlTraining = "health" | "paraphilia" | "soften" | "flaw" | "obedience" |
		"entertain skill" | "oral skill" | "fuck skill" | "anal skill" | "whore skill";

	export interface HeadGirlTrainee {
		ID: number;
		training: HeadGirlTraining;
	}

	/**
	 * These variables shall not be in the game state and there is a hope they will be exterminated in the future
	 */
	interface TemporaryVariablesInTheGameState {
		gameover?: string;
		slaveMarket?: SlaveMarketName;
		prisonCrime?: Zeroable<string>;
		enunciate?: Enunciation;
		activeSlaveOneTimeMinAge?: number;
		activeSlaveOneTimeMaxAge?: number;
		one_time_age_overrides_pedo_mode?: number;
		fixedNationality?: string;
		fixedRace?: string;
		oneTimeDisableDisability?: number;
		sortQuickList?: string;
		slaveAfterRA?: SlaveState;

		slavesToImportMax?: number;

		brandApplied?: number;
		degradation?: number;
		partner?: number | "daughter" | "father" | "mother" | "sister" | "relation" | "relationship" | "rivalry" | "";

		activeArcologyIdx?: number;

		passageSwitchHandler?: () => void;
		showAllEntries?: {
			costsBudget: number;
			repBudget: number;
		};

		brothelSpots?: number;
		clubSpots?: number;
		dairySpots?: number;
		servantsQuartersSpots?: number;
		clubBonuses?: number;
		brothelSlavesGettingHelp?: number;
		clubSlavesGettingHelp?: number;

		lastWeeksRepErrors?: string;
		lastWeeksCashErrors?: string;

		slaveUsedRest?: 1;
		arcadeDemandDegResult?: 1 | 2 | 3 | 4 | 5;

		FarmerDevotionThreshold?: number;
		FarmerDevotionBonus?: number;
		FarmerTrustThreshold?: number;
		FarmerTrustBonus?: number;
		FarmerHealthBonus?: number;

		milkmaidDevotionThreshold?: number;
		milkmaidDevotionBonus?: number;
		milkmaidTrustThreshold?: number;
		milkmaidTrustBonus?: number;
		milkmaidHealthBonus?: number;

		AS: number;
		HGTrainSlavesIDs?: HeadGirlTrainee[];
		heroSlaveID?: number;
		seed?: number;
		applyCareerBonus?: Bool;
		prostheticsConfig?: string;
		nationalitiescheck?: object;
		cellPath?: number[];
		relation: number;

		heroSlaves: SlaveTemplate[];
		HGTastes?: number;

		//#region FCTV
		usedRemote: Bool;
		//#endregion
	}

	export interface GameVariables extends DefaultGameStateVariables, ResetOnNGPVariables,
		DeprecatedGameVariables, TemporaryVariablesInTheGameState {
	}
}


code:
declare global {
	// extensions
	interface Array<T> {
		toStringExt(delimiter?: string, lastDelimiter?: string): string;
		includes(needle: any): boolean; // because we use silly unions with 0
	}

	interface Number {
		toFixedHTML(fractionDigits?: number): string;
	}

	interface Window {
		storyProxy?: object;
	}

	const V: FC.GameVariables;
	function createReadonlyProxy<T>(target: T): Readonly<T>;
	function createCheatProxy<T>(target: T): T;
}

export {}


code:
import {DeepPartial} from "ts-essentials";
declare global {
	export namespace FC {
		export type SlaveState = InstanceType<typeof App.Entity.SlaveState>;
		export type PlayerState = InstanceType<typeof App.Entity.PlayerState>;

		export type DeepPartialSlaveState = DeepPartial<SlaveState>;

		type SlaveStateRequiredAttributes = "ID" | "slaveName";
		export interface SlaveTemplate extends DeepPartial<Omit<SlaveState, SlaveStateRequiredAttributes>>,
			Pick<SlaveState, SlaveStateRequiredAttributes> {
			removedLimbs?: number[];
		}

		export type SlaveUpdate = DeepPartialSlaveState;

		//#region SlaveState types
		namespace Rules {
			type Living = "spare" | "normal" | "luxurious";
			type Rest = "none" | "cruel" | "restrictive" | "permissive" | "mandatory";
			type Mobility = "restrictive" | "permissive";
			type Speech = "restrictive" | "permissive" | "accent elimination" | "language lessons";
			type Relationship = "restrictive" | "just friends" | "permissive";
			type Lactation = "none" | "induce" | "maintain";
			type Punishment = "confinement" | "whipping" | "chastity" | "situational";
			type Reward = "relaxation" | "drugs" | "orgasm" | "situational" | "confinement";

			interface LivingFreezed extends Record<string, Living> {
				LUXURIOUS: 'luxurious';
				NORMAL: 'normal';
				SPARE: 'spare';
			}

			interface RestFreezed extends Record<string, Rest> {
				NONE: "none";
				MIN: "cruel";
				MID: "restrictive";
				MAX: "permissive";
				MANDATORY: "mandatory";
			}
		}

		type Assignment =
			// Penthouse Assignments
			'rest' | 'please you' | 'take classes' | 'be a servant' | 'whore' | 'serve the public' | 'be a subordinate slave' |
			'get milked' | 'work a glory hole' | 'stay confined' |
			// Leadership Assignments
			'guard you' | 'be your Head Girl' | 'recruit girls' | 'be your agent' | 'live with your agent' |
			// Facility Assignments
			'be confined in the arcade' | 'be the Madam' | 'work in the brothel' | 'be the Wardeness' | 'be confined in the cellblock' |
			'be the DJ' | 'serve in the club' | 'be the Nurse' | 'get treatment in the clinic' | 'be the Milkmaid' | 'work in the dairy' |
			'be the Farmer' | 'work as a farmhand' | 'live with your Head Girl' | 'be your Concubine' | 'serve in the master suite' |
			'be the Matron' | 'work as a nanny' | 'be the Schoolteacher' | 'learn in the schoolroom' | 'be the Stewardess' |
			'work as a servant' | 'be the Attendant' | 'rest in the spa' |
			// Does this one exist?
			'labor in the production line' |
			// Other
			'choose her own job' |
			// Pseudo-jobs
			'@Lurcher' | '@Pit' | '@be imported' | '@lay in tank';

		interface AssignmentFreeze extends Record<string, Assignment> {
			// Penthouse Assignments
			REST: 'rest';
			FUCKTOY: 'please you';
			CLASSES: 'take classes';
			HOUSE: 'be a servant';
			WHORE: 'whore';
			PUBLIC: 'serve the public';
			SUBORDINATE: 'be a subordinate slave';
			MILKED: 'get milked';
			GLORYHOLE: 'work a glory hole';
			CONFINEMENT: 'stay confined';
			// Leadership Assignments
			BODYGUARD: 'guard you';
			HEADGIRL: 'be your Head Girl';
			RECRUITER: 'recruit girls';
			AGENT: 'be your agent';
			AGENTPARTNER: 'live with your agent';
			// Facility Assignments
			ARCADE: 'be confined in the arcade';
			MADAM: 'be the Madam';
			BROTHEL: 'work in the brothel';
			WARDEN: 'be the Wardeness';
			CELLBLOCK: 'be confined in the cellblock';
			DJ: 'be the DJ';
			CLUB: 'serve in the club';
			NURSE: 'be the Nurse';
			CLINIC: 'get treatment in the clinic';
			MILKMAID: 'be the Milkmaid';
			DAIRY: 'work in the dairy';
			FARMER: 'be the Farmer';
			FARMYARD: 'work as a farmhand';
			HEADGIRLSUITE: 'live with your Head Girl';
			CONCUBINE: 'be your Concubine';
			MASTERSUITE: 'serve in the master suite';
			MATRON: 'be the Matron';
			NURSERY: 'work as a nanny';
			TEACHER: 'be the Schoolteacher';
			SCHOOL: 'learn in the schoolroom';
			STEWARD: 'be the Stewardess';
			QUARTER: 'work as a servant';
			ATTENDANT: 'be the Attendant';
			SPA: 'rest in the spa';
			// Does this one exist?
			BABY_FACTORY: 'labor in the production line';
			// Other
			CHOICE: 'choose her own job';
			// Pseudo-jobs
			LURCHER: '@Lurcher';
			PIT: '@Pit';
			IMPORTED: '@be imported';
			TANK: '@lay in tank';
		}
		type Fetish = WithNone<"mindbroken" | "submissive" | "cumslut" | "humiliation" | "buttslut" | "boobs" | "sadist" |
			"masochist" | "dom" | "pregnancy">;
		type BehavioralFlaw = WithNone<
			| "arrogant" // clings to her dignity, thinks slavery is beneath her
			| "bitchy" // : can 't keep her opinions to herself
			| "odd" // says and does odd things
			| "hates men" // hates men
			/** hates women */
			| "hates women"
			| "gluttonous" // likes eating, gains weight
			| "anorexic" // dislikes eating and being forced to eat, loses weight
			| "devout" // resistance through religious faith
			| "liberated" // believes slavery is wrong
		>;

		type BehavioralQuirk = WithNone<
			/** believes she has value as a slave */
			| "confident"
			/** often has as witty or cunning remark ready, knows when to say it */
			| "cutting"
			/** is funny */
			| "funny"
			/** loves working out */
			| "fitness"
			/** likes spending time with women */
			| "adores women"
			/** likes spending time with men */
			| "adores men"
			/** defines herself on the thoughts of others */
			| "insecure"
			/** breaks cultural norms */
			| "sinful"
			/** advocates slavery */
			| "advocate">;

		type SexualFlaw = WithNone<
			/**  hates oral sex */
			| "hates oral"
			/** hates anal sex */
			| "hates anal"
			/** dislikes penetrative sex */
			| "hates penetration"
			/** nervous when naked */
			| "shamefast"
			/** believes sex should be based on love and consent */
			| "idealistic"
			/** dislikes sex */
			| "repressed"
			/** inert during sex */
			| "apathetic"
			/** sexually crude and has little sense of what partners find disgusting during sex */
			| "crude"
			/** sexually judgemental and often judges her sexual partners' performance */
			| "judgemental"
			/** disregards herself in sex */
			| "neglectful"
			/** addicted to cum */
			| "cum addict"
			/** addicted to anal */
			| "anal addict"
			/** addicted to being the center of attention */
			| "attention whore"
			/** addicted to her own breasts */
			| "breast growth"
			/** sexually abusive */
			| "abusive"
			/** loves causing pain and suffering */
			| "malicious"
			/** hates herself */
			| "self hating"
			/** addicted to being pregnant */
			| "breeder">;

		type SexualQuirk = WithNone<
			/** can take a facefucking */
			"gagfuck queen"
			/** knows how far she can go without getting hurt */
			| "painal queen"
			/** knows how much resistance her partners want */
			| "strugglefuck queen"
			/** is a tease */
			| "tease"
			/** enjoys the closeness of sex */
			| "romantic"
			/** enjoys breaking sexual boundaries */
			| "perverted"
			/** enjoys bring her partners to orgasm */
			| "caring"
			/** willing to do anything */
			| "unflinching"
			/** prefers big cocks */
			| "size queen">;

		type BreastShape = "normal" | "perky" | "saggy" | "torpedo-shaped" | "downward-facing" | "wide-set" | "deflated";
		type Diet = "healthy" | "restricted" | "corrective" | "muscle building" | "fattening" | "slimming" | "XX" | "XY" | "XXY" |
			"cum production" | "cleansing" | "fertility" | "high caloric";
		type Drug = "no drugs" |
			"breast injections" | "butt injections" | "lip injections" | "nipple enhancers" | "penis enhancement" | "testicle enhancement" |
			"intensive breast injections" | "intensive butt injections" | "intensive penis enhancement" | "intensive testicle enhancement" |
			"fertility drugs" | "super fertility drugs" |
			"psychosuppressants" | "psychostimulants" | "steroids" |
			"hyper breast injections" | "hyper butt injections" | "hyper penis enhancement" | "hyper testicle enhancement" |
			"female hormone injections" | "male hormone injections" | "priapism agents" |
			"anti-aging cream" | "appetite suppressors" | "hormone enhancers" | "hormone blockers" |
			"penis atrophiers" | "testicle atrophiers" | "clitoris atrophiers" | "labia atrophiers" | "nipple atrophiers" | "lip atrophiers" |
			"breast redistributors" | "butt redistributors" | "sag-B-gone" | "growth stimulants" | "stimulants";

		type EarWear = WithNone<"hearing aids" | "muffling ear plugs" | "deafening ear plugs">;
		type EarShape = WithNone<"damaged" | "normal" | "pointy" | "elven" | "ushi" | "robot">;
		type EarTypeKemonomimi = WithNone<"normal" | "neko" | "inu" | "kit" | "tanuki" | "usagi">;
		type EyebrowStyle = "bald" | "curved" | "elongated" | "high-arched" | "natural" | "rounded" | "shaved" | "shortened" |
			"slanted inwards" | "slanted outwards" | "straight";
		type EyebrowThickness = "pencil-thin" | "thin" | "threaded" | "natural" | "tapered" | "thick" | "bushy";
		type EyeWear = WithNone<"glasses" | "blurring glasses" | "corrective glasses" | "blurring contacts" | "corrective contacts">;
		type FaceShape = "masculine" | "androgynous" | "normal" | "cute" | "sensual" | "exotic";
		type GenderGenes =
			/** female */
			"XX"
			/** Triple X syndrome female */
			| "XXX"
			/** male */
			| "XY"
			/** Klinefelter syndrome male */
			| "XXY"
			/** XYY syndrome male */
			| "XYY"
			| "X0"
			| "X";
		type GestationDrug = "slow gestation" | "speed up" | "labor suppressors";
		type HornType = WithNone<"curved succubus horns" | "backswept horns" | "cow horns" | "one long oni horn" |
			"two long oni horns" | "small horns">;
		type InflationLiquid = WithNone<"water" | "cum" | "milk" | "food" | "aphrodisiac" | "curative" | "tightener" | "urine" | "stimulant">;
		type TailType = WithNone<"mod" | "combat" | "sex">;
		type Markings = WithNone<"beauty mark" | "birthmark" | "freckles" | "heavily freckled">;
		type TailShape = WithNone<"neko" | "inu" | "kit" | "kitsune" | "tanuki" | "ushi" | "usagi" | "risu" | "uma">;
		type ToyHole = "all her holes" | "mouth" | "boobs" | "pussy" | "ass" | "dick";
		type OvaryImplantType = 0 | "fertility" | "sympathy" | "asexual";
		type NippleShape = "huge" | "puffy" | "inverted" | "tiny" | "cute" | "partially inverted" | "fuckable";
		/**
		 * 0: no; 1: yes; 2: heavy
		 */
		type PiercingType = 0 | 1 | 2;
		type ClitoralPiercingType = PiercingType | 3;
		type Race = "amerindian" | "asian" | "black" | "indo-aryan" | "latina" | "malay" | "middle eastern" | "mixed race" |
			"pacific islander" | "semitic" | "southern european" | "white";
		type SizingImplantType = WithNone<"normal" | "string" | "fillable" | "advanced fillable" | "hyper fillable">;
		type SmartPiercingSetting = WithNone<"off" | "all" | "no default setting" | "random" | "women" | "men" | "vanilla" | "oral" | "anal" |
			"boobs" | "submissive" | "humiliation" | "pregnancy" | "dom" | "masochist" | "sadist" | "anti-women" | "anti-men">;
		type TeethType = "normal" | "crooked" | "gapped" | "straightening braces" | "cosmetic braces" | "removable" | "pointy" |
			"fangs" | "fang" | "baby" | "mixed";
		type MinorInjury = Zeroable<"black eye" | "bad bruise" | "split lip" | "sore ass">;

		type RelationShipKind =
			/** married to you */
			-3
			/** emotionally bound to you */
			| -2
			/** emotional slut */
			| -1
			| 0
			/** friends with relationshipTarget */
			| 1
			/** best friends with relationshipTarget */
			| 2
			/** friends with benefits with relationshipTarget */
			| 3
			/** lover with relationshipTarget */
			| 4
			/** relationshipTarget 's slave wife */
			| 5;

		type RivalryType =
			/** None */
			0
			/** dislikes rivalryTarget */
			| 1
			/** rival of rivalryTarget */
			| 2
			/** bitterly hates rivalryTarget */
			| 3;

		type IndentureType =
			/** complete protection */
			2
			/** some protection */
			| 1
			/** no protection */
			| 0;

		type HeightImplant = -1 | 0 | 1;
		type Hearing = -2 | -1 | 0;

		type AnimalKind = "human" | "dog" | "pig" | "horse" | "cow";
		type SpermType = AnimalKind | "sterile";

		type GeneticQuirk = 0 | 1 | 2;
		interface GeneticQuirks {
			/** Oversized breasts. Increased growth rate, reduced shrink rate. Breasts try to return to oversized state if reduced. */
			macromastia: GeneticQuirk | 3;
			/** Greatly oversized breasts. Increased growth rate, reduced shrink rate. Breasts try to return to oversized state if reduced.
			 *
			 * **macromastia + gigantomastia** - Breasts never stop growing. Increased growth rate, no shrink rate. */
			gigantomastia: GeneticQuirk | 3;
			/** is prone to having twins, shorter pregnancy recovery rate */
			fertility: GeneticQuirk;
			/** is prone to having multiples, even shorter pregnancy recovery rate
			 *
			 * **fertility + hyperFertility** - will have multiples, even shorter pregnancy recovery rate */
			hyperFertility: GeneticQuirk;
			/** pregnancy does not block ovulation, slave can become pregnant even while pregnant */
			superfetation: GeneticQuirk;
			/** Pleasurable pregnancy and orgasmic birth. Wider hips, looser and wetter vagina. High pregadaptation and low birth damage. */
			uterineHypersensitivity: GeneticQuirk;
			/** is abnormally tall. gigantism + dwarfism - is very average*/
			gigantism: GeneticQuirk;
			/** is abnormally short. gigantism + dwarfism - is very average*/
			dwarfism: GeneticQuirk;
			/** has a flawless face. pFace + uFace - Depends on carrier status, may swing between average and above/below depending on it */
			pFace: GeneticQuirk;
			/** has a hideous face. pFace + uFace - Depends on carrier status, may swing between average and above/below depending on it */
			uFace: GeneticQuirk;
			/** has pale skin, white hair and red eyes */
			albinism: GeneticQuirk;
			/** may have mismatched eyes, the eye color stored here is always the left eye */
			heterochromia: GeneticQuirk | string;
			/** ass never stops growing. Increased growth rate, reduced shrink rate. */
			rearLipedema: GeneticQuirk;
			/** has (or will have) a huge dong */
			wellHung: GeneticQuirk;
			/** constantly gains weight unless dieting, easier to gain weight. wGain + wLoss - weight gain/loss fluctuates randomly */
			wGain: GeneticQuirk;
			/** constantly loses weight unless gaining, easier to lose weight. wGain + wLoss - weight gain/loss fluctuates randomly */
			wLoss: GeneticQuirk;
			/** body attempts to normalize to an androgynous state */
			androgyny: GeneticQuirk;
			/** constantly gains muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */
			mGain: GeneticQuirk;
			/** constantly loses muscle mass, easier to gain muscle. mGain + mLoss - muscle gain/loss amplified, passively lose muscle unless building */
			mLoss: GeneticQuirk;
			/** slave can only ever birth girls */
			girlsOnly: GeneticQuirk;
		}
		interface FetusGenetics {
			gender: GenderGenes;
			name: string;
			surname: Zeroable<string>;
			mother: number;
			motherName: string;
			father: number;
			fatherName: string;
			nationality: string;
			race: Race;
			intelligence: number;
			face: number;
			faceShape: FaceShape;
			eyeColor: string
			hColor: string;
			skin: string;
			markings: Markings;
			behavioralFlaw: BehavioralFlaw;
			sexualFlaw: SexualFlaw;
			pubicHStyle: string;
			underArmHStyle: string;
			clone: Zeroable<string>;
			cloneID: number;
			geneticQuirks: Partial<GeneticQuirks>;
			fetish: Fetish;
			spermY: number;
			inbreedingCoeff?: number;
		}
		//#endregion

		type LimbState = InstanceType<typeof App.Entity.LimbState>;

		interface LimbsState {
			arm: {
				left: LimbState;
				right: LimbState;
			};
			leg: {
				left: LimbState,
				right: LimbState;
			};
			PLimb: number;
		}

		interface PregnancyData {
			type: string;
			normalOvaMin: number;
			normalOvaMax: number;
			normalBirth: number;
			minLiveBirth: number;
			drugsEffect: number;
			fetusWeek: number[];
			fetusSize: number[];
			fetusRate: number[];
			sizeType: number;
		}

		type HumanState = SlaveState | PlayerState;

		export namespace Medicine {
			export namespace Surgery {
				/**
				 * Describes surgical procedure
				 */
				export interface Procedure {
					/**
					 * Type code that identifies this kind of procedure.
					 * Currently unused, but planned for future use by RA for prioritizing procedures
					 */
					typeId: string;
					/**
					 * Short label for the procedure. Can be used as a link text.
					 */
					label: string;
					/**
					 * If procedure is targeted at changing object characteristic, this is the net change (signed)
					 */
					targetEffect: number;
					/**
					 * Description of the procedure, more or less detailed
					 */
					description: string;
					/**
					 * Money costs (positive when you pay for it)
					 */
					costs: number;
					/**
					 * Projected health loss (positive when health decreases)
					 */
					healthCosts: number;
					/**
					 * Function to perform the procedure
					 * If action is undefined, the procedure can't be applied (and .description contains the reason)
					 */
					action: slaveOperation;
					/**
					 * surgery type for passages like "Surgery Degradation"
					 */
					surgeryType: string;
				}

				export interface SizingOptions {
					/** include possible augmentation procedures */
					augmentation?: boolean;
					/** include possible reduction procedures */
					reduction?: boolean;
					/** include option to install string implants */
					strings?: boolean;
					/** include implant change options */
					replace?: boolean;
				}
			}
			export namespace OrganFarm {
				interface GrowingOrgan {
					type: string;
					weeksToCompletion: number;
					ID: number;
				}
				export namespace Organs {
				}
			}
		}
	}
}

export {}


code:
declare namespace FC {
	type SlaveSchoolName = "GRI" | "HA" | "NUL" | "SCP" | "TCR" | "TFS" | "TGA" | "TSS" | "LDE" | "TUO";
	type LawlessMarkets = "generic" | "gangs and smugglers" | "heap" | "indentures" | "low tier criminals" | "military prison" | "neighbor" |
		"wetware" | "white collar" | SlaveSchoolName;
	type SlaveMarketName =  LawlessMarkets | "corporate";
	type Gingering = Zeroable<"antidepressant" | "depressant" | "stimulant" | "vasoconstrictor" | "vasodilator" | "aphrodisiac" | "ginger">;
	type GingeringDetection = Zeroable<"slaver" | "mercenary" | "force">;

	namespace SlaveSummary {
		interface SmartPiercing {
			setting: {
				off: string,
				submissive: string,
				lesbian: string,
				oral: string,
				humiliation: string,
				anal: string,
				boobs: string,
				sadist: string,
				masochist: string,
				dom: string,
				pregnancy: string,
				vanilla: string,
				all: string,
				none: string,
				monitoring: string,
				men: string,
				women: string,
				"anti-men": string,
				"anti-women": string,
			}
		}
	}
}


code:
import {StoryMoment, Passage} from "twine-sugarcube";

declare module "twine-sugarcube" {
	interface SugarCubeStoryVariables extends FC.GameVariables {
	}

	interface SugarCubeSetupObject {
		ArcologyNamesSupremacistWhite: string[];
		ArcologyNamesSupremacistAsian: string[];
		ArcologyNamesSupremacistLatina: string[];
		ArcologyNamesSupremacistMiddleEastern: string[];
		ArcologyNamesSupremacistBlack: string[];
		ArcologyNamesSupremacistIndoAryan: string[];
		ArcologyNamesSupremacistPacificIslander: string[];
		ArcologyNamesSupremacistMalay: string[];
		ArcologyNamesSupremacistAmerindian: string[];
		ArcologyNamesSupremacistSouthernEuropean: string[];
		ArcologyNamesSupremacistSemitic: string[];
		ArcologyNamesSupremacistMixedRace: string[];
		ArcologyNamesSubjugationistWhite: string[];
		ArcologyNamesSubjugationistAsian: string[];
		ArcologyNamesSubjugationistLatina: string[];
		ArcologyNamesSubjugationistMiddleEastern: string[];
		ArcologyNamesSubjugationistBlack: string[];
		ArcologyNamesSubjugationistIndoAryan: string[];
		ArcologyNamesSubjugationistPacificIslander: string[];
		ArcologyNamesSubjugationistMalay: string[];
		ArcologyNamesSubjugationistAmerindian: string[];
		ArcologyNamesSubjugationistSouthernEuropean: string[];
		ArcologyNamesSubjugationistSemitic: string[];
		ArcologyNamesSubjugationistMixedRace: string[];
		ArcologyNamesGenderRadicalist: string[];
		ArcologyNamesGenderFundamentalist: string[];
		ArcologyNamesPaternalist: string[];
		ArcologyNamesDegradationist: string[];
		ArcologyNamesAssetExpansionist: string[];
		ArcologyNamesSlimnessEnthusiast: string[];
		ArcologyNamesTransformationFetishist: string[];
		ArcologyNamesBodyPurist: string[];
		ArcologyNamesMaturityPreferentialist: string[];
		ArcologyNamesYouthPreferentialistLow: string[];
		ArcologyNamesYouthPreferentialist: string[];
		ArcologyNamesPastoralist: string[];
		ArcologyNamesPhysicalIdealist: string[];
		ArcologyNamesChattelReligionist: string[];
		ArcologyNamesRomanRevivalist: string[];
		ArcologyNamesNeoImperialist: string[];
		ArcologyNamesAztecRevivalist: string[];
		ArcologyNamesEgyptianRevivalist: string[];
		ArcologyNamesEdoRevivalist: string[];
		ArcologyNamesArabianRevivalist: string[];
		ArcologyNamesChineseRevivalist: string[];
		ArcologyNamesRepopulationist: string[];
		ArcologyNamesEugenics: string[];
		ArcologyNamesHedonisticDecadence: string[];
		ArcologyNamesIntellectualDependency: string[];
		ArcologyNamesSlaveProfessionalism: string[];
		ArcologyNamesPetiteAdmiration: string[];
		ArcologyNamesStatuesqueGlorification: string[];

		badWords: string[];
		badNames: string[];
		chattelReligionistSlaveNames: string[];
		romanSlaveNames: string[];
		romanSlaveSurnames: string[];
		aztecSlaveNames: string[];
		ancientEgyptianSlaveNames: string[];
		edoSlaveNames: string[];
		edoSlaveSurnames: string[];
		bimboSlaveNames: string[];
		cowSlaveNames: string[];
		whiteAmericanMaleNames: string[];
		whiteAmericanSlaveNames: string[];
		whiteAmericanSlaveSurnames: string[];

		attendantCareers: string[];
		bodyguardCareers: string[];
		DJCareers: string[];
		educatedCareers: string[];
		entertainmentCareers: string[];
		facilityCareers: string[];
		farmerCareers: string[];
		gratefulCareers: string[];
		HGCareers: string[];
		madamCareers: string[];
		matronCareers: string[];
		menialCareers: string[];
		milkmaidCareers: string[];
		nurseCareers: string[];
		recruiterCareers: string[];
		schoolteacherCareers: string[];
		servantCareers: string[];
		stewardessCareers: string[];
		uneducatedCareers: string[];
		veryYoungCareers: string[];
		wardenessCareers: string[];
		whoreCareers: string[];
		youngCareers: string[];

		fakeBellies: string[];
		filterRaces: string[];
		filterRacesLowercase: FC.Race[];
		filterRegions: string[];
		heightBoostingShoes: string[];
		highHeels: string[];
		humiliatingClothes: string[];
		modestClothes: string[];
		sluttyClothes: string[];

		pregData: Record<string, FC.PregnancyData>;

		malenamePoolSelector: Record<string, string[]>;
		maleSurnamePoolSelector: Record<string, string[]>;
		namePoolSelector: Record<string, string[]>;
		surnamePoolSelector: Record<string, string[]>;
		raceSelector: Record<string, Record<FC.Race, number>>;

		naturalSkins: string[];
		naturalNippleColors: string[];

		pettyCriminalPool: string[];
		gangCriminalPool: string[];
		militaryCriminalPool: string[];
		whiteCollarCriminalPool: string[];

		baseNationalities: string[];
		paraphiliaList: string[]; // actually FC.SexualFlaw[]
		prosthetics: Record<string, FC.Data.ProstheticDefinition>;
	}

	// These are SugarCube private APIs used in the project
	interface StateAPI {
		expired: StoryMoment[];
		clearTemporary(): void;
	}

	interface UIBarAPI {
		update(): void;
	}
}

export {};


code:
interface assistant {
	appearance: "normal" | "monstergirl" | "shemale" | "amazon" | "businesswoman" | "goddess" | "hypergoddess" | "schoolgirl" | "loli" | "preggololi" | "fairy" | "pregnant fairy" | "slimegirl" | "angel" | "cherub" | "imp" | "witch" | "ERROR_1606_APPEARANCE_FILE_CORRUPT" | "incubus" | "succubus";
	fsAppearance: "paternalist" | "degradationist" | "supremacist" | "subjugationist" | "roman revivalist" | "aztec revivalist" | "egyptian revivalist" | "edo revivalist" | 	"arabian revivalist" | 	"chinese revivalist" | "chattel religionist" | "repopulation focus" | "eugenics" | "physical idealist" | "hedonistic decadence" | "gender radicalist" | "gender fundamentalist" | "asset expansionist" | "transformation fetishist" | "pastoralist" | "maturity preferentialist" | "youth preferentialist" | "slimness enthusiast" | "body purist" | "intellectual dependency" | "slave professionalism" | "petite admiration" | "statuesque glorification" | "neo imperialist";
	personality: 1 | 0;
	name: string;
	power: number;
	fsOptions: 1 | 0;
	market: {
		relationship: "nonconsensual" | "incestuous" | "cute";
		limit: number;
		aggressiveness: number;
	};
	main: number;
}

interface appearance {
	"normal": fsAppearance,
	"monstergirl": fsAppearance,
	"shemale": fsAppearance,
	"amazon": fsAppearance,
	"businesswoman": fsAppearance,
	"goddess": fsAppearance,
	"hypergoddess": fsAppearance,
	"schoolgirl": fsAppearance,
	"loli": fsAppearance,
	"preggololi": fsAppearance,
	"fairy": fsAppearance,
	"pregnant fairy": fsAppearance,
	"slimegirl": fsAppearance,
	"angel": fsAppearance,
	"cherub": fsAppearance,
	"imp": fsAppearance,
	"witch": fsAppearance,
	"ERROR_1606_APPEARANCE_FILE_CORRUPT": fsAppearance,
	"incubus": fsAppearance,
	"succubus": fsAppearance,
}

interface fsAppearance {
	"paternalist": string,
	"degradationist": string,
	"supremacist": string,
	"subjugationist": string,
	"roman revivalist": string,
	"aztec revivalist": string,
	"egyptian revivalist": string,
	"edo revivalist": string,
	"arabian revivalist": string,
	"chinese revivalist": string,
	"chattel religionist": string,
	"repopulation focus": string,
	"eugenics": string,
	"physical idealist": string,
	"hedonistic decadence": string,
	"gender radicalist": string,
	"gender fundamentalist": string,
	"asset expansionist": string,
	"transformation fetishist": string,
	"pastoralist": string,
	"maturity preferentialist": string,
	"youth preferentialist": string,
	"slimness enthusiast": string,
	"body purist": string,
	"intellectual dependency": string,
	"slave professionalism": string,
	"petite admiration": string,
	"statuesque glorification": string,
	"neo imperialist": string,
}


code:
// Extension from mousetrap-record
interface MousetrapStatic {
	record(callback: (this: MousetrapStatic, sequence: string[]) => void): void;
}

// d3-dtree

declare namespace d3dTree {
	interface Person {
		name: string;
	}
	interface Marriage {
		spouse: Person;
		/**
		 * List of children nodes
		 */
		children: Person[];
	}

	interface DataItem {
		/**
		 * The name of the node
		 */
		name: string;
		/**
		 * The CSS class of the node
		 */
		class: string;
		/**
		 * The CSS class of the text in the node
		 */
		textClass: string;
		/**
		 * Generational height offset
		 */
		depthOffset?: number;
		/** Marriages is a list of nodes
		 * Each marriage has one spouse
		 */
		marriages: Marriage[];
		/**
		 * Custom data passed to renderers
		 */
		extra?: object;
	}

	interface Options {
		target: string;
		debug: boolean;
		width: number;
		height: number;
		hideMarriageNodes: boolean;
		marriageNodeSize: number;
		/**
		 *  Callbacks should only be overwritten on a need to basis.
		 * See the section about callbacks below.
		 */
		callbacks: {
		},
		margin: {
			top: number;
			right: number;
			bottom: number;
			left: number;
		},
		nodeWidth: number;
		styles: {
			node: string;
			linage: string;
			marriage: string;
			text: string;
		}
	}

	interface Tree {
		/**
		 * Reset zoom and position to initial state
		 * @param duration Default is 500
		 */
		resetZoom(duration?: number): void;
		/**
		 * Zoom to a specific position
		 * @param x
		 * @param y
		 * @param zoom = 1
		 * @param duration = 500
		 */
		zoomTo(x: number, y: number, zoom?: number, duration?: number): void;
		/**
		 * Zoom to a specific node
		 * @param nodeId
		 * @param zoom = 2
		 * @param duration = 500
		 */
		zoomToNode(nodeId: string, zoom?: number, duration?: number): void;
		/**
		 * Zoom to fit the entire tree into the viewport
		 * @param duration = 500
		 */
		zoomToFit(duration?: number): void;
	}

	interface dTree {
		init(data: DataItem[], options: Partial<Options>): Tree;
	}
}

declare const dTree: d3dTree.dTree;


code:
# Build and run an FC Docker container
# $ docker build -t fc .
# $ docker run -d --rm -p 8080:80 fc
# Access with brownser at http://localhost:8080

# Compile
FROM ubuntu
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=America/New_York
RUN apt update
RUN apt install -y git
WORKDIR /opt
RUN git clone https://gitgud.io/pregmodfan/fc-pregmod.git
WORKDIR /opt/fc-pregmod
RUN chmod +x devTools/tweeGo/tweego_nix*
RUN bash ./compile.sh

# Install the 3d renders hosted on mega.nz
RUN apt install -y megatools unzip
WORKDIR /tmp
RUN megadl --path=renders.zip https://mega.nz/#!upoAlBaZ!EbZ5wCixxZxBhMN_ireJTXt0SIPOywO2JW9XzTIPhe0
RUN unzip renders.zip
RUN cp -r 'Free Cities v 0.10.4 renders'/resources /opt/fc-pregmod/bin/

# Serve with nginx
FROM nginx
COPY --from=0 /opt/fc-pregmod/bin /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
RUN mv FC_pregmod.html index.html

path: docker/Dockerfile


code:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="FinalHTML" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<Import Project="devTools\FC.targets" />
	<PropertyGroup>
		<OutputDirectory>.\bin\</OutputDirectory>
		<JSMoudleFileName>fc.js</JSMoudleFileName>
	</PropertyGroup>

	<PropertyGroup Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'X64' ">
		<ArchitectureSuffix>64</ArchitectureSuffix>
	</PropertyGroup>
	<PropertyGroup Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'X86' ">
		<ArchitectureSuffix>86</ArchitectureSuffix>
	</PropertyGroup>

	<PropertyGroup Condition=" '$([MSBuild]::IsOsPlatform(Windows))' ">
		<TweeGoExe>tweego_win$(ArchitectureSuffix).exe</TweeGoExe>
	</PropertyGroup>
	<PropertyGroup Condition=" '$([MSBuild]::IsOsPlatform(Linux))' ">
		<TweeGoExe>tweego_nix$(ArchitectureSuffix)</TweeGoExe>
	</PropertyGroup>
	<PropertyGroup Condition=" '$([MSBuild]::IsOsPlatform(OSX))' ">
		<TweeGoExe>tweego_osx$(ArchitectureSuffix)</TweeGoExe>
	</PropertyGroup>

	<Target Name="CollectGitInfo" DependsOnTargets="FindGit">
		<Exec Command="$(GitExe) rev-parse --short HEAD" ConsoleToMsBuild="true" EchoOff="true">
			<Output TaskParameter="ConsoleOutput" PropertyName="GitHash" />
		</Exec>
	</Target>

	<Target Name="DisplayMessages" DependsOnTargets="CollectGitInfo">
		<Message Text="MSBuildProjectDirectory: $(MSBuildProjectDirectory)" />
		<Message Text="ArchitectureSuffix: $(ArchitectureSuffix)" Importance="high" />
		<Message Text="TweeGoExe: $(TweeGoExe)" Importance="high" />
		<Message Text="PA: $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)" />
		<Message Text="Git found: $(GitExeFound)" Importance="high" />
		<Message Text="Git executable: $(GitExe)" Importance="high" />
		<Message Text="HEAD commit hash: $(GitHash)" Importance="high" />
    </Target>

	<Target Name="createDirs">
		<MakeDir Directories="$(OutputDirectory)\resources"/>
	</Target>

	<Target Name="JSModule" DependsOnTargets="createDirs;DisplayMessages">
		<ItemGroup>
			<jsScripts Include=".\js\**\*.js" /> <!-- will be sorted aphabetically -->
		</ItemGroup>
		<ConcatFiles Inputs="@(jsSCripts)" BaseDir="$(MSBuildProjectDirectory)" Output="$(OutputDirectory)\$(JSMoudleFileName)"/>
	</Target>

	<Target Name="InjectGitHash" DependsOnTargets="CollectGitInfo" Condition=" '$(GitExeFound)'" >
		<WriteLinesToFile
			File="src/002-config/fc-version.js.commitHash.js"
			Lines="App.Version.commitHash = '$(GitHash)'%3B"
			Overwrite="true"
			Encoding="UTF-8"/>
	</Target>

	<Target Name="RemoveGeneratedFiles" DependsOnTargets="FindGit" Condition=" '$(GitExeFound)'" >
		<Delete Files="src/002-config/fc-version.js.commitHash.js"/>
	</Target>

	<Target Name="tmpOutput" DependsOnTargets="JSModule;InjectGitHash">
		<Exec Command="devTools\tweeGo\$(TweeGoExe) --module=$(OutputDirectory)\$(JSMoudleFileName) --head devTools\head.html -o $(OutputDirectory)\tmp.html src\" />
	</Target>

	<Target Name="FinalHTML" DependsOnTargets="tmpOutput;RemoveGeneratedFiles">
		<Delete Files="$(OutputDirectory)\$(JSMoudleFileName)" />
		<Move SourceFiles="$(OutputDirectory)\tmp.html" DestinationFiles="$(OutputDirectory)\FC_pregmod.html" />
	</Target>

	<Target Name="JavaSanityCheck">
		<Exec Command="java -jar .\devTools\javaSanityCheck\SanityCheck.jar" />
	</Target>

	<!-- Twine targets -->

	<Target Name="TwineCSS">
		<ItemGroup>
			<cssFiles Include=".\src\**\*.css" /> <!-- will be sorted aphabetically -->
		</ItemGroup>
		<ConcatFiles Inputs="@(cssFiles)" BaseDir="$(MSBuildProjectDirectory)" Output="$(MSBuildProjectDirectory)\devNotes\twine CSS.txt"/>
	</Target>

	<Target Name="TwineJS">
		<ItemGroup>
			<jsFiles Include=".\js\**\*.js;.\src\**\*.js" Exclude=".\src\art\assistantArt.js"/> <!-- will be sorted aphabetically -->
		</ItemGroup>
		<ConcatFiles Inputs="@(jsFiles)" BaseDir="$(MSBuildProjectDirectory)" Output="$(MSBuildProjectDirectory)\devNotes\twine JS.raw"/>
		<StripComments
			InputFilename="$(MSBuildProjectDirectory)\devNotes\twine JS.raw"
			OutputFilename="$(MSBuildProjectDirectory)\devNotes\twine JS.txt"
		/>
	</Target>

	<Target Name="Twine" DependsOnTargets="TwineCSS;TwineJS"/>

</Project>


code:
const gulp = require('gulp'),
	concat = require('gulp-concat'),
	git = require('gulp-git'),
	log = require('fancy-log-levels'),
	noop = require('gulp-noop'),
	postcss = require('gulp-postcss'),
	shell = require('gulp-shell'),
	sort = require('gulp-sort'),
	sourcemaps = require('gulp-sourcemaps'),
	autoprefixer = require('autoprefixer'),
	which = require('which'),
	fs = require('fs'),
	path = require('path'),
	os = require('os'),
	yargs = require('yargs'),
	cfg = require('./build.config.json');

const args = yargs.options({
	verbosity: {type: 'number', default: 0},
	release: {type: 'boolean', default: false},
	embedsourcemaps: {type: 'boolean', default: false},
	sourcemapsincludecontent: {type: 'boolean', default: false}
}).argv;

const htmlOut = "tmp.html";

log(args.verbosity);

function tweeCompilerExecutable() {
	const systemTweego = which.sync('tweego', {nothrow: true});
	if (systemTweego) {
		log.info('Found system tweego at ', systemTweego);
		return systemTweego;
	}
	const archSuffix = os.arch() === 'x64' ? '64' : '86';
	const platformSuffix = {
		'Darwin': 'osx',
		'Linux': 'nix',
		'Windows_NT': 'win'
	}[os.type()];
	const extension = os.type() === 'Windows_NT' ? '.exe' : '';
	const res = path.join('.', 'devTools', 'tweeGo', `tweego_${platformSuffix}${archSuffix}${extension}`);
	log.info('Using bundled tweego at ', res);
	return res;
}

function concatFiles(srcGlob, destDir, destFileName) {
	return gulp.src(srcGlob)
		.pipe(sort())
		.pipe(concat(destFileName))
		.pipe(gulp.dest(destDir));
}

function processScripts(srcGlob, destDir, destFileName) {
	const addSourcemaps = !args.release;
	const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf('*')));
	return gulp.src(srcGlob)
		.pipe(sort())
		.pipe(addSourcemaps ? sourcemaps.init() : noop())
		.pipe(concat(destFileName))
		.pipe(addSourcemaps ?
			sourcemaps.write(args.embedsourcemaps ? undefined : '.', {
				includeContent: args.sourcemapsincludecontent,
				sourceRoot: prefix,
				sourceMappingURLPrefix: path.relative(cfg.dirs.output, destDir)
			}) :
			noop())
		.pipe(gulp.dest(destDir));
}

function processStylesheets(srcGlob, destDir, destFileName) {
	const addSourcemaps = !args.release;
	const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf('*')));
	return gulp.src(srcGlob)
		.pipe(sort())
		.pipe(addSourcemaps ? sourcemaps.init() : noop())
		.pipe(concat(destFileName))
		.pipe(cfg.options.css.autoprefix ?
			postcss([autoprefixer({overrideBrowserslist: ['last 2 versions']})]) :
			noop())
		.pipe(addSourcemaps ?
			sourcemaps.write(args.embedsourcemaps ? undefined : '.', {
				includeContent: args.sourcemapsincludecontent,
				sourceRoot: prefix,
				sourceMappingURLPrefix: path.relative(cfg.dirs.output, destDir)
			}) :
			noop())
		.pipe(gulp.dest(destDir));
}

function processSrc(name, processorFunc, globs, destDir, destFileName, ...args) {
	let tasks = [];
	if (!Array.isArray(globs) || globs.length === 1) {
		const src = Array.isArray(globs) ? globs[0] : globs;
		tasks.push(() => processorFunc(src, destDir, destFileName, args));
		tasks[tasks.length - 1].displayName = "process-" + name;
	} else { // many globs
		const ext = path.extname(destFileName);
		const bn = path.basename(destFileName, ext);
		for (let i = 0; i < globs.length; ++i) {
			tasks.push(() => processorFunc(globs[i], destDir, `${bn}-${i}${ext}`, args));
			tasks[tasks.length - 1].displayName = `process-${name}-${i}`;
		}
	}
	const res = gulp.parallel(...tasks);
	res.displayName = name;
	return res;
}

function injectGitCommit(cb) {
	git.revParse({args: '--short HEAD'}, function(err, hash) {
		if (!err) {
			log.info('current git hash: ', hash);
			fs.writeFile(cfg.gitVersionFile, `App.Version.commitHash = '${hash}';\n`, cb);
		} else {
			cb();
		}
	});
}

function cleanupGit(cb) {
	if (fs.existsSync(cfg.gitVersionFile)) {
		fs.unlink(cfg.gitVersionFile, cb);
	} else {
		cb();
	}
}

function compileStory() {
	let sources = [path.join(cfg.dirs.intermediate, "story")];
	sources.push(...cfg.sources.story.media);

	let modules = [path.join(cfg.dirs.intermediate, "module")];
	let moduleArgs = modules.map(fn => `--module=${fn}`);
	const cmdLine = `${tweeCompilerExecutable()} -f ${cfg.twineformat} --head=${cfg.sources.head} -o ${path.join(cfg.dirs.intermediate, htmlOut)} ${moduleArgs.join(' ')} ${sources.join(' ')}`;

	log.info(cmdLine);
	return gulp.src(sources, {read: false})
		.pipe(shell(cmdLine, {env: cfg.options.twee.environment}));
}

const processors = {
	"css": {
		func: processStylesheets,
		output: "styles.css"
	},
	"js": {
		func: processScripts,
		output: "script.js"
	},
	"twee": {
		func: concatFiles,
		output: "story.twee"
	},
	"media": {
		func: null
	}
};

function prepareComponent(name) {
	const c = cfg.sources[name];
	const outDir = path.join(cfg.dirs.intermediate, name);
	const subTasks = [];
	for (const srcType in c) {
		const proc = processors[srcType];
		if (proc.func) {
			subTasks.push(processSrc(`${name}-${srcType}`, proc.func, c[srcType], outDir, proc.output, cfg.options[srcType]));
		}
	}
	let r = gulp.parallel(subTasks);
	r.displayName = "prepare-" + name;
	return r;
}

function moveHTMLInPlace(cb) {
	fs.rename(path.join(cfg.dirs.intermediate, htmlOut), path.join(cfg.dirs.output, cfg.output), cb);
}

function clean(cb) {
	if (fs.existsSync(cfg.gitVersionFile)) {
		fs.unlinkSync(cfg.gitVersionFile);
	}
	fs.rmdirSync(cfg.dirs.intermediate, {recursive: true});
	cb();
}

function prepare(cb) {
	return gulp.series(clean, injectGitCommit, gulp.parallel(prepareComponent("module"), prepareComponent("story")))(cb);
}

if (fs.statSync('.git').isDirectory()) {
	gulp.task('buildHTML', gulp.series(prepare, compileStory, cleanupGit));
} else {
	gulp.task('buildHTML', gulp.series(prepare, compileStory));
}

exports.clean = clean;
exports.default = gulp.series('buildHTML', moveHTMLInPlace);


code:
/* eslint-disable no-var */
// @ts-ignore
"use strict";

var App = { }; // eslint-disable-line no-redeclare

// When adding namespace declarations, please consider needs of those using VSCode:
// when you declare App.A{ A1:{}, A2:{} }, VSCode considers A, A1, and A2 to be
// sealed namespaces and no new members are added to them with nested declaration later on.
// This breaks code completion completely. Please instead declare them as:
// App.A = {}; App.A.A1 = {}; App.A.A2 = {}. Thank you.

// Also, such declaration basically required only for namespaces that span more than a single file.

App.Arcology = {};
App.Arcology.Cell = {};
App.Art = {};
App.Corporate = {};
App.Data = {};
App.Data.FCTV = {};
App.Data.HeroSlaves = {};
App.Data.Policies = {};
App.Data.Policies.Selection = {};
App.Data.Weather = {};
App.Debug = {};
App.Desc = {};
App.Desc.Player = {};
App.Encyclopedia = {};
App.Encyclopedia.Entries = {};
App.EndWeek = {};
App.Entity = {};
App.Entity.Utils = {};
App.Events = {};
App.Facilities = {};
App.Facilities.Arcade = {};
App.Facilities.Brothel = {};
App.Facilities.Cellblock = {};
App.Facilities.Clinic = {};
App.Facilities.Club = {};
App.Facilities.Dairy = {};
App.Facilities.Farmyard = {};
App.Facilities.HGSuite = {};
App.Facilities.Incubator = {};
App.Facilities.MasterSuite = {};
App.Facilities.Nursery = {};
App.Facilities.Pit = {};
App.Facilities.Schoolroom = {};
App.Facilities.ServantsQuarters = {};
App.Facilities.Spa = {};
App.Interact = {};
App.Intro = {};
App.Neighbor = {};
App.MainView = {};
App.Markets = {};
App.Medicine = {};
App.Medicine.Modification = {};
App.Medicine.Modification.Brands = {};
App.Medicine.Modification.Select = {};
App.Medicine.OrganFarm = {};
/** @type {Object.<string, App.Medicine.OrganFarm.Organ>} */
App.Medicine.OrganFarm.Organs = {};
App.Medicine.Salon = {};
App.Medicine.Surgery = {};
App.RA = {};
App.Reminders = {};
App.SF = {};
App.SecExp = {};
App.SlaveAssignment = {};
App.UI = {};
App.UI.Budget = {};
App.UI.DOM = {};
App.UI.DOM.Widgets = {};
App.UI.SlaveInteract = {};
App.UI.View = {};
App.Update = {};
App.Utils = {};


code:
/** @type {FC.Rules.LivingFreezed} */
globalThis.LivingRule = Object.freeze({LUXURIOUS: 'luxurious', NORMAL: 'normal', SPARE: 'spare'});
/** @type {FC.Rules.RestFreezed} */
globalThis.RestRule = Object.freeze({MANDATORY: 'mandatory', MAX: 'permissive', MID: 'restrictive', MIN: 'cruel', NONE: 'none'});
/** @type {FC.AssignmentFreeze} */
globalThis.Job = Object.freeze({
	// Penthouse Assignments
	REST: 'rest',
	FUCKTOY: 'please you',
	CLASSES: 'take classes',
	HOUSE: 'be a servant',
	WHORE: 'whore',
	PUBLIC: 'serve the public',
	SUBORDINATE: 'be a subordinate slave',
	MILKED: 'get milked',
	GLORYHOLE: 'work a glory hole',
	CONFINEMENT: 'stay confined',
	// Leadership Assignments
	BODYGUARD: 'guard you',
	HEADGIRL: 'be your Head Girl',
	RECRUITER: 'recruit girls',
	AGENT: 'be your agent',
	AGENTPARTNER: 'live with your agent',
	// Facility Assignments
	ARCADE: 'be confined in the arcade',
	MADAM: 'be the Madam',
	BROTHEL: 'work in the brothel',
	WARDEN: 'be the Wardeness',
	CELLBLOCK: 'be confined in the cellblock',
	DJ: 'be the DJ',
	CLUB: 'serve in the club',
	NURSE: 'be the Nurse',
	CLINIC: 'get treatment in the clinic',
	MILKMAID: 'be the Milkmaid',
	DAIRY: 'work in the dairy',
	FARMER: 'be the Farmer',
	FARMYARD: 'work as a farmhand',
	HEADGIRLSUITE: 'live with your Head Girl',
	CONCUBINE: 'be your Concubine',
	MASTERSUITE: 'serve in the master suite',
	MATRON: 'be the Matron',
	NURSERY: 'work as a nanny',
	TEACHER: 'be the Schoolteacher',
	SCHOOL: 'learn in the schoolroom',
	STEWARD: 'be the Stewardess',
	QUARTER: 'work as a servant',
	ATTENDANT: 'be the Attendant',
	SPA: 'rest in the spa',
	// Does this one exist?
	BABY_FACTORY: 'labor in the production line',
	// Other
	CHOICE: 'choose her own job',
	// Pseudo-jobs
	LURCHER: '@Lurcher',
	PIT: '@Pit',
	IMPORTED: '@be imported',
	TANK: '@lay in tank'
});

globalThis.PersonalAttention = Object.freeze({
	TRADE: 'trading',
	WAR: 'warfare',
	SLAVING: 'slaving',
	ENGINEERING: 'engineering',
	MEDICINE: 'medicine',
	MAID: 'upkeep',
	HACKING: 'hacking',
	SUPPORTHG: 'HG'
});


code:
// A whitelist for ingame variables.  Used to init the game or fill in gaps.  Also used as a whitelist.  Anything not on this list will be removed on BC.
App.Data.defaultGameStateVariables = {
	// Page
	returnTo: "init",
	nextButton: "Continue",
	nextLink: "Alpha disclaimer",
	storedLink: "",

	// Version
	ver: 0,
	pmodVer: 0,
	releaseID: 0,

	// Slaves
	/** @type {Object.<number, number>} */
	slaveIndices: {},
	genePool: [],
	missingTable: {},
	/** @type {App.Entity.SlaveState[]} */
	slaves: [],

	// PC
	/** @type {App.Entity.PlayerState} */
	PC: {},
	freshPC: 0,
	IsInPrimePC: 3,
	IsPastPrimePC: 5000,
	playerAging: 2,

	// Save
	saveImported: 0,

	// Other
	cheater: 0,
	cash: 0,
	cashLastWeek: 0,
	taintedSaveFile: 0,

	// UI content
	UI: {
		slaveSummary: {
			abbreviation: {
				clothes: 2,
				devotion: 2,
				diet: 2,
				drugs: 2,
				genitalia: 2,
				health: 2,
				hormoneBalance: 2,
				mental: 2,
				nationality: 2,
				origins: 2,
				physicals: 2,
				race: 2,
				rules: 2,
				rulesets: 2,
				skills: 2,
			}
		},
		compressSocialEffects: 0
	},
	/** @type {marketGlobal|null} */
	market: null,
	FSNamePref: 0,
	HGFormality: 1,
	HGSeverity: 0,
	abbreviateSidebar: 1,
	adamPrinciple: 0,
	allowFamilyTitles: 0,
	allowMaleSlaveNames: false,
	autosave: 1,
	baseDifficulty: 3,
	dangerousPregnancy: 0,
	debugMode: 0,
	debugModeCustomFunction: 0,
	difficultySwitch: 0,
	disableLisping: 0,
	displayAssignments: 1,
	economy: 100,
	expansionRequestsAllowed: 1,
	extremeUnderage: 0,
	formatNumbers: 1,
	fucktoyInteractionsPosition: 1,
	slaveInteractLongForm: false,
	headGirlSoftensFlaws: 1,
	headGirlTrainsFlaws: 1,
	headGirlTrainsHealth: 1,
	headGirlTrainsObedience: 1,
	headGirlTrainsParaphilias: 1,
	headGirlTrainsSkills: 1,
	imageChoice: 1,
	inbreeding: 1,
	lastBDayEvent: -1,
	lineSeparations: 1,
	limitFamilies: 0,
	makeDicks: 0,
	modRequestsAllowed: 1,
	neighboringArcologies: 3,
	neighborDisplay: "list",
	newDescriptions: 0,
	newModelUI: 1,
	nicknamesAllowed: 1,
	positionMainLinks: -1,
	profiler: 0,
	realRoyalties: 0,
	retainCareer: 1,
	ngpParams: {},
	rulesAssistantAuto: 0,
	rulesAssistantMain: 1,
	seeAge: 1,
	seeArcology: 1,
	seeAvatar: 1,
	seeBestiality: 0,
	seeCircumcision: 1,
	seeDesk: 1,
	seeDetails: 1,
	seeDicks: 25,
	seeDicksAffectsPregnancy: 1,
	seeExtreme: 0,
	seeFCNN: 1,
	seeFaces: 1,
	seeHeight: 0,
	seeHyperPreg: 0,
	seeIllness: 1,
	seeImages: 0,
	seeIncest: 1,
	seeMainFetishes: 0,
	seeNationality: 1,
	seePee: 1,
	seePreg: 1,
	seeRace: 1,
	seeReportImages: 1,
	seeSummaryImages: 1,
	seeVectorArtHighlights: 1,
	showAgeDetail: 1,
	showAppraisal: 1,
	showAssignToScenes: 1,
	showBodyMods: 1,
	showBoobCCs: 1,
	showClothing: 1,
	showDickCMs: 1,
	showDistantRelatives: 0,
	showEWD: 1,
	showEWM: 1,
	showEconomicDetails: 0,
	showHeightCMs: 1,
	showImplantEffects: 1,
	showInches: 1,
	showMissingSlaves: false,
	showMissingSlavesSD: false,
	showNeighborDetails: 1,
	showNumbers: 2,
	showNumbersMax: 20,
	showScores: 1,
	showSexualHistory: 1,
	showTipsFromEncy: 1,
	showVignettes: 1,
	slavePanelStyle: 1,
	sortSlavesBy: "devotion",
	sortSlavesMain: 1,
	sortSlavesOrder: "descending",
	summaryStats: 0,
	surnameOrder: 0,
	/** @type {Object.<string, string>} */
	tabChoice: {Main: "all"},
	universalRulesAssignsSelfFacility: 0,
	universalRulesBirthing: 0,
	universalRulesCSec: 0,
	universalRulesChildrenBecomeBreeders: 0,
	universalRulesConsent: 0,
	universalRulesFacilityWork: 1,
	universalRulesImmobileSlavesMaintainMuscles: 0,
	universalRulesImpregnation: "none",
	universalRulesNewSlavesRA: 1,
	universalRulesRest: 0,
	useAccordion: 1,
	useFSNames: 1,
	useSlaveListInPageJSNavigation: 0,
	useSlaveSummaryOverviewTab: 0,
	useSlaveSummaryTabs: 0,
	useTabs: 0,
	verboseDescriptions: 0,
	verticalizeArcologyLinks: 0,
	weightAffectsAssets: 1,
	curativeSideEffects: 1,
	disableLongDamage: 1,
	// Last-used strings in Locate Slave
	findName: "",
	findBackground: "",
	findData: "",

	// eslint-disable-next-line camelcase
	pedo_mode: 0,
	minimumSlaveAge: 16,
	fertilityAge: 13,
	potencyAge: 13,
	AgePenalty: 1,
	precociousPuberty: 0,
	loliGrow: 0,
	retirementAge: 45,
	customRetirementAge: 45,
	customMenialRetirementAge: 65,
	sortIncubatorList: "Unsorted",
	AgeEffectOnTrainerPricingPC: 1,
	AgeEffectOnTrainerEffectivenessPC: 1,
	AgeTrainingUpperBoundPC: 14,
	AgeTrainingLowerBoundPC: 12,
	childSex: 0,
	showClothingErection: true,

	// Default location
	continent: "North America",
	terrain: "rural",
	language: "English",

	AProsperityCapModified: 0,
	secExpEnabled: 0,
};

// Corp data
App.Data.CorpInitData = {
	Announced: 0,
	Incorporated: 0,
	Market: 0,
	Econ: 0,
	CashDividend: 0,
	Div: 0,
	ExpandToken: 0,
	Spec: 0,
	SpecToken: 0,
	SpecRaces: []
};

// Black Market
App.Data.FSWares = [
	"AssetExpansionistResearch",
	"GenderRadicalistResearch",
	"HedonisticDecadenceResearch",
	"SlaveProfessionalismResearch",
	"SlimnessEnthusiastResearch",
	"TransformationFetishistResearch",
	"YouthPreferentialistResearch",
];

App.Data.illegalWares = [
	"AnimalOrgans",
	"asexualReproduction",
	"BlackmarketPregAdaptation",
	"childhoodFertilityInducedNCS",
	"PGHack",
	"RapidCellGrowthFormula",
	"sympatheticOvaries",
	"UterineRestraintMesh",
];

// The other half of the above whitelist.  However, entries in this array will be forced to the values set here upon starting NG+.
App.Data.resetOnNGPlus = {
	policies: {
		retirement: {
			sex: 0,
			milk: 0,
			cum: 0,
			births: 0,
			kills: 0,

			/** @type {FC.Zeroable<string>} */
			fate: 0,
			menial2Citizen: 0,
			customAgePolicy: 0,
			physicalAgePolicy: 0
		},
		SMR: {
			basicSMR: 1,
			healthInspectionSMR: 0,
			educationSMR: 0,
			frigiditySMR: 0,
			weightSMR: 0,
			honestySMR: 0,

			beauty: {
				basicSMR: 0,
				qualitySMR: 0
			},
			height: {
				basicSMR: 0,
				advancedSMR: 0
			},
			intelligence: {
				basicSMR: 0,
				qualitySMR: 0
			},
			eugenics: {
				faceSMR: 0,
				heightSMR: 0,
				intelligenceSMR: 0
			}
		},

		childProtectionAct: 1,
		culturalOpenness: 0,
		proRefugees: 0,
		publicFuckdolls: 0,

		proRecruitment: 0,
		cash4Babies: 0,
		regularParties: 0,
		publicPA: 0,
		coursingAssociation: 0,

		raidingMercenaries: 0,
		mixedMarriage: 0,
		goodImageCampaign: 0,
		alwaysSubsidizeRep: 0,
		alwaysSubsidizeGrowth: 0,

		immigrationCash: 0,
		immigrationRep: 0,
		enslavementCash: 0,
		enslavementRep: 0,
		cashForRep: 0,

		oralAppeal: 0,
		vaginalAppeal: 0,
		analAppeal: 0,
		sexualOpenness: 0,
		bestialityOpenness: 0,
		gumjobFetishism: 0,
		gumjobFetishismSMR: 0
	},

	FCTV: {
		receiver: -1,
		channel: {},
		pcViewership: {
			count: 0,
			frequency: 4,
		},
		remote: 0,
		weekEnabled: 0
	},
	/** @type {assistant} */
	assistant: {},
	targetArcology: {fs: "New"},
	readySlaves: 0,

	plot: 1,
	assignmentRecords: {},
	marrying: [], // array of slave being married this week
	organs: [],
	corp: App.Data.CorpInitData,
	dividendTimer: 0,
	dividendRatio: 0,
	personalShares: 0,
	publicShares: 0,
	SF: {},
	thisWeeksFSWares: 0,
	thisWeeksIllegalWares: 0,
	Sweatshops: 0,

	milkTap: 0,
	rivalID: 0,
	eliteAuctioned: 0,
	slavesSacrificedThisWeek: 0,
	subSlaves: 0,

	HGtraining: "",
	mercenariesTitle: "",
	hormones: 0,
	FSReminder: 0,
	facility: {},
	boomerangStats: {},
	FSNonconformist: "",
	econAdvantage: 0,

	foughtThisWeek: 0,
	/* rebellions */
	slaveRebellionEventFires: 0,
	citizenRebellionEventFires: 0,
	slaveRebellion: 0,
	citizenRebellion: 0,
	engageRule: 0,
	irregulars: 0,
	repairTime: 3,
	arcRepairTime: 0,
	garrison: {},
	/* armed forces stats */
	militiaFreeManpower: 0,
	militiaTotalCasualties: 0,
	slavesTotalCasualties: 0,
	mercFreeManpower: 0,
	mercTotalCasualties: 0,
	createdSlavesUnits: 0,
	createdMilitiaUnits: 0,
	createdMercUnits: 0,
	/* battle relevant vars */
	attackType: "none",
	attackThisWeek: 0,
	majorBattle: 0,
	chosenTactic: "none",
	leadingTroops: "none",
	attackTroops: 0,
	attackEquip: 0,
	battleTerrain: "none",
	maxTurns: 10,
	battleResult: 4, // sets battleResult value outside accepted range (-3,3) to avoid evaluation problems
	losses: 0,
	enemyLosses: 0,
	battleTurns: 0,
	tacticsSuccessful: 0,
	leaderWounded: 0,
	gainedCombat: 0,
	gainedWarfare: 0,
	SFIntervention: 0,
	rebellingID: [],
	saveValid: 0,
	/* units */
	/** @type {FC.SecExp.PlayerUnitData} */
	secBots: {},
	/** @type {FC.SecExp.PlayerHumanUnitData[]} */
	militiaUnits: [],
	/** @type {FC.SecExp.PlayerHumanUnitData[]} */
	slaveUnits: [],
	/** @type {FC.SecExp.PlayerHumanUnitData[]} */
	mercUnits: [],
	/* base vars */
	SecExp: {},

	reminderEntry: "",
	reminderWeek: "",
	lastWeeksCashIncome: {},
	lastWeeksCashExpenses: {},
	lastWeeksRepIncome: {},
	lastWeeksRepExpenses: {},
	currentRule: {},
	costs: 0,
	seeBuilding: 0,
	slaveOneTimeMinAge: 0,
	slaveOneTimeMaxAge: 0,
	purchasedSagBGone: 0,
	eliteFail: 0,
	eliteFailTimer: 0,
	nurseryGrowthStimsSetting: 0,
	MadamIgnoresFlaws: 0,
	MadamNoSex: 0,
	farmyardBreeding: 0,
	farmyardRestraints: 0,
	farmyardShows: 0,
	farmyardPregSetting: 0,
	DJignoresFlaws: 0,
	DJnoSex: 0,
	DJRepBonus: 0,
	fuckSlaves: 0,
	publicServants: 0,

	localEcon: 0,
	econRate: 0,
	drugsCost: 0,
	rulesCost: 0,
	modCost: 0,
	surgeryCost: 0,
	/** @type {FC.ArcologyState[]} */
	arcologies: [],
	HackingSkillMultiplier: 0,
	upgradeMultiplierArcology: 0,
	upgradeMultiplierMedicine: 0,
	upgradeMultiplierTrade: 0,
	nationalities: {},
	/** @type {Record<FC.Assignment, Set<number>>} */
	JobIDMap: {},
	averageTrust: 0,
	averageDevotion: 0,
	enduringTrust: 0,
	enduringDevotion: 0,
	/** @type {FC.RA.Rule[]} */
	defaultRules: [],
	/** @type {Object.<string, number[]>} */
	rulesToApplyOnce: {},

	REFeminizationCheckinIDs: [],
	REMILFCheckinIDs: [],
	REOrientationCheckinIDs: [],
	REUglyCheckinIDs: [],
	REButtholeCheckinIDs: [],
	REFutaSisterCheckinIDs: [],
	REReductionCheckinIDs: [],

	deathIDs: {
		health: [],
		overdose: [],
		age: []
	},
	burstIDs: [],
	birthIDs: [],
	induceIDs: [],
	/** @type {FC.SlaveStateOrZero} */
	activeSlave: 0,
	activeChild: 0,
	reminders: [],

	/** @type {FC.SlaveStateOrZero} */
	boomerangSlave: 0,
	boomerangWeeks: 0,
	boomerangBuyer: 0,

	bioreactorPerfectedID: 0,

	independenceDay: 0,
	invasionVictory: 0,
	daughtersVictory: 0,

	dormitory: 20,
	dormitoryPopulation: 0,
	rooms: 5,
	roomsPopulation: 0,

	brothelDecoration: "standard",
	brothelUpgradeDrugs: 0,
	brothelAdsSpending: 0,
	brothelAdsOld: 0,
	brothelAdsModded: 0,
	brothelAdsImplanted: 0,
	brothelAdsStacked: 0,
	brothelAdsPreg: 0,
	brothelAdsXX: 0,
	brothelName: "the Brothel",
	brothel: 0,
	brothelBoost: {
		selected: 0, eligible: 0
	},
	dairyDecoration: "standard",
	dairyPrepUpgrade: 0,
	dairyStimulatorsUpgrade: 0,
	dairyStimulatorsSetting: 0,
	dairyStimulatorsSettingChanged: 0,
	dairyFeedersUpgrade: 0,
	dairyFeedersSetting: 0,
	dairyFeedersSettingChanged: 0,
	dairyPregUpgrade: 0,
	dairyPregSetting: 0,
	dairyPregSettingChanged: 0,
	dairyRestraintsUpgrade: 0,
	dairyRestraintsSetting: 0,
	dairySlimMaintainUpgrade: 0,
	dairySlimMaintain: 0,
	dairyHyperPregRemodel: 0,
	dairyWeightSetting: 0,
	dairyHormonesSetting: 0,
	dairyImplantsSetting: 1,
	dairyUpgradeMenials: 0,
	createBioreactors: 0,
	bioreactorsAnnounced: 0,
	bioreactorsHerm: 0,
	bioreactorsXX: 0,
	bioreactorsXY: 0,
	bioreactorsBarren: 0,
	dairyName: "the Dairy",
	dairy: 0,
	cumSlaves: 0,
	clubDecoration: "standard",
	clubUpgradePDAs: 0,
	clubAdsSpending: 0,
	clubAdsOld: 0,
	clubAdsModded: 0,
	clubAdsImplanted: 0,
	clubAdsStacked: 0,
	clubAdsPreg: 0,
	clubAdsXX: 0,
	clubName: "the Club",
	club: 0,
	servantsQuartersDecoration: "standard",
	servantsQuartersUpgradeMonitoring: 0,
	servantsQuarters: 0,
	servantsQuartersName: "the Servants' Quarters",
	schoolroomDecoration: "standard",
	schoolroomUpgradeSkills: 0,
	schoolroomUpgradeLanguage: 0,
	schoolroomUpgradeRemedial: 0,
	schoolroomRemodelBimbo: 0,
	schoolroom: 0,
	schoolroomName: "the Schoolroom",
	spaDecoration: "standard",
	spa: 0,
	spaSpots: 0,
	spaUpgrade: 0,
	spaFix: 0,
	spaName: "the Spa",

	// Incubator Subsection
	incubator: 0,
	incubatorBulkRelease: 0,
	incubatorOrgans: [],
	incubatorUpgradeSpeed: 5,
	incubatorUpgradeWeight: 0,
	incubatorUpgradeMuscles: 0,
	incubatorUpgradeGrowthStims: 0,
	incubatorUpgradeReproduction: 0,
	incubatorUpgradeOrgans: 0,
	incubatorImprintSetting: "trust",
	incubatorWeightSetting: 0,
	incubatorMusclesSetting: 0,
	incubatorGrowthStimsSetting: 0,
	incubatorReproductionSetting: 0,
	incubatorUpgradePregAdaptation: 0,
	incubatorPregAdaptationSetting: 0,
	incubatorPregAdaptationPower: 0,

	incubatorName: "the Incubator",
	tanks: [],

	clinicDecoration: "standard",
	clinic: 0,
	clinicUpgradeFilters: 0,
	clinicUpgradeScanner: 0,
	clinicUpgradePurge: 0,
	clinicObservePregnancy: 1,
	clinicInflateBelly: 0,
	clinicSpeedGestation: 0,
	clinicName: "the Clinic",
	arcadeDecoration: "standard",
	arcadeUpgradeInjectors: 0,
	arcadeUpgradeFuckdolls: 0,
	arcadeUpgradeCollectors: 0,
	arcadeUpgradeHealth: -1,
	arcadeName: "the Arcade",
	arcade: 0,
	fuckdollsSold: 0,
	cellblockDecoration: "standard",
	cellblockUpgrade: 0,
	cellblock: 0,
	cellblockName: "the Cellblock",
	cellblockWardenCumsInside: 1,
	masterSuiteDecoration: "standard",
	masterSuiteUpgradeLuxury: 0,
	masterSuiteUpgradePregnancy: 0,				/* Is the upgrade active? */
	masterSuitePregnancyFertilityDrugs: 0,			/* Are slaves being put on fertility drugs? */
	masterSuitePregnancyFertilitySupplements: 0,	/* Are those drugs being supplemented (health benefits and (even) more multiple pregnancies) */
	masterSuitePregnancySlaveLuxuries: 0,			/* Are the slaves being given some nicer things to reduce stress during preg? (health/devotion/trust benefits) */
	universalHGImpregnateMasterSuiteToggle: 0,		/* Will the HG impregnate fertile slaves in the MS? */
	masterSuiteHyperPregnancy: 0,
	masterSuite: 0,
	masterSuiteName: "the Master Suite",

	// Nursery Subsection
	/** Counts the number of children the nursery can support */
	nursery: 0,
	/** Counts the number of nannies the nursery can support */
	nurseryNannies: 0,
	/** Counts the number of children currently in the nursery */
	nurseryChildren: 0,
	/** Check for whether the children are influenced by the nannies */
	nannyInfluence: 0,
	nurseryDecoration: "standard",
	nurseryWeight: 0,
	nurseryMuscles: 0,
	nurseryHormones: 0,
	nurseryOrgans: 0,								// not currently in use
	nurseryImprintSetting: 0,
	nurseryWeightSetting: 0,
	nurseryMusclesSetting: 0,
	nurseryHormonesSetting: 0,
	nurseryName: "the Nursery",
	/** Array of children in the Nursery */
	cribs: [],
	cribsIndices: {},
	sortNurseryList: "Unsorted",
	targetAgeNursery: 18,

	// Farmyard Subsection
	farmyard: 0,
	farmyardShowgirls: [],			/* array of farmhands putting on shows */
	farmyardFarmers: [],			/* array of farmhands farming */
	farmMenials: 0,
	farmMenialsSpace: 0,
	farmyardDecoration: "standard",
	farmyardUpgrades: {
		pump: 0,
		fertilizer: 0,
		hydroponics: 0,
		machinery: 0,
		seeds: 0,
	},
	farmyardCrops: 0,
	farmyardStables: 0,
	farmyardKennels: 0,
	farmyardCages: 0,
	activeCanine: 0,
	activeHooved: 0,
	activeFeline: 0,
	animalsBought: {
		canines: 0,
		felines: 0,
		hooved: 0,

		beagles: 0,
		bulldogs: 0,
		frenchBulldogs: 0,
		germanShepherds: 0,
		goldenRetrievers: 0,
		labradorRetrievers: 0,
		poodles: 0,
		rottweilers: 0,
		siberianHuskies: 0,
		yorkshireTerriers: 0,

		bulls: 0,
		horses: 0,
		pigs: 0,

		abbysinians: 0,
		bengals: 0,
		birmans: 0,
		maineCoons: 0,
		orientalShorthairs: 0,
		persians: 0,
		ragdolls: 0,
		russianBlues: 0,
		siameses: 0,
		sphynxes: 0,

		dingos: 0,
		foxes: 0,
		jackals: 0,
		wolves: 0,

		zebras: 0,

		cougars: 0,
		jaguars: 0,
		leopards: 0,
		lions: 0,
		lynx: 0,
		pumas: 0,
		tigers: 0,
	},
	canines: [],
	hooved: [],
	felines: [],
	farmyardName: "the Farmyard",

	HGSuite: 0,
	HGSuiteSurgery: 1,
	HGSuiteDrugs: 1,
	HGSuiteHormones: 1,
	HGSuiteEquality: 0,
	HGSuiteName: "the Head Girl Suite",

	/** @type {FC.Facilities.Pit} */
	pit: null,

	dojo: 0,
	feeder: 0,
	cockFeeder: 0,
	suppository: 0,
	weatherCladding: 0,
	weatherAwareness: 0,
	boobAccessibility: 0,
	servantMilkers: 0,

	studio: 0,
	studioFeed: 0,
	PCSlutContacts: 1,

	/* Porn star counts (prestige 1) and ID's (prestige 3) */
	pornStars: {},

	pregInventor: 0,
	pregInventorID: 0,
	pregInventions: 0,

	legendaryWhoreID: 0,
	legendaryEntertainerID: 0,
	legendaryCowID: 0,
	legendaryBallsID: 0,
	legendaryWombID: 0,
	legendaryAbolitionistID: 0,

	FSAnnounced: 0,
	FSGotRepCredits: 0,
	FSCreditCount: 5,
	FSSingleSlaveRep: 10,
	FSSpending: 0,
	FSLockinLevel: 100,
	FSPromenade: {
		Subjugationist: 0, Supremacist: 0, GenderRadicalist: 0, GenderFundamentalist: 0, Paternalist: 0, Degradationist: 0, BodyPurist: 0, TransformationFetishist: 0, YouthPreferentialist: 0, MaturityPreferentialist: 0, SlimnessEnthusiast: 0, AssetExpansionist: 0, Pastoralist: 0, PhysicalIdealist: 0, ChattelReligionist: 0, RomanRevivalist: 0, AztecRevivalist: 0, EgyptianRevivalist: 0, EdoRevivalist: 0, ArabianRevivalist: 0, ChineseRevivalist: 0, NeoImperialist: 0, Repopulationist: 0, Eugenics: 0, Hedonism: 0, IntellectualDependency: 0, SlaveProfessionalism: 0, PetiteAdmiration: 0, StatuesqueGlorification: 0
	},

	// new corporation variables
	newCorp: 1,
	vanillaShareSplit: 1,

	/* Slave sexual services and goods variables */
	classSatisfied: {
		lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0
	},
	whoreBudget: {
		lowerClass: 7, middleClass: 40, upperClass: 200, topClass: 1500
	},
	sexDemandResult: {
		lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0
	},
	arcadePrice: 2,
	clubSlaveSexAmount: 0,
	/** @type {App.Entity.SlaveState|number} */
	shelterSlave: 0,
	shelterSlaveBought: 0,
	shelterAbuse: 0,
	shelterSlaveGeneratedWeek: 0,

	pregAccessibility: 0,
	dickAccessibility: 0,
	ballsAccessibility: 0,
	buttAccessibility: 0,
	ageMode: 0,
	boughtItem: {
		clothing: {
			// alternate clothing access variables
			bunny: 0,
			conservative: 0,
			chains: 0,
			western: 0,
			oil: 0,
			habit: 0,
			toga: 0,
			huipil: 0,
			kimono: 0,
			harem: 0,
			qipao: 0,
			imperialarmor: 0,
			imperialsuit: 0,
			egypt: 0,
			belly: 0,
			maternityDress: 0,
			maternityLingerie: 0,
			lazyClothes: 0,
			bimbo: 0,
			courtesan: 0,
			petite: 0,
			// non-fs
			military: 0,
			cultural: 0,
			middleEastern: 0,
			pol: 0,
			costume: 0,
			pantsu: 0,
			career: 0,
			dresses: 0,
			bodysuits: 0,
			casual: 0,
			underwear: 0,
			sports: 0,
			pony: 0,
			swimwear: 0,
		},
		shoes: {
			heels: 0,
		},
		toys: {
			enema: 0,
			medicalEnema: 0,
			buckets: 0,
			dildos: 0,
			gags: 0,
			vaginalAttachments: 0,
			buttPlugs: 0,
			buttPlugTails: 0,
			smartVibes: 0,
			smartVaginalAttachments: 0,
		},
	},
	dairyPiping: 0,
	milkPipeline: 0,
	cumPipeline: 0,
	wcPiping: 0,
	burstee: 0,
	slaveDeath: 0,
	playerBred: 0,
	propOutcome: 0,
	EliteSires: ["crazy", "futa", "moves", "preggo", "quick", "virgin"],
	startingPoint: -1,
	raped: -1,
	children: [],
	missingParentID: -10000,
	startingSlaveRelative: 0,
	mom: 0,
	/* animalParts: 0,*/
	pregSpeedControl: 0,
	playerSurgery: 0,
	bodyswapAnnounced: 0,
	surnamesForbidden: 0,
	menstruation: 0,
	FCNNstation: 0,
	MercenariesMessageSent: 0,
	SpecialForcesMessageSent: 0,
	finalChoice: "none",
	eliteTotal: 12,
	eliteDead: 0,
	eliteVegetable: 0,
	eliteFate: 0,
	swanSong: 0,
	swanSongWeek: 99999,
	failedElite: 0,
	eugenicsFullControl: 0,
	badC: 0,
	poorKnight: 0,
	imperialEventWeek: 0,
	assholeKnight: 0,
	newBaron: 0,
	badB: 0,

	schoolSuggestion: 0,
	TSS: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	TUO: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	GRI: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	SCP: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	LDE: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	TGA: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	TCR: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	TFS: {
		farmUpgrade: 0, schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0, compromiseWeek: 0
	},
	futaAddiction: 0,
	HA: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},
	NUL: {
		schoolUpgrade: 0, schoolPresent: 0, schoolProsperity: 0, subsidize: 0, schoolAnnexed: 0, studentsBought: 0, schoolSale: 0
	},

	IDNumber: 1,

	week: 1,

	slaveTutor: {
		HeadGirl: [],
		Recruiter: [],
		Bodyguard: [],
		Madam: [],
		DJ: [],
		Nurse: [],
		Teacher: [],
		Attendant: [],
		Matron: [],
		Stewardess: [],
		Milkmaid: [],
		Farmer: [],
		Wardeness: []
	},
	tutorGraduate: [],

	weddingPlanned: 0,
	/** @type {string|Array<{ID:number, trainingRegimen:string}>} */
	personalAttention: "sex",
	HeadGirlID: 0,
	HGTimeInGrade: 0,
	RecruiterID: 0,
	recruiterTarget: "desperate whores",
	oldRecruiterTarget: "desperate whores",
	recruiterProgress: 0,
	recruiterIdleRule: "number",
	recruiterIdleNumber: 20,
	recruiterIOUs: 0,
	bodyguardTrains: 1,
	BodyguardID: 0,
	MadamID: 0,
	djID: 0,
	MilkmaidID: 0,
	milkmaidImpregnates: 0,
	FarmerID: 0,
	StewardessID: 0,
	stewardessImpregnates: 0,
	SchoolteacherID: 0,
	AttendantID: 0,
	MatronID: 0,
	NurseID: 0,
	WardenessID: 0,
	ConcubineID: 0,

	justiceEvents: ["slave deal", "slave training", "majority deal", "indenture deal", "virginity deal", "breeding deal"], /* not in setupVars because we remove events from this array as they occur */
	prisonCircuit: ["low tier criminals", "gangs and smugglers", "white collar", "military prison"],
	prisonCircuitIndex: 0,

	ui: "start",
	tooltipsEnabled: 0,

	brandTarget: {primary: "left buttock", secondary: "left buttock", local: "left buttock"},
	brandDesign: {primary: "your initials", official: "your initials", local: "your initials"},

	scarTarget: {primary: "left cheek", secondary: "left cheek", local: "left cheek"},
	scarDesign: {primary: "generic", local: "generic"},

	oralTotal: 0,
	vaginalTotal: 0,
	analTotal: 0,
	mammaryTotal: 0,
	penetrativeTotal: 0,
	milkTotal: 0,
	cumTotal: 0,
	foodTotal: 0,
	birthsTotal: 0,
	abortionsTotal: 0,
	miscarriagesTotal: 0,
	pitKillsTotal: 0,
	pitFightsTotal: 0,

	collaboration: 0,
	/** @type {FC.SlaveStateOrZero} */
	traitor: 0,
	traitorType: 0,
	traitorWeeks: 0,
	traitorStats: 0,
	hackerSupport: 0,
	/** @type {FC.SlaveStateOrZero} */
	hostage: 0,
	/** @type {FC.Bool} */
	hostageAnnounced: 0,
	/** @type {FC.Bool} */
	hostageRescued: 0,
	/** @type {FC.Bool} */
	hostageGiveIn: 0,
	/** @type {FC.SlaveStateOrZero} */
	hostageWife: 0,
	rivalSet: 0,
	/** @type {FC.Zeroable<FC.FutureSocietyNoun>} */
	rivalryFS: 0,
	/** @type {FC.Bool} */
	rivalryFSAdopted: 0,
	/** @type {FC.Zeroable<FC.Race>} */
	rivalryFSRace: 0,
	rivalOwner: 0,
	rivalOwnerEnslaved: 0,
	rivalryPower: 0,
	rivalryDuration: 0,
	/** @type {FC.Zeroable<FC.Race>} */
	rivalRace: 0,
	rivalGender: 0,
	nationHate: 0,
	eventResults: {},

	dispensary: 0,
	dispensaryUpgrade: 0,
	organFarmUpgrade: 0,
	/** @type {FC.Medicine.OrganFarm.GrowingOrgan[]} */
	completedOrgans: [],
	ImplantProductionUpgrade: 0,
	permaPregImplant: 0,
	injectionUpgrade: 0,
	hormoneUpgradeMood: 0,
	hormoneUpgradeShrinkage: 0,
	hormoneUpgradePower: 0,
	pubertyHormones: 0,
	dietXXY: 0,
	dietCleanse: 0,
	cumProDiet: 0,
	dietFertility: 0,
	curativeUpgrade: 0,
	growthStim: 0,
	reproductionFormula: 0,
	aphrodisiacUpgrade: 0,
	aphrodisiacUpgradeRefine: 0,
	healthyDrugsUpgrade: 0,
	superFertilityDrugs: 0,
	bellyImplants: 0,
	cervixImplants: 0,
	meshImplants: 0,
	prostateImplants: 0,
	youngerOvaries: 0,
	sympatheticOvaries: 0,
	fertilityImplant: 0,
	asexualReproduction: 0,
	animalOvaries: 0, /* {pigOvaries: 0, canineOvaries: 0, horseOvaries: 0, cowOvaries: 0} currently unused*/
	animalTesticles: 0, /* {pigTestes: 0, dogTestes: 0, horseTestes: 0, cowTestes: 0} currently unused*/
	animalMpreg: 0, /* {pigMpreg: 0, dogMpreg: 0, horseMpreg: 0, cowMpreg: 0} currently unused*/
	geneticMappingUpgrade: 0,
	pregnancyMonitoringUpgrade: 0,
	cloningSystem: 0,
	geneticFlawLibrary: 0,

	surgeryUpgrade: 0,

	barracks: 0,
	mercenaries: 0,
	mercenariesHelpCorp: 0,
	personalArms: 0,

	/** @type {FC.Gingering} */
	gingering: 0,
	/** @type {FC.SlaveStateOrZero} */
	beforeGingering: 0,
	/** @type {FC.Bool} */
	gingeringDetected: 0,
	/** @type {FC.GingeringDetection} */
	gingeringDetection: 0,
	surgeryDescription: 0,
	encyclopedia: "How to Play",

	/** @type {string[]} */
	trinkets: [],
	SPcost: 1000,
	debtWarned: 0,
	internationalTrade: 1,
	internationalVariety: 0,
	slaveCostFactor: 0.95,
	menialDemandFactor: 0,
	menialSupplyFactor: 0,
	demandTimer: 0,
	supplyTimer: 0,
	elapsedDemandTimer: 0,
	elapsedSupplyTimer: 0,
	slaveCostRandom: 0,
	deltaDemand: 0,
	deltaDemandOld: 0,
	deltaSupply: 0,
	deltaSupplyOld: 0,
	NPCSexSupply: {
		lowerClass: 3000, middleClass: 3000, upperClass: 3000, topClass: 3000
	},
	NPCMarketShare: {
		lowerClass: 1000, middleClass: 1000, upperClass: 1000, topClass: 1000
	},
	sexSubsidies: {
		lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0
	},
	sexSupplyBarriers: {
		lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0
	},
	facilityCost: 100,
	enduringRep: 1000,
	rep: 0,
	repLastWeek: 0,

	arcologyUpgrade: {
		drones: 0, hydro: 0, apron: 0, grid: 0, spire: 0
	},

	AGrowth: 2,
	ACitizens: 4250,
	lowerClass: 3120,
	LSCBase: 800,
	visitors: 0,
	rentDefaults: {
		lowerClass: 20, middleClass: 50, upperClass: 180, topClass: 650
	},
	rent: {
		lowerClass: 20, middleClass: 50, upperClass: 180, topClass: 650
	},
	rentEffectL: 1,
	middleClass: 890,
	MCBase: 200,
	rentEffectM: 1,
	upperClass: 200,
	UCBase: 40,
	rentEffectU: 1,
	topClass: 40,
	TCBase: 20,
	rentEffectT: 1,
	GDP: 278.6,
	NPCSlaves: 900,
	ASlaves: 900,
	AProsperityCap: 0,

	food: 125000,
	foodLastWeek: 0,
	foodProduced: 0,
	foodStored: 0,
	farmyardFoodCost: 5,
	foodCost: 25,
	foodMarket: 0,
	foodRate: {
		slave: 2, lower: 1.8, middle: 2, upper: 2.2, top: 2.4
	},
	foodConsumption: 0,	/* total amount food consumed per week */
	revealFoodEffects: 0,
	rations: 0,
	/** @type {App.Arcology.Building | null} */
	building: null,

	menials: 0,
	fuckdolls: 0,
	menialBioreactors: 0,
	prestigeAuctioned: 0,
	slaveMarketLimit: 20,
	slavesSeen: 0,

	slaveOrphanageTotal: 0,
	citizenOrphanageTotal: 0,
	privateOrphanageTotal: 0,
	breederOrphanageTotal: 0,

	LurcherID: 0,
	coursed: 0,
	StudID: 0,
	raided: 0,

	expiree: 0,
	retiree: 0,
	birthee: 0,
	FSSlaveProfLawTrigger: 0,
	citizenRetirementTrigger: 0,
	FSSupLawTrigger: 0,
	FSSubLawTrigger: 0,
	nicaea: {
		announceable: 0,
		announced: 0,
		preparation: 0,
		involvement: -2,
		power: 0,
		held: 0,
		focus: "",
		assignment: "",
		achievement: "",
		name: "",
		influence: 0,
	},

	/** @type {FC.Zeroable<FC.PeacekeepersState>} */
	peacekeepers: 0,
	peacekeepersFate: 0,
	peacekeepersGone: 0,
	mercRomeo: 0,

	oralUseWeight: 5,
	vaginalUseWeight: 5,
	analUseWeight: 5,
	mammaryUseWeight: 1,
	penetrativeUseWeight: 1,

	weatherToday: {},
	weatherLastWeek: 0,
	weatherType: 0,
	weatherRemaining: 0,

	customSlaveOrdered: 0,
	/**
	 * I am not a slave object! Do not treat me like one!
	 * @type {App.Entity.CustomSlaveOrder}
	 */
	customSlave: {},

	huskSlaveOrdered: 0,
	/** @type {App.Entity.CustomSlaveOrder} */
	huskSlave: {},

	/* non-vanilla shit*/

	targetAge: 18,
	pubertyLength: 5,
	maxGrowthAge: 24,

	/* Job Fulfillment Center */
	JFC: {
		/** @type {FC.Bool} */
		order: 0,
		reorder: 0
	},

	/** @type {FC.Bool} */
	cheatMode: 0,
	cheatModeM: 1,
	experimental: {
		nursery: 0,
		food: 0,
		animalOvaries: 0,
		dinnerParty: 0
	},
	NaNArray: [],

	/* Misc mod variables */
	recruiterEugenics: 0,

	prostheticsUpgrade: 0,
	adjustProstheticsCompleted: 0,
	adjustProsthetics: [], /* format: {id: string, workleft: int, slaveID: int}*/
	/* task: {type: "research"/"craft/craftFit", id: string, workLeft: int, [if constructFit] slaveID: int}*/
	researchLab: {
		level: 0,
		aiModule: 1,
		tasks: [],
		maxSpace: 0,
		hired: 0,
		menials: 0,
	},
	prosthetics: {},

	merchantFSWares: App.Data.FSWares,
	merchantIllegalWares: App.Data.illegalWares,
	RapidCellGrowthFormula: 0,
	immortalityFormula: 0,
	UterineRestraintMesh: 0,
	PGHack: 0,
	BlackmarketPregAdaptation: 0,

	diversePronouns: 0,

	/* Career-skill gain */
	masteredXP: 200,

	/* Weather effect on economy */
	antiWeatherFreeze: 0,
	econWeatherDamage: 0,
	disasterResponse: 0,

	postSexCleanUp: 1,

	sideBarOptions: {
		Cash: 1, Upkeep: 1, SexSlaveCount: 1, roomPop: 1, Rep: 1, GSP: 1, Authority: 1, Security: 1, Crime: 1, confirmWeekEnd: 0,
	},
	DefaultBirthDestination: "individually decided fates",
	legendaryFacility: 0,
	heroSlavesPurchased: [],
	fcnn: [
		("...coming up at the top of the hour: Catgirl slaves, science fact or science fiction..."),
		("...coming up at the top of the hour: Malnockestivi Smith, Free Cities' first MtFtMtFtH transgendered person..."),
		("...new arcology construction up 23% worldwide this year, according to..."),
		("...United States Congress spends 1,264th consecutive day gridlocked over post office..."),
		("...coming up at the top of the hour: Arcology owners: oversexed oligarchs or attractive, oversexed oligarchs?..."),
		("...coming up at the top of the hour: Anal sex: not just for sex any more..."),
		("...coming up at the top of the hour: Oral sex: the new hello..."),
		("...new book by prominent feminist suggests that women should not be used as sexual appliances..."),
		("...just ahead, interview with Desha Moore, prominent advocate for compulsory female enslavement..."),
		("...just ahead, Slave Market Trends: will the pierced anus be in again this year..."),
		("...just ahead, Slave Market Trends: upstart slave trainers avoid implants..."),
		("...implant technology firm BusTech notches successful initial public offering..."),
		("...the upcoming shortage of authentic leather and what it means for the whip industry..."),
		("...dairy conglomerate Creem Inc. denies allegations of adulterating breast milk with..."),
		("...two-time award-winning actress Linda Loveless debuted new implants on the red carpet this..."),
		("...dick size: are your slaves lying to you when they tell you you're too big..."),
		("...just ahead, slave expert's opinion on best shemale slaves to use for double penetration..."),
		("...Free Cities social conservatives criticize marriage, say your slaves should be enough..."),
		("...councilman Taggart suggested in a public address that involuntary enslavement..."),
		("...councilman Taggart denies allegations that he has remained faithful to his wife..."),
		("...councilman Taggart presented evidence that regulation of the sex slave market would..."),
		("...after a word from our sponsors. Creem Inc.: for all your dairy needs..."),
		("...after a word from our sponsors. Horstmann Ltd, Free Cities' finest whipmakers..."),
		("...after a word from our sponsors. Coming soon to theaters, Quintuple, the musical..."),
		("...critical of low-end slave training corporation Wallerson & Sons for practices that they say..."),
		("...training corporation Wallerson & Sons called a study on slave illness rates 'ludicrous,' but..."),
		("...our tech correspondent: the possibilities of virally-administered gene therapy..."),
		("...our tech correspondent: breakthrough in in-vitro drug treatments that promise to..."),
		("...our tech correspondent: next year to see release of two competing aphrodisiacs..."),
		("...our tech correspondent: the coming permanent aphrodisiac implants, and what they mean..."),
		("...Sex Slaves in Space: what it takes to keep a mining crew happy for an 18-month contract..."),
		("...the implant-drug balance: how much tissue growth is necessary to support larger..."),
		("...the actress stated that the cut to full nudity in the script violated contractual..."),
		("...doping scandal as Slave Games watchdog alleges champion used internal reservoir of lube..."),
		("...next on Extreme Surgery: the mouthpussy experimenters and what they..."),
		("...'A hole's a hole,' said CEO of upstart budget glory hole franchise..."),
		("...underground slave pit fights step into the light this evening as..."),
		("...underground slave pit fight champion, freed yesterday, sells herself back into..."),
		("...with the lead designer of the MP17, the new machine pistol marketed specifically for bodyguards..."),
		("...the new Aegis drone series: because your arcology's security is your most important possession..."),
		("...the BAe Goshawk: because you deserve to travel at twice the speed of sound in the finest style..."),
		("...this year's Goat.cx award for outstanding orifice innovation goes to..."),
		("...public controversy over cannibalism. Decadence taken too far or an acceptable next step..."),
		("...sixth day of street cleaners' strike. Spokesman for the strikers: 'It's getting too nasty..."),
		("...debuts new book, 'So Long, And Thanks For All The Dicks', in which the recently retired sex slaves tell-all about..."),
		("...cure for lactose intolerance, for which he was awarded the International Association of Pastoralist..."),
		("...from the Free Cities have become increasingly common clientele for the black market..."),
		("...a risky gamble on the three-hour-long hardcore sex scene, but the box office figures for just..."),
		("...claiming that even tourists to the Free Cities were at risk of sexual enslavement..."),
	],

	murderAttemptWeek: 80,
	illegalDeals: {
		/** @type {FC.Zeroable<{week: number, company: string}>} */
		military: 0,
		/** @type {FC.Zeroable<{week: number, company: string}>} */
		trade: 0,
		menialDrug: 0,
		/** @type {FC.Zeroable<{type: string, company: string}>} */
		slave: 0
	},
	tempEventToggle: 0,
	/**
	 * Assignments texts for slaves who choose their own assignment, set at during the first pass in  App.SlaveAssignment.choosesOwnJob()
	 * @type {Object.<number, string>}
	 */
	choosesOwnAssignmentText: {},
	favorites: []
};

App.Data.ignoreGameStateVariables = [
	// pronouns
	"Mothers",
	"mothers",
	"Fathers",
	"Husbands",
	"Husband",
	"Brother",
	"Son",
	"Shota",
	"Men",
	"Man",
	"fathers",
	"husbands",
	"husband",
	"brother",
	"son",
	"shota",
	"men",
	"man",
	"Mother",
	"Wives",
	"Wife",
	"Sister",
	"Daughter",
	"Loli",
	"Women",
	"Woman",
	"mother",
	"wives",
	"wife",
	"sister",
	"daughter",
	"loli",
	"women",
	"woman",
	"Girl",
	"Herself",
	"Hers",
	"Her",
	"She",
	"girl",
	"herself",
	"hers",
	"her",
	"she",
	"Father",
	"father",
	"Boy",
	"Himself",
	"His",
	"Him",
	"He",
	"boy",
	"himself",
	"his",
	"him",
	"he",

	// Enunciate
	"enunciate"
];