code:
declare namespace FC {
	/**
	 * This interface defines all (almost, see ArcologyStateFSPeculiarities below) the FS-related
	 * arcology properties.
	 * * `research`: FS provides -Research property [Bool], otherwise has to be set to `undefined`
	 * * `SMR`: FS provides SMR policy, [Bool], otherwise has to be set to `undefined`
	 * * `policy`: string union of boolean laws and other policies, otherwise has to be set to `undefined`
	 * * `choice`: string union of numeric laws and choices, that may have other values except `0` and `1`.
	 */
	interface FutureSocietyIdMap {
		FSSupremacist: {
			noun: "Racial Supremacism", adj: "Supremacist", deco: "Supremacist",
			research: undefined, SMR: true, policy: "LawME", choice: undefined
		};
		FSSubjugationist: {
			noun: "Racial Subjugationism", adj: "Subjugationist", deco: "Subjugationist",
			research: undefined, SMR: true, policy: "LawME", choice: undefined
		};
		FSGenderRadicalist: {
			noun: "Gender Radicalism", adj: "Gender Radicalist", deco: "Gender Radicalist",
			research: true, SMR: undefined, policy: "LawBeauty", choice: "LawFuta"
		};
		FSGenderFundamentalist: {
			noun: "Gender Fundamentalism", adj: "Gender Fundamentalist", deco: "Gender Fundamentalist",
			research: true, SMR: true, policy: "LawBimbo" | "LawBeauty", choice: undefined
		};
		FSDegradationist: {
			noun: "Degradationism", adj: "Degradationist", deco: "Degradationist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSPaternalist: {
			noun: "Paternalism", adj: "Paternalist", deco: "Paternalist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSBodyPurist: {
			noun: "Body Purism", adj: "Body Purist", deco: "Body Purist",
			research: true, SMR: true, policy: "Law" | "CatLaw", choice: undefined
		};
		FSTransformationFetishist: {
			noun: "Transformation Fetishism", adj: "Transformation Fetishist", deco: "Transformation Fetishist",
			research: true, SMR: true, policy: undefined, choice: undefined
		};
		FSYouthPreferentialist: {
			noun: "Youth Preferentialism", adj: "Youth Preferentialist", deco: "Youth Preferentialist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSMaturityPreferentialist: {
			noun: "Maturity Preferentialism", adj: "Maturity Preferentialist", deco: "Maturity Preferentialist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSSlimnessEnthusiast: {
			noun: "Slimness Enthusiasm", adj: "Slimness Enthusiast", deco: "Slimness Enthusiast",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSAssetExpansionist: {
			noun: "Asset Expansionism", adj: "Asset Expansionist", deco: "Asset Expansionist",
			research: true, SMR: true, policy: undefined, choice: undefined
		};
		FSPastoralist: {
			noun: "Pastoralism", adj: "Pastoralist", deco: "Pastoralist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSCummunism: {
			noun: "Cummunism", adj: "Cummunist", deco: undefined,
			research: true, SMR: undefined, policy: undefined, choice: undefined
		};
		FSPhysicalIdealist: {
			noun: "Physical Idealism", adj: "Physical Idealist", deco: "Physical Idealist",
			research: true, SMR: true, policy:	"Law" | "StrongFat", choice: undefined
		};
		FSHedonisticDecadence: {
			noun: "Decadent Hedonism", adj: "Decadent Hedonist", deco: "Hedonistic",
			research: "" | "Diet", SMR: true, policy: "Law" | "Law2", choice: "StrongFat"
		};
		FSChattelReligionist: {
			noun: "Chattel Religionism", adj: "Chattel Religionist", deco: "Chattel Religionist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSNull: {
			noun: "Multiculturalism", adj: "Multiculturalist", deco: undefined,
			research: undefined, SMR: undefined, policy: undefined, choice: undefined
		};
		FSIncestFetishist: {
			noun: "Incest Fetishism", adj: "Incest Fetishist", deco: undefined,
			research: true, SMR: undefined, policy: undefined, choice: undefined
		};
		FSRomanRevivalist: {
			noun: "Roman Revivalism", adj: "Roman Revivalist", deco: "Roman Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSNeoImperialist: {
			noun: "Neo-Imperialism", adj: "Neo-Imperialist", deco: "Neo-Imperialist",
			research: undefined, SMR: true, policy: "Law1" | "Law2", choice: undefined
		};
		FSEgyptianRevivalist: {
			noun: "Egyptian Revivalism", adj: "Egyptian Revivalist", deco: "Egyptian Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSEdoRevivalist: {
			noun: "Edo Revivalism", adj: "Edo Revivalist", deco: "Edo Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSArabianRevivalist: {
			noun: "Arabian Revivalism", adj: "Arabian Revivalist", deco: "Arabian Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSChineseRevivalist: {
			noun: "Chinese Revivalism", adj: "Chinese Revivalist", deco: "Chinese Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSAztecRevivalist: {
			noun: "Aztec Revivalism", adj: "Aztec Revivalist", deco: "Aztec Revivalist",
			research: undefined, SMR: true, policy: "Law", choice: undefined
		};
		FSRepopulationFocus: {
			noun: "Repopulation Focus", adj: "Repopulationist", deco: "Repopulationist",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSRestart: {
			noun: "Eugenics", adj: "Eugenics", deco: "Eugenics",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSIntellectualDependency: {
			noun: "Intellectual Dependency", adj: "Intellectual Dependency", deco: "Intellectual Dependency",
			research: true, SMR: true, policy: "Law" | "LawBeauty", choice: undefined
		};
		FSSlaveProfessionalism: {
			noun: "Slave Professionalism", adj: "Slave Professional", deco: "Slave Professionalism",
			research: true, SMR: true, policy: "Law", choice: undefined
		};
		FSPetiteAdmiration: {
			noun: "Petite Admiration", adj: "Petite Admiration", deco: "Petite Admiration",
			research: true, SMR: true, policy: "Law" | "Law2", choice: undefined
		};
		FSStatuesqueGlorification: {
			noun: "Statuesque Glorification", adj: "Statuesque Glorification", deco: "Statuesque Glorification",
			research: true, SMR: true, policy: "Law" | "Law2", choice: undefined
		}
	}

	type FutureSociety = keyof FutureSocietyIdMap;
	type FutureSocietyNoun = FutureSocietyIdMap[keyof FutureSocietyIdMap]["noun"];
	type FutureSocietyAdj = FutureSocietyIdMap[keyof FutureSocietyIdMap]["adj"];
	type FutureSocietyDeco = FutureSocietyIdMap[keyof FutureSocietyIdMap]["deco"] | "standard";

	type FutureSocietyWithResearchMap = {
		[K in keyof FutureSocietyIdMap]: FutureSocietyIdMap[K]["research"] extends true ? `${K}Research`
		: FutureSocietyIdMap[K]["research"] extends string ? `${K}${FutureSocietyIdMap[K]["research"]}Research`
		: never;
	}

	type FutureSocietyPolicy = {
		[K in keyof FutureSocietyIdMap]: FutureSocietyIdMap[K]["policy"] extends string ?
		`${K}${FutureSocietyIdMap[K]["policy"]}` : never;
	}

	type FutureSocietyChoice = {
		[K in keyof FutureSocietyIdMap]: FutureSocietyIdMap[K]["choice"] extends string ?
		`${K}${FutureSocietyIdMap[K]["choice"]}` : never;
	}

	type FutureSocietyHasResearchAny = FutureSocietyWithResearchMap[FutureSociety];
	type FutureSocietyPolicyAny = FutureSocietyPolicy[FutureSociety];
	type FutureSocietyChoiceAny = FutureSocietyChoice[FutureSociety];

	type FSDecoName<T extends FutureSociety> = FutureSocietyIdMap[T]["deco"] extends undefined ? never : `${T}Decoration`
	type FSSMRName<T extends FutureSociety> = FutureSocietyIdMap[T]["SMR"] extends undefined ? never : `${T}SMR`

	type FSPolicyValue = number | "unset";

	type FSName<T extends string> = T extends `FS${infer Name}` ? Name : never;

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

	type ArcologyStateBase = {
		name: string;
		direction: Zeroable<ArcologyDirection>;
		government: string;
		leaderID: number;
		honeymoon: number;
		prosperity: number;
		ownership: number;
		minority: number;
		PCminority: number;
		demandFactor: number;
		embargo: number;
		embargoTarget: Zeroable<ArcologyDirection>;
		influenceTarget: Zeroable<ArcologyDirection>;
		influenceBonus: number;
		CyberEconomic: number;
		CyberEconomicTarget: Zeroable<ArcologyDirection>;
		CyberReputation: number;
		CyberReputationTarget: Zeroable<ArcologyDirection>;
		rival: number;
		childhoodFertilityInducedNCSResearch: Bool;
		hackingEconomic: number;
		hackingEconomicTarget: number;
		hackingReputationTarget: number;
		hackingReputation: number;
		weeks: number;
	}

	type ArcologyStateFSPeculiarities = {
		FSSupremacistRace: Zeroable<Race>;
		FSSubjugationistRace: Zeroable<Race>;

		FSEgyptianRevivalistIncestPolicy: number;
		FSEgyptianRevivalistInterest: number;

		FSRepopulationFocusPregPolicy: number;
		FSRepopulationFocusMilfPolicy: number;
		FSRepopulationFocusInterest: number;

		FSEugenicsChastityPolicy: number;
		FSEugenicsSterilizationPolicy: number;
		FSEugenicsInterest: number;

		FSChattelReligionistCreed: number;
	}

	type ArcologyStateFS = ArcologyStateFSPeculiarities &
		Record<FutureSociety, FSPolicyValue> &
		Record<FutureSocietyHasResearchAny, Bool> &
		Record<FSDecoName<FutureSociety>, number> &
		Record<FSSMRName<FutureSociety>, Bool> &
		Record<FutureSocietyPolicyAny, Bool> &
		Record<FutureSocietyChoiceAny, number>;

	type ArcologyState = ArcologyStateBase & ArcologyStateFS;

}


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: Fanatey/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;
			decorated: boolean;
		}

