declare module "twine-sugarcube" {
	export interface SugarCubeSetupObject {
		Action: { new(parameter?:any): Action };
		Appearance: { new(playerCharacter: PlayerCharacter): Appearance };
		BodyDescription: { new(character:Character): BodyDescription };
		Consumable: { new(): Consumable };
		Drugs: { new(): Drugs };
		Events: { new(): Events };
		GameTime: { new(): GameTime };
		Inventory: { new(): Inventory };
		Location:{ new(): GameLocation };
		LocationIdentifier:{ new(): LocationIdentifier };
		LocationTravelRequest:{ new(destination:LocationIdentifier,from:LocationIdentifier,time:number): LocationTravelRequest };
		Mood: { new(): Mood };
		Moodlet: { new(): Moodlet };
		MoodletGroup: { new(): MoodletGroup };
		NPCAccessor:{ new(): NPCAccessor };
		OutfitItem: { new(): OutfitItem };
		Pain: { new(): Pain };
		PersonalityScale: { new(): PersonalityScale };
		PlayerCharacter: { new(): PlayerCharacter };
		Quest: {
			handler: object; new(questId?: any): Quest 
		};
		QuestsDict: { new(): QuestsDict };
		Skill: { new(): Skill };
		UserStyle: {new(): UserStyle};
		VersionControl: { new(): VersionControl };


		//#region Listeners
			listeners_timeUpdate:{[key: string]: (minutes:number)=>void};
		//#endregion

		actionTemplates:{[key: string]: ActionTemplate;}
		activeEffects:{[key: string]: ActiveEffect;}
		appearanceModificators: { [key: string]: AppearanceModificatorDefinition; };
		bodypart: { [key: string]: BodypartDefinition;}
		consumables: { [key: string]: ConsumableDefinition;}
		deco: { [key: string]: { [key: string]: any; }}
		drugs: { [key: string]: DrugDefinition}
		effects: { [key: string]: Effect;}
		consumableMenus:{ [key: string]: ConsumableMenuDefinition}
		items: { [key: string]: ItemDefinition; };
		jobs: { [key: string]: JobDefinition};
		locations: { [key: string]: LocationDefinition; };
		moodlets: { [key: string]: Moodlet; };
		moodletGroups: { [key: string]: MoodletGroup; };
		npcs:{ [key: string]: NPCDefinition; };
		npcDefaults:{ [key: string]: NPCDefaultDefinition; };
		npcGenerators:{[key:string]: (flags:NPCGenerateOptions)=>NPCGenerateOptions};
		npcImages:{[key:string]: NPCImageDefinition};
		npcPreferences:{ [key: string]: NPCPreferenceDefinition; };
		outfits: { [key: string]: OutfitDefinition; };
		outfitsDefaults: {[key: string]: {[key: string]: any; } };
		outfitItemImagePath: {[key: string]: string | {[key: string]: any; } };
		painReasons:  {[key: string]: PainReasonDefinition}
		personalityScales: {[key: string]: PersonalityScaleDefinition};
		skills: { [key: string]: SkillDefinition; };
		startingCharacters: {[key: string]: StartCharacterDefinition};
		