		namespace SlaveSummary {
			interface SmartVibrator {
				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,
				},
				system: {
					"piercing": string,
					"bullet": string,
					"vibe": string
				}
			}
		}
	}
}


code:
declare namespace FC {
	namespace Desc {
		interface LongSlaveOptions {
			descType?: DescType;
			market?: Zeroable<SlaveMarketName | SpecialMarketName | "starting">;
			marketText?: string; /* extra text to be appended to the first line of the description, dependent on the original market */
			noArt?: boolean;
		}
	}
}


code:
declare namespace FC {
	export type Upgrade = InstanceType<typeof App.Upgrade>;

	interface IUpgrade {
		/** The variable name of the upgrade. */
		property: string;
		/** Properties pertaining to any tiers available. */
		tiers: IUpgradeTier[];
		/** Any object the upgrade property is part of, if not the default `V`. */
		object?: Object;
	}

	interface IUpgradeTier {
		/** The value `property` must be set to in order to display this tier. */
		value: any;
		/** The value to set `property` to upon purchase of the upgrade, if any. */
		upgraded?: any;
		/** The link text. */
		link?: string;
		/** The text to display for the current tier of the upgrade. */
		text: string;
		/**
		 * How much the upgrade costs.
		 *
		 * If one is not provided, the upgrade will be free.
		 */
		cost?: number;
		/** Any handler to run upon purchase. */
		handler?: () => void;
		/** Any additional information to display upon hover on the link. */
		notes?: string[];
		/**
		 * Any prerequisites that must be met before the upgrade is available.
		 *
		 * If none are given, the upgrade will always be available.
		 */
		prereqs?: boolean[];
		/** Any additional nodes to attach. */
		nodes?: Array<string|HTMLElement|DocumentFragment>;
	}

	interface IFacilityAssignment {
		/** The name of the assignment. */
		position: string;
		/** The assignment type. */
		assignment: Assignment;
		/** Whether the assigned slaves engage in sex with the public. */
		publicSexUse: boolean;
		/** Whether fuckdolls can work here. */
		fuckdollAccepted: boolean;
		/** Whether slaves assigned here can work at another assignment at the same time. */
		partTime?: boolean;
	}

	interface IManagerAssignment {
		/** The name of the assignment. */
		position: string;
		/** The assignment name's abbreviated form, if any. */
		positionAbbreviation?: string;
		/** The assignment type. */
		assignment: Assignment;
		/** A list of careers that count towards past experience. */
		careers: string[];
		/** Which of a slave's manager skills is affected. */
		skill: string;
		/** Whether the assigned slaves engage in sex with the public. */
		publicSexUse: boolean;
		/** Whether fuckdolls can work here. */
		fuckdollAccepted: boolean;
		/** Whether broodmothers can work here. */
		broodmotherAccepted: boolean;
		/** If slaves assigned here must be able to walk. */
		shouldWalk: boolean;
		/** If slaves assigned here must be able to hold items. */
		shouldHold: boolean;
		/** If slaves assigned here must be able to see. */
		shouldSee: boolean;
		/** If slaves assigned here must be able to hear. */
		shouldHear: boolean;
		/** If slaves assigned here must be able to talk. */
		shouldTalk: boolean;
		/** If slaves assigned here must have cognitive function. */
		shouldThink: boolean;
		/** The minimum required devotion level to be assigned here. */
		requiredDevotion: number;
	}

	interface FacilityFramework {
		/** The variable name of the facility. */
		baseName: string;
		/** The generic form of the facility. */
		genericName: string|null;
		/** An object listing all the available positions in the facility. */
		jobs: Record<string, IFacilityAssignment>;
		/** The default job in the facility. */
		defaultJob: string;
		/** Properties pertaining to the facility's manager. */
		manager: IManagerAssignment;
		/** Whether the facility can use FS decorations. */
		decorated: boolean;
	}

	namespace Facilities {
		export type Facility = InstanceType<typeof App.Facilities.Facility>;
		export type Animal = InstanceType<typeof App.Entity.Animal>;

		interface Decoration extends Record<FC.FutureSocietyDeco, string> {}

		interface Rule {
			/** The variable name of the rule. */
			property: string;
			/** Any prerequisites that must be met for the rule to be displayed. */
			prereqs: boolean[];
			/** Properties pertaining to any options available. */
			options: Array<{
				/** The text displayed when the rule is active. */
				text: string;
				/** The link text to set the rule to active. */
				link: string;
				/** The value to set `property` to when the rule is active. */
				value: any;
				/** Any handler to run upon setting the value. */
				handler?: (value: any) => void;
				/** Any additional information to display with on the link. */
				note?: string;
				/** Any prerequisites that must be met for the option to be displayed. */
				prereqs?: boolean[];
			}>;
			/** Any additional nodes to attach. */
			nodes?: Array<string|HTMLElement|DocumentFragment>;
			/** Any object the rule property is part of, if not the default `V`. */
			object?: Object;
		}

		interface Expand {
			/**
			 * The number of spots to add per expansion.
			 *
			 * Defaults to 5.
			 */
			amount?: number;
			/**
			 * How much expanding the facility costs.
			 *
			 * Defaults to 1000 times the number of slaves the facility can currently support.
			 */
			cost?: number;
			/**
			 * A short description of how many slaves are in the facility out of how many possible.
			 *
			 * Defaults to `"${facilityName} can support ${possible} slaves. It currently has ${current} slaves."`.
			 */
			desc?: string;
			/** The maximum number of times the facility can be expanded, if any. */
			maximum?: number;
			/** Any link to remove all slaves from the facility, if not the default. */
			removeAll?: HTMLDivElement;
			/**
			 * The assignment to assign the facility's manager to upon decommission.
			 *
			 * Defaults to `"rest"`.
			 */
			removeManager?: FC.Assignment;
			/**
			 * The assignment to assign the facility's employees to upon decommission.
			 *
			 * Defaults to `"rest"`.
			 */
			removeSlave?: FC.Assignment;
			/**
			 * Whether the facility cannot be expanded.
			 *
			 * Defaults to `false`.
			 */
			unexpandable?: boolean;
		}

		interface Pit {
			/** Defaults to "the Pit" if not otherwise set. */
			name: string;

			/** The animal fighting a slave if not null. */
			animal: string | "random";
			/** The type of audience the Pit has. */
			audience: "none" | "free" | "paid";
			/** Whether or not the bodyguard is fighting this week. */
			bodyguardFights: boolean;
			/** The type of decoration the Pit is using. */
			decoration: FC.FutureSocietyDeco;
			/**
			 * Who is fighting this week.
			 *
			 * | Value | Description                |
			 * |------:|:---------------------------|
			 * | 0     | Two random slaves          |
			 * | 1     | Random slave and bodyguard |
			 * | 2     | Random slave and animal    |
			 * | 3	   | True random				|
			 * | 4 	   | Two specific slaves		|
			 */
			fighters: number;
			/** 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 ID of the slave fighting one of your beasts for their life. */
			slaveFightingAnimal: number;
			/** The IDs of the two slaves chosen to fight this week. */
			slavesFighting: number[];
			/** The virginities of the loser not allowed to be taken. */
			virginities: "neither" | "vaginal" | "anal" | "all"
		}
	}
}


code:
declare namespace FC {
    interface Loan {
		/** The lender's name. */
		name: 'bank' | 'shark';
		/** The amount they've lent. */
		principal: number;
		/** The week on which repayment is due. */
		deadline: number;
		/** The number of installments remaining until the full amount is paid. */
		installments: number;
		/** The Annual Percentage Rate. */
		apr: number;
		/** The amount of interest the loan will accumulate. */
		interest: number;
		/** The full amount that will be paid. */
		full: number;
	}

	interface SlaveStatisticData {
		/** ID of relevant slave */
		ID: number,
		slaveName: string,
		customLabel: string,
		income: number,
		adsIncome: number,
		rep: number,
		food: number,
		cost: number,
		customers: number,

		milk?:number,
		cum?:number,
		fluid?:number,
	}
}


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;
	}

	interface Rival {
		/**
		- 0: Init
		- 1: Not established
		- 2: Established
		- 3: Captured
		- 4: Killed
		- 5: Enslaved
		 */
		state: number;
		duration: number;
		prosperity: number;
		power: number;
		race?: FC.Race;
		/**
		- 1: Female
		- 2: Male
		 */
		gender?: number;
		ID?: number;
		FS: {
			name: string;
			race?: FC.Race;
			adopted?: number;
		}
		/**
			- 0: Unknown / Gone
			- 1: Announced
			- 2: Rescued
			- 3: Given in. Currently unused, is checked but commented out within src/endWeek/saDevotion.js
			*/
		hostageState: number,
	}

	interface Peacekeepers {
		/**
		- 0: Gone
		- 1: Not established
		- 2: Established
		- 3: Independent
		 */
		state: number;
		generalName?: string;
		strength?: number;
		attitude?: number;
		undermining?: number;
		influenceAnnounced?: number;
		tastes?: string;
	}

	export type RecruiterTarget = "desperate whores" | "young migrants" | "recent divorcees" |
		"expectant mothers" | "dissolute sissies" | "reassignment candidates" | "other arcologies";

	interface DeprecatedGameVariables {
		/** @deprecated */
		surgeryType: string;

		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;
	}

	export interface ReminderEntry {
		message: string | Node;
		week: number;
		category: string;
		slaveID?: number;
	}

	export interface TrinketData {
		name: string,
		id?: number | null
		extra?: string,
		napkinShape?: string
	}

	/**
	 * 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;
		sortQuickList?: string;
		/** @deprecated */
		returnTo: string;

		slavesToImportMax?: number;

		activeArcologyIdx?: number;

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

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

		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;

		activeSlave: Zeroable<SlaveState>;
		readySlave: Zeroable<SlaveState>;
		newSlavePool: Array<FC.SlaveState>
		event?: InstanceType<typeof App.Events.BaseEvent>;
		AS: number;
		seed?: string;
		applyCareerBonus?: Bool;
		careerBonusNeeded?: number[];
		prostheticsConfig?: string;

		oldLimbs: any;

		heroSlaves: SlaveTemplate[];
		endweekFlag?: boolean;
	}

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


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

	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 AnimalState = InstanceType<typeof App.Entity.Animal>;

		export type DeepPartialSlaveState = DeepPartial<SlaveState>;

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

		export interface GingeredSlave extends SlaveState {
			// note that all members are optional...GingeredSlave and SlaveState are bidirectionally interchangeable
			gingering?: InstanceType<typeof App.Entity.GingeringParameters>;
			beforeGingering?: SlaveState;
		}

		export interface ReportSlave extends SlaveState {
			paraphiliaSatisfied: number;
			pornFameBonus: number;
			inappropriateLactation: number;
			fetishChanged: number;
			slaveUsedRest: 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" | "bestiality">;

		interface FetishFreeze extends Record<string, Fetish> {
			NONE: "none";
			MINDBROKEN: "mindbroken";
			SUBMISSIVE: "submissive";
			CUMSLUT: "cumslut";
			HUMILIATION: "humiliation";
			BUTTSLUT: "buttslut";
			BOOBS: "boobs";
			SADIST: "sadist";
			MASOCHIST: "masochist";
			DOM: "dom";
			PREGNANCY: "pregnancy";
			BESTIALITY: "bestiality";
		}

		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"
			/** addicted to fucking animals */
			| "animal lover">;

		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" | "spherical";
		type Clothes = "a ball gown" | "a bimbo outfit" | "a biyelgee costume" | "a bra" | "a bunny outfit" | "a burkini" |
			"a burqa" | "a button-up shirt" | "a button-up shirt and panties" | "a chattel habit" | "a cheerleader outfit" | "a comfortable bodysuit" |
			"a courtesan dress" | "a cybersuit" | "a dirndl" | "a fallen nuns habit" | "a Fuckdoll suit" | "a gothic lolita dress" | "a halter top dress" |
			"a hanbok" | "a hijab and abaya" | "a hijab and blouse" | "a huipil" | "a kimono" | "a klan robe" | "a latex catsuit" | "a leotard" |
			"a long qipao" | "a maternity dress" | "a military uniform" | "a mini dress" | "a monokini" | "a mounty outfit" | "a nice maid outfit" |
			"a nice nurse outfit" | "a nice pony outfit" | "a niqab and abaya" | "a one-piece swimsuit" | "a penitent nuns habit" | "a police uniform" |
			"a red army uniform" | "a Santa dress" | "a scalemail bikini" | "a schoolgirl outfit" | "a schutzstaffel uniform" | "a skimpy loincloth" |
			"a slave gown" | "a slutty klan robe" | "a slutty maid outfit" | "a slutty nurse outfit" | "a slutty outfit" | "a slutty pony outfit" |
			"a slutty qipao" | "a slutty schutzstaffel uniform" | "a sports bra" | "a string bikini" | "a striped bra" | "a succubus outfit" |
			"a sweater" | "a sweater and cutoffs" | "a sweater and panties" | "a t-shirt" | "a t-shirt and jeans" | "a t-shirt and panties" |
			"a t-shirt and thong" | "a tank-top" | "a tank-top and panties" | "a thong" | "a toga" | "a tube top" | "a tube top and thong" |
			"an apron" | "an oversized t-shirt" | "an oversized t-shirt and boyshorts" | "attractive lingerie" | "attractive lingerie for a pregnant woman" |
			"battlearmor" | "Imperial Plate" | "a tight Imperial bodysuit" | "battledress" | "body oil" | "boyshorts" | "chains" | "choosing her own clothes" |
			"clubslut netting" | "conservative clothing" | "cutoffs" | "cutoffs and a t-shirt" | "harem gauze" | "jeans" | "kitty lingerie" |
			"leather pants" | "leather pants and a tube top" | "leather pants and pasties" | "lederhosen" | "nice business attire" | "no clothing" |
			"overalls" | "panties" | "panties and pasties" | "pasties" | "restrictive latex" | "shibari ropes" | "slutty business attire" |
			"slutty jewelry" | "spats and a tank top" | "sport shorts" | "sport shorts and a sports bra" | "sport shorts and a t-shirt" |
			"stretch pants and a crop-top" | "striped panties" | "striped underwear" | "uncomfortable straps" |	"Western clothing";
		type BellyAccessory = WithNone<"a small empathy belly" | "a medium empathy belly" | "a large empathy belly" | "a huge empathy belly" |
			"a corset" | "an extreme corset" | "a support band">;
		type Collar = WithNone<"ancient Egyptian" | "cruel retirement counter" | "uncomfortable leather" | "tight steel" | "shock punishment" |
			"heavy gold" | "pretty jewelry" | "nice retirement counter" | "bell collar" | "leather with cowbell" | "bowtie" | "neck tie" |
			"neck corset" | "stylish leather" | "satin choker" | "preg biometrics" | "silk ribbon">;
		type HairStyle = "afro"| "braided" | "cornrows" | "curled" | "dreadlocks" | "eary" | "bun" | "messy bun" | "ponytail" | "tails" |
			"drills" | "luxurious" | "messy" | "neat" | "permed" | "bangs" | "hime" | "strip" | "up" | "shaved" | "trimmed" | "buzzcut" | "bald" | "undercut" |
			"double buns" | "chignon" | "french twist" | "crown braid" | "dutch braid" | "double dutch braid" | "pixie cut" | "bob cut";
		type Shoes = "heels" | "pumps" | "extreme heels" | "boots" | "flats" | "platform heels" | "extreme heels" | "extreme platform heels" | "platform shoes";
		type MouthAccessory = "dildo gag" | "massive dildo gag" | "ball gag" | "bit gag" | "ring gag";
		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" | "cow" | "robot" | "orcish" | "sheep" | "deer" | "gazelle" | "bird" | "dragon">;
		type EarTopType = WithNone<"normal" | "cat" | "leopard" | "tiger" | "jaguar" | "lion" | "dog" | "wolf" | "jackal" | "fox" | "raccoon" | "rabbit" | "squirrel"| "horse">;
		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"| "stinger">;
		type AppendagesType = WithNone<"mod" | "flight" | "sex" | "falcon" | "arachnid" | "kraken">;
		type Markings = WithNone<"beauty mark" | "birthmark" | "freckles" | "heavily freckled">;
		type TailShape = WithNone<"cat" | "leopard" | "tiger" | "jaguar" | "lion" | "dog" | "wolf" | "jackal" | "fox" | "kitsune" | "tanuki" | "raccoon" | "rabbit" | "squirrel" | "horse" | "bird" | "phoenix" | "peacock" | "raven" | "swan" | "sheep" | "cow" | "gazelle" | "deer" | "succubus" | "dragon" >;
		type WingsShape = WithNone<"angel" | "seraph" | "demon"| "dragon" | "phoenix" | "bird"| "fairy" | "butterfly" | "moth" | "insect" | "evil" >;
		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" | "flat";
		type LactationType = 0 | 1 | 2;
		type VaginaLubeType = 0 | 1 | 2;
		type WombImplantType = WithNone<"restraint">;
		type LabiaType = 0 | 1 | 2 | 3;
		type ClitType = 0 | 1 | 2 | 3 | 4 | 5;
		type AnusType = 0 | 1 | 2 | 3 | 4;
		type ProstateType = 0 | 1 | 2 | 3;
		type dietCumType = 0 | 1 | 2;
		type dietMilkType = 0 | 1 | 2;
		/**
		 * 0: no; 1: yes; 2: heavy
		 */
		type PiercingType = 0 | 1 | 2;
		type Piercing = "ear" | "nose" | "eyebrow" | "lips" | "tongue" | "nipple" | "areola" | "navel" | "corset" | "genitals" | "vagina" | "dick" | "anus";
		type Race = "amerindian" | "asian" | "black" | "indo-aryan" | "latina" | "malay" | "middle eastern" | "mixed race" |
			"pacific islander" | "catgirl" | "semitic" | "southern european" | "white";

		type SizingImplantType = "normal" | "string" | "fillable" | "advanced fillable" | "hyper fillable";
		type LipsImplantType = "normal";
		type InstalledSizingImplantType = WithNone<SizingImplantType>;
		type InstalledLipsImplantType = WithNone<LipsImplantType>;
		type SizableBodyPart = "lips" | "boobs" | "butt" | "dick" | "balls";
		type SizingImplantTarget = "boobs" | "butt" | "lips";

		interface BodyPartImplantTypeMap {
			lips: LipsImplantType;
			boobs: SizingImplantType;
			butt: SizingImplantType;
		}

		type BodyPartInstalledImplantType<Target extends SizingImplantTarget> = WithNone<BodyPartImplantTypeMap[Target]>;

		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 AnimalType = "human" | "dog" | "pig" | "horse" | "cow";
		type SpermType = AnimalType | "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;
			/** abnormal production of amniotic fluid
			 * only affects fetuses */
			polyhydramnios: GeneticQuirk;
			/** inappropriate lactation*/
			galactorrhea: GeneticQuirk | 3;
			/** retains childlike characteristics*/
			neoteny: GeneticQuirk | 3;
			/** rapid aging
			 *
			 * **neoteny + progeria** - progeria wins, not that she'll make it to the point that neoteny really kicks in */
			progeria: GeneticQuirk | 3,
		}
		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 LimbType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10

		type ArmState = InstanceType<typeof App.Entity.ArmState>;
		type LegState = InstanceType<typeof App.Entity.LegState>;

		interface LimbsState {
			arm: {
				left: ArmState;
				right: ArmState;
			};
			leg: {
				left: LegState,
				right: LegState;
			};
			PLimb: 0 | 1 | 2 | 3;
		}

		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;

		type ImageFormat = "png"|"jpg"|"gif"|"webp"|"webm"|"mp4";
		export interface CustomImage {
			filename?: string;
			format?: ImageFormat;
		}
	}
}