		connectedLocationAdd:(label:string,destination:LocationIdentifier,duration:number,image:string,content:string,flags:ConnectedLocationFlags)=>void;
		connectionExecute:(connectedLocation:ConnectedLocation)=>string;
		crimeLikelihood: (crimeId:string,location:LocationIdentifier)=>number;
		durationToString: any;
		executeActionOfIndex:(index:number)=>void;
		executeConnectedLocationByHotkey:(hotkey:string)=>void;
		executeConnectedLocationOfIndex:(index:number)=>void;
		executeESCLocation:()=>void;
		filterDict:<T extends {}>(obj:T,filter: Filter) => T;
		func: (passage: string, ...arguments: Array<string|number>)=>any;
		generateNPC:(dict:NPCsDict,purpose:string,flags:NPCGenerateOptions)=>NPC;
		getActionTemplate:(id:string)=>ActionTemplate;
		getBodyparts:()=> {[key: string]:BodypartDefinition };
		getBodypart:(bodypartId:string)=>BodypartDefinition;
		getConsumable: (type:string)=>{ [key: string]: any; };
		getConsumableMenu: (id:string)=>ConsumableMenuDefinition;
		getDeco: (type:string,position:string,id:number|string)=>{ [key: string]: any; };
		getDrug: (type:string)=>DrugDefinition;
		getDecoPosition: (type:string,position:string) => { [key: string]: any; }
		getDecoPositions: (type:string)=>string[];
		getEffect: (type:string)=>Effect;
		getGenericActionApplied:(actionId:string)=>any;
		getLocation: (locationId: string)=>LocationDefinition;
		getNPCPreference:(preferenceId:string)=>NPCPreferenceDefinition;
		getRandomNpcImage:(filters:{[key:string]:any})=>NPCImageDefinition;
		getStartingCharacter: (type:string)=>StartCharacterDefinition;
		getStartingCharactersByFilter: (filters:{},shallow:boolean)=>{};

		hasBodypart:(bodypartId:string)=>boolean;

		makeSVG: (tag:string, attrs:any,innerHTML?:string|number|undefined) => SVGElement;
		mediaPath(rawPath:string):string;
		mediaPathImage(rawPath:string):string;
		mediaPathRawToString(rawPath:ImagePath):string;
		mergeDeep: (target:any, ...sources:any) => any;

		npcDescription:(npcIdOrObject:string|NPC)=>string;

		randomName: (type:string)=>string;

		startingCharacterApply:(id:string)=>void;
		startingCharacterTagsIncludes:(tag:string)=>boolean;

		tooltip:(elSelector:string, contentSelector:string)=>void;
		travel:(travelRequest:LocationTravelRequest)=>void;
		

		dailySVars:any;


		/**
		 * Executes events in priority-order and according to their weight.
		 * 
		 * Each event can end the execution of the events coming behind it. In this case, the `exitCode` is `STOPPED_BY_EVENT`. Default passage rendering should be omitted then.
		 *
		 * @type {(events:PrioritizedEventDict)=>{exitCode:EEventsExecuteExitCode,contents:string}}
		 */
		eventsExecute:(events:PrioritizedEventDict)=>{exitCode:EEventsExecuteExitCode,contents:string,actions:Action[]};

		eventsGet:(tags:string|string[])=>PrioritizedEventDict;

		gt:(...args:any)=>void;
		/**
		 * Returns whether the place the playercharacter currently is at has internet access.
		 * @returns {boolean}
		 */
		hasInternet(): boolean;

		navigationOverride:(destinationPassageName:string)=>string;
		recursionCounterGT:number[];

		settingsApply:(settings: any)=>void;

		tooltipCounter:number;

		wardrobeSettings:WardrobeSettings;
		weekDayIntToString: any;
		worldSettings:any;

		isWebVersion:boolean;

		difficultyOfHighHeels(shoes?: OutfitItemShoes,levelCategory?:number):ESkillDifficulty
		skillHistoryDrawGraph(domElementId:string,skillID:string):void;

		appearanceFunctions:{
			current: {[key:string]: (pc:PlayerCharacter) => string};
			lasting: {[key:string]: (pc:PlayerCharacter) => string};
			genetic: {[key:string]: (pc:PlayerCharacter) => string};
		}
		wardrobeWearableFunctions:{[key:string]:((outfitOwned:OutfitOwned)=>string|null)};
	}
	
	export interface SugarCubeStoryVariables {
		events: Events;
		finances: any;
		housing:any;
		inventory: Inventory;
		jobs: any;
		location: GameLocation;
		npcs:NPCsDict;
		pc: PlayerCharacter;
		q: QuestsDict;
		settings:any;
		startCharacter: string;
		time: GameTime;
		wardrobe:Wardrobe;