export {}


code:
declare namespace FC {
	namespace UseSlave {
		interface Option {
			/** The link text. */
			link: string;
			/** The text that appears when the option is selected. */
			desc: string;
			/** The link tooltip. */
			tooltip: string;
			/** Any prerequisites required for the option to appear. */
			prereq: () => boolean;
			/** Any effects the option has. */
			effect: () => void;
			/** The partner's reaction to the action. */
			reaction: string;
		}
	}
}


code:
declare namespace FC {
	type prostheticID = "interfaceP1" | "interfaceP2" | "interfaceP3" | "basicL" | "sexL" | "beautyL" | "combatL" | "felidaeL" | "canidaeL" | "felidaeCL" | "canidaeCL" | "cyberneticL"
		| "ocular" | "cochlear" | "electrolarynx" | "interfaceTail" | "modT" | "sexT" | "combatT" | "combatT2" |/* "erectile" |*/ "interfaceBack" | "modW" | "flightW"
		| "sexA" | "combatW" | "combatA1" | "combatA2";

	type prostheticName = "basic prosthetic interface" | "advanced prosthetic interface" | "quadrupedal prosthetic interface" | "set of basic prosthetic limbs" | "set of advanced sex limbs"
		| "set of advanced beauty limbs" | "set of advanced combat limbs" | "set of quadruped feline limbs" | "set of quadruped canine limbs" | "set of feline combat limbs"
		| "set of canine combat limbs" | "set of cybernetic limbs" | "ocular implant" | "cochlear implant" | "electrolarynx" | "prosthetic tail interface" | "modular tail"
		| "pleasure tail" | "combat tail" | `combat tail, type "Stinger"` | "prosthetic back interface" | "modular pair of wings" | "pair of flight capable wings"
		| "set of pleasure appendages" | `"set of combat appendages, type "Falcon"` | `set of combat appendages, type "Arachnid"` | `set of combat appendages, type "Kraken"`;

	type LimbArgument = "left arm" | "right arm" | "left leg" | "right leg"
	type LimbArgumentAll = "all" | LimbArgument

	type BodySide = "left" | "right"
	type BodySideAll = "both" | BodySide

	interface AdjustProsthetics {
		id: prostheticID;
		workLeft: number;
		slaveID: number;
	}

	type TaskType = "research" | "craft" | "craftFit";

	interface Tasks {
		type: TaskType;
		id: prostheticID;
		workLeft: number;
		craftFit?: number;
	}

	interface ResearchLab {
		level: number;
		aiModule: number;
		tasks: Tasks;
		maxSpace: number;
		hired: number;
		menials: number;
	}

	namespace Data.Medicine.SizingImplants {
		type DynamicName = (volume: number) => string;
		type DynamicCostFactor = (volume: number) => number;

		interface FillDrainData {
			limit: number;
			step: number[];
			healthCost: number;
			materialCostFactor: number;
		}
		interface ImplantType {
			name: string | DynamicName;
			specificMaterialCost: number | DynamicCostFactor;
			workCostFactor: {
				installation: number;
				removal: number;
			}
			healthCostFactor: {
				installation: number;
				removal: number;
			},
			availableSizes: number[] | (() => number[]);
			/** If defined the implant is fillable and can be filled up to the given size */
			fill?: FillDrainData;
			/** If defined the implant is drainable and can be drained down to the given size */
			drain?: FillDrainData;
		}

		type SizingImplantDatabase = {
			[K in SizingImplantTarget]: Record<BodyPartImplantTypeMap[K], FC.Data.Medicine.SizingImplants.ImplantType>;
		}
	}

	namespace Medicine {

		type ProcedureInstance = InstanceType<typeof App.Medicine.Surgery.Procedure>;
		type SizingImplantProcedure = InstanceType<typeof App.Medicine.Surgery.Procedures.SizingImplantProcedure>;

		type SizingImplantProcedureConstructor<T extends SizingImplantProcedure = SizingImplantProcedure> = new (...args: any[]) => T;

		interface ImplantProcedureCreators {
			install: (slave: FC.SlaveState, implantType: SizingImplantType, volume: number, fleshExcess: number) => ProcedureInstance;
			remove: (slave: FC.SlaveState) => ProcedureInstance;
			replace: (slave: FC.SlaveState, implantType: SizingImplantType, volume: number, fleshExcess: number) => ProcedureInstance;

			fill: (slave: FC.SlaveState, amount: number) => ProcedureInstance;
			drain: (slave: FC.SlaveState, amount: number) => ProcedureInstance;
		}

		type ImplantInfo<Target extends SizingImplantTarget> = {
			type: BodyPartInstalledImplantType<Target>;
			volume: number;
		}

		interface AssetSizingProcedureSet extends ImplantProcedureCreators {
			reduce: (slave: SlaveState, name: string, amount: number) => ProcedureInstance;
		}

		namespace Surgery {
			/**
			 * Describes surgical procedure
			 */
			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;
			}

			type SizingOptions<Target extends SizingImplantTarget> = {
				targetSize?: NumericRange;
				/**
				 * Allowed procedures for given implant type
				 */
				allowedTypes?: Set<BodyPartInstalledImplantType<Target>>;
				/** include options with implant change */
				replace?: boolean;
			}

			type DefinitiveSizedOptions<Target extends SizingImplantTarget> = Required<SizingOptions<Target>>;
		}
		namespace OrganFarm {
			interface GrowingOrgan {
				type: string;
				weeksToCompletion: number;
				ID: number;
			}
			namespace Organs {
			}
		}
	}
}


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" | "juvenile detention" |
		"neighbor" | "wetware" | "white collar" | SlaveSchoolName;
	type OrdinaryMarkets = "kidnappers" | "trainers" | "hunters" | "raiders" | "underage raiders" | "corporate";
	type SlaveMarketName = LawlessMarkets | OrdinaryMarkets;
	type SpecialMarketName = "Elite Slave" | "Household Liquidator" | "Custom Slave" | "Husk Slave" | "Slave Shelter" | "JobFulfillmentCenterOrder" | "Prestigious Slave" | "Special Slave";
	type Gingering = Zeroable<"antidepressant" | "depressant" | "stimulant" | "vasoconstrictor" | "vasodilator" | "aphrodisiac" | "ginger">;
	type GingeringDetection = Zeroable<"slaver" | "mercenary" | "force">;
	type SlaveActs = "PCChildrenFathered" | "PCKnockedUp" | "anal" | "births" | "birthsTotal" | "cum" | "laborCount" | "mammary" | "milk" | "oral" | "penetrative" | "pitKills" | "miscarriages" | "publicUse" | "slavesFathered" | "slavesKnockedUp" | "vaginal" | "abortions" | "birth" | "bestiality";

	interface SlaveSchool {
		title: string,
		nickname: string,
		branchName: string,
		slaveNoun: string,
		readonly requirements: boolean,
	}

	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 Mods {
		/** The base mod interface, from which all mod interfaces inherit. */
		interface Base {
			/** Whether the mod is enabled. */
			enabled: boolean;
		}

		/** Properties relating to the food system mod. */
		interface Food extends Base {
			/** How much food the arcology has, in kg. */
			amount: number;
			/** The base price of 1kg of food. */
			cost: number;
			/** How much food the arcology had at the end of last week, in kg. */
			lastWeek: number;
			/** Whether the food market has been established. */
			market: boolean;
			/** The amount of food produced this week, in kg. */
			produced: number;
			/** The amount of food each class consumes in a week. */
			rate: {
				/** The amount of food a slave consumes in a week, in kg. */
				slave: 8,
				/** The amount of food the lower class consumes in a week, in kg. */
				lower: 14.5,
				/** The amount of food the middle class consumes in a week, in kg. */
				middle: 16,
				/** The amount of food the upper class consumes in a week, in kg. */
				upper: 17.5,
				/** The amount of food the elite class consumes in a week, in kg. */
				top: 19,
			},
			/**
			 * How much food you are providing your citizens weekly.
			 *
			 * Not in kg.
			 */
			rations: 0 | 1 | 2 | 3 | 4 | 5;
			/** How much food the arcology has produced in total, in kg. */
			total: number;
			/** Whether the player has received a warning about a lack of food. */
			warned: boolean;
		}
	}
}


code:
declare namespace FC {
    namespace Util {
        interface DiffBase<T> {
            /**
             * The original object
             */
            diffOriginal: T
            /**
             * The changes applied to the object
             */
            diffChange: Partial<T>
        }

        type DiffRecorder<T> = T & DiffBase<T>
	}

	interface NumericRange {
		min: number;
		max: number;
	}
}


code:
declare namespace App.UI.DOM {
	function makeElementTS<K extends keyof HTMLElementTagNameMap>(
		tag: K, content?: string | Node, classNames?: string[]): HTMLElementTagNameMap[K];
	/** @deprecated */
	function makeElementTS<K extends keyof HTMLElementTagNameMap>(
		tag: K, content?: string | Node, classNames?: string): HTMLElementTagNameMap[K];

	function appendNewElementTS<K extends keyof HTMLElementTagNameMap>(
		tag: K, parent: ParentNode, content?: string | Node, classNames?: string[]): HTMLElementTagNameMap[K];
	/** @deprecated */
	function appendNewElementTS<K extends keyof HTMLElementTagNameMap>(
		tag: K, parent: ParentNode, content?: string | Node, className?: string): HTMLElementTagNameMap[K];
}


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

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

	interface SugarCubeSetupObject {
		// Any usages of the global setup object should be replaced by App.Data.misc
	}

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

	interface UIBarAPI {
		update(): void;
	}
}

export {};


code:
type assistantAppearance = "normal" | "monstergirl" | "shemale" | "amazon" | "businesswoman" | "goddess" | "hypergoddess" | "schoolgirl" | "loli" | "preggololi" | "fairy" | "pregnant fairy" | "slimegirl" | "cowgirl"| "harpygirl" | "kitsunegirl" | "lamiagirl" | "spidergirl" | "angel" | "cherub" | "imp" | "witch" | "ERROR_1606_APPEARANCE_FILE_CORRUPT" | "incubus" | "succubus";

type fsAssistantAppearance = "default" | "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" | "neoimperialist";
interface assistant {
	appearance: assistantAppearance;
	fsAppearance: fsAssistantAppearance
	personality: -1 | 0 | 1;
	name: string;
	power: number;
	fsOptions: FC.Bool;
	options: FC.Bool;
	market: {
		relationship: "nonconsensual" | "incestuous" | "cute" | "romantic";
		limit: number;
		aggressiveness: number;
	};
	main: number;
	Extra1: FC.Bool;
	Extra2: FC.Bool;
	announcedName: FC.Bool;
	customImage: FC.CustomImage;
}

type appearance = Record<assistantAppearance, fsAppearance>;

type fsAppearance = Record<fsAssistantAppearance, string>;


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

interface Number {
	/**
	 * Returns whether the value is between the given bounds, with optional inclusivity. Exclusive by default.
	 * @param min The minimum value to check against.
	 * @param max The maximum value to check against.
	 * @param inclusive Whether to include the bounds values.
	 */
	 isBetween(min: number, max: number, inclusive?: boolean): boolean;
}

type EnumerablePropertyKey<T extends PropertyKey> = T extends symbol ? never : (T extends number ? string : T);

interface ObjectConstructor {
	keys<K extends PropertyKey, V>(o: Partial<Record<K, V>>): EnumerablePropertyKey<K>[];
	entries<K extends PropertyKey, V>(o: Partial<Record<K, V>>): [EnumerablePropertyKey<K>, V][];
}

// 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:
import {Tippy} from "./tippy";

declare global {
    const tippy: Tippy;
}


code:
import * as Popper from '@popperjs/core';

export type BasePlacement = Popper.BasePlacement;

export type Placement = Popper.Placement;

export type Content =
  | string
  | Element
  | DocumentFragment
  | ((ref: Element) => string | Element | DocumentFragment);

export type SingleTarget = Element;

export type MultipleTargets = string | Element[] | NodeList;

export type Targets = SingleTarget | MultipleTargets;

export interface ReferenceElement<TProps = Props> extends Element {
  _tippy?: Instance<TProps>;
}