		actions:{[actionId:string]:{cooldownEnd:number}}
		
		ARGS: Array<string>;
		connectedLocations: ConnectedLocation[];

		
		/**
		 * The location to go back to once an event has fired.
		 *
		 * @type {LocationIdentifier}
		 */
		eventReturnLocation: LocationIdentifier;
		here: string;
		location_var: object;
		locationTravelRequest?:LocationTravelRequest;
		media_path: string;
		modVars:any;
		quest: (id:string)=>Quest;
		result: number | string;
		/**
		 * The version of the game. Format is xxxxxxx.xx.xx.
		 * @type {number}
		 * @example
		 * version = 10345; //1.3.45
		 */
		version: number;

		callStack: [string,number][];
	}

	export interface SugarCubeTemporaryVariables{
		actions:Action[];

		temporaryEvents:PrioritizedEventDict;

		thisMainPassage:string;
	}
	
}

declare global {
	export interface Array<T>{
		getRandomWeighted(): T;
		fancyMathEvaluate(): number;
		filterByObject(filter: object): Array<T>;

		isConsecutive(stepSize?:number): boolean;

		randomWeightedByPosition(p:number): T;

		sortByPriority(): Array<T>;
	}

	interface Date{
		format: (formatString:string)=>string;
		
		/**
		 * Returns whether the date lies in the future according to the game-time. Returns false if the given time is now. Returns true if gametime is not initialized.
		 * @type {()=>boolean}
		 */
		isFuture: ()=>boolean;
	}

	interface Math {
		
		/**
		 * Rounds to the higher number if positive, to the lower number if negative.
		 * @type {(n:number)=>number}
		 */
		ceilAbs: (n:number)=>number;

		
		/**
		 * @link https://stackoverflow.com/a/36481059/7200161
		 *
		 * @type {(mean?:number, stdev?:number)=>number}
		 */
		gaussianRandom:(mean?:number, stdev?:number)=>number;

		logBase: (n:number, base:number)=>number;
	}

	export interface Number{
		roundToDecimal:(decimalPlaces:number)=>number;
		toBoolean:()=>boolean;
		
	}

	export interface String{
		formatUnicorn(format:{}):string;
		removeLeading(leading:string):string;
		toBoolean():boolean;
	}

	export class Util{
		static slugify(s:string): string;
	}

	export interface Window{
		rand(x:number,y:number): number;
		NPCsDict: { new(): NPCsDict };
		Wardrobe: { new(): Wardrobe };
	}

	export interface ActFlags{
		
		/**
		 * Overwrite the label in the action bar
		 * @type {?string}
		 */
		ab_label?:string;

		
		
		/**
		 * What's that again?
		 * @todo
		 * @type {?string}
		 */
		action?:string;

		/**
		 * Minimum required arousal
		 * @type {?number}
		 */
		arousal?:number;

		
		/**
		 * Overwrite contents
		 * @type {?string}
		 */
		contents?:string;

		contents_header?:string;
		contents_footer?:string;

		
		/**
		 * Captured vars-array (e.g. ['_npcID'])
		 * @type {?string[]}
		 */
		capture?:string[];

		cost?:{both?:number;cash?:number;bank?:number};

		
		/**
		 * The action is disabled. Show the value as tooltip.
		 * @type {?string}
		 */
		disabled?:string;

		//	'fetish':			The action can't be done if you're appalled by this fetish (string or array of strings)
		
		
		/**
		 * Don't show this action?
		 * @type {boolean}
		 */
		hidden?:boolean;

		image?:string;

		
		/**
		 * Label (if not set as arg[0])
		 * @type {?string}
		 */
		label?:string;
		
		
		/**
		 * minium required mood
		 * @type {?number}
		 */
		mood?:number;

		moodlet?:string;
		
		
		/**
		 * In case of a string, refers to the field `actions`
		 * @type {?{
		 * 			[personalityId:string]:PersonalityRequirement|string
		 * 		}}
		 */
		personality?:{
			[personalityId:string]:PersonalityRequirement|string
		};

		priority?:number;

		repeatReset?:{
			id?:string;
			days?:number;
		}

		/**
		 * (e.g. '{intelligence:50}')
		 * @type {?{[skillId:string]:number}}
		 */
		skillRequirment?:{[skillId:string]:number};

		template?:string|string[];
		/**
		 * Added time in minutes. Display the time but don't really add it if negative.
		 * @type {?number}
		 */
		time?:number;

		willpower?:number;
	}

	type ActionTemplate = (flags:ActFlags)=>ActFlags;

	export interface ActiveEffect{
		isActive: boolean|((pc:PlayerCharacter)=>boolean);
		effect:Effect|string;
	}

	export interface AppearanceChange{
		time: Date;
		key: string;
		from: any;
		to: any;
	}

	export interface AppearanceModificatorDefinition{
		label:string;
		desc:string;
		
		/**
		 * High comes first.
		 * @type {number}
		 */
		priority?:number;

		
		/**
		 * Sets the appearance value. Use sparingly.
		 *
		 * @type {?number}
		 */
		set?:number;

		
		/**
		 * Sets the max number the appearance can reach.
		 * @type {?number}
		 */
		max?:number;

		
		/**
		 * Sets the min number the appearance can reach.
		 * @type {?number}
		 */
		min?:number;


		
		/**
		 * Decreases the appearance by the given number;
		 * @type {?number}
		 */
		dec?:number;

		
		/**
		 * Increases the appearance by the given number;
		 * @type {?number}
		 */
		inc?:number;
	}


	export interface StartCharacterDefinition{
			hidden?:boolean;

			/**
			 * The description that's displayed to the player
			 * @type {?string}
			 */
			desc?:string

			finances?:{
				
				/**
				 * The starting cash of the character.
				 * @type {?number}
				 */
				cash?:number
			},

			housing?:{
				home?: string
			},

			/**
			 * Obvious things are obvious
			 * @type {?string}
			 */
			image?:string

			
			/**
			 * Used internally in `setup.getStartingCharacter`. Don't overwrite.
			 * @type {?string[]}
			 */
			inheritance?:string[]

			items?:{
				[key: string]: number | {
						generateFunction:string,
						generateParameters?:any[]
					}
				
			}

			
			/**
			 * What is displayed to the player
			 * @type {?string}
			 */
			label?:string

			location?:{
				[key: string]:{
					[key: string]:any
				}
			}

			locationTags?:{
				[key: string]:{
					[key: string]:any
				}
			}

			npcs?:{
				bulk?:{
					[key: string]:{
						values?:{
							rel?:number,
							fam?:number
						},
						filters?:{
							[key: string]:any
						}
					}
				}
				[key: string]: any
			}
			
			
			/**
			 * Another character defintion that is to be inherited.
			 * @type {?string}
			 */
			parent?:string

			/**
			 * Starting values of the PlayerCharacter. Every field of this class can be overwritten.
			 * @type {?{ [key: string]: any; }}
			 */
			pc?:{ [key: string]: any; }

			personality?:{ [key: string]: number; }

			quests?:{
				[key: string]: boolean;
			}

			school?:{
				[key: string]: any;
			}

			skills?:{
				[key: string]: number;
			}

			
			/**
			 * Categories of the starting character.
			 * @type {string[]}
			 */
			tags?:string[]

			time?: any;

			traits?:{
				[key: string]: number;
			}
			wardrobe?:{
				itemsByFilter?:{
					[key: string]:{
						filters?:{
							[key: string]:any;
						};
						count?: number;
						action?: 'add'|'wear';
					}
				},
				items?:{
					[key: string]:'add'|'wear';
				}
			};
	}

	export interface BodypartDefinition{
		
		id?:string;

		/**
		 * Name of another bodypart this bodypart is a synonym for.
		 * @type {?string}
		 */
		synonymFor?:string;


		
		/**
		 * Is this bodypart inside the body? Default: false.
		 * @type {?boolean}
		 */
		inside?:boolean;


		covered?:boolean|((pc:PlayerCharacter) => boolean);

		
		/**
		 * Which activities clean this bodypart.
		 * @type {string[]}
		 */
		clean?:string[];

		cumDisabled?:boolean;
		painDisabled?:boolean;

		label?:string;
		painDesc?:string;
	}

	export interface Character{
		eyecolor:EEyeColor;
		eyesize:EEyeSize;

		hairColor:EHairColor;
		hairLengthCategory:EHairLength;
	}

	export interface ConnectedLocation{
		forPassage : string,
		destination: LocationIdentifier,
		label: string,
		image: string,
		duration: number,
		class: string,
		priority: number,
		content: string,
		hotkeys: any,
		indecencyBlocked?:boolean,
		tags?:string[];
		capturedVars: {[key:string]:any};
	}

	export interface ConnectedLocationFlags{
		allowedVehicles?:string[];
		capture?:string[];
		class?:string;
		hotkeys?:string[];
		indecencyBlocked?:boolean;
		priority?:number;
		tags?:string[];
	}

	export interface ConsumableDefinition{
		alcohol?:number;

		costItems?:string[];

		desc?:string;

		
		/**
		 * Relative calories with 1 being an healthy amount.
		 * @type {?number}
		 */
		energy?:number;

		hunger?: number;

		image?: string;
		imageRand?: ImageRand;

		label?:string;

		moodletIds?:string[];

		price?: number;
		
		thirst?:number;

		/**
		 * The time it takes to consume.
		 * @type {number}
		 */
		time:number;
		type: 'drink'|'meal'|'candy';
	}
	
	export interface ConsumableMenuDefinition{
		payment:'cash'|'bank'|'both';
		categories:{
			[key:string] : {
				label:string;
				items:{
					[key:string] : {
						
						/**
						 * Overwrites the original items price with a flat number. In case of a function, the original price is taken as input. `Math.round()` is always applied to the result then.
						 * @type {(number|((n:number)=>number))}
						 */
						price?:number|((n:number)=>number);
					}
				}
			}
		}
	}

	export interface DrugDefinition{
		deterioration: number;
		effects:{[key: string]:{condition:any; effect:string;}};

		byproduct?:DrugByproductDefinition;
		
		/*{
			buildup: 1.5,
			deterioration: 0.0017,
			effects:{
				hangover:{
					condition:{mainEffectsInactive:true},
					effect: 'hangover'
				}
			}
		}*/
	}

	export interface DrugByproductDefinition extends DrugDefinition{
		buildup: number;
	}

	export interface DrugInCharacter{
		vol:number;byproduct?:number;
	}

	export interface Effect{
		
		/**
		 * If true, an icon will be displayed in the sidebar. Make sure to specify `desc` and `image` in this case.
		 * @type {?boolean}
		 */
		sidebar?:boolean;
		desc?:string;
		image?: string;

		
		/**
		 * ID of a moodlet that should automatically be enabled while the effect is active.
		 * @type {string}
		 */
		moodlet?: string;

		
		/**
		 * Influences variables such as cerebral skill learning. 1 is the default value.
		 * 
		 * Multiplicative
		 * @type {number}
		 */
		consciousness?: number;


		
		/**
		 * Plain reduction of overall pain.
		 * @type {?number}
		 */
		painReduction?: number;

		
		/**
		 * Plain increase in pain in bodypart for given reason.
		 * @type {?{[bodypartId:string]:{[painReasonId:string]:number}}}
		 */
		pain?:{[bodypartId:string]:{[painReasonId:string]:number}};

		painGain?:{
			[bodypartId:string]:
				number
		}

		painRegen?:{
			[bodypartId:string]:
				number
		}
		
		/**
		 * Plain increase in skill.
		 * @type {?{[skillId:string]:number}}
		 */
		skills?:{[skillId:string]:number};

		
		/**
		 * Percentage of skill gain. 1 is default. 0.9 would be a 10% decrease in skill gain.
		 * @type {{
		 * 			[skillId:string]:number
		 * 		}}
		 */
		skillGain?:{
			[skillId:string]:number
		}

		skillTagGain?:{
			[tag:string]:number
		}
	}

	export interface ExpiringVar<T>{
		val:T;
		til:Date;
	}

	export interface Filter{

	}

	export interface GameEvent{
		priority: number, weight: number,  contents: string
	}

	type ImagePath = string|(string|number)[];

	export interface ImageRand{

	}


	export interface ItemDefinition{
		
		
		/**
		 * An optional description to be displayed to the player.
		 * @type {?string}
		 */
		desc?: string;

		
		/**
		 * Information on how the item behaves if used as furniture.
		 * @type {?object}
		 */
		furniture?:object;

		/**
		 * Path to the image of the item.
		 * @type {string}
		 */
		image:string;

		/**
		 * The label that's displayed to the player. Defaults to the id of the item.
		 * @type {?string}
		 */
		label?:string;

		
		/**
		 * How many items of the same type fit into a purse.
		 * @type {?number}
		 */
		limit?:number;

		
		/**
		 * A passage the player is sent to when he clicks the item in the inventory.
		 * @type {?string}
		 */
		passage?:string;

		
		/**
		 * Default price.
		 * @type {?number}
		 */
		price?: number;
		
	}

	export interface JobDefinition{

	}

	export interface LocationDefinition{
		image:ImagePath|LocationImageDefinition;
		openTimes?:TimespanIdentifier;
	}

	export interface LocationImageDefinition{
		day: ImagePath;
		/**
		 * Defaults to day.
		 * @type {?ImagePath}
		 */
		night?:ImagePath;
		/**
		 * Defaults to day.
		 * @type {?ImagePath}
		 */
		winterDay?:ImagePath;
		/**
		 * Defaults to night.
		 * @type {?ImagePath}
		 */
		winterNight?:ImagePath;
	}

	export type NPC = NPCAccessor & Character & {[key:string]:any};

	export interface NPCActivity{
		location:string;
		activity:string[];
	}

	export interface NPCDefinition{
		passage?:string;
		image?:string;

		rel?:number;

		dna?:string;

		firstname?:string;
		nickname?:string;
		lastname?:string;
		usedname?:string;

		dob?:number;
		gender: EGender;

		haircol?:number;
		height?:number;

		notes?:string;

		//thdick?:string;
		dick?:EDickSize;
		bust?:number;
		spermpot?:number;

		sexskill?:number;

		rep?:number;

		intel?:number;

		hotcat_rating?:number;

		preference?:{[key:string]:NPCPreference};

		defaults?:string[];

		
		/**
		 * Information on where the NPC is and what they do there at a given time.
		 * @type {?Timetable<NPCActivity>}
		 */
		timetable?:Timetable<NPCActivity>;
	}

	export interface NPCDefaultDefinition{

	}

	export interface NPCGenerateOptions {

		generators?:string[];

		fields?:{gender?:EGender} & {[key:string]:any};

		vars?:{[key:string]:any};
	}

	export interface NPCImageDefinition{
		path:string;
		age: EAgeBracket;
		gender:EGender;
	}

	export interface NPCPreference{
		state: ENPCPreference;
	}

	export interface NPCPreferenceDefinition{
		matches:(pc:PlayerCharacter)=>boolean;

	}

	export type OutfitDefinition = OutfitDefinitionBodysuit | OutfitDefinitionBra | OutfitDefinitionClothes | OutfitDefinitionCoat | OutfitDefinitionPanties | OutfitDefinitionPurse | OutfitDefinitionShoes | OutfitDefinitionSwimwear;

	export interface OutfitDefinitionRaw{
		quality: EOutfitQuality;
		vendor:string;
		index?: number;
		description?: string;
		
		/**
		 * When accessing an Outfit-object, use the getter `image`, since it supports legacy outfits as well.
		 * @type {?string}
		 */
		imagePath?:string;
	}

	export interface OutfitDefinitionBodysuit extends OutfitDefinitionRaw{
		type:'bodysuit';
		subtype?:number;
		material?:number;
		fun?:number;
		thinness?:number;
		cover?:number;
		coverFront?:number;
		coverBack?:number;
	}

	export interface OutfitDefinitionBra extends OutfitDefinitionRaw{
		type:'bra';
		subtype?: number;
		fun?: number;
		thinness?: number;
		material?: number;
		cover?: number;
	}

	export interface OutfitDefinitionClothes extends OutfitDefinitionRaw{
		type:'clothes';
		subtype:string;
		thinness: number;
		topcut?: number;
		includesBra?: number;
		includesPanties?: number;
		isDress?:number;
		isOnepiece?: number;
		inhib?: number;
		pantsShortness?:number;
		skirtShortness?:number;
		coverTop?:number;
		coverBack?:number;
		coverFront?:number;
		
		/**
		 * 4 seems to be prostitution.
		 * @type {number}
		 */
		style?: number;

		style2?: number;

		style3?:number;

		bimbo?:number;
	}

	export interface OutfitDefinitionCoat extends OutfitDefinitionRaw{
		type:'coat';
		warm:number;
	}

	export interface OutfitDefinitionPanties extends OutfitDefinitionRaw{
		type:'panties';
		subtype?: number;
		fun?: number;
		thinness?: number;
		material?: number;
		coverBack?:number;
		coverFront?:number;
	}

	export interface OutfitDefinitionPurse extends OutfitDefinitionRaw{
		type:'purse';
	}

	export interface OutfitDefinitionShoes extends OutfitDefinitionRaw{
		type:'shoes';
		style?:number;
		cut?:number;
		heels?:number;
	}

	export interface OutfitDefinitionSwimwear extends OutfitDefinitionRaw{
		type:'swimwear';
		subtype?:string;
		thinness:number;
		topcut?:number;
		coverTop?:number;
		coverFront?:number;
		coverBack?:number;
		includesBra?:number;
		includesPanties:number;
		isOnepiece?:number;
		bimbo?:number;
		inhib:number;
	}

	export type OutfitOwned = OutfitDefinition & OutfitOwnerShipData;

	export interface OutfitOwnerShipData{
		h?:number;
		l?:number;
		bmi?:number;
	}

	export interface PainReasonDefinition{
		
		/**
		 * How much the pain deteriorats each hour.
		 * @type {number}
		 */
		deterioration: number;
		label: string;
		description:string;
	}

	export interface PersonalityRequirement{
		impact: number|string;
		/**
		 * Costs willpower if you're under the value, but not if you're over it.
		 * @type {?number}
		 */
		min?:number;

		/**
		 * Costs willpower if you're over the value, but not if you're under it.
		 * @type {?number}
		 */
		max?:number;

		
		/**
		 * Costs you willpower if you're under or over the value.
		 * @type {?number}
		 */
		target?:number;
	}

	export interface PersonalityScaleDefinition{
		
		/**
		 * Hide this from the player if true. Will not appear in lists and won't be  mentioned in dialogs.
		 * @type {?boolean}
		 */
		hidden?:boolean;
		start: number;
		interval: number[];
		label: string | string[];
		desc?: string;
		image?:string;
		actions?:{[key:string]:PersonalityRequirement};
		impacts?:{[key:string]:number};
		msg_tooHigh?:string;
		msg_tooLow?:string;
		functions?:{[key:string]:(any:any) => any}
	}

	export interface PrioritizedEventDict{
		[priority:number]:GameEvent
	}

	export interface SexEncounter{
		
		/**
		 * The ID of the npc Sveta had sex with. If she has sex with more than one character (e.g. threesome) an encounter has to be created for each of them.
		 * @type {string}
		 */
		npcId: string,
		time:Date,
		types: ESexEncounterType[],
		/**
		 * Is Sveta aware of the sex-act? False in case of hypnosis, blackouts, etc.
		 * @type {boolean}
		 */
		aware: boolean,
		/*civ: Cum in vagina
		civa:Cum in vagina aware*/
		tags: string[]
	}

	export interface SexStatistics{/*
		bj:SexStatistic;
		hj:SexStatistic;
		vaginal:SexStatistic;
		anal:SexStatistic;*/
		[key:string]: SexStatistic
	}

	export interface SexStatistic{
		/*love:number[];
		friend:number[];
		acquaintance:number[];
		stranger:number[];*/
		[key:string]: number[]
	}

	export interface SkillDefinition{
		
		label ?: string;
		description?:string;
		descibtionByLevel?:{[key:number]: string};
		image?:string;

		dailyExpLimit?:number|((levelAtStartOfDay:number)=>number);
		
		/**
		 * If true, the amount of gained experience depends on the difficulty of a task.
		 * @type {?boolean}
		 */
		isDifficultyBased?:boolean;
		
		/**
		 * Hide this skill from players in overviews when set to true.
		 * @type {?boolean}
		 */
		hidden?: boolean;

		/**
		 * A function that provides a skill level.
		 * @type {(skillLevel:number)=>number} Experience
		 */
		e2s?: (skillLevel:number)=>number;

		/**
		 * A function that provides a number of required skillpoints.
		 * @type {(skillLevel:number)=>number} Skill Level
		 */
		s2e?: (skillLevel:number)=>number;

		functions?: {[functionId:string]:Function};
		vars?:{[key:string]:any};
	}
	
	export interface SkillOfCharacter{
		
		
		/**
		 * The maximum number the experience can reach. 0 if disabled.
		 * @type {number}
		 */
		ceil:number;
		
		/**
		 * Current number of experience points.
		 * @type {number}
		 */
		experience:number;

		
		/**
		 * History of this skill for the last days.
		 * @type {number[]}
		 */
		experienceHistory:number[];

		
		/**
		 * The minimum number the experience can reach.
		 * @type {number}
		 */
		floor: number;

		/**
		 * The last daystart this skill has been used.
		 * @type {number}
		 */
		lastUsed: number;
	}

	export interface TimespanIdentifier{
		days?: ('MO'|'TU'|'WE'|'TH'|'FR'|'SA'|'SU'|'work')[];
		daysBL?: ('MO'|'TU'|'WE'|'TH'|'FR'|'SA'|'SU'|'work')[];
		
		/**
		 * True: The day needs to be a school holiday. False: The day needs to be 
		 * @type {?boolean}
		 */
		holiday?:EDayVacationState;
		/*vacation?:boolean;*/
		begin?:number[];
		end?:number[];
	}

	

	export interface Timetable<T>{
		[key:string]:{
			time: TimespanIdentifier;
			result?: T;
			subtable?:Timetable<T>;
			either?:T[];
		}
	}

	export interface WardrobeSettings{
		
		/**
		 * Maximum difference of the bmi-value of bought and worn clothes.
		 * @type {number}
		 */
		bmiSizeMaxDifference: number;
	}

	export interface WornOutfitDefinition{
		bra: string,
		coat: string,
		clothes: string,
		panties: string,
		purse: string,
		shoes: string
	}

}


export { };