export interface PopperElement<TProps = Props> extends HTMLDivElement {
  _tippy?: Instance<TProps>;
}

export interface LifecycleHooks<TProps = Props> {
  onAfterUpdate(
    instance: Instance<TProps>,
    partialProps: Partial<TProps>
  ): void;
  onBeforeUpdate(
    instance: Instance<TProps>,
    partialProps: Partial<TProps>
  ): void;
  onCreate(instance: Instance<TProps>): void;
  onDestroy(instance: Instance<TProps>): void;
  onHidden(instance: Instance<TProps>): void;
  onHide(instance: Instance<TProps>): void | false;
  onMount(instance: Instance<TProps>): void;
  onShow(instance: Instance<TProps>): void | false;
  onShown(instance: Instance<TProps>): void;
  onTrigger(instance: Instance<TProps>, event: Event): void;
  onUntrigger(instance: Instance<TProps>, event: Event): void;
  onClickOutside(instance: Instance<TProps>, event: Event): void;
}

export interface RenderProps {
  allowHTML: boolean;
  animation: string | boolean;
  arrow: boolean | string | SVGElement | DocumentFragment;
  content: Content;
  inertia: boolean;
  maxWidth: number | string;
  role: string;
  theme: string;
  zIndex: number;
}

export interface GetReferenceClientRect {
  (): ClientRect | DOMRect;
  contextElement?: Element;
}

export interface Props extends LifecycleHooks, RenderProps {
  animateFill: boolean;
  appendTo: 'parent' | Element | ((ref: Element) => Element);
  aria: {
    content?: 'auto' | 'describedby' | 'labelledby' | null;
    expanded?: 'auto' | boolean;
  };
  delay: number | [number | null, number | null];
  duration: number | [number | null, number | null];
  followCursor: boolean | 'horizontal' | 'vertical' | 'initial';
  getReferenceClientRect: null | GetReferenceClientRect;
  hideOnClick: boolean | 'toggle';
  ignoreAttributes: boolean;
  inlinePositioning: boolean;
  interactive: boolean;
  interactiveBorder: number;
  interactiveDebounce: number;
  moveTransition: string;
  offset:
    | [number, number]
    | (({
        placement,
        popper,
        reference,
      }: {
        placement: Placement;
        popper: Popper.Rect;
        reference: Popper.Rect;
      }) => [number, number]);
  placement: Placement;
  plugins: Plugin<unknown>[];
  popperOptions: Partial<Popper.Options>;
  render:
    | ((
        instance: Instance
      ) => {
        popper: PopperElement;
        onUpdate?: (prevProps: Props, nextProps: Props) => void;
      })
    | null;
  showOnCreate: boolean;
  sticky: boolean | 'reference' | 'popper';
  touch: boolean | 'hold' | ['hold', number];
  trigger: string;
  triggerTarget: Element | Element[] | null;
}

export interface DefaultProps extends Omit<Props, 'delay' | 'duration'> {
  delay: number | [number, number];
  duration: number | [number, number];
}

export interface Instance<TProps = Props> {
  clearDelayTimeouts(): void;
  destroy(): void;
  disable(): void;
  enable(): void;
  hide(): void;
  hideWithInteractivity(event: MouseEvent): void;
  id: number;
  plugins: Plugin<TProps>[];
  popper: PopperElement<TProps>;
  popperInstance: Popper.Instance | null;
  props: TProps;
  reference: ReferenceElement<TProps>;
  setContent(content: Content): void;
  setProps(partialProps: Partial<TProps>): void;
  show(): void;
  state: {
    isEnabled: boolean;
    isVisible: boolean;
    isDestroyed: boolean;
    isMounted: boolean;
    isShown: boolean;
  };
  unmount(): void;
}

export interface TippyStatics {
  readonly currentInput: {isTouch: boolean};
  readonly defaultProps: DefaultProps;
  setDefaultProps(partialProps: Partial<DefaultProps>): void;
}

export interface Tippy<TProps = Props> extends TippyStatics {
  (targets: SingleTarget, optionalProps?: Partial<TProps>): Instance<TProps>;
}

export interface Tippy<TProps = Props> extends TippyStatics {
  (targets: MultipleTargets, optionalProps?: Partial<TProps>): Instance<
    TProps
  >[];
}

declare const tippy: Tippy;

// =============================================================================
// Addon types
// =============================================================================
export interface DelegateInstance<TProps = Props> extends Instance<TProps> {
  destroy(shouldDestroyTargetInstances?: boolean): void;
}

export interface Delegate<TProps = Props> {
  (
    targets: SingleTarget,
    props: Partial<TProps> & {target: string}
  ): DelegateInstance<TProps>;
}

export interface Delegate<TProps = Props> {
  (
    targets: MultipleTargets,
    props: Partial<TProps> & {target: string}
  ): DelegateInstance<TProps>[];
}

export type CreateSingletonProps<TProps = Props> = TProps & {
  overrides: Array<keyof TProps>;
};

export type CreateSingletonInstance<TProps = CreateSingletonProps> = Instance<
  TProps
> & {
  setInstances(instances: Instance<any>[]): void;
  show(target?: ReferenceElement | Instance | number): void;
  showNext(): void;
  showPrevious(): void;
};

export type CreateSingleton<TProps = Props> = (
  tippyInstances: Instance<any>[],
  optionalProps?: Partial<CreateSingletonProps<TProps>>
) => CreateSingletonInstance<CreateSingletonProps<TProps>>;

declare const delegate: Delegate;
declare const createSingleton: CreateSingleton;

// =============================================================================
// Plugin types
// =============================================================================
export interface Plugin<TProps = Props> {
  name?: string;
  defaultValue?: any;
  fn(instance: Instance<TProps>): Partial<LifecycleHooks<TProps>>;
}

export interface AnimateFill extends Plugin {
  name: 'animateFill';
  defaultValue: false;
}

export interface FollowCursor extends Plugin {
  name: 'followCursor';
  defaultValue: false;
}

export interface InlinePositioning extends Plugin {
  name: 'inlinePositioning';
  defaultValue: false;
}

export interface Sticky extends Plugin {
  name: 'sticky';
  defaultValue: false;
}

declare const animateFill: AnimateFill;
declare const followCursor: FollowCursor;
declare const inlinePositioning: InlinePositioning;
declare const sticky: Sticky;

// =============================================================================
// Misc types
// =============================================================================
export interface HideAllOptions {
  duration?: number;
  exclude?: Instance | ReferenceElement;
}

export type HideAll = (options?: HideAllOptions) => void;

declare const hideAll: HideAll;
declare const roundArrow: string;

export default tippy;
export {
  hideAll,
  delegate,
  createSingleton,
  animateFill,
  followCursor,
  inlinePositioning,
  sticky,
  roundArrow,
};


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/fc-docker/Dockerfile


code:
# Create docker and upload to gitgud.io
# docker build -t gitgud.io:5050/user/project .
# docker login gitgud.io
# docker push gitgud.io:5050/user/project
#
# Debug build process
# docker build --no-cache --progress=plain -t megacmd .

# Create debian as base image
FROM debian

# Update
RUN apt-get -y update
RUN apt-get -y upgrade

# Install zip
RUN apt-get -y install zip

# mega cmd
# Install dependencies, when changing mega versions these may need to be adjusted
RUN apt-get -y install libc-ares2 libcrypto++6 libmediainfo0v5 libpcrecpp0v5 libzen0v5
# Install mega cmd
RUN apt-get -y install wget
RUN wget https://mega.nz/linux/MEGAsync/Debian_10.0/amd64/megacmd_1.4.0-3.1_amd64.deb
RUN dpkg -i megacmd_1.4.0-3.1_amd64.deb

path: docker/megacmd/Dockerfile


code:
/* eslint-disable one-var */
const autoprefixer = require('autoprefixer'),
	chalk = require('chalk'),
	concat = require('gulp-concat'),
	gulp = require('gulp'),
	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'),
	stripCssJSComments = require('gulp-strip-comments'),
	childProcess  = require('child_process'),
	which = require('which'),
	fs = require('fs'),
	path = require('path'),
	os = require('os'),
	yargs = require('yargs'),
	cfg = require('./build.config.json');

// defines build options which can be supplied from the command line
// example: npx gulp --minify --verbosity 6
const args = yargs.options({
	verbosity: {type: 'number', default: 1},
	release: {type: 'boolean', default: false},
	minify: {type: 'boolean', default: false},
	embedsourcemaps: {type: 'boolean', default: false},
	sourcemapsincludecontent: {type: 'boolean', default: false}
}).argv;

/** Filename for the temporary output. Tweego will write here and then it will be moved into the output dir */
const htmlOut = "tmp.html";

// set log verbosity basing on the command line argument
log(args.verbosity);

// -------------- Helper functions -----------------------

/**
 * @summary Locates tweego executable.
 *
 *  Looks in the host $PATH, otherwise uses one of the bundled in devTools/tweeGo
 */
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;
}

/**
 * @summary Selects minify executable
 *
 * Similar to tweeCompilerExecutable(), but returns path to the minify executable. However, since
 * there are executables only for amd64, it will report error and throw (which will in turn stop
 * the build) on other architectures.
 */
function minifierExecutable() {
	if (os.arch() !== 'x64') {
		log.error(chalk.red("Minification only available on amd64 systems."));
		throw "Build interrupted";
	}
	const archSuffix = 'amd64';
	const platformSuffix = {
		'Darwin': 'darwin',
		'Linux': 'linux',
		'Windows_NT': 'win'
	}[os.type()];
	const extension = os.type() === 'Windows_NT' ? '.exe' : '';
	const res = path.join('.', 'devTools', 'minify', `minify_${platformSuffix}_${archSuffix}${extension}`);
	log.info('Using minifier at ', res);
	return res;
}

/**
 * @summary Composes tweego invocation command
 *
 * Combines paths to tweego and options defined in the build.config.json file to
 * return a full tweego launch command, which will combine all story elements, pick up modules,
 * and generate an HTML file in the intermidiate directory
 */
function tweeCompileCommand() {
	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}`);
	return `${tweeCompilerExecutable()} --head=${cfg.sources.head} -o ${path.join(cfg.dirs.intermediate, htmlOut)} ${moduleArgs.join(' ')} ${sources.join(' ')}`;
}

/**
 * gulp-sort uses String.localeCompare() by default, which may be case-insensitive,
 * while we require case -sensitive sorting for sources
 */
function pathcmp(a, b) {
	return (a.path < b.path ? -1 : (a.path > b.path ? 1 : 0));
}

/**
 * Creates a pipeline that sorts and combines files
 */
function concatFiles(srcGlob, destDir, destFileName) {
	return gulp.src(srcGlob)
		.pipe(sort(pathcmp))
		.pipe(concat(destFileName))
		.pipe(gulp.dest(destDir));
}

/**
 * Creates a pipeline for processing JS scripts
 *
 * The pipeline collects sources, sorts them, concatenates and
 * saves in the destination dir. If no "release" command line switch was
 * supplied, sourcemaps will be written for the files
 */
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(pathcmp))
		.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));
}

/**
 * Creates a pipeline for processing CSS stylesheets
 *
 * The pipeline collects sources, sorts them, concatenates, pass through
 * an autoprefixer and saves in the destination dir. If no "release" command
 * line switch was supplied, sourcemaps will be written for the files
 */
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(pathcmp))
		.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));
}

/**
 * Creates tasks for processing sources with provided function
 *
 * This function is a workaround. Gulp can handle multiple globs at time, but
 * for writing sourcemaps we have to process them one by one, because we detect
 * where to write source maps from each glob pattern in order to make them accessible
 * from the compiled HTML
 */
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;
}

/** Returns true if the working directory is a Git repository */
function isGitCheckout() {
	return fs.statSync('.git').isDirectory();
}

/** Invokes git and writes hash of the head commit to the file, specified in the 'gitVersionFile' build config property */
function injectGitCommit(cb) {
	childProcess.exec('git rev-parse --short HEAD', function(error, stdout) {
		if (!error) {
			log.info('current git hash: ', stdout);
			fs.writeFile(cfg.gitVersionFile, `App.Version.commitHash = '${stdout.trimEnd()}';\n`, cb);
		} else {
			log.error(chalk.red(`Error running git. Error: ${error}`));
			cb();
		}
	});
}

/** Ensures the file with the git commit hash does not exists */
function cleanupGit(cb) {
	if (fs.existsSync(cfg.gitVersionFile)) {
		fs.unlink(cfg.gitVersionFile, cb);
	} else {
		cb();
	}
}

// --------------- build tasks definitions -----------------
/*
The main build process, which produces the assembled HTML file, consists of several stages.
The game sources, which are .twee, .js, and .css files, belong to one of the two categories:
they are either part of the story in Tweego terms, or modules. These categories are called
"components" below. For each component files of the same type are processed in the same way
and results for each component/file type pair are concatenated file in the intermediate builds
directory and a source map for that file.
When all intermediate files are ready, tweego picks them up and assembles the HTML file.
*/

// Create task to execute tweego
gulp.task('compileStory', shell.task(tweeCompileCommand(), {env: {...process.env, ...cfg.options.twee.environment}, verbose: args.verbosity >= 3}));

/**
 * Creates tasks for preparing intermidiate files for a component
 * @param {*} name "story" or "module"
 */
function prepareComponent(name) {
	const processors = {
		"css": {
			func: processStylesheets,
			output: "-styles.css"
		},
		"js": {
			func: processScripts,
			output: "-script.js"
		},
		"twee": {
			func: concatFiles,
			output: "-story.twee"
		},
		"media": {
			func: null
		}
	};

	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, `${name}${proc.output}`, cfg.options[srcType]));
		}
	}
	let r = gulp.parallel(subTasks);
	r.displayName = "prepare-" + name;
	return r;
}

/**
 *  Creates a task for compiling a theme
 * @param {string} themeName theme directory name
 */
function makeThemeCompilationTask(themeName) {
	const taskName = `make-theme-${themeName}`;
	gulp.task(taskName, function() {
		return concatFiles(`themes/${themeName}/**/*.css`, cfg.dirs.output, `${themeName}.css`);
	});
	return taskName;
}

/** Moves compiled HTML file from the intermidiate location to the final output */
function moveHTMLInPlace(cb) {
	fs.rename(path.join(cfg.dirs.intermediate, htmlOut), path.join(cfg.dirs.output, cfg.output), cb);
}

// If we were asked to minify the file, instead of moving invoke the minify utility with output in the final dir
if (args.minify) { // do not touch minifierExecutable(), which throws on errors, unconditionally
	gulp.task('moveAndMinifyHTML', shell.task(
		`${minifierExecutable()} --html-keep-comments --js-keep-var-names -o "${path.join(cfg.dirs.output, cfg.output)}" "${path.join(cfg.dirs.intermediate, htmlOut)}"`, {verbose: args.verbosity >= 3}));
}

/** Removes intermediate compilation files if any */
function removeIntermediateFiles(cb) {
	if (fs.existsSync(cfg.dirs.intermediate)) {
		fs.rm(cfg.dirs.intermediate, {recursive: true}, cb);
	} else {
		cb();
	}
}

// Creates task to assemble components in the intermediate dir where they are ready for tweego
gulp.task('prepare', gulp.parallel(prepareComponent("module"), prepareComponent("story")));

// Create the main build and clean tasks, which include writing Git commit hash if we are working in a Git repo
if (isGitCheckout()) {
	exports.clean = gulp.parallel(cleanupGit, removeIntermediateFiles);
	gulp.task('buildHTML', gulp.series(exports.clean, 'prepare', injectGitCommit, 'compileStory', cleanupGit));
} else {
	exports.clean = gulp.parallel(removeIntermediateFiles);
	gulp.task('buildHTML', gulp.series(exports.clean, 'prepare', 'compileStory'));
}

// Creates theme build task for each subdirectory in the 'themes' dir
const themeTasks = fs.readdirSync('themes')
	.filter(entry => fs.statSync(path.join('themes', entry)).isDirectory())
	.map(entry => makeThemeCompilationTask(entry));

// Create user-invocable targets for building HTML and themes
exports.html = gulp.series('buildHTML', args.minify ? 'moveAndMinifyHTML' : moveHTMLInPlace);
exports.themes = gulp.parallel(themeTasks);

// Set the default target which is invoked when no target is explicitly provided by user
exports.default = exports.html;
// Convenient shortcut to build everything (HTML and themes)
exports.all = gulp.parallel(exports.html, exports.themes);

// legacy tasks

gulp.task('twineCSS', function() {
	return concatFiles([...cfg.sources.module.css, ...cfg.sources.story.css], 'devNotes', 'twine CSS.txt');
});

gulp.task('twineJS', function() {
	return gulp.src([...cfg.sources.module.js, ...cfg.sources.story.js, '!src/art/assistantArt.js'])
		.pipe(stripCssJSComments({trim: true}))
		.pipe(sort(pathcmp))
		.pipe(concat('twine JS.txt'))
		.pipe(gulp.dest('devNotes'));
});

exports.twine = gulp.parallel('twineCSS', 'twineJS');


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.Budget = {};
App.Corporate = {};
App.Corporate.Division = {};
App.Corporate.Shared = {};
App.Data = {};
App.Data.Arcology = {};
App.Data.FCTV = {};
App.Data.HeroSlaves = {};
App.Data.Medicine = {};
App.Data.Policies = {};
App.Data.Policies.Selection = {};
App.Data.SecExp = {};
App.Data.Slave = {};
App.Data.Weather = {};
App.Debug = {};
App.Desc = {};
App.Desc.Player = {};
App.Encyclopedia = {};
App.EndWeek = {};
App.EndWeek.Player = {};
App.EndWeek.Shared = {};
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.Facilities.TransportHub = {};
App.Interact = {};
App.Interact.Sale = {};
App.Intro = {};
App.MainView = {};
App.Markets = {};
App.Medicine = {};
App.Medicine.Modification = {};
App.Medicine.Modification.Brands = {};
App.Medicine.Modification.Select = {};
App.Medicine.OrganFarm = {};
App.Medicine.Salon = {};
App.Medicine.Surgery = {};
App.Medicine.Surgery.Procedures = {};
App.Medicine.Surgery.Reactions = {};
App.Mods = {};
App.Mods.DinnerParty = {};
App.Mods.SecExp = {};
App.Mods.SF = {};
App.Neighbor = {};
App.PersonalAttention = {};
App.RA = {};
App.RA.Activation = {};
App.Ratings = {};
App.SlaveAssignment = {};
App.StartingGirls = {};
App.Status = {};
App.Status.storyReady = false;
App.UI = {};
App.UI.Cheat = {};
App.UI.DOM = {};
App.UI.DOM.Widgets = {};
App.UI.SlaveInteract = {};
App.UI.View = {};
App.Update = {};
App.Utils = {};
App.Utils.Math = {};


code:
App.Data.Arcology.Terrain = ["marine", "marine", "oceanic", "ravine", "rural", "rural", "rural", "urban", "urban"];
App.Data.Arcology.Continents = ["Africa", "Asia", "Asia", "Australia", "Western Europe", "Southern Europe", "Central Europe", "Eastern Europe", "Scandinavia", "Japan", "North America", "North America", "South America", "the Middle East"];


code:
App.Data.Assistant = {};
/**
 * Assistant appearances mapped to the FS that love seeing her look like she do.
 * @type {Map<FC.FutureSociety, Array<assistantAppearance>>}
 */
App.Data.Assistant.appearanceForFS = new Map([
	["FSSupremacist", ["amazon", "monstergirl", "succubus"]],
	["FSSubjugationist", ["amazon", "businesswoman", "imp"]],
	["FSGenderRadicalist", ["incubus", "monstergirl", "shemale", "succubus", "witch"]],
	["FSGenderFundamentalist", ["angel", "cherub", "fairy", "goddess", "hypergoddess", "loli", "preggololi", "pregnant fairy", "schoolgirl", "succubus", "witch"]],
	["FSDegradationist", ["businesswoman", "imp", "incubus", "monstergirl", "preggololi", "succubus"]],
	["FSPaternalist", ["angel", "cherub", "fairy", "goddess", "hypergoddess", "loli", "preggololi", "pregnant fairy", "schoolgirl"]],
	["FSBodyPurist", ["amazon", "angel", "fairy", "goddess", "incubus", "loli", "pregnant fairy", "succubus", "witch"]],
	["FSTransformationFetishist", ["businesswoman", "ERROR_1606_APPEARANCE_FILE_CORRUPT", "incubus", "shemale", "succubus", "witch"]],
	["FSYouthPreferentialist", ["angel", "cherub", "imp", "loli", "preggololi", "schoolgirl", "shemale", "succubus", "witch"]],
	["FSMaturityPreferentialist", ["angel", "businesswoman", "goddess", "incubus", "succubus", "witch"]],
	["FSSlimnessEnthusiast", ["cherub", "imp", "loli", "schoolgirl", "shemale", "succubus", "witch"]],
	["FSAssetExpansionist", ["businesswoman", "hypergoddess", "incubus", "shemale", "succubus", "witch"]],
	["FSPastoralist", ["cowgirl", "goddess", "hypergoddess", "incubus", "shemale", "succubus", "witch"]],
	["FSPhysicalIdealist", ["amazon", "incubus", "shemale", "succubus", "witch"]],
	["FSHedonisticDecadence", ["goddess", "hypergoddess", "imp", "incubus", "preggololi", "succubus", "witch"]],
	["FSChattelReligionist", ["angel", "cherub", "goddess", "imp", "incubus", "monstergirl", "succubus", "witch"]],
	["FSNull", []],
	["FSRomanRevivalist", ["amazon", "businesswoman", "incubus", "succubus"]],
	["FSNeoImperialist", ["amazon", "businesswoman", "incubus", "shemale", "angel"]],
	["FSEgyptianRevivalist", ["goddess", "incubus", "monstergirl", "succubus"]],
	["FSEdoRevivalist", ["amazon", "incubus", "kitsunegirl", "loli", "monstergirl", "succubus"]],
	["FSArabianRevivalist", ["businesswoman", "incubus", "schoolgirl", "succubus"]],
	["FSChineseRevivalist", ["incubus", "monstergirl", "schoolgirl", "succubus"]],
	["FSAztecRevivalist", ["amazon", "businesswoman", "incubus", "succubus"]],
	["FSRepopulationFocus", ["goddess", "hypergoddess", "preggololi", "pregnant fairy", "succubus", "witch"]],
	["FSRestart", ["angel", "businesswoman", "goddess", "incubus", "loli", "schoolgirl", "succubus", "witch"]],
	["FSIntellectualDependency", ["shemale", "succubus", "witch"]],
	["FSSlaveProfessionalism", ["angel", "businesswoman", "incubus", "goddess", "schoolgirl", "succubus"]],
	["FSPetiteAdmiration", ["cherub", "fairy", "imp", "incubus", "loli", "preggololi", "pregnant fairy", "schoolgirl", "succubus", "witch"]],
	["FSStatuesqueGlorification", ["amazon", "goddess", "incubus", "succubus", "witch"]]
]);

/**
 * @type {Map<assistantAppearance, {readonly requirements: boolean}>}
 */
App.Data.Assistant.appearances = new Map([
	["normal", {get requirements() { return true; }}],
	["monstergirl", {get requirements() { return (V.seeDicks > 0); }}],
	["shemale", {get requirements() { return V.seeDicks > 0; }}],
	["amazon", {get requirements() { return true; }}],
	["businesswoman", {get requirements() { return true; }}],
	["goddess", {get requirements() { return (V.seePreg !== 0); }}],
	["hypergoddess", {get requirements() { return (V.seePreg !== 0 && V.seeHyperPreg !== 0); }}],
	["schoolgirl", {get requirements() { return true; }}],
	["loli", {get requirements() { return (V.minimumSlaveAge < 13); }}],
	["preggololi", {get requirements() { return (V.seePreg !== 0 && V.minimumSlaveAge < 13); }}],
	["fairy", {get requirements() { return true; }}],
	["pregnant fairy", {get requirements() { return (V.seePreg !== 0); }}],

	// Extra
	["slimegirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],
	["cowgirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],
	["harpygirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],
	["kitsunegirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],
	["lamiagirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],
	["spidergirl", {get requirements() { return (V.assistant.Extra1 === 1); }}],

	// Extra 2
	["angel", {get requirements() { return (V.assistant.Extra2 === 1); }}],
	["cherub", {get requirements() { return (V.assistant.Extra2 === 1); }}],
	["incubus", {get requirements() { return (V.assistant.Extra2 === 1 && V.seeDicks > 0); }}],
	["succubus", {get requirements() { return (V.assistant.Extra2 === 1); }}],
	["imp", {get requirements() { return (V.assistant.Extra2 === 1); }}],
	["witch", {get requirements() { return (V.assistant.Extra2 === 1); }}],
	["ERROR_1606_APPEARANCE_FILE_CORRUPT", {get requirements() { return (V.assistant.Extra2 === 1); }}],
]);