// Generated by dts-bundle-generator v9.5.1

/**
 * A button binding.
 *
 * @group Input
 * @subgroup Buttons API
 */
export type ButtonBinding = {
	keyboard?: ChordedKey | ChordedKey[];
	keyboardCode?: string | string[];
	gamepad?: ChordedKGamepadButton | ChordedKGamepadButton[];
	mouse?: ChordedMouseButton | ChordedMouseButton[];
};
/**
 * A buttons definition for an action (jump, walk-left, run).
 *
 * @group Input
 * @subgroup Buttons API
 */
export type ButtonsDef = Record<string, ButtonBinding>;
/**
 * A button binding device
 *
 * @group Input
 * @subgroup Buttons API
 */
export type ButtonBindingDevice = "keyboard" | "gamepad" | "mouse";
declare class ChordedButtonDetector<T extends string = string> {
	mods: Map<T, boolean>;
	committers: Map<T, {
		check: Set<T>;
		btns: Map<string, T[]>;
	}>;
	buttonsUsed: Set<string>;
	updateBinding(button: string, bindings: T[]): void;
	handleDown(key: T): string[];
	handleUp(key: T): string[];
}
export declare class ButtonProcessor {
	byKey: ChordedButtonDetector<ChordedKey>;
	byKeyCode: ChordedButtonDetector<string>;
	byMouse: ChordedButtonDetector<ChordedMouseButton>;
	byGamepad: ChordedButtonDetector<ChordedKGamepadButton>;
	state: ButtonState<string, never>;
	updateBinding(name: string, b: ButtonBinding): void;
	private _maybePress;
	private _maybeRelease;
	processKeydown(key: Key, keyCode: string, state: AppState): void;
	processKeyup(key: Key, keyCode: string, state: AppState): void;
	processMousedown(mb: MouseButton, state: AppState): void;
	processMouseup(mb: MouseButton, state: AppState): void;
	processGamepadButtonDown(gb: KGamepadButton, state: AppState): void;
	processGamepadButtonUp(gb: KGamepadButton, state: AppState): void;
	update(): void;
	process(state: AppState): void;
}
/**
 * A serialized game object. Created using {@link GameObjRaw.serialize `GameObjRaw.serialize()` } method.
 *
 * @since v4000.0
 * @group Game Obj
 * @subgroup Prefabs
 */
export interface SerializedGameObj {
	components: Record<string, any>;
	tags: string[];
	children?: SerializedGameObj[];
}
/**
 * @group Events
 */
export declare class Registry<T> extends Map<number, T> {
	private lastID;
	push(v: T): number;
	pushd(v: T): () => void;
}
/**
 * A controller for all events in KAPLAY.
 *
 * @example
 * ```js
 * // Create a new event
 * const logHi = onUpdate(() => {
 *    debug.log("hi");
 * });
 *
 * // Pause the event
 * logHi.paused = true;
 *
 * // Cancel the event
 * logHi.cancel();
 *
 * ```
 *
 * @group Events
 */
export declare class KEventController {
	/** If the event is paused */
	paused: boolean;
	/** The game obj that attached this event */
	controller?: GameObj | null;
	/** Cancel the event */
	cancel: () => void;
	constructor(cancel: () => void);
	static join(events: KEventController[]): KEventController;
	static replace(oldEv: KEventController, newEv: KEventController): KEventController;
}
export declare class KEvent<Args extends any[] = any[]> {
	private cancellers;
	private handlers;
	add(action: (...args: Args) => unknown): KEventController;
	addOnce(action: (...args: (Args | PromiseLike<Args>)[]) => void): KEventController;
	next(): Promise<Args>;
	trigger(...args: Args): void;
	numListeners(): number;
	clear(): void;
}
export declare class KEventHandler<EventMap extends Record<string, any[]>> {
	private handlers;
	on<Name extends keyof EventMap>(name: Name, action: (...args: EventMap[Name]) => void): KEventController;
	onOnce<Name extends keyof EventMap>(name: Name, action: (...args: EventMap[Name]) => void): KEventController;
	next<Name extends keyof EventMap>(name: Name): Promise<unknown>;
	trigger<Name extends keyof EventMap>(name: Name, ...args: EventMap[Name]): void;
	remove<Name extends keyof EventMap>(name: Name): void;
	clear(): void;
	numListeners<Name extends keyof EventMap>(name: Name): number;
}
declare const CSS_COLOR_MAP: {
	black: string;
	silver: string;
	gray: string;
	white: string;
	maroon: string;
	red: string;
	purple: string;
	fuchsia: string;
	green: string;
	lime: string;
	olive: string;
	yellow: string;
	navy: string;
	blue: string;
	teal: string;
	aqua: string;
	aliceblue: string;
	antiquewhite: string;
	aquamarine: string;
	azure: string;
	beige: string;
	bisque: string;
	blanchedalmond: string;
	blueviolet: string;
	brown: string;
	burlywood: string;
	cadetblue: string;
	chartreuse: string;
	chocolate: string;
	coral: string;
	cornflowerblue: string;
	cornsilk: string;
	crimson: string;
	cyan: string;
	darkblue: string;
	darkcyan: string;
	darkgoldenrod: string;
	darkgray: string;
	darkgreen: string;
	darkkhaki: string;
	darkmagenta: string;
	darkolivegreen: string;
	darkorange: string;
	darkorchid: string;
	darkred: string;
	darksalmon: string;
	darkseagreen: string;
	darkslateblue: string;
	darkslategray: string;
	darkturquoise: string;
	darkviolet: string;
	deeppink: string;
	deepskyblue: string;
	dimgray: string;
	dodgerblue: string;
	firebrick: string;
	floralwhite: string;
	forestgreen: string;
	gainsboro: string;
	ghostwhite: string;
	gold: string;
	goldenrod: string;
	greenyellow: string;
	honeydew: string;
	hotpink: string;
	indianred: string;
	indigo: string;
	ivory: string;
	khaki: string;
	lavender: string;
	lavenderblush: string;
	lawngreen: string;
	lemonchiffon: string;
	lightblue: string;
	lightcoral: string;
	lightcyan: string;
	lightgoldenrodyellow: string;
	lightgray: string;
	lightgreen: string;
	lightpink: string;
	lightsalmon: string;
	lightseagreen: string;
	lightskyblue: string;
	lightslategray: string;
	lightsteelblue: string;
	lightyellow: string;
	limegreen: string;
	linen: string;
	mediumaquamarine: string;
	mediumblue: string;
	mediumorchid: string;
	mediumpurple: string;
	mediumseagreen: string;
	mediumslateblue: string;
	mediumspringgreen: string;
	mediumturquoise: string;
	mediumvioletred: string;
	midnightblue: string;
	mintcream: string;
	mistyrose: string;
	moccasin: string;
	navajowhite: string;
	oldlace: string;
	olivedrab: string;
	orange: string;
	orangered: string;
	orchid: string;
	palegoldenrod: string;
	palegreen: string;
	paleturquoise: string;
	palevioletred: string;
	papayawhip: string;
	peachpuff: string;
	peru: string;
	pink: string;
	plum: string;
	powderblue: string;
	rebeccapurple: string;
	rosybrown: string;
	royalblue: string;
	saddlebrown: string;
	salmon: string;
	sandybrown: string;
	seagreen: string;
	seashell: string;
	sienna: string;
	skyblue: string;
	slateblue: string;
	slategray: string;
	snow: string;
	springgreen: string;
	steelblue: string;
	tan: string;
	thistle: string;
	tomato: string;
	turquoise: string;
	violet: string;
	wheat: string;
	whitesmoke: string;
	yellowgreen: string;
};
/**
 * @group Math
 * @subgroup Colors
 */
export type RGBValue = [
	number,
	number,
	number
];
/**
 * @group Math
 * @subgroup Colors
 */
export type RGBAValue = [
	number,
	number,
	number,
	number
];
/**
 * @group Math
 * @subgroup Colors
 */
export type CSSColorKeywords = keyof typeof CSS_COLOR_MAP;
/**
 * A serialized color.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedColor {
	r: number;
	g: number;
	b: number;
}
/**
 * 0-255 RGBA color.
 *
 * @group Math
 * @subgroup Colors
 */
export declare class Color {
	/** Red (0-255. */
	r: number;
	/** Green (0-255). */
	g: number;
	/** Blue (0-255). */
	b: number;
	constructor(r: number, g: number, b: number);
	static fromArray(arr: [
		number,
		number,
		number
	]): Color;
	/**
	 * Create color from hex string or literal.
	 *
	 * @example
	 * ```js
	 * Color.fromHex(0xfcef8d)
	 * Color.fromHex("#5ba675")
	 * Color.fromHex("d46eb3")
	 * ```
	 *
	 * @since v3000.0
	 */
	static fromHex(hex: string | number): Color;
	static fromHSL(h: number, s: number, l: number): Color;
	/**
	 * Create a color from a CSS color name
	 *
	 * @param cssColor - The color name.
	 *
	 * @example
	 * ```js
	 * loadHappy();
	 *
	 * add([
	 *     rect(512, 512, {
	 *         radius: [0, 96, 96, 96]
	 *     }),
	 *     color("#663399"),
	 *     pos(40, 40),
	 * ]);
	 *
	 * add([
	 *     text("css", { size: 192, font: "happy" }),
	 *     pos(90, 310)
	 * ]);
	 * ```
	 *
	 * @static
	 * @returns The color.
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	static fromCSS(cssColor: CSSColorKeywords): Color;
	static RED: Color;
	static GREEN: Color;
	static BLUE: Color;
	static YELLOW: Color;
	static MAGENTA: Color;
	static CYAN: Color;
	static WHITE: Color;
	static BLACK: Color;
	clone(): Color;
	/** Lighten the color (adds RGB by n). */
	lighten(a: number): Color;
	/** Darkens the color (subtracts RGB by n). */
	darken(a: number): Color;
	invert(): Color;
	mult(other: Color): Color;
	/**
	 * Linear interpolate to a destination color.
	 *
	 * @since v3000.0
	 */
	lerp(dest: Color, t: number): Color;
	/**
	 * Convert color into HSL format.
	 *
	 * @since v3001.0
	 */
	toHSL(): [
		number,
		number,
		number
	];
	eq(other: Color): boolean;
	toString(): string;
	/**
	 * Return the hex string of color.
	 *
	 * @since v3000.0
	 */
	toHex(): string;
	/**
	 * Return the color converted to an array.
	 *
	 * @since v3001.0
	 */
	toArray(): Array<number>;
	serialize(): {
		r: number;
		g: number;
		b: number;
	};
	static deserialize(data: {
		r: number;
		g: number;
		b: number;
	}): Color;
}
/**
 * Possible color arguments for various functions.
 *
 * @group Math
 * @subgroup Colors
 */
export type ColorArgs = [
	Color
]
/**
 * rgb(new Color(255, 255, 255), 1)
 *
 * This is only used to parse directly the color of background. This
 * syntax shouldn't be used to set opacity. Use `opacity()` comp instead.
 */
 | [
	Color,
	number
] | RGBValue
/**
 * rgb(255, 255, 255, 1)
 *
 * This is only used to parse directly the color of background. This
 * syntax shouldn't be used to set opacity. Use `opacity()` comp instead.
 */
 | RGBAValue | [
	string
] | [
	number[]
] | [
] | [
	CSSColorKeywords & (string & {})
] | [
	number
];
/**
 * A valid value for lerp.
 *
 * @group Math
 * @subgroup Tween
 */
export type LerpValue = number | Vec2 | Color;
/**
 * Possible arguments for a Vec2.
 *
 * @group Math
 * @subgroup Vectors
 */
export type Vec2Args = [
	number,
	number
] | [
	number
] | [
	Vec2
] | [
	number | Vec2
] | [
];
/**
 * @group Math
 * @subgroup Advanced
 */
export declare class Quad {
	x: number;
	y: number;
	w: number;
	h: number;
	constructor(x: number, y: number, w: number, h: number);
	scale(other: Quad): Quad;
	pos(): Vec2;
	clone(): Quad;
	eq(other: Quad): boolean;
	toString(): string;
}
/**
 * @group Math
 * @subgroup Advanced
 */
export declare class Mat2 {
	a: number;
	b: number;
	c: number;
	d: number;
	constructor(a: number, b: number, c: number, d: number);
	mul(other: Mat2): Mat2;
	transform(point: Vec2): Vec2;
	get inverse(): Mat2;
	get transpose(): Mat2;
	get eigenvalues(): number[];
	eigenvectors(e1: number, e2: number): number[][];
	get det(): number;
	get trace(): number;
	static rotation(radians: number): Mat2;
	static scale(x: number, y: number): Mat2;
}
export declare class Mat23 {
	a: number;
	b: number;
	c: number;
	d: number;
	e: number;
	f: number;
	_inverse: Mat23 | null;
	constructor(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number);
	static fromMat2(m: Mat2): Mat23;
	toMat2(): Mat2;
	static fromTranslation(t: Vec2): Mat23;
	static fromRotation(radians: number): Mat23;
	static fromScale(s: Vec2): Mat23;
	static fromSkew(s: Vec2): Mat23;
	clone(): Mat23;
	setMat23(m: Mat23): this;
	setIdentity(): this;
	setTRS(x: number, y: number, angle: number, sx: number, sy: number): void;
	mul(other: Mat23): Mat23;
	translateSelfV(t: Vec2): Mat23;
	translateSelf(x: number, y: number): Mat23;
	rotateSelf(degrees: number): Mat23;
	scaleSelfV(s: Vec2): Mat23;
	scaleSelf(x: number, y: number): Mat23;
	skewSelfV(s: Vec2): Mat23;
	skewSelf(x: number, y: number): Mat23;
	mulSelf(other: Mat23): Mat23;
	transform(p: Vec2): Vec2;
	transformPointV(p: Vec2, o: Vec2): Vec2;
	transformVectorV(v: Vec2, o: Vec2): Vec2;
	transformPoint(x: number, y: number, o: Vec2): Vec2;
	transformVector(x: number, y: number, o: Vec2): Vec2;
	get det(): number;
	get inverse(): Mat23;
	getTranslation(): Vec2;
	getRotation(): number;
	getScale(): Vec2;
	getSkew(): Vec2;
}
/**
 * A random number generator using the linear congruential generator algorithm.
 *
 * @group Math
 * @subgroup Random
 */
export declare class RNG {
	/**
	 * The current seed value used by the random number generator.
	 */
	seed: number;
	constructor(seed: number);
	/**
	 * Generate a random number between 0 and 1.
	 *
	 * @example
	 * ```js
	 * const rng = new RNG(Date.now())
	 * const value = rng.gen() // Returns number between 0-1
	 * ```
	 *
	 * @returns A number between 0 and 1.
	 */
	gen(): number;
	/**
	 * Generate a random number between two values.
	 *
	 * @param a - The minimum value.
	 * @param b - The maximum value.
	 *
	 * @example
	 * ```js
	 * const rng = new RNG(Date.now())
	 * const value = rng.genNumber(10, 20) // Returns number between 10-20
	 * ```
	 *
	 * @returns A number between a and b.
	 */
	genNumber(a: number, b: number): number;
	/**
	 * Generate a random 2D vector between two vectors.
	 *
	 * @param a - The minimum vector.
	 * @param b - The maximum vector.
	 *
	 * @example
	 * ```js
	 * const rng = new RNG(Date.now())
	 * const vec = rng.genVec2(vec2(0,0), vec2(100,100))
	 * ```
	 *
	 * @returns A vector between vectors a and b.
	 */
	genVec2(a: Vec2, b: Vec2): Vec2;
	/**
	 * Generate a random color between two colors.
	 *
	 * @param a - The first color.
	 * @param b - The second color.
	 *
	 * @example
	 * ```js
	 * const rng = new RNG(Date.now())
	 * const color = rng.genColor(rgb(0,0,0), rgb(255,255,255))
	 * ```
	 *
	 * @returns A color between colors a and b.
	 */
	genColor(a: Color, b: Color): Color;
	/**
	 * Generate a random value of a specific type.
	 *
	 * @param args - No args for [0-1], one arg for [0-arg], or two args for [arg1-arg2].
	 *
	 * @example
	 * ```js
	 * const rng = new RNG(Date.now())
	 * const val = rng.genAny(0, 100) // Number between 0-100
	 * const vec = rng.genAny(vec2(0,0), vec2(100,100)) // Vec2
	 * const col = rng.genAny(rgb(0,0,0), rgb(255,255,255)) // Color
	 * ```
	 *
	 * @returns A random value.
	 */
	genAny<T = RNGValue>(...args: [
	] | [
		T
	] | [
		T,
		T
	]): T;
}
/**
 * @group Math
 * @subgroup Shapes
 */
export type ShapeType = Point | Circle | Line | Rect | Polygon | Ellipse;
/**
 * @group Math
 * @subgroup Raycast
 */
export type RaycastHit = {
	fraction: number;
	normal: Vec2;
	point: Vec2;
	gridPos?: Vec2;
	object?: GameObj;
};
/**
 * @group Math
 * @subgroup Raycast
 */
export type RaycastResult = RaycastHit | null;
export declare class Point {
	pt: Vec2;
	constructor(pt: Vec2);
	transform(m: Mat23, s?: Shape): Point;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Point;
	collides(shape: ShapeType): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
export declare class Line {
	p1: Vec2;
	p2: Vec2;
	constructor(p1: Vec2, p2: Vec2);
	transform(m: Mat23, s?: Shape): Line;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Line;
	collides(shape: ShapeType | Vec2): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
/**
 * @group Math
 */
export declare class Rect {
	pos: Vec2;
	width: number;
	height: number;
	constructor(pos: Vec2, width: number, height: number);
	static fromPoints(p1: Vec2, p2: Vec2): Rect;
	center(): Vec2;
	points(): [
		Vec2,
		Vec2,
		Vec2,
		Vec2
	];
	transform(m: Mat23, s?: Shape): Polygon;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Rect;
	distToPoint(p: Vec2): number;
	sdistToPoint(p: Vec2): number;
	collides(shape: ShapeType | Vec2): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
/**
 * @group Math
 */
export declare class Circle {
	center: Vec2;
	radius: number;
	constructor(center: Vec2, radius: number);
	transform(tr: Mat23, s?: Shape): Ellipse;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Circle;
	collides(shape: ShapeType | Vec2): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
/**
 * @group Math
 */
export declare class Ellipse {
	center: Vec2;
	radiusX: number;
	radiusY: number;
	angle: number;
	constructor(center: Vec2, rx: number, ry: number, degrees?: number);
	static fromMat2(tr: Mat2): Ellipse;
	toMat2(): Mat2;
	transform(tr: Mat23): Ellipse;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Ellipse;
	collides(shape: ShapeType): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
/**
 * @group Math
 */
export declare class Polygon {
	pts: Vec2[];
	constructor(pts: Vec2[]);
	transform(m: Mat23, s?: Shape): Polygon;
	bbox(r?: Rect): Rect;
	area(): number;
	clone(): Polygon;
	collides(shape: ShapeType | Vec2): boolean;
	contains(point: Vec2): boolean;
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	random(): Vec2;
	cut(a: Vec2, b: Vec2, srcUv?: Vec2[], dstUv?: [
		Vec2[],
		Vec2[]
	]): [
		Polygon | null,
		Polygon | null
	];
	serialize(): any;
	support(direction: Vec2): Vec2;
	get gjkCenter(): Vec2;
	closestPt(p: Vec2): Vec2 | undefined;
}
/**
 * @group Math
 * @subgroup Tween
 */
export type StepPosition = "jump-start" | "jump-end" | "jump-none" | "jump-both";
/**
 * A serialized 2d vector.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedVec2 {
	x: number;
	y: number;
}
/**
 * A 2D vector.
 *
 * @group Math
 */
export declare class Vec2 {
	/** The x coordinate */
	x: number;
	/** The y coordinate */
	y: number;
	constructor(x?: number, y?: number);
	/** Set the X and Y of this vector */
	set(x: number, y: number): Vec2;
	/** Create a new Vec2 from an angle in degrees */
	static fromAngle(deg: number): Vec2;
	/** Create a new Vec2 from an array */
	static fromArray(arr: Array<number>): Vec2;
	/** An empty vector. (0, 0) */
	static ZERO: Vec2;
	/** A vector with both components of 1. (1, 1) */
	static ONE: Vec2;
	/** A vector signaling to the left. (-1, 0) */
	static LEFT: Vec2;
	/** A vector signaling to the right. (1, 0) */
	static RIGHT: Vec2;
	/** A vector signaling up. (0, -1) */
	static UP: Vec2;
	/** A vector signaling down. (0, 1) */
	static DOWN: Vec2;
	/** Closest orthogonal direction: LEFT, RIGHT, UP, or DOWN */
	toAxis(): Vec2;
	/** Clone the vector */
	clone(): Vec2;
	static copy(v: Vec2, out: Vec2): Vec2;
	/** Returns the sum with another vector. */
	add(...args: Vec2Args): Vec2;
	static addScaled(v: Vec2, other: Vec2, s: number, out: Vec2): Vec2;
	/**
	 * Calculates the sum of the vectors
	 * @param v - The first term
	 * @param x - The x of the second term
	 * @param y - The y of the second term
	 * @param out - The vector sum
	 *
	 * @returns The sum of the vectors
	 */
	static addc(v: Vec2, x: number, y: number, out: Vec2): Vec2;
	/**
	 * Calculates the sum of the vectors
	 * @param v - The first term
	 * @param other - The second term
	 * @param out - The vector sum
	 *
	 * @returns The sum of the vectors
	 */
	static add(v: Vec2, other: Vec2, out: Vec2): Vec2;
	/** Returns the difference with another vector. */
	sub(...args: Vec2Args): Vec2;
	/**
	 * Calculates the difference of the vectors
	 * @param v - The first term
	 * @param x - The x of the second term
	 * @param y - The y of the second term
	 * @param out - The vector difference
	 *
	 * @returns The difference of the vectors
	 */
	static subc(v: Vec2, x: number, y: number, out: Vec2): Vec2;
	/**
	 * Calculates the difference of the vectors
	 * @param v - The first term
	 * @param other - The second term
	 * @param out - The vector difference
	 *
	 * @returns The difference of the vectors
	 */
	static sub(v: Vec2, other: Vec2, out: Vec2): Vec2;
	/** Scale by another vector. or a single number */
	scale(...args: Vec2Args): Vec2;
	/**
	 * Calculates the scale of the vector
	 * @param v - The vector
	 * @param x - The x scale
	 * @param y - The y scale
	 * @param out - The scaled vector
	 *
	 * @returns The scale of the vector
	 */
	static scale(v: Vec2, s: number, out: Vec2): Vec2;
	/**
	 * Calculates the scale of the vector
	 * @param v - The vector
	 * @param x - The x scale
	 * @param y - The y scale
	 * @param out - The scaled vector
	 *
	 * @returns The scale of the vector
	 */
	static scalec(v: Vec2, x: number, y: number, out: Vec2): Vec2;
	/**
	 * Calculates the scale of the vector
	 * @param v - The vector
	 * @param other - The scale
	 * @param out - The scaled vector
	 *
	 * @returns The scale of the vector
	 */
	static scalev(v: Vec2, other: Vec2, out: Vec2): Vec2;
	/** Scale by the inverse of another vector. or a single number */
	invScale(...args: Vec2Args): Vec2;
	/** Get distance between another vector */
	dist(...args: Vec2Args): number;
	/**
	 * Calculates the distance between the vectors
	 * @param v - The vector
	 * @param other - The other vector
	 *
	 * @returns The between the vectors
	 */
	static dist(v: Vec2, other: Vec2): number;
	/** Get squared distance between another vector */
	sdist(...args: Vec2Args): number;
	/**
	 * Calculates the squared distance between the vectors
	 * @param v - The vector
	 * @param other - The other vector
	 *
	 * @returns The distance between the vectors
	 */
	static sdist(v: Vec2, other: Vec2): number;
	/**
	 * Get length of the vector
	 *
	 * @since v3000.0
	 */
	len(): number;
	/**
	 * Calculates the length of the vector
	 * @param v - The vector
	 *
	 * @returns The length of the vector
	 */
	static len(v: Vec2): number;
	/**
	 * Get squared length of the vector
	 *
	 * @since v3000.0
	 */
	slen(): number;
	/**
	 * Calculates the squared length of the vector
	 * @param v - The vector
	 *
	 * @returns The squared length of the vector
	 */
	static slen(v: Vec2): number;
	/**
	 * Get the unit vector (length of 1).
	 */
	unit(): Vec2;
	static unit(v: Vec2, out: Vec2): Vec2;
	/**
	 * Get the perpendicular vector.
	 */
	normal(): Vec2;
	static normal(v: Vec2, out: Vec2): Vec2;
	/**
	 * Get the reflection of a vector with a normal.
	 *
	 * @since v3000.0
	 */
	reflect(normal: Vec2): Vec2;
	/**
	 * Get the projection of a vector onto another vector.
	 *
	 * @since v3000.0
	 */
	project(on: Vec2): Vec2;
	/**
	 * Get the rejection of a vector onto another vector.
	 *
	 * @since v3000.0
	 */
	reject(on: Vec2): Vec2;
	rotate(vecOrAngle: Vec2 | number): Vec2;
	/**
	 * Calculates the rotated vector
	 * @param v - The vector
	 * @param dir - The rotation vector
	 * @param out - The rotated vector
	 *
	 * @returns The rotated vector
	 */
	static rotate(v: Vec2, dir: Vec2, out: Vec2): Vec2;
	/**
	 * Calculates the rotated vector
	 * @param v - The vector
	 * @param angle - The angle in radians
	 * @param out - The rotated vector
	 *
	 * @returns The rotated vector
	 */
	static rotateByAngle(v: Vec2, angle: number, out: Vec2): Vec2;
	invRotate(vecOrAngle: Vec2 | number): Vec2;
	/**
	 * Calculates the inverse rotated vector
	 * @param v - The vector
	 * @param dir - The rotation vector
	 * @param out - The rotated vector
	 *
	 * @returns The rotated vector
	 */
	static inverseRotate(v: Vec2, dir: Vec2, out: Vec2): Vec2;
	/**
	 * Get the dot product with another vector.
	 */
	dot(p2: Vec2): number;
	/**
	 * Get the dot product between 2 vectors.
	 *
	 * @since v3000.0
	 */
	static dot(v: Vec2, other: Vec2): number;
	/**
	 * Get the cross product with another vector.
	 *
	 * @since v3000.0
	 */
	cross(p2: Vec2): number;
	/**
	 * Get the cross product between 2 vectors.
	 *
	 * @since v3000.0
	 */
	static cross(v: Vec2, other: Vec2): number;
	/**
	 * Get the angle of the vector in degrees.
	 */
	angle(...args: Vec2Args): number;
	/**
	 * Calculates the angle represented by the vector in radians
	 * @param v - The vector
	 *
	 * @returns Angle represented by the vector in radians
	 */
	static toAngle(v: Vec2): number;
	/**
	 * Get the angle between this vector and another vector.
	 *
	 * @since v3000.0
	 */
	angleBetween(...args: Vec2Args): number;
	/**
	 * Calculates the angle between the vectors in radians
	 * @param v - First vector
	 * @param other - Second vector
	 *
	 * @returns Angle between the vectors in radians
	 */
	static angleBetween(v: Vec2, other: Vec2): number;
	/**
	 * Linear interpolate to a destination vector (for positions).
	 */
	lerp(dest: Vec2, t: number): Vec2;
	/**
	 * Linear interpolate src and dst by t
	 * @param src - First vector
	 * @param dst - Second vector
	 * @param t - Percentage
	 * @param out - The linear interpolation between src and dst by t
	 *
	 * @returns The linear interpolation between src and dst by t
	 */
	static lerp(src: Vec2, dst: Vec2, t: number, out: Vec2): Vec2;
	/**
	 * Spherical linear interpolate to a destination vector (for rotations).
	 *
	 * @since v3000.0
	 */
	slerp(dest: Vec2, t: number): Vec2;
	/**
	 * Spherical interpolate src and dst by t
	 * @param src - First vector
	 * @param dst - Second vector
	 * @param t - Percentage
	 * @param out - The spherical interpolation between src and dst by t
	 *
	 * @returns The spherical interpolation between src and dst by t
	 */
	static slerp(src: Vec2, dst: Vec2, t: number, out: Vec2): Vec2;
	/**
	 * If the vector (x, y) is zero.
	 *
	 * @since v3000.0
	 */
	isZero(): boolean;
	/**
	 * To n precision floating point.
	 */
	toFixed(n: number): Vec2;
	/**
	 * Multiply by a Mat4.
	 *
	 * @since v3000.0
	 */
	transform(m: Mat4): Vec2;
	/**
	 * See if one vector is equal to another.
	 *
	 * @since v3000.0
	 */
	eq(other: Vec2): boolean;
	/** Converts the vector to a {@link Rect `Rect()`} with the vector as the origin.
	 * @since v3000.0.
	 */
	bbox(): Rect;
	/** Converts the vector to a readable string. */
	toString(): string;
	/** Converts the vector to an array.
	 * @since v3001.0
	 */
	toArray(): Array<number>;
	serialize(): SerializedVec2;
	static deserialize(data: SerializedVec2): Vec2;
}
/**
 * @group Math
 */
export declare class Mat4 {
	m: number[];
	constructor(m?: number[]);
	static translate(p: Vec2): Mat4;
	static scale(s: Vec2): Mat4;
	static rotateX(a: number): Mat4;
	static rotateY(a: number): Mat4;
	static rotateZ(a: number): Mat4;
	translate(p: Vec2): this;
	scale(p: Vec2): this;
	rotate(a: number): Mat4;
	mult(other: Mat4): Mat4;
	multVec2(p: Vec2): Vec2;
	getTranslation(): Vec2;
	getScale(): Vec2;
	getRotation(): number;
	getSkew(): Vec2;
	invert(): Mat4;
	clone(): Mat4;
	toString(): string;
}
/**
 * @group Assets
 * @subgroup Data
 */
export type ShaderData = Shader;
/**
 * Possible values for a shader Uniform.
 *
 * @group Rendering
 * @subgroup Shaders
 */
export type UniformValue = number | Vec2 | Color | Mat4 | Mat23 | number[] | Vec2[] | Color[] | Texture;
/**
 * Possible uniform value, basically any but "u_tex".
 *
 * @group Rendering
 * @subgroup Shaders
 */
export type UniformKey = string;
/**
 * @group Rendering
 * @subgroup Shaders
 */
export type Uniform = Record<UniformKey, UniformValue>;
/**
 * A shader, yeah.
 *
 * @group Rendering
 * @subgroup Shaders
 */
export declare class Shader {
	ctx: GfxCtx;
	glProgram: WebGLProgram;
	constructor(ctx: GfxCtx, vert: string, frag: string, attribs: string[]);
	compile(vert: string, frag: string, attribs: string[]): WebGLProgram;
	bind(): void;
	unbind(): void;
	send(uniform: Uniform): void;
	free(): void;
}
/**
 * @group Draw
 * @subgroup Picture
 */
export type Material = {
	tex?: Texture;
	shader?: Shader;
	uniform?: Uniform;
	blend?: BlendMode;
};
/**
 * @group Draw
 * @subgroup Picture
 */
export type PictureCommand = {
	material: Material;
	index: number;
	count: number;
};
/**
 * A picture holding drawing data
 *
 * @group Draw
 * @subgroup Picture
 */
export declare class Picture {
	vertices: number[];
	indices: number[];
	commands: PictureCommand[];
	mesh?: Mesh;
	/**
	 * Creates an empty picture if no data is given, otherwise deserializes the data
	 * @param data - Optional archived picture data
	 */
	constructor(data?: string);
	/**
	 * Serializes this picture to a JSON string
	 * @returns a string containing JSON picture data
	 */
	archive(): string;
	free(): void;
}
/**
 * Drawing options for drawPicture
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawPictureOpt = RenderProps & {};
export type GfxCtx = ReturnType<typeof initGfx>;
/**
 * @group Rendering
 * @subgroup Canvas
 */
export declare class Texture {
	ctx: GfxCtx;
	src: null | ImageSource;
	glTex: WebGLTexture;
	width: number;
	height: number;
	constructor(ctx: GfxCtx, w: number, h: number, opt?: TextureOpt);
	static fromImage(ctx: GfxCtx, img: ImageSource, opt?: TextureOpt): Texture;
	update(img: ImageSource, x?: number, y?: number): void;
	bind(): void;
	unbind(): void;
	/** Frees up texture memory. Call this once the texture is no longer being used to avoid memory leaks. */
	free(): void;
}
/**
 * @group Rendering
 * @subgroup Shaders
 */
export type VertexFormat = {
	name: string;
	size: number;
}[];
/**
 * @group Rendering
 * @subgroup Canvas
 */
export declare class BatchRenderer {
	ctx: GfxCtx;
	glVBuf: WebGLBuffer;
	glIBuf: WebGLBuffer;
	vqueue: number[];
	iqueue: number[];
	stride: number;
	maxVertices: number;
	maxIndices: number;
	vertexFormat: VertexFormat;
	numDraws: number;
	curPrimitive: GLenum | null;
	curTex: Texture | null;
	curShader: Shader | null;
	curUniform: Uniform | null;
	curBlend: BlendMode;
	curFixed: boolean | undefined;
	picture: Picture | null;
	constructor(ctx: GfxCtx, format: VertexFormat, maxVertices: number, maxIndices: number);
	push(primitive: GLenum, vertices: number[], indices: number[], shader: Shader, tex: (Texture | null) | undefined, uniform: (Uniform | null) | undefined, blend: BlendMode, width: number, height: number, fixed: boolean): void;
	flush(width: number, height: number): void;
	free(): void;
	setBlend(blend: BlendMode): void;
}
/**
 * @group Rendering
 * @subgroup Shaders
 */
export declare class Mesh {
	ctx: GfxCtx;
	glVBuf: WebGLBuffer;
	glIBuf: WebGLBuffer;
	vertexFormat: VertexFormat;
	count: number;
	constructor(ctx: GfxCtx, format: VertexFormat, vertices: number[], indices: number[]);
	draw(primitive?: GLenum, index?: GLuint, count?: GLuint): void;
	free(): void;
}
declare function initGfx(gl: WebGLRenderingContext, opts?: KAPLAYOpt): {
	gl: WebGLRenderingContext;
	opts: KAPLAYOpt;
	onDestroy: (action: () => unknown) => void;
	destroy: () => void;
	pushTexture2D: (item: WebGLTexture) => void;
	popTexture2D: () => void;
	pushArrayBuffer: (item: WebGLBuffer) => void;
	popArrayBuffer: () => void;
	pushElementArrayBuffer: (item: WebGLBuffer) => void;
	popElementArrayBuffer: () => void;
	pushFramebuffer: (item: WebGLFramebuffer) => void;
	popFramebuffer: () => void;
	pushRenderbuffer: (item: WebGLRenderbuffer) => void;
	popRenderbuffer: () => void;
	pushViewport: (item: {
		x: number;
		y: number;
		w: number;
		h: number;
	}) => void;
	popViewport: () => void;
	pushProgram: (item: WebGLProgram) => void;
	popProgram: () => void;
	setVertexFormat: (fmt: VertexFormat) => void;
};
export type Frame = {
	tex: Texture;
	q: Quad;
	id: number;
};
export interface TexMap {
	tex: Texture;
	el: HTMLCanvasElement;
	ctx: CanvasRenderingContext2D;
}
declare class FilterTexPacker {
	private _p;
	private _f;
	private _gfx;
	private _w;
	private _h;
	private _pad;
	_textures: Texture[];
	_big: Frame[];
	_used: Map<number, {
		rect: Rect;
		tex: Texture;
		used: number;
	}>;
	_curMap: TexMap;
	_tex2Map: Map<Texture, TexMap>;
	constructor(_p: TexPacker, _f: TexFilter, _gfx: GfxCtx, _w: number, _h: number, _pad: number);
	private _hasPendingRefresh;
	private _newTexture;
	_sync(): void;
	_single(img: ImageSource): Frame;
	_blit(img: ImageSource, x: number, y: number, chopX: number, chopY: number, imgWidth: number, imgHeight: number): void;
	_add(img: ImageSource, chopQuad: Quad | undefined): Frame;
	_addPrepacked(img: ImageSource, frames: Quad[]): Frame[];
	_free(): void;
	_remove(packerId: number): void;
}
export declare class TexPacker {
	private _gfx;
	private _w;
	private _h;
	private _pad;
	_packers: Partial<Record<string, FilterTexPacker>>;
	_last: number;
	_idsToPackers: Record<number, FilterTexPacker>;
	constructor(_gfx: GfxCtx, _w: number, _h: number, _pad: number);
	_getPacker(filter: TexFilter, name?: string): FilterTexPacker;
	_saveFrame(packer: FilterTexPacker, tex: Texture, quad: Quad): Frame;
	/**
	 * create the default 1x1 white pixel used for primitives at uv = (1, 1) on the nearest filter texture
	 *
	 * must be called prior to initializing anything else, as it doesn't check for
	 * collisions with anything!
	 */
	_createWhitePixel(): Frame;
	add(img: ImageSource, filter: TexFilter, chopQuad?: Quad): Frame;
	addPrepacked(img: ImageSource, filter: TexFilter, frames: Quad[]): Frame[];
	addSingle(img: ImageSource, filter: TexFilter): Frame;
	syncIfPending(): void;
	_remove(id: number): void;
	_free(): void;
}
/**
 * @group Assets
 * @subgroup Types
 */
export interface GfxFont {
	map: Record<string, Frame>;
	size: number;
	filter: TexFilter;
}
/**
 * @group Assets
 * @subgroup Data
 */
export type BitmapFontData = GfxFont;
/**
 * @group Assets
 * @subgroup Types
 */
export interface LoadBitmapFontOpt {
	/**
	 * A string of characters to map to every sprite in the characters grid
	 *
	 * @default " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
	 */
	chars?: string;
	/**
	 * Rasterization filter to use, if different than the global font filter.
	 */
	filter?: TexFilter;
}
/**
 * How the text should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawTextOpt = RenderProps & {
	/**
	 * The text to render.
	 */
	text: string;
	/**
	 * The name of font to use.
	 */
	font?: string | FontData | Asset<FontData> | BitmapFontData | Asset<BitmapFontData>;
	/**
	 * The size of text (the height of each character).
	 */
	size?: number;
	/**
	 * Text alignment (default "left")
	 *
	 * @since v3000.0
	 */
	align?: TextAlign;
	/**
	 * The maximum width. Will wrap word around if exceed.
	 */
	width?: number;
	/**
	 * The gap between each line (only available for bitmap fonts).
	 *
	 * @since v2000.2
	 */
	lineSpacing?: number;
	/**
	 * The gap between each character (only available for bitmap fonts).
	 *
	 * @since v2000.2
	 */
	letterSpacing?: number;
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
	/**
	 * Transform the pos, scale, rotation or color for each character based on the index or char (only available for bitmap fonts).
	 *
	 * @since v2000.1
	 */
	transform?: CharTransform | CharTransformFunc;
	/**
	 * Stylesheet for styled chunks, in the syntax of "this is a [stylename]styled[/stylename] word" (only available for bitmap fonts).
	 *
	 * @since v2000.2
	 */
	styles?: Record<string, CharTransform | CharTransformFunc>;
	/**
	 * If true, any (whitespace) indent on the first line of the paragraph
	 * will be copied to all of the lines for those parts that text-wrap.
	 */
	indentAll?: boolean;
	/**
	 * Locale for text segmentation (e.g., 'hi' for Hindi, 'ar' for Arabic, 'bn' for Bengali).
	 * Helps with proper grapheme cluster detection for complex scripts.
	 * Only used when Intl.Segmenter is available in the browser.
	 *
	 * @since v4000.0
	 */
	locale?: string;
};
/**
 * A function that returns a character transform config. Useful if you're generating dynamic styles.
 *
 * @group Rendering
 * @subgroup Text
 */
export type CharTransformFunc = (idx: number, ch: string, param: string) => CharTransform;
/**
 * Describes how to transform each character.
 *
 * @group Rendering
 * @subgroup Text
 */
export interface CharTransform {
	/**
	 * Offset to apply to the position of the text character.
	 * Shifts the character's position by the specified 2D vector.
	 */
	pos?: Vec2;
	/**
	 * Scale transformation to apply to the text character's current scale.
	 * When a number, it is scaled uniformly.
	 * Given a 2D vector, it is scaled independently along the X and Y axis.
	 */
	scale?: Vec2 | number;
	/**
	 * Skew transformation to skew each of the characters, in degrees of tilt.
	 * When a number, it skews the text to the right as with italic text.
	 * Given a 2D vector, it affects the skew of the horizontal and vertical sides.
	 */
	skew?: Vec2 | number;
	/**
	 * Increases the amount of degrees to rotate the text character.
	 */
	angle?: number;
	/**
	 * Color transformation applied to the text character.
	 * Multiplies the current color with this color.
	 */
	color?: Color;
	/**
	 * Opacity multiplication applied to the text character.
	 * For example, an opacity of 0.4 with 2 set in the transformation, the resulting opacity will be 0.8 (0.4 × 2).
	 */
	opacity?: number;
	/**
	 * If true, the styles applied by this specific {@link DrawTextOpt.styles} entry transform
	 * will override, rather than compose with, the default styles given in {@link DrawTextOpt.transform} and by other
	 * components' styles.
	 */
	override?: boolean;
	/**
	 * If the font for this character should be different from the default font
	 * or the one specified in {@link DrawTextOpt.font}.
	 * Because the font can't be composed like the other properties,
	 * this will override the font even if {@link CharTransform.override} is false.
	 */
	font?: string | FontData;
	/**
	 * If true, characters that have a X scale that is not 1 won't have the bounding box stretched to fit the character,
	 * and may end up overlapping with adjacent characters.
	 *
	 * @default true
	 */
	stretchInPlace?: boolean;
	/**
	 * A name for a shader that will be applied to this character only.
	 */
	shader?: string;
	/**
	 * Values to use for the shader's uniform inputs.
	 * If there is no shader set (by this character's transform or an entire-text
	 * transform), this is not used.
	 */
	uniform?: Uniform;
}
/**
 * How the text should be aligned.
 *
 * @group Rendering
 * @subgroup Text
 */
export type TextAlign = "center" | "left" | "right";
/**
 * @group Assets
 * @subgroup Data
 */
export declare class FontData {
	fontface: FontFace;
	outline: Outline | null;
	size: number;
	filter: TexFilter;
	constructor(fontface: FontFace, opt?: LoadFontOpt);
}
/**
 * Formatted text with info on how and where to render each character.
 *
 * @group Rendering
 * @subgroup Text
 */
export type FormattedText = {
	width: number;
	height: number;
	chars: FormattedChar[];
	opt: DrawTextOpt;
	renderedText: string;
};
/**
 * One formatted character.
 *
 * @group Rendering
 * @subgroup Text
 */
export interface FormattedChar {
	ch: string;
	frame: Frame;
	width: number;
	height: number;
	pos: Vec2;
	scale: Vec2;
	skew: Vec2;
	angle: number;
	color: Color;
	opacity: number;
	font?: string | FontData;
	stretchInPlace: boolean;
	shader?: string;
	uniform?: Uniform;
}
/**
 * @group Rendering
 * @subgroup Text
 */
export type FontAtlas = {
	font: BitmapFontData;
	maxHeight: number;
	outline: Outline | null;
	ascent: number;
	descent: number;
	lineHeight: number;
};
/**
 * @group Rendering
 * @subgroup Text
 */
export type StyledTextInfo = {
	charStyleMap: Record<number, [
		string,
		string
	][]>;
	text: string;
};
/**
 * @group Rendering
 * @subgroup Canvas
 */
export declare class FrameBuffer {
	ctx: GfxCtx;
	tex: Texture;
	glFramebuffer: WebGLFramebuffer;
	glRenderbuffer: WebGLRenderbuffer;
	constructor(ctx: GfxCtx, w: number, h: number, opt?: TextureOpt);
	get width(): number;
	get height(): number;
	toImageData(): ImageData;
	toDataURL(): string;
	clear(): void;
	draw(action: () => void): void;
	bind(): void;
	unbind(): void;
	free(): void;
}
export type AppGfxCtx = {
	/** How many draw calls we're doing last frame */
	lastDrawCalls: number;
	/** Font atlases */
	fontAtlases: Record<string, FontAtlas>;
	/** The graphics context */
	ggl: GfxCtx;
	/** Default shader */
	defShader: Shader;
	whitePixel: Frame;
	/** FrameBuffer */
	frameBuffer: FrameBuffer;
	/** Post Shader, used in postEffect() */
	postShader: string | null;
	postShaderUniform: Uniform | (() => Uniform) | null;
	renderer: BatchRenderer;
	pixelDensity: number;
	transform: Mat23;
	transformStack: Mat23[];
	transformStackIndex: number;
	/** The background texture */
	bgTex: Texture;
	bgColor: Color | null;
	bgAlpha: number;
	/**
	 * The
	 */
	width: number;
	height: number;
	/**
	 * Where the game is rendered.
	 */
	viewport: Viewport;
	fixed: boolean;
	gl: WebGLRenderingContext;
	/**
	 * Scratch vec2
	 */
	scratchPt: Vec2;
};
/**
 * @group Rendering
 * @subgroup Canvas
 */
export type Viewport = {
	x: number;
	y: number;
	width: number;
	height: number;
	scale: number;
};
export declare class SoundData {
	buf: AudioBuffer;
	constructor(buf: AudioBuffer);
	static fromAudioBuffer(buf: AudioBuffer): SoundData;
	static fromArrayBuffer(buf: ArrayBuffer): Promise<SoundData>;
	static fromURL(url: string): Promise<SoundData>;
}
/**
 * How the sprite should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawSpriteOpt = RenderProps & {
	/**
	 * The sprite name in the asset manager, or the raw sprite data.
	 */
	sprite: string | SpriteData | Asset<SpriteData>;
	/**
	 * If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.
	 */
	frame?: number;
	/**
	 * Width of sprite. If `height` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width horizontally.
	 */
	width?: number;
	/**
	 * Height of sprite. If `width` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width vertically.
	 */
	height?: number;
	/**
	 * When set to true, `width` and `height` will not scale the sprite but instead render multiple tiled copies of them until the specified width and height. Useful for background texture pattern etc.
	 */
	tiled?: boolean;
	/**
	 * If flip the texture horizontally.
	 */
	flipX?: boolean;
	/**
	 * If flip the texture vertically.
	 */
	flipY?: boolean;
	/**
	 * The sub-area to render from the texture, by default it'll render the whole `quad(0, 0, 1, 1)`
	 */
	quad?: Quad;
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
	/**
	 * The position
	 */
	pos?: Vec2;
};
/**
 * Frame-based animation configuration.
 *
 * @group Assets
 * @subgroup Types
 */
export type SpriteAnim = number | {
	/**
	 * The starting frame.
	 */
	from?: number;
	/**
	 * The end frame.
	 */
	to?: number;
	/**
	 * If this anim should be played in loop.
	 */
	loop?: boolean;
	/**
	 * When looping should it move back instead of go to start frame again.
	 */
	pingpong?: boolean;
	/**
	 * This anim's speed in frames per second.
	 */
	speed?: number;
	/**
	 * List of frames for the animation.
	 *
	 * If this property exists, **from, to, and pingpong will be ignored**.
	 */
	frames?: number[];
};
/**
 * A dict of name <-> animation.
 *
 * @group Assets
 * @subgroup Types
 */
export type SpriteAnims = Record<string, SpriteAnim>;
/**
 * Sprite loading options.
 *
 * @group Assets
 * @subgroup Types
 */
export interface LoadSpriteOpt {
	/**
	 * If the single image area contains multiple sprites in a grid, how many frames are in the area horizontally.
	 */
	sliceX?: number;
	/**
	 * If the single image area contains multiple sprites arranged in a grid, how many frames are in the area vertically.
	 */
	sliceY?: number;
	/**
	 * 9 slice sprite for proportional scaling.
	 *
	 * @since v3000.0
	 */
	slice9?: NineSlice;
	/**
	 * Individual frames' bounding boxes, if the frames are not in a grid and so sliceX/sliceY won't do.
	 * If present, overrides sliceX and sliceY. If the given sprite source is a list of images, each image is
	 * its own frame, and this is not used.
	 *
	 * Format: x, y, w, and h are in **pixels**
	 *
	 * @since v3000.0
	 */
	frames?: Quad[];
	/**
	 * Animation configuration.
	 */
	anims?: SpriteAnims;
	/**
	 * If the sprite is a single image.
	 */
	singular?: boolean;
	/**
	 * The tex filter to use, if different than the global sprite filter
	 */
	filter?: TexFilter;
	/**
	 * If you've already packed your spritesheet, you can set this to false to tell KAPLAY not to repack it
	 * when loading it into the main texture. However, this may negatively impact rendering performance if
	 * it causes future sprites to not fit and be moved to a different GPU texture.
	 *
	 * This doesn't apply if you use singular: true, because the entire image will be its own texture then.
	 *
	 * @default true
	 */
	repack?: boolean;
}
/**
 * @group Assets
 * @subgroup Types
 */
export type NineSlice = {
	/**
	 * The width of the 9-slice's left column.
	 */
	left: number;
	/**
	 * The width of the 9-slice's right column.
	 */
	right: number;
	/**
	 * The height of the 9-slice's top row.
	 */
	top: number;
	/**
	 * The height of the 9-slice's bottom row.
	 */
	bottom: number;
	/**
	 * How regions should tile when the sprite is scaled.
	 * - `"none"`: All regions stretch (default)
	 * - `"edges"`: Edge regions (top, bottom, left, right) tile, center stretches
	 * - `"center"`: Center region tiles, edges stretch
	 * - `"all"`: Both edges and center tile
	 *
	 * Corners never tile.
	 */
	tileMode?: "none" | "edges" | "center" | "all";
};
/**
 * Possible values for loading an sprite using {@link loadSprite `loadSprite`}.
 *
 * @group Assets
 * @subgroup Types
 */
export type LoadSpriteSrc = string | ImageSource;
export declare class SpriteData {
	frames: Frame[];
	anims: SpriteAnims;
	slice9: NineSlice | null;
	constructor(frames: Frame[], anims?: SpriteAnims, slice9?: NineSlice | null);
	/**
	 * @since v3001.0
	 */
	get width(): number;
	get height(): number;
	static fromSpriteSrc(src: LoadSpriteSrc, opt?: LoadSpriteOpt): Promise<SpriteData>;
	static fromMultiple(data: ImageSource[], opt?: LoadSpriteOpt): SpriteData;
	static fromSingle(data: ImageSource, opt?: LoadSpriteOpt): SpriteData;
}
/**
 * An asset is a resource that is loaded asynchronously.
 *
 * It can be a sprite, a sound, a font, a shader, etc.
 */
export declare class Asset<D> {
	loaded: boolean;
	data: D | null;
	error: Error | null;
	_bucketOnLoad: (() => void) | undefined;
	private onLoadEvents;
	private onErrorEvents;
	private onFinishEvents;
	constructor(loader: Promise<D>);
	static loaded<D>(data: D): Asset<D>;
	onLoad(action: (data: D) => void): this;
	onError(action: (err: Error) => void): this;
	onFinish(action: () => void): this;
	then(action: (data: D) => void): Asset<D>;
	catch(action: (err: Error) => void): Asset<D>;
	finally(action: () => void): Asset<D>;
}
/**
 * @group Assets
 * @subgroup Types
 */
export declare class AssetBucket<D> {
	onGet?: (() => void) | undefined;
	assets: Map<string, Asset<D>>;
	waiters: KEventHandler<any>;
	errorWaiters: KEventHandler<any>;
	lastUID: number;
	constructor(onGet?: (() => void) | undefined);
	add(name: string | null, loader: Promise<D>): Asset<D>;
	addLoaded(name: string | null, data: D): Asset<D>;
	get(handle: string): Asset<D> | undefined;
	progress(): number;
	getFailedAssets(): [
		string,
		Asset<D>
	][];
	waitFor(name: string, timeout: number): PromiseLike<D>;
}
/** @ignore */
export type InternalAssetsCtx = ReturnType<typeof initAssets>;
declare const initAssets: (ggl: GfxCtx, opt: MustKAPLAYOpt, appGfx: AppGfxCtx) => {
	urlPrefix: string;
	sprites: AssetBucket<SpriteData>;
	fonts: AssetBucket<FontData>;
	bitmapFonts: AssetBucket<GfxFont>;
	sounds: AssetBucket<SoundData>;
	shaders: AssetBucket<Shader>;
	custom: AssetBucket<any>;
	prefabAssets: AssetBucket<SerializedGameObj>;
	music: Record<string, string>;
	packer: TexPacker;
	loaded: boolean;
};
/**
 * @group Assets
 * @subgroup Data
 */
export type AsepriteData = {
	frames: Array<{
		frame: {
			x: number;
			y: number;
			w: number;
			h: number;
		};
	}>;
	meta: {
		size: {
			w: number;
			h: number;
		};
		frameTags: Array<{
			name: string;
			from: number;
			to: number;
			direction: "forward" | "reverse" | "pingpong";
		}>;
	};
};
/**
 * @group Assets
 * @subgroup Data
 */
export type SpriteAtlasData = Record<string, SpriteAtlasEntry>;
/**
 * A sprite in a sprite atlas.
 *
 * @group Assets
 * @subgroup Types
 */
export type SpriteAtlasEntry = Omit<LoadSpriteOpt, "repack"> & {
	/**
	 * X position of the top left corner.
	 */
	x: number;
	/**
	 * Y position of the top left corner.
	 */
	y: number;
	/**
	 * Sprite area width.
	 */
	width: number;
	/**
	 * Sprite area height.
	 */
	height: number;
};
/**
 * Audio play configurations.
 *
 * @group Audio
 */
export interface AudioPlayOpt {
	/**
	 * If audio should start out paused.
	 *
	 * @since v3000.0
	 */
	paused?: boolean;
	/**
	 * If audio should be played again from start when its ended.
	 */
	loop?: boolean;
	/**
	 * Volume of audio. 1.0 means full volume, 0.5 means half volume.
	 */
	volume?: number;
	/**
	 * Playback speed. 1.0 means normal playback speed, 2.0 means twice as fast.
	 */
	speed?: number;
	/**
	 * Detune the sound. Every 100 means a semitone.
	 *
	 * @example
	 * ```js
	 * // play a random note in the octave
	 * play("noteC", {
	 *     detune: randi(0, 12) * 100,
	 * })
	 * ```
	 */
	detune?: number;
	/**
	 * The start time, in seconds.
	 */
	seek?: number;
	/**
	 * The stereo pan of the sound.
	 * -1.0 means fully from the left channel, 0.0 means centered, 1.0 means fully right.
	 * Defaults to 0.0.
	 */
	pan?: number;
	/**
	 * If the audio node should start out connected to another audio node rather than
	 * KAPLAY's default volume node. Defaults to undefined, i.e. use KAPLAY's volume node.
	 */
	connectTo?: AudioNode;
}
/**
 * @group Audio
 */
export interface AudioPlay {
	/**
	 * Start playing audio.
	 *
	 * @since v3000.0
	 */
	play(time?: number): void;
	/**
	 * Seek time.
	 *
	 * @since v3000.0
	 */
	seek(time: number): void;
	/**
	 * Stop the sound.
	 *
	 * @since v3001.0
	 */
	stop(): void;
	/**
	 * If the sound is paused.
	 *
	 * @since v2000.1
	 */
	paused: boolean;
	/**
	 * Playback speed of the sound. 1.0 means normal playback speed, 2.0 means twice as fast.
	 */
	speed: number;
	/**
	 * Detune the sound. Every 100 means a semitone.
	 *
	 * @example
	 * ```js
	 * // tune down a semitone
	 * music.detune = -100
	 *
	 * // tune up an octave
	 * music.detune = 1200
	 * ```
	 */
	detune: number;
	/**
	 * Volume of the sound. 1.0 means full volume, 0.5 means half volume.
	 */
	volume: number;
	/**
	 * The stereo pan of the sound.
	 * -1.0 means fully from the left channel, 0.0 means centered, 1.0 means fully right.
	 * Defaults to 0.0.
	 */
	pan?: number;
	/**
	 * If the audio should start again when it ends.
	 */
	loop: boolean;
	/**
	 * The current playing time (not accurate if speed is changed).
	 */
	time(): number;
	/**
	 * The total duration.
	 */
	duration(): number;
	/**
	 * Register an event that runs when audio ends.
	 *
	 * @since v3000.0
	 */
	onEnd(action: () => void): KEventController;
	then(action: () => void): KEventController;
	/**
	 * Disconnect the audio node from whatever it is currently connected to
	 * and connect it to the passed-in audio node, or to Kaplay's default volume node
	 * if no node is passed.
	 */
	connect(node?: AudioNode): void;
}
/** @ignore */
export interface InternalAudioCtx {
	ctx: AudioContext;
	masterNode: GainNode;
}
/**
 * The {@link fakeMouse `fakeMouse()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface FakeMouseComp extends Comp {
	/**
	 * Whether the fake mouse is pressed.
	 */
	get isPressed(): boolean;
	/**
	 * Trigger press (onClick).
	 */
	press(): void;
	/**
	 * Trigger release.
	 */
	release(): void;
	/**
	 * Register an event that runs when the fake mouse performs a click.
	 */
	onPress(action: () => void): void;
	/**
	 * Register an event that runs when the fake mouse releases.
	 */
	onRelease(action: () => void): void;
}
/**
 * Options for the {@link fakeMouse `fakeMouse()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type FakeMouseOpt = {
	/**
	 * Whether the fake mouse should follow the real mouse. Defaults to `true`.
	 */
	followMouse?: boolean;
};
/**
 * @group Timer
 */
export interface TimerController {
	/**
	 * The time left for the callback to be called.
	 */
	timeLeft: number;
	/**
	 * If the event handler is paused.
	 */
	paused: boolean;
	/**
	 * Cancel the event handler.
	 */
	cancel(): void;
	/**
	 * Register an event when finished.
	 */
	onEnd(action: () => void): void;
	then(action: () => void): TimerController;
}
/**
 * Event controller for tween.
 *
 * @group Timer
 */
export interface TweenController extends TimerController {
	/**
	 * The current time in the duration of the tween
	 */
	currentTime: number;
	/**
	 * Finish the tween now and cancel.
	 */
	finish(): void;
}
/**
 * The {@link timer `timer()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface TimerComp extends Comp {
	/**
	 * The maximum number of loops per frame allowed,
	 * to keep loops with sub-frame intervals from freezing the game.
	 */
	maxLoopsPerFrame: number;
	/**
	 * Run the callback after n seconds.
	 */
	wait(time: number, action?: () => void): TimerController;
	/**
	 * Run the callback every n seconds.
	 *
	 * If waitFirst is false (the default), the function will
	 * be called once on the very next frame, and then loop like normal.
	 *
	 * @since v3000.0
	 */
	loop(time: number, action: () => void, maxLoops?: number, waitFirst?: boolean): TimerController;
	/**
	 * Tweeeeen! Note that this doesn't specifically mean tweening on this object's property, this just registers the timer on this object, so the tween will cancel with the object gets destroyed, or paused when obj.paused is true.
	 *
	 * @since v3000.0
	 */
	tween<V extends LerpValue>(from: V, to: V, duration: number, setValue: (value: V) => void, easeFunc?: (t: number) => number): TweenController;
}
/**
 * Collision resolution data.
 *
 * @group Physics
 */
export declare class Collision {
	/**
	 * The first game object in the collision.
	 */
	source: GameObj;
	/**
	 * The second game object in the collision.
	 */
	target: GameObj;
	/**
	 * The contact normal.
	 */
	normal: Vec2;
	/**
	 * The length of the displacement.
	 */
	distance: number;
	/**
	 * If the collision is resolved.
	 */
	resolved: boolean;
	constructor(source: GameObj, target: GameObj, normal: Vec2, distance: number, resolved?: boolean);
	/**
	 * The displacement source game object have to make to avoid the collision.
	 */
	get displacement(): Vec2;
	/**
	 * Get a new collision with reversed source and target relationship.
	 */
	reverse(): Collision;
	/**
	 * If the 2 objects have any overlap, or they're just touching edges.
	 *
	 * @since v3000.0
	 */
	hasOverlap(): boolean;
	/**
	 * If the collision happened (roughly) on the left side.
	 */
	isLeft(): boolean;
	/**
	 * If the collision happened (roughly) on the right side.
	 */
	isRight(): boolean;
	/**
	 * If the collision happened (roughly) on the top side.
	 */
	isTop(): boolean;
	/**
	 * If the collision happened (roughly) on the bottom side.
	 */
	isBottom(): boolean;
	/**
	 * Prevent collision resolution if not yet resolved.
	 *
	 * @since v3000.0
	 */
	preventResolution(): void;
}
/**
 * The {@link area `area()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface AreaComp extends Comp {
	/**
	 * Collider area info.
	 */
	area: {
		/**
		 * If we use a custom shape over render shape.
		 */
		shape: Shape | null;
		/**
		 * Area scale.
		 */
		scale: Vec2;
		/**
		 * Area offset.
		 */
		offset: Vec2;
		/**
		 * Cursor on hover.
		 */
		cursor: Cursor | null;
	};
	/**
	 * If this object should ignore collisions against certain other objects.
	 *
	 * @since v3000.0
	 */
	collisionIgnore: Tag[];
	/**
	 * Restitution ("bounciness") of the object.
	 */
	restitution?: number;
	/**
	 * Friction of the object.
	 */
	friction?: number;
	/**
	 * Whether collision detection should be done even without body.
	 */
	isSensor: boolean;
	/**
	 * If was just clicked on last frame.
	 */
	isClicked(): boolean;
	/**
	 * If is being hovered on.
	 */
	isHovering(): boolean;
	/**
	 * Check collision with another game obj.
	 *
	 * @since v3000.0
	 */
	checkCollision(other: GameObj<AreaComp>): Collision | null;
	/**
	 * Get all collisions currently happening.
	 *
	 * @since v3000.0
	 */
	getCollisions(): Collision[];
	/**
	 * If is currently colliding with another game obj.
	 */
	isColliding(o: GameObj<AreaComp>): boolean;
	/**
	 * If is currently overlapping with another game obj (like isColliding, but will return false if the objects are just touching edges).
	 */
	isOverlapping(o: GameObj<AreaComp>): boolean;
	/**
	 * Returns true if the objects collide in screen space
	 * @param other
	 */
	isVisuallyColliding(other: GameObj<AreaComp>): boolean;
	/**
	 * Register an event runs when clicked.
	 *
	 * @since v2000.1
	 */
	onClick(f: () => void, btn?: MouseButton): KEventController;
	/**
	 * Register an event runs once when hovered.
	 *
	 * @since v3000.0
	 */
	onHover(action: () => void): KEventController;
	/**
	 * Register an event runs every frame when hovered.
	 *
	 * @since v3000.0
	 */
	onHoverUpdate(action: () => void): KEventController;
	/**
	 * Register an event runs once when unhovered.
	 *
	 * @since v3000.0
	 */
	onHoverEnd(action: () => void): KEventController;
	/**
	 * Register an event runs once when collide with another game obj with certain tag.
	 *
	 * @since v2001.0
	 */
	onCollide(tag: Tag, f: (obj: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event runs once when collide with another game obj.
	 *
	 * @since v2000.1
	 */
	onCollide(f: (obj: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event runs every frame when collide with another game obj with certain tag.
	 *
	 * @since v3000.0
	 */
	onCollideUpdate(tag: Tag, f: (obj: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event runs every frame when collide with another game obj.
	 *
	 * @since v3000.0
	 */
	onCollideUpdate(f: (obj: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event runs once when stopped colliding with another game obj with certain tag.
	 *
	 * @since v3000.0
	 */
	onCollideEnd(tag: Tag, f: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event runs once when stopped colliding with another game obj.
	 *
	 * @since v3000.0
	 */
	onCollideEnd(f: (obj: GameObj) => void): void;
	/**
	 * If has a certain point inside collider.
	 */
	hasPoint(p: Vec2): boolean;
	/**
	 * Push out from another solid game obj if currently overlapping.
	 */
	resolveCollision(obj: GameObj): void;
	/**
	 * Get the geometry data for the collider in local coordinate space.
	 *
	 * @since v3000.0
	 */
	localArea(): Shape;
	/**
	 * Get the geometry data for the collider in world coordinate space.
	 */
	worldArea(): Shape;
	/**
	 * Get the bounding box of the geometry data for the collider in world coordinate space.
	 */
	worldBbox(): Rect;
	/**
	 * Get the geometry data for the collider in screen coordinate space.
	 */
	screenArea(): Shape;
	serialize(): any;
}
/**
 * Options for the {@link area `area()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface AreaCompOpt {
	/**
	 * The shape of the area (currently only Rect and Polygon is supported).
	 *
	 * @example
	 * ```js
	 * add([
	 *     sprite("butterfly"),
	 *     pos(100, 200),
	 *     // a triangle shape!
	 *     area({ shape: new Polygon([vec2(0), vec2(100), vec2(-100, 100)]) }),
	 * ])
	 * ```
	 */
	shape?: Shape;
	/**
	 * Area scale.
	 */
	scale?: number | Vec2;
	/**
	 * Area offset.
	 */
	offset?: Vec2;
	/**
	 * Cursor on hover.
	 */
	cursor?: Cursor;
	/**
	 * If this object should ignore collisions against certain other objects.
	 *
	 * @since v3000.0
	 */
	collisionIgnore?: Tag[];
	/**
	 * Bounciness factor between 0 and 1.
	 *
	 * @since v4000.0
	 */
	restitution?: number;
	/**
	 * Friction factor between 0 and 1.
	 *
	 * @since v4000.0
	 */
	friction?: number;
	/**
	 * Whether collision detection should be done even without body.
	 *
	 * @since v4000.0
	 */
	isSensor?: boolean;
}
/**
 * The serialized {@link fixed `fixed()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedFixedComp {
	fixed?: boolean;
}
/**
 * The {@link fixed `fixed()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface FixedComp extends Comp {
	/**
	 * If the obj is unaffected by camera
	 */
	fixed: boolean;
	serialize(): SerializedFixedComp;
}
/**
 * The serialized {@link pos `pos()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedPosComp {
	pos: {
		x: number;
		y: number;
	};
}
/**
 * The {@link pos `pos()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface PosComp extends Comp {
	/**
	 * Object's current world position.
	 */
	pos: Vec2;
	/**
	 * Move how many pixels per second. If object is 'solid', it won't move into other 'solid' objects.
	 */
	move(xVel: number, yVel: number): void;
	move(vel: Vec2): void;
	/**
	 * Move how many pixels, without multiplying dt, but still checking for 'solid'.
	 */
	moveBy(dx: number, dy: number): void;
	moveBy(d: Vec2): void;
	/**
	 * Move to a spot with a speed (pixels per second), teleports if speed is not given.
	 */
	moveTo(dest: Vec2, speed?: number): void;
	moveTo(x: number, y: number, speed?: number): void;
	/**
	 * Get / Set the position of the object on the screen.
	 *
	 * @since v2000.0
	 */
	screenPos: Vec2;
	/**
	 * Get / Set the position of the object relative to the root.
	 *
	 * @since v2000.0
	 */
	worldPos: Vec2;
	/**
	 * Transform a local point (relative to this) to a screen point (relative to the camera)
	 */
	toScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): Vec2;
	/**
	 * Transform a local point (relative to this) to a world point (relative to the root)
	 *
	 * @since v3001.0
	 */
	toWorld(this: GameObj<PosComp>, p: Vec2): Vec2;
	/**
	 * Transform a screen point (relative to the camera) to a local point (relative to this)
	 *
	 * @since v3001.0
	 */
	fromScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): Vec2;
	/**
	 * Transform a world point (relative to the root) to a local point (relative to this)
	 *
	 * @since v3001.0
	 */
	fromWorld(this: GameObj<PosComp>, p: Vec2): Vec2;
	/**
	 * Transform a point relative to this to a point relative to other
	 *
	 * @since v3001.0
	 */
	toOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): Vec2;
	/**
	 * Transform a point relative to other to a point relative to this
	 *
	 * @since v3001.0
	 */
	fromOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): Vec2;
	/**
	 * Serialize the current state comp
	 */
	serialize(): SerializedPosComp;
}
/**
 * @group Plugins
 */
export type System = {
	name: string;
	run: () => void;
	when: SystemPhase[];
};
declare enum SystemPhase {
	BeforeUpdate = 0,
	BeforeFixedUpdate = 1,
	BeforeDraw = 2,
	AfterUpdate = 3,
	AfterFixedUpdate = 4,
	AfterDraw = 5
}
/**
 * Game Object events with their arguments.
 *
 * If looking for use it with `obj.on()`, ignore first parameter (Game Obj)
 *
 * @group Events
 * @subgroup Game Obj
 */
export type GameObjEventMap = {
	/** Triggered every frame */
	update: [
		GameObj
	];
	/** Triggered every frame at a fixed 50fps rate */
	fixedUpdate: [
		GameObj
	];
	/** Triggered every frame before update */
	draw: [
		GameObj
	];
	/** Triggered when object is added */
	add: [
		GameObj
	];
	/** Triggered when object is destroyed */
	destroy: [
		GameObj
	];
	/** Triggered when component is used */
	use: [
		GameObj,
		string
	];
	/** Triggered when component is unused */
	unuse: [
		GameObj,
		string
	];
	/** Triggered when tag is added */
	tag: [
		GameObj,
		string
	];
	/** Triggered when tag is removed */
	untag: [
		GameObj,
		string
	];
	/**
	 * Triggered when an object is clicked.
	 *
	 * From `area()` component.
	 */
	click: [
		GameObj
	];
	/**
	 * Triggered when an object is hovered.
	 *
	 * From `area()` component.
	 */
	hover: [
		GameObj
	];
	/**
	 * Triggered when an object stops being hovered.
	 *
	 * From `area()` component.
	 */
	hoverEnd: [
		GameObj
	];
	/**
	 * Triggered when an object is being hovered.
	 *
	 * From `area()` component.
	 */
	hoverUpdate: [
		GameObj
	];
	/**
	 * Triggered when object collides with another object
	 *
	 * From {@link area `area()`} component
	 */
	collide: [
		GameObj,
		GameObj,
		Collision
	];
	/**
	 * Triggered every frame when object collides with another object
	 *
	 * From {@link area `area()`} component
	 */
	collideUpdate: [
		GameObj,
		GameObj,
		Collision
	];
	/**
	 * Triggered when object stops colliding with another object
	 *
	 * From {@link area `area()`} component
	 */
	collideEnd: [
		GameObj,
		GameObj,
		Collision
	];
	/**
	 * Triggered when object is hurted
	 *
	 * From {@link health `health()`} component
	 */
	hurt: [
		GameObj,
		hurt: number
	];
	/**
	 * Triggered when object is healed
	 *
	 * From {@link health `health()`} component
	 */
	heal: [
		GameObj,
		heal: number
	];
	/**
	 * Triggered when object dies
	 *
	 * From {@link health `health()`} component
	 */
	death: [
		GameObj
	];
	/**
	 * Triggered before physics resolves
	 *
	 * From {@link body `body()`} component
	 */
	beforePhysicsResolve: [
		GameObj,
		col: Collision
	];
	/**
	 * Triggered after physics resolves
	 *
	 * From {@link body `body()`} component
	 */
	physicsResolve: [
		GameObj,
		col: Collision
	];
	/**
	 * Triggered when object is on the ground
	 *
	 * From {@link body `body()`} component
	 */
	ground: [
		GameObj
	];
	/**
	 * Triggered when object is falling
	 *
	 * From {@link body `body()`} component
	 */
	fall: [
		GameObj
	];
	/**
	 * Triggered when object stops falling
	 *
	 * From {@link body `body()`} component
	 */
	fallOff: [
		GameObj
	];
	/**
	 * Triggered when object head butt something (like Mario with brick)
	 *
	 * From {@link body `body()`} component
	 */
	headbutt: [
		GameObj
	];
	/**
	 * Triggered when an object lands on this object
	 *
	 * From {@link body `body()`} component
	 */
	land: [
		GameObj
	];
	/**
	 * Triggered when object is headbutted by another object
	 *
	 * From {@link body `body()`} component
	 */
	headbutted: [
		GameObj
	];
	/**
	 * Triggered when object double jumps
	 *
	 * From {@link doubleJump `doubleJump()`} component
	 */
	doubleJump: [
		GameObj
	];
	/**
	 * Triggered when object goes out of view
	 *
	 * From {@link offscreen `offscreen()`} component
	 */
	exitView: [
		GameObj
	];
	/**
	 * Triggered when object enters view
	 *
	 * From {@link offscreen `offscreen()`} component
	 */
	enterView: [
		GameObj
	];
	/**
	 * Triggered when a sprite animation starts
	 *
	 * From {@link sprite `sprite()`} component
	 */
	animStart: [
		GameObj,
		anim: string
	];
	/**
	 * Triggered when a sprite animation ends
	 *
	 * From {@link sprite `sprite()`} component
	 */
	animEnd: [
		GameObj,
		anim: string
	];
	/**
	 * From {@link agent `agent()`} component
	 */
	navigationNext: [
		GameObj,
		GameObj,
		Vec2
	];
	/**
	 * From {@link agent `agent()`} component
	 */
	navigationEnded: [
		GameObj,
		GameObj
	];
	/**
	 * From {@link agent `agent()`} component
	 */
	navigationStarted: [
		GameObj,
		GameObj
	];
	/**
	 * From {@link agent `agent()`} component
	 */
	targetReached: [
		GameObj,
		GameObj
	];
	/**
	 * From {@link patrol `patrol()`} component
	 */
	patrolFinished: [
		GameObj
	];
	/**
	 * From {@link sentry `sentry()`} component
	 */
	objectSpotted: [
		GameObj,
		GameObj[]
	];
	/**
	 * From {@link animate `animate()`} component
	 */
	animateChannelFinished: [
		GameObj,
		channel: string
	];
	/**
	 * From {@link animate `animate()`} component
	 */
	animateFinished: [
		GameObj
	];
	/**
	 * From level of {@link addLevel `addLevel()`} function
	 */
	spatialMapChanged: [
		GameObj
	];
	/**
	 * From level of {@link addLevel `addLevel()`} function
	 */
	navigationMapInvalid: [
		GameObj
	];
	/**
	 * From level of {@link addLevel `addLevel()`} function
	 */
	navigationMapChanged: [
		GameObj
	];
};
/**
 * @group Events
 * @subgroup Game Obj
 */
export type GameObjEvents = GameObjEventMap & {
	[key: string]: any[];
};
/**
 * @group Events
 * @subgroup Game Obj
 */
export type GameObjEventNames = keyof GameObjEventMap;
/**
 * App events with their arguments
 *
 * @group Events
 */
export type AppEventMap = {
	mouseMove: [
	];
	mouseDown: [
		MouseButton
	];
	mousePress: [
		MouseButton
	];
	mouseRelease: [
		MouseButton
	];
	charInput: [
		string
	];
	keyPress: [
		Key
	];
	keyDown: [
		Key
	];
	keyPressRepeat: [
		Key
	];
	keyRelease: [
		Key
	];
	touchStart: [
		Vec2,
		Touch
	];
	touchMove: [
		Vec2,
		Touch
	];
	touchEnd: [
		Vec2,
		Touch
	];
	gamepadButtonDown: [
		KGamepadButton,
		KGamepad
	];
	gamepadButtonPress: [
		KGamepadButton,
		KGamepad
	];
	gamepadButtonRelease: [
		KGamepadButton,
		KGamepad
	];
	gamepadStick: [
		string,
		Vec2,
		KGamepad
	];
	gamepadConnect: [
		KGamepad
	];
	gamepadDisconnect: [
		KGamepad
	];
	buttonDown: [
		string
	];
	buttonPress: [
		string
	];
	buttonRelease: [
		string
	];
	scroll: [
		Vec2
	];
	hide: [
	];
	show: [
	];
	resize: [
	];
	input: [
	];
	update: [
	];
	fixedUpdate: [
	];
	frameEnd: [
	];
	draw: [
	];
};
/**
 * All Game State events with their arguments
 *
 * @group Events
 */
export type GameEventMap = {
	load: [
	];
	loadError: [
		string,
		Asset<any>
	];
	loading: [
		number
	];
	error: [
		Error
	];
	sceneLeave: [
		string
	];
	sceneEnter: [
		string
	];
};
/**
 * The function definition for a scene
 *
 * @group Scenes
 * @subgroup Types
 */
export type SceneDef = (...args: any) => void;
/**
 * The state of a scene.
 *
 * @group Scenes
 * @subgroup Types
 */
export type SceneState = {
	sceneID: string | null;
	args: unknown[];
};
/**
 * The "Game" it's all the state related to the game running
 */
export type Game = {
	/**
	 * The last game object id used.
	 */
	gameObjLastId: number;
	/**
	 * Game global events.
	 */
	events: KEventHandler<GameEventMap>;
	/**
	 * Where game object global events are stored.
	 */
	gameObjEvents: KEventHandler<GameObjEventMap>;
	/**
	 * Event Handlers that are cancelled on scene change.
	 */
	sceneEvents: KEventController[];
	/**
	 * The root game object, parent of all game objects.
	 */
	root: GameObj<TimerComp>;
	/**
	 * The gravity vector of the game.
	 */
	gravity: Vec2 | null;
	/**
	 * The scenes of the game.
	 */
	scenes: Record<string, SceneDef>;
	/**
	 * The scene stack that stores the scene states
	 */
	sceneStack: Array<SceneState>;
	/**
	 * The current active scene arguments
	 */
	currentSceneArgs: unknown[];
	/**
	 * The current scene of the game.
	 */
	currentScene: string | null;
	/**
	 * The layers of the game.
	 */
	layers: string[] | null;
	/**
	 * The default layer index of the game.
	 */
	defaultLayerIndex: number;
	/**
	 * All systems added to the game.
	 */
	systems: System[];
	/**
	 * The systems added to the game, sorted by event.
	 */
	systemsByEvent: [
		System[],
		System[],
		System[],
		System[],
		System[],
		System[]
	];
	defaultAssets: {
		ka?: Asset<SpriteData>;
		boom?: Asset<SpriteData>;
		burp?: SoundData;
		happy?: string;
		bean?: string;
	};
	logs: DebugLog[];
	cam: CamData;
	/**
	 * The default RNG used by rng functions.
	 */
	defRNG: RNG;
	/**
	 * If game just crashed.
	 */
	crashed: boolean;
	/**
	 * How many areas are in the game.
	 */
	areaCount: number;
	/**
	 * Fake Mouse game obj.
	 */
	fakeMouse: GameObj<FakeMouseComp | PosComp> | null;
	/** */
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
	/**
	 * All text inputs in the game.
	 */
	allTextInputs: Set<GameObj>;
	/**
	 * Deprecated functions we already warned about.
	 */
	warned: Set<string>;
};
/**
 * @group Rendering
 * @subgroup Camera
 */
export type CamData = {
	pos: Vec2 | null;
	scale: Vec2;
	angle: number;
	shake: number;
	transform: Mat23;
};
/**
 * A frame renderer.
 *
 * @ignore
 */
export interface FrameRenderer {
	frameStart: () => void;
	frameEnd: () => void;
	fixedUpdateFrame: () => void;
	updateFrame: () => void;
}
/**
 * Screen recording control handle.
 *
 * @group Data
 */
export interface Recording {
	/**
	 * Pause the recording.
	 */
	pause(): void;
	/**
	 * Resume the recording.
	 */
	resume(): void;
	/**
	 * Stop the recording and get the video data as a Blob. This
	 * finalizes the recording, so trying to do anything else with it
	 * later will throw an error.
	 *
	 * @since v3000.0
	 */
	stop(): Promise<Blob>;
	/**
	 * Stop the recording and downloads the file. Like `stop()`, this finalizes
	 * the recording, and trying to do anything else with it later will throw
	 * an error.
	 *
	 * @param filename - The suggested file name to initially present to the player
	 * (they can always change it in their browser's save dialog). If none is specified
	 * the format is 'kaplay-{current date and time}.{file extension}'.
	 */
	download(filename?: string): void;
	/**
	 * The currently used MIME type that was selected when the recording was
	 * started.
	 */
	readonly mimeType: string;
	/**
	 * The recommended file extension for the output file, minus the dot. For
	 * MP4 this will be `"mp4"`, for WEBM, `"webm"`, etc.
	 *
	 * This value is calculated using the MIME type and so it might be wrong.
	 * For example if you're in Safari and manage to get a recording started using
	 * the `video/quicktime` format, this property will report `"quicktime"`, even
	 * though the correct file extension is `.mov`.
	 */
	readonly fileExt: string;
}
/**
 * Available debugging message styles.
 *
 * @group Debug
 */
export type DebugLogStyle = "info" | "warn" | "error";
/**
 * Acceptable values for debugging message.
 *
 * @group Debug
 */
export type DebugMessage = string | {
	toString(): string;
} | Error;
/**
 * @group Debug
 */
export type DebugLog = {
	msg: DebugMessage;
	time: number;
	style: DebugLogStyle;
};
/**
 * An interface for debugging the game.
 *
 * @group Debug
 */
export interface Debug {
	/**
	 * Pause the whole game.
	 */
	paused: boolean;
	/**
	 * Draw bounding boxes of all objects with `area()` component, hover to inspect their states.
	 */
	inspect: boolean;
	/**
	 * Global time scale.
	 */
	timeScale: number;
	/**
	 * Show the debug log or not.
	 */
	showLog: boolean;
	/**
	 * Current frames per second, that the game is running using
	 * (may be limited by the `maxFPS` or `maxTimeStep` options)
	 */
	fps(): number;
	/**
	 * Raw frames per second from the browser unaffected by
	 * the `maxFPS` or `maxTimeStep` options.
	 */
	rawFPS(): number;
	/**
	 * Total number of frames elapsed.
	 *
	 * @since v3000.0
	 */
	numFrames(): number;
	/**
	 * Number of draw calls made last frame.
	 */
	drawCalls(): number;
	/**
	 * Step to the next frame. Useful with pausing.
	 */
	stepFrame(): void;
	/**
	 * Clear the debug log.
	 */
	clearLog(): void;
	/**
	 * Log a message to the on-screen debug log, with optional
	 * style wrapping.
	 *
	 * @param message - The messages to log
	 * @param wrapStyle - Style to wrap all messages
	 *
	 * @example
	 * ```
	 * debug.logMessage(["oh", "hi"], "warn");
	 * ```
	 *
	 * @since v4000.0
	 */
	logMessage(message: DebugMessage[], wrapStyle?: DebugLogStyle): void;
	/**
	 * Log a message with the info style (white) to the on-screen debug log.
	 *
	 * @param message - The message to log
	 *
	 * @example
	 * ```
	 * debug.log("oh", "hi")
	 * ```
	 */
	log(...message: DebugMessage[]): void;
	/**
	 * Log a message with the warn style (yellow) to the on-screen debug log.
	 *
	 * @param message - The message to log
	 *
	 * @example
	 * ```
	 * debug.warn("oh", "humm")
	 * ```
	 *
	 * @since v4000.0
	 */
	warn(...message: DebugMessage[]): void;
	/**
	 * Log a message with the error style (pink since kaboom) to the on-screen debug log.
	 *
	 * @param message - The message to log
	 *
	 * @example
	 * ```
	 * debug.error("oh", "no")
	 * ```
	 */
	error(...message: DebugMessage[]): void;
	/**
	 * The recording handle if currently in recording mode.
	 *
	 * @since v2000.1
	 */
	curRecording: Recording | null;
	/**
	 * Get total number of objects.
	 *
	 * @since v3001.0
	 */
	numObjects(): number;
}
/**
 * The serialized {@link blend `blend()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedBlendComp {
	blend: BlendMode;
}
/**
 * The {@link blend `blend()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface BlendComp extends Comp {
	blend: BlendMode;
	serialize(): SerializedBlendComp;
}
/**
 * The serialized {@link circle `circle()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedCircleComp {
	radius: number;
	fill?: boolean;
}
/**
 * The {@link circle `circle()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface CircleComp extends Comp {
	draw: Comp["draw"];
	/** Radius of circle. */
	radius: number;
	/**
	 * Render area of the circle.
	 *
	 * @since v3000.0
	 */
	renderArea(): Circle;
	serialize(): SerializedCircleComp;
}
/**
 * Options for the {@link circle `circle()``} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface CircleCompOpt {
	/**
	 * If fill the circle (useful if you only want to render outline with
	 * {@link outline `outline()`} component).
	 */
	fill?: boolean;
}
/**
 * The serialized {@link color `color()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedColorComp {
	color: {
		r: number;
		g: number;
		b: number;
	};
}
/**
 * The {@link color `color()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface ColorComp extends Comp {
	color: Color;
	serialize(): SerializedColorComp;
}
/**
 * Options for the {@link drawon `drawon()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type DrawonCompOpt = {
	childrenOnly?: boolean;
	refreshOnly?: boolean;
};
/**
 * The {@link drawon `drawon()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface DrawonComp extends Comp {
	refresh(): void;
}
/**
 * The serialized {@link ellipse `ellipse()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedEllipseComp {
	radiusX: number;
	radiusY: number;
	fill?: boolean;
}
/**
 * The {@link ellipse `ellipse()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface EllipseComp extends Comp {
	draw: Comp["draw"];
	/** Semi-major axis of ellipse. */
	radiusX: number;
	/** Semi-minor axis of ellipse. */
	radiusY: number;
	/**
	 * Render area of the ellipse.
	 */
	renderArea(): Ellipse;
	serialize(): SerializedEllipseComp;
}
/**
 * Options for the {@link ellipse `ellipse()``} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface EllipseCompOpt {
	/**
	 * If fill is false, the ellipse is not filled (useful if you only want to render outline with
	 * {@link outline `outline()`} component).
	 */
	fill?: boolean;
}
/**
 * The serialized {@link fill `fill()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedFillComp {
	fill?: boolean;
}
/**
 * The {@link fill `fill()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface FillComp extends Comp {
	/**
	 * If the obj is unaffected by camera
	 */
	fill: boolean;
	serialize(): SerializedFillComp;
}
/**
 * The serialized {@link mask `mask()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedMaskComp {
	mask: Mask;
}
/**
 * The {@link mask `mask()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface MaskComp extends Comp {
	mask: Mask;
	serialize(): SerializedMaskComp;
}
/**
 * The list of easing functions available.
 *
 * @group Math
 * @subgroup Tween
 */
export type EaseFuncs = "linear" | "easeInSine" | "easeOutSine" | "easeInOutSine" | "easeInQuad" | "easeOutQuad" | "easeInOutQuad" | "easeInCubic" | "easeOutCubic" | "easeInOutCubic" | "easeInQuart" | "easeOutQuart" | "easeInOutQuart" | "easeInQuint" | "easeOutQuint" | "easeInOutQuint" | "easeInExpo" | "easeOutExpo" | "easeInOutExpo" | "easeInCirc" | "easeOutCirc" | "easeInOutCirc" | "easeInBack" | "easeOutBack" | "easeInOutBack" | "easeInElastic" | "easeOutElastic" | "easeInOutElastic" | "easeInBounce" | "easeOutBounce" | "easeInOutBounce";
/**
 * A function that takes a time value and returns a new time value.
 *
 * @group Math
 * @subgroup Tween
 */
export type EaseFunc = (t: number) => number;
/**
 * The serialized {@link opacity `opacity()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedOpacityComp {
	opacity: number;
}
/**
 * The {@link opacity `opacity()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface OpacityComp extends Comp {
	/** Opacity of the current object. */
	opacity: number;
	/** Fade in at the start. */
	fadeIn(time?: number, easeFunc?: EaseFunc): TweenController;
	/** Fade out at the start. */
	fadeOut(time?: number, easeFunc?: EaseFunc): TweenController;
	serialize(): SerializedOpacityComp;
}
/**
 * How the line should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawLineOpt = Omit<RenderProps, "angle" | "scale"> & {
	/**
	 * Starting point of the line.
	 */
	p1: Vec2;
	/**
	 * Ending point of the line.
	 */
	p2: Vec2;
	/**
	 * The width, or thickness of the line,
	 */
	width?: number;
};
export type LineJoin = "none" | "round" | "bevel" | "miter";
export type LineCap = "butt" | "round" | "square";
/**
 * How the lines should look like.
 */
export type DrawLinesOpt = Omit<RenderProps, "angle" | "scale"> & {
	/**
	 * The points that should be connected with a line.
	 */
	pts: Vec2[];
	/**
	 * The width, or thickness of the lines,
	 */
	width?: number;
	/**
	 * The radius of each corner.
	 */
	radius?: number | number[];
	/**
	 * Line join style (default "none").
	 */
	join?: LineJoin;
	/**
	 * Line cap style (default "none").
	 */
	cap?: LineCap;
	/**
	 * Line bias, the position of the line relative to its center (default 0).
	 */
	bias?: number;
	/**
	 * Maximum miter length, anything longer becomes bevel.
	 */
	miterLimit?: number;
};
/**
 * The serialized {@link outline `outline()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedOutlineComp {
	outline: {
		width: number;
		color: SerializedColor;
		opacity: number;
		join: LineJoin;
		miterLimit: number;
		cap: LineCap;
	};
}
/**
 * The {@link outline `outline()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface OutlineComp extends Comp {
	outline: Outline;
	serialize(): SerializedOutlineComp;
}
/**
 * Options for the {@link particles `particles()`}'s component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type EmitterOpt = {
	/**
	 * Shape of the emitter. If given, particles spawn within this shape.
	 */
	shape?: ShapeType;
	/**
	 * Lifetime of the emitter.
	 */
	lifetime?: number;
	/**
	 * Rate of emission in particles per second if the emitter should emit out of itself.
	 */
	rate?: number;
	/**
	 * Position (relative) of emission.
	 */
	position: Vec2;
	/**
	 * Direction of emission.
	 */
	direction: number;
	/**
	 * Spread (cone) of emission around the direction.
	 */
	spread: number;
};
/**
 * Options for the {@link particles `particles()`}'s component
 *
 * @group Components
 * @subgroup Component Types
 */
export type ParticlesOpt = {
	/**
	 * Maximum number of simultaneously rendered particles.
	 */
	max: number;
	/**
	 * Minimum and maximum lifetime of a particle in seconds.
	 */
	lifeTime?: [
		number,
		number
	];
	/**
	 * Minimum and maximum speed of a particle in pixels per second.
	 */
	speed?: [
		number,
		number
	];
	/**
	 * Minimum and maximum acceleration of a particle in pixels per second^2.
	 */
	acceleration?: [
		Vec2,
		Vec2
	];
	/**
	 * Minimum and maximum damping of a particle.
	 */
	damping?: [
		number,
		number
	];
	/**
	 * Minimum and maximum start angle of a particle.
	 */
	angle?: [
		number,
		number
	];
	/**
	 * Minimum and maximum angular velocity of a particle.
	 */
	angularVelocity?: [
		number,
		number
	];
	/**
	 * Scale from start to end for a particle.
	 */
	scales?: number[] | Vec2[];
	/**
	 * Colors from start to end for a particle.
	 */
	colors?: Color[];
	/**
	 * Opacity from start to end for a particle.
	 */
	opacities?: number[];
	/**
	 * Quads from start to end for a particle.
	 */
	quads?: Quad[];
	/**
	 * Texture used for the particle.
	 */
	texture: Texture;
};
/**
 * The {@link particles `particles()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface ParticlesComp extends Comp {
	emitter: {
		/**
		 * Relative position of the emitter
		 */
		position: Vec2;
		/**
		 * Relative direction of the emitter
		 */
		direction: number;
	};
	/**
	 * Emit a number of particles
	 */
	emit(n: number): void;
	/**
	 * Called when the emitter expires
	 */
	onEnd(cb: () => void): void;
}
/**
 * The {@link picture `picture()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface PictureComp extends Comp {
	picture: Picture;
}
/**
 * Options for the {@link picture `picture()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type PictureCompOpt = {
	picture: Picture;
};
/**
 * How the polygon should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawPolygonOpt = RenderProps & {
	/**
	 * The points that make up the polygon
	 */
	pts: Vec2[];
	/**
	 * If fill the shape with color (set this to false if you only want an outline).
	 */
	fill?: boolean;
	/**
	 * Manual triangulation.
	 */
	indices?: number[];
	/**
	 * The center point of transformation in relation to the position.
	 */
	offset?: Vec2;
	/**
	 * The radius of each corner.
	 */
	radius?: number | number[];
	/**
	 * The color of each vertex.
	 *
	 * @since v3000.0
	 */
	colors?: Color[];
	/**
	 * The opacity of each vertex.
	 *
	 * @since v4000.0
	 */
	opacities?: number[];
	/**
	 * The uv of each vertex.
	 *
	 * @since v3001.0
	 */
	uv?: Vec2[];
	/**
	 * The texture if uv are supplied.
	 *
	 * @since v3001.0
	 */
	tex?: Texture;
	/**
	 * Triangulate concave polygons.
	 *
	 * @since v3001.0
	 */
	triangulate?: boolean;
};
/**
 * The {@link polygon `polygon()`} component.
 *
 * @since v3001.0
 * @group Components
 * @subgroup Component Types
 */
export interface PolygonComp extends Comp {
	draw: Comp["draw"];
	/**
	 * Points in the polygon.
	 */
	pts: Vec2[];
	/**
	 * The radius of each corner.
	 */
	radius?: number | number[];
	/**
	 * The color of each vertex.
	 */
	colors?: Color[];
	/**
	 * The opacity of each vertex.
	 */
	opacities?: number[];
	/**
	 * The uv of each vertex.
	 *
	 * @since v3001.0
	 */
	uv?: Vec2[];
	/**
	 * The texture used when uv coordinates are present.
	 *
	 * @since v3001.0
	 */
	tex?: Texture;
	renderArea(): Polygon;
}
/**
 * Options for the {@link polygon `polygon()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type PolygonCompOpt = Omit<DrawPolygonOpt, "pts">;
/**
 * The serialized {@link rect `rect()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedRectComp {
	width: number;
	height: number;
	radius?: number | [
		number,
		number,
		number,
		number
	];
	fill?: boolean;
}
/**
 * The {@link rect `rect()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface RectComp extends Comp {
	draw: Comp["draw"];
	/**
	 * Width of rectangle.
	 */
	width: number;
	/**
	 * Height of rectangle.
	 */
	height: number;
	/**
	 * The radius of each corner.
	 */
	radius?: number | [
		number,
		number,
		number,
		number
	];
	/**
	 * @since v3000.0
	 */
	renderArea(): Rect;
	serialize(): SerializedRectComp;
}
/**
 * Options for the {@link rect `rect()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface RectCompOpt {
	/**
	 * Radius of the rectangle corners.
	 */
	radius?: number | [
		number,
		number,
		number,
		number
	];
	/**
	 * If fill the rectangle (useful if you only want to render outline with outline() component).
	 */
	fill?: boolean;
}
/**
 * The serialized {@link shader `shader()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializeShaderComp {
	shader: string;
}
/**
 * The {@link shader `shader()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface ShaderComp extends Comp {
	/**
	 * Uniform values to pass to the shader.
	 */
	uniform?: Uniform;
	/**
	 * The shader ID.
	 */
	shader: string;
	serialize(): SerializeShaderComp;
}
/**
 * The serialized {@link sprite `sprite()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export type SerializedSpriteComp = SpriteCompOpt & {
	sprite: string;
};
/**
 * Current animation data.
 */
export interface SpriteCurAnim {
	name: string;
	timer: number;
	loop: boolean;
	speed: number;
	/**
	 * The current index relative to the start of the
	 * associated `frames` array for this animation.
	 * This may be greater than the number of frames
	 * in the sprite.
	 */
	frameIndex: number;
	pingpong: boolean;
	onEnd: () => void;
}
/**
 * The {@link sprite `sprite()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SpriteComp extends Comp {
	draw: Comp["draw"];
	/**
	 * Name of the sprite.
	 */
	sprite: string;
	/**
	 * Width for sprite.
	 */
	width: number;
	/**
	 * Height for sprite.
	 */
	height: number;
	/**
	 * Current frame in the entire spritesheet.
	 */
	frame: number;
	/**
	 * Current frame in relative to the animation that is currently playing.
	 */
	animFrame: number;
	/**
	 * The rectangular area of the texture to render.
	 */
	quad: Quad;
	/**
	 * Play a piece of anim.
	 */
	play(anim: string, options?: SpriteAnimPlayOpt): void;
	/**
	 * Stop current anim.
	 */
	stop(): void;
	/**
	 * Get total number of frames.
	 */
	numFrames(): number;
	/**
	 * Get the current animation data.
	 *
	 * @since v3001.0
	 */
	getCurAnim(): SpriteCurAnim | null;
	/**
	 * Get current anim name.
	 *
	 * @deprecated Use `getCurAnim().name` instead.
	 */
	curAnim(): string | undefined;
	/**
	 * Check if object's sprite has an animation.
	 */
	hasAnim(name: string): boolean;
	/**
	 * Get an animation.
	 */
	getAnim(name: string): SpriteAnim | null;
	/**
	 * Speed multiplier for all animations (for the actual fps for an anim use .play("anim", { speed: 10 })).
	 */
	animSpeed: number;
	/**
	 * Flip texture horizontally.
	 */
	flipX: boolean;
	/**
	 * Flip texture vertically.
	 */
	flipY: boolean;
	/**
	 * Register an event that runs when an animation is played.
	 */
	onAnimStart(action: (anim: string) => void): KEventController;
	/**
	 * Register an event that runs when an animation is ended.
	 */
	onAnimEnd(action: (anim: string) => void): KEventController;
	/**
	 * @since v3000.0
	 */
	renderArea(): Rect;
	serialize(): SerializedSpriteComp;
}
/**
 * Options for the {@link sprite `sprite()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SpriteCompOpt {
	/**
	 * If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.
	 */
	frame?: number;
	/**
	 * If provided width and height, don't stretch but instead render tiled.
	 */
	tiled?: boolean;
	/**
	 * Stretch sprite to a certain width.
	 */
	width?: number;
	/**
	 * Stretch sprite to a certain height.
	 */
	height?: number;
	/**
	 * Play an animation on start.
	 */
	anim?: string;
	/**
	 * Speed multiplier for all animations (for the actual fps for an anim use .play("anim", { speed: 10 })).
	 */
	animSpeed?: number;
	/**
	 * Flip texture horizontally.
	 */
	flipX?: boolean;
	/**
	 * Flip texture vertically.
	 */
	flipY?: boolean;
	/**
	 * The rectangular sub-area of the texture to render, default to full texture `quad(0, 0, 1, 1)`.
	 */
	quad?: Quad;
	/**
	 * If fill the sprite (useful if you only want to render outline with outline() component).
	 */
	fill?: boolean;
}
/**
 * The serialized {@link text `text()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedTextComp {
	text: string;
	size?: number;
	font?: string;
	width?: number;
	align?: TextAlign;
	lineSpacing?: number;
	letterSpacing?: number;
	indentAll?: boolean;
}
/**
 * The {@link text `text()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface TextComp extends Comp {
	draw: Comp["draw"];
	/**
	 * The text to render.
	 */
	text: string;
	/**
	 * The text size.
	 */
	textSize: number;
	/**
	 * The font to use.
	 */
	font: string | BitmapFontData;
	/**
	 * Width of text.
	 */
	width: number;
	/**
	 * Height of text.
	 */
	height: number;
	/**
	 * Text alignment ("left", "center" or "right", default "left").
	 *
	 * @since v3000.0
	 */
	align: TextAlign;
	/**
	 * The gap between each line.
	 *
	 * @since v2000.2
	 */
	lineSpacing: number;
	/**
	 * The gap between each character.
	 *
	 * @since v2000.2
	 */
	letterSpacing: number;
	/**
	 * Transform the pos, scale, rotation or color for each character based on the index or char.
	 *
	 * @since v2000.1
	 */
	textTransform: CharTransform | CharTransformFunc;
	/**
	 * Stylesheet for styled chunks, in the syntax of "this is a [style]text[/style] word".
	 *
	 * @since v2000.2
	 */
	textStyles: Record<string, CharTransform | CharTransformFunc>;
	/**
	 * @since v3000.0
	 */
	renderArea(): Rect;
	_renderAreaVersion: number;
	/**
	 * The text data object after formatting, that contains the
	 * renering info as well as the parse data of the formatting tags.
	 */
	formattedText(): FormattedText;
	serialize(): SerializedTextComp;
}
/**
 * Options for the {@link text `text()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface TextCompOpt {
	/**
	 * Height of text.
	 */
	size?: number;
	/**
	 * The font to use.
	 */
	font?: string | BitmapFontData;
	/**
	 * Wrap text to a certain width.
	 */
	width?: number;
	/**
	 * Text alignment ("left", "center" or "right", default "left").
	 *
	 * @since v3000.0
	 */
	align?: TextAlign;
	/**
	 * The gap between each line.
	 *
	 * @since v2000.2
	 */
	lineSpacing?: number;
	/**
	 * The gap between each character.
	 *
	 * @since v2000.2
	 */
	letterSpacing?: number;
	/**
	 * Transform the pos, scale, rotation or color for each character based on the index or char.
	 *
	 * @since v2000.1
	 */
	transform?: CharTransform | CharTransformFunc;
	/**
	 * Stylesheet for styled chunks, in the syntax of "this is a [style]text[/style] word".
	 *
	 * @since v2000.2
	 */
	styles?: Record<string, CharTransform | CharTransformFunc>;
	/**
	 * If true, any (whitespace) indent on the first line of the paragraph
	 * will be copied to all of the lines for those parts that text-wrap.
	 */
	indentAll?: boolean;
}
/**
 * The {@link uvquad `uvquad()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface UVQuadComp extends Comp {
	draw: Comp["draw"];
	/**
	 * Width of rect.
	 */
	width: number;
	/**
	 * Height of height.
	 */
	height: number;
	/**
	 * @since v3000.0
	 */
	renderArea(): Rect;
}
export interface VideoComp extends Comp {
	width: number;
	height: number;
	currentTime: number;
	duration: number;
	play(): void;
	pause(): void;
	mute: boolean;
	renderArea(): Rect;
}
export type VideoCompOpt = {
	width: number;
	height: number;
};
/**
 * The {@link agent `agent()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface AgentComp extends Comp {
	agentSpeed: number;
	allowDiagonals: boolean;
	getDistanceToTarget(): number;
	getNextLocation(): Vec2 | null;
	getPath(): Vec2[] | null;
	getTarget(): Vec2 | null;
	isNavigationFinished(): boolean;
	isTargetReachable(): boolean;
	isTargetReached(): boolean;
	setTarget(target: Vec2): void;
	onNavigationStarted(cb: () => void): KEventController;
	onNavigationNext(cb: () => void): KEventController;
	onNavigationEnded(cb: () => void): KEventController;
	onTargetReached(cb: () => void): KEventController;
}
/**
 * Options for the {@link agent `agent()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type AgentCompOpt = {
	speed?: number;
	allowDiagonals?: boolean;
};
/**
 * The {@link level `level()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface LevelComp extends Comp {
	tileWidth(): number;
	tileHeight(): number;
	numRows(): number;
	numColumns(): number;
	/**
	 * Spawn a tile from a symbol defined previously.
	 */
	spawn(sym: string, p: Vec2): GameObj | null;
	spawn(sym: string, x: number, y: number): GameObj | null;
	/**
	 * Spawn a tile from a component list.
	 *
	 * @returns The spawned game object, or null if the obj hasn't components.
	 */
	spawn<T>(obj: CompList<T>, p: Vec2): GameObj<T> | null;
	spawn<T>(sym: CompList<T>, x: number, y: number): GameObj<T> | null;
	/**
	 * Total width of level in pixels.
	 */
	levelWidth(): number;
	/**
	 * Total height of level in pixels.
	 */
	levelHeight(): number;
	/**
	 * Get all game objects that's currently inside a given tile.
	 */
	getAt(tilePos: Vec2): GameObj[];
	/**
	 * Raycast all game objects on the given path.
	 */
	raycast(origin: Vec2, direction: Vec2): RaycastResult;
	/**
	 * Convert tile position to pixel position.
	 */
	tile2Pos(tilePos: Vec2): Vec2;
	tile2Pos(x: number, y: number): Vec2;
	/**
	 * Convert pixel position to tile position.
	 */
	pos2Tile(pos: Vec2): Vec2;
	pos2Tile(x: number, y: number): Vec2;
	/**
	 * Find the path to navigate from one tile to another tile.
	 *
	 * @returns A list of traverse points in tile positions.
	 */
	getTilePath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null;
	/**
	 * Find the path to navigate from one tile to another tile.
	 *
	 * @returns A list of traverse points in pixel positions.
	 */
	getPath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null;
	getSpatialMap(): GameObj[][];
	removeFromSpatialMap(obj: GameObj): void;
	insertIntoSpatialMap(obj: GameObj): void;
	onSpatialMapChanged(cb: () => void): KEventController;
	onNavigationMapInvalid(cb: () => void): KEventController;
	invalidateNavigationMap(): void;
	onNavigationMapChanged(cb: () => void): KEventController;
	serialize(): any;
}
/**
 * Options for the {@link level `level()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface LevelCompOpt {
	/**
	 * Width of each block.
	 */
	tileWidth: number;
	/**
	 * Height of each block.
	 */
	tileHeight: number;
	/**
	 * Definition of each tile.
	 */
	tiles: {
		[sym: string]: (pos: Vec2) => CompList<Comp>;
	};
	/**
	 * Called when encountered a symbol not defined in "tiles".
	 */
	wildcardTile?: (sym: string, pos: Vec2) => CompList<Comp> | null | undefined;
}
/**
 * @group Components
 * @subgroup Component Types
 */
export type PathFindOpt = {
	allowDiagonals?: boolean;
};
export interface Graph {
	getNeighbors(node: number): number[];
	getCost(node: number, neighbor: number): number;
	getHeuristic(node: number, goal: number): number;
	getPath(from: number, to: number): number[];
	getWaypointPath(from: Vec2, to: Vec2, opt: any): Vec2[];
	nodes: number[];
}
export interface PathfinderMapComp extends Comp {
	/**
	 * Get navigation waypoints to reach the given target from the given origin.
	 */
	navigate(origin: Vec2, target: Vec2, navigationOpt: any): Vec2[] | undefined;
	/**
	 * The graph to use for navigation.
	 */
	graph: Graph | undefined;
}
export interface PathfinderMapCompOpt {
	/**
	 * The graph to use for navigation. If null, the ancestors are queried for a pathfinderMap component.
	 */
	graph?: Graph;
}
export interface PathfinderComp extends Comp {
	/**
	 * Get navigation waypoints to reach the given target from the current position.
	 */
	navigateTo(target: Vec2): Vec2[] | undefined;
	/**
	 * Get the graph used for navigastion if any.
	 */
	graph: Graph | undefined;
}
export interface PathfinderCompOpt {
	/**
	 * The graph to use for navigation. If null, the ancestors are queried for a pathfinderMap component.
	 */
	graph?: Graph;
	/**
	 * The navigation options depending on the kind of graph used.
	 */
	navigationOpt?: any;
}
export interface PatrolComp extends Comp {
	/**
	 * Path to follow. If null, doesn't move.
	 */
	waypoints: Vec2[] | undefined;
	/**
	 * Speed of the movement during patrol.
	 */
	patrolSpeed: number;
	/**
	 * Current subgoal, if any.
	 */
	nextLocation: Vec2 | undefined;
	/**
	 * Attaches an event handler which is called when using "stop" and the end of the path is reached.
	 * @param cb - The event handler called when the patrol finishes.
	 */
	onPatrolFinished(cb: (objects: GameObj[]) => void): KEventController;
}
export type PatrolEndBehavior = "loop" | "ping-pong" | "stop";
export interface PatrolCompOpt {
	/**
	 * Path to follow. If null, starts suspended.
	 */
	waypoints?: Vec2[];
	/**
	 * Speed of the movement during patrol.
	 */
	speed?: number;
	/**
	 * What to do after the last waypoint has been reached.
	 */
	endBehavior?: PatrolEndBehavior;
}
/**
 * The {@link sentry `sentry()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SentryComp extends Comp {
	/**
	 * The direction the sentry is pointing to.
	 */
	direction?: Vec2;
	/**
	 * The direction of the sentry as an angle in degrees.
	 */
	directionAngle?: number;
	/**
	 * The field of view of the sentry in degrees.
	 */
	fieldOfView?: number;
	/**
	 * The objects spotted most recently.
	 */
	spotted: GameObj<any>[];
	/**
	 * Attaches an event handler which is called when objects of interest are spotted.
	 * @param cb - The event handler called when objects are spotted.
	 */
	onObjectsSpotted(cb: (objects: GameObj[]) => void): KEventController;
	/**
	 * Returns true if the object is within the field of view.
	 * @param obj - The object to test.
	 * @param direction - The direction to look at.
	 * @param fieldOfView - The field of view in degrees.
	 */
	isWithinFieldOfView(obj: GameObj<PosComp>, direction?: Vec2, fieldOfView?: number): boolean;
	/**
	 * Returns true if there is a line of sight to the object.
	 * @param obj - The object to test.
	 */
	hasLineOfSight(obj: GameObj<PosComp>): boolean;
}
/**
 * Options for the {@link sentry `sentry()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SentryCompOpt {
	/**
	 * The direction the sentry is pointing to. If undefined, direction has no influence.
	 */
	direction?: Vec2 | number;
	/**
	 * The field of view of the sentry in degrees. If undefined, defaults to human fov of 200 degrees.
	 */
	fieldOfView?: number;
	/**
	 * If true, line of sight matters. This means that objects which are blocked from view by areas are invisible.
	 */
	lineOfSight?: boolean;
	/**
	 * When using line of sight, the objects which are transparent for the ray. Include at least a tag identifying the sentry.
	 */
	raycastExclude?: string[];
	/**
	 * The frequency of checking, defaults to every second.
	 */
	checkFrequency?: number;
}
export type SentryCandidatesCb = () => GameObj<any>[];
export type SentryCandidates = SentryCandidatesCb | QueryOpt;
/**
 * The {@link tile `tile()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface TileComp extends Comp {
	/**
	 * The tile position inside the level.
	 */
	tilePos: Vec2;
	/**
	 * If the tile is an obstacle in pathfinding.
	 */
	isObstacle: boolean;
	/**
	 * How much a tile is cost to traverse in pathfinding (default 0).
	 */
	cost: number;
	/**
	 * If the tile has hard edges that cannot pass in pathfinding.
	 */
	edges: Edge[];
	/**
	 * Position offset when setting `tilePos`.
	 */
	tilePosOffset: Vec2;
	readonly edgeMask: EdgeMask;
	getLevel(): GameObj<LevelComp>;
	tileMove(dir: Vec2): void;
	moveLeft(): void;
	moveRight(): void;
	moveUp(): void;
	moveDown(): void;
}
/**
 * Options for the {@link tile `tile()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export type TileCompOpt = {
	/**
	 * If the tile is an obstacle in pathfinding.
	 */
	isObstacle?: boolean;
	/**
	 * How much a tile is cost to traverse in pathfinding (default 0).
	 */
	cost?: number;
	/**
	 * If the tile has hard edges that cannot pass in pathfinding.
	 */
	edges?: Edge[];
	/**
	 * Position offset when setting `tilePos`.
	 */
	offset?: Vec2;
};
export type TimeDirection = "forward" | "reverse" | "ping-pong";
export type Interpolation = "none" | "linear" | "slerp" | "spline";
export interface AnimateOpt {
	/**
	 * Duration of the animation in seconds
	 */
	duration: number;
	/**
	 * Loops, Default is undefined aka infinite
	 */
	loops?: number;
	/**
	 * Behavior when reaching the end of the animation. Default is forward.
	 */
	direction?: TimeDirection;
	/**
	 * Easing function. Default is linear time.
	 */
	easing?: EaseFunc;
	/**
	 * Interpolation function. Default is linear interpolation.
	 */
	interpolation?: Interpolation;
	/**
	 * Timestamps in percent for the given keys, if omitted, keys are equally spaced.
	 */
	timing?: number[];
	/**
	 * Easings for the given keys, if omitted, easing is used.
	 */
	easings?: EaseFunc[];
}
export interface AnimateCompOpt {
	/**
	 * Changes the angle so it follows the motion, requires the rotate component
	 */
	followMotion?: boolean;
	/**
	 * The animation is added to the base values of pos, angle, scale and opacity instead of replacing them
	 */
	relative?: boolean;
}
export interface BaseValues {
	pos: Vec2;
	angle: number;
	scale: Vec2;
	opacity: number;
}
/**
 * The {@link animate `animate()`} component.
 */
export interface AnimateComp extends Comp {
	/**
	 * Animates a property on this object.
	 * @param name - Name of the property to animate.
	 * @param keys - Keys determining the value at a certain point in time.
	 * @param opts - Options.
	 */
	animate<T extends LerpValue>(name: string, keys: T[], opts: AnimateOpt): void;
	/**
	 * Removes the animation from the given property.
	 * @param name - Name of the property to remove the animation from.
	 */
	unanimate(name: string): void;
	/**
	 * Removes the animations from all properties
	 */
	unanimateAll(): void;
	/**
	 * Attaches an event handler which is called when all the animation channels have finished.
	 * @param cb - The event handler called when the animation finishes.
	 */
	onAnimateFinished(cb: () => void): KEventController;
	/**
	 * Attaches an event handler which is called when an animation channels has finished.
	 * @param cb - The event handler called when an animation channel finishes.
	 */
	onAnimateChannelFinished(cb: (name: string) => void): KEventController;
	/**
	 * Base values for relative animation
	 */
	base: BaseValues;
	animation: {
		/**
		 * Pauses playing
		 */
		paused: boolean;
		/**
		 * Move the animation to a specific point in time
		 * @param time - Time to move the animation to in seconds
		 */
		seek(time: number): void;
		/**
		 * Returns the duration of the animation
		 */
		duration: number;
		/**
		 * Returns the animation with the specified name
		 * @param name - Name of the animation to retrieve
		 */
		get(name: string): Anim;
		/**
		 * Play the animation with the specified name
		 * @param name
		 */
		play(name: string): void;
		/**
		 * Stop playing the current animation
		 */
		stop(): void;
	};
	/**
	 * Serializes the animation of this object to plain Javascript types
	 */
	serializeAnimations(): Record<string, AnimationChannels>;
	/**
	 * Serializes the options of this object to plain Javascript types
	 */
	serializeAnimationOptions(): {
		followMotion?: boolean;
		relative?: boolean;
	};
}
declare class AnimateChannel {
	name: string;
	duration: number;
	loops: number;
	direction: TimeDirection;
	easing: EaseFunc;
	interpolation: Interpolation;
	isFinished: boolean;
	timing: number[] | undefined;
	easings: EaseFunc[] | undefined;
	relative: boolean;
	constructor(name: string, opts: AnimateOpt, relative: boolean);
	update(obj: GameObj<any>, t: number): boolean;
	/**
	 * Returns the first key index for the given time, as well as the relative time towards the second key.
	 * @param t - The time in seconds.
	 * @param timing - The optional timestamps in percent.
	 *
	 * @returns The first key index for the given time, as well as the relative time towards the second key.
	 */
	getLowerKeyIndexAndRelativeTime(t: number, count: number, timing?: number[]): [
		number,
		number,
		boolean
	];
	setValue<T>(obj: GameObj<any>, name: string, value: T): void;
	serialize(): AnimationChannel;
}
export type AnimationChannelKeys = number[] | number[][];
export type AnimationOptions = {
	duration: number;
	loops?: number;
	direction?: TimeDirection;
	easing?: string;
	interpolation?: Interpolation;
	timing?: number[];
	easings?: string[];
};
export type AnimationChannel = {
	keys: AnimationChannelKeys;
} & AnimationOptions;
export type AnimationChannels = Record<string, AnimationChannel>;
declare class Anim {
	name: string;
	opts: AnimateCompOpt;
	channels: AnimateChannel[];
	isFinished: boolean;
	constructor(name: string, opts: AnimateCompOpt);
	get duration(): number;
	animate<T extends LerpValue>(name: string, keys: T[], opts: AnimateOpt): void;
	unanimate(name: string): void;
	unanimateAll(): void;
	play(): void;
	stop(): void;
	serialize(): Record<string, AnimationChannel>;
	_update(obj: GameObj<AnimateComp>, t: number): void;
}
/**
 * The serialized {@link health `health()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializeHealthComp {
	hp: number;
	maxHP: number;
}
/**
 * The {@link health `health()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface HealthComp extends Comp {
	/**
	 * Current health points. Setting it to a lower or higher value will trigger onHurt() and onHeal().
	 * Setting it to a value greater than maxHP will set it to maxHP.
	 * Setting it to a value less than 0 will set it to 0 and trigger onDeath().
	 */
	hp: number;
	/**
	 * Max amount of HP.
	 */
	maxHP: number;
	/**
	 * Whether hp is 0.
	 */
	readonly dead: boolean;
	/**
	 * Register an event that runs when the hp is lowered.
	 *
	 * @since v2000.1
	 */
	onHurt(action: (deltaHP?: number) => void): KEventController;
	/**
	 * Register an event that runs when the hp is increased.
	 *
	 * @since v2000.1
	 */
	onHeal(action: (deltaHP?: number) => void): KEventController;
	/**
	 * Register an event that runs when object's HP becomes zero.
	 *
	 * @since v2000.1
	 */
	onDeath(action: () => void): KEventController;
	serialize(): SerializeHealthComp;
}
/**
 * The {@link lifespan `lifespan()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface LifespanCompOpt {
	/**
	 * Fade out duration (default 0 which is no fade out).
	 */
	fade?: number;
}
/**
 * The serialized {@link color `color()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializeNameComp {
	name: string;
}
/**
 * The {@link named `named()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface NamedComp extends Comp {
	/** The name assigned to this object. */
	name: string;
	serialize(): SerializeNameComp;
}
/**
 * The serialized {@link state `state()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializeStateComp {
	initState: string;
	stateList: string[];
	transitions: Record<string, string | string[]>;
}
/**
 * The {@link state `state()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface StateComp<T extends string> extends Comp {
	/**
	 * Current state.
	 */
	state: T;
	/**
	 * Enter a state, trigger onStateEnd for previous state and onStateEnter for the new State state.
	 */
	enterState: (state: T, ...args: any) => void;
	/**
	 * Register event that runs once when a specific state transition happens. Accepts arguments passed from `enterState(name, ...args)`.
	 *
	 * @since v2000.2
	 */
	onStateTransition(from: T, to: T, action: () => void): KEventController;
	/**
	 * Register event that runs once when enters a specific state. Accepts arguments passed from `enterState(name, ...args)`.
	 */
	onStateEnter: (state: T, action: (...args: any) => void) => KEventController;
	/**
	 * Register an event that runs once when leaves a specific state.
	 */
	onStateEnd: (state: T, action: () => void) => KEventController;
	/**
	 * Register an event that runs every frame when in a specific state.
	 */
	onStateUpdate: (state: T, action: () => void) => KEventController;
	/**
	 * Register an event that runs every frame when in a specific state.
	 */
	onStateDraw: (state: T, action: () => void) => KEventController;
	serialize(): SerializeStateComp;
}
/**
 * The serialized {@link stay `stay()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializeStayComp {
	scenesToStay: string[];
}
/**
 * The {@link stay `stay()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface StayComp extends Comp {
	/**
	 * If the obj should not be destroyed on scene switch.
	 */
	stay: boolean;
	/**
	 * Array of scenes that the obj will stay on.
	 */
	scenesToStay?: string[];
	serialize(): SerializeStayComp;
}
/**
 * The {@link textInput `textInput()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface TextInputComp extends Comp {
	/**
	 * Enable the text input array to be modified by user input.
	 *
	 * Setting this to true is the same as calling focus(), and will
	 * clear focus on all other active textInput objects.
	 */
	hasFocus: boolean;
	/**
	 * The "real" text that the user typed, without any escaping.
	 */
	typedText: string;
	/**
	 * Focuses this text input so that it will receive input, and
	 * removes focus from all other text inputs.
	 */
	focus(): void;
	/**
	 * Event that runs when the text input gains focus.
	 */
	onFocus(cb: () => void): KEventController;
	/**
	 * Event that runs when the text input loses focus.
	 */
	onBlur(cb: () => void): KEventController;
	/**
	 * Event that runs when the user types any character in the text input
	 * and causes its value to change.
	 *
	 * This runs *after* the display text is updated with the escaped version
	 * of the typed text, so in the event handler you can override the
	 * displayed text with another version (like if you want to add syntax
	 * highlighting or something). See also {@link TextComp.text}.
	 */
	onInput(cb: () => void): KEventController;
	/**
	 * Runs immediately after onBlur if the value has changed while the text
	 * input has been focused.
	 */
	onChange(cb: () => void): KEventController;
}
/**
 * The {@link body `body()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface BodyComp extends Comp {
	/**
	 * Object current velocity.
	 *
	 * @since v3001.0
	 */
	vel: Vec2;
	/**
	 * How much velocity decays (velocity *= 1 / (1 + damping * dt) every frame).
	 *
	 * @since v3001.0
	 */
	damping: number;
	/**
	 * If object is static, it won't move, all non static objects won't move past it, and all
	 * calls to addForce(), applyImpulse(), or jump() on this body will do absolutely nothing.
	 */
	isStatic: boolean;
	/**
	 * Initial speed in pixels per second for jump().
	 */
	jumpForce: number;
	/**
	 * Gravity multiplier.
	 */
	gravityScale: number;
	/**
	 * Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).
	 *
	 * @since v3000.0
	 */
	mass: number;
	/**
	 * If object should move with moving platform (default true).
	 *
	 * @since v3000.0
	 */
	stickToPlatform?: boolean;
	/**
	 * Current platform landing on.
	 */
	curPlatform(): GameObj | null;
	/**
	 * If currently landing on a platform.
	 *
	 * @since v2000.1
	 */
	isGrounded(): boolean;
	/**
	 * If currently falling.
	 *
	 * @since v2000.1
	 */
	isFalling(): boolean;
	/**
	 * If currently rising.
	 *
	 * @since v3000.0
	 */
	isJumping(): boolean;
	/**
	 * Applies an impulse
	 * @param impulse - The impulse vector, applied directly
	 */
	applyImpulse(impulse: Vec2): void;
	/**
	 * Applies a force
	 * @param force - The force vector, applied after scaled by the inverse mass
	 */
	addForce(force: Vec2): void;
	/**
	 * Upward thrust.
	 */
	jump(force?: number): void;
	/**
	 * Register an event that runs when a collision is resolved.
	 *
	 * @since v3000.0
	 */
	onPhysicsResolve(action: (col: Collision) => void): KEventController;
	/**
	 * Register an event that runs before a collision would be resolved.
	 *
	 * @since v3000.0
	 */
	onBeforePhysicsResolve(action: (col: Collision) => void): KEventController;
	/**
	 * Register an event that runs when the object is grounded.
	 *
	 * @since v2000.1
	 */
	onGround(action: () => void): KEventController;
	/**
	 * Register an event that runs when the object starts falling.
	 *
	 * @since v2000.1
	 */
	onFall(action: () => void): KEventController;
	/**
	 * Register an event that runs when the object falls off platform.
	 *
	 * @since v3000.0
	 */
	onFallOff(action: () => void): KEventController;
	/**
	 * Register an event that runs when the object bumps into something on the head.
	 *
	 * @since v2000.1
	 */
	onHeadbutt(action: () => void): KEventController;
	/**
	 * Register an event that runs when an object lands on this object.
	 *
	 * @since v3001.0
	 */
	onLand(action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs when the object is bumped by another object head.
	 */
	onHeadbutted(action: (obj: GameObj) => void): KEventController;
	serialize(): any;
}
/**
 * Options for the {@link body `body()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface BodyCompOpt {
	/**
	 * How much velocity decays (velocity *= 1 / (1 + damping * dt) every frame).
	 *
	 * @since v3001.0
	 */
	damping?: number;
	/**
	 * Initial speed in pixels per second for jump().
	 */
	jumpForce?: number;
	/**
	 * Maximum velocity when falling.
	 */
	maxVelocity?: number;
	/**
	 * Gravity multiplier.
	 */
	gravityScale?: number;
	/**
	 * If object is static, it won't move, all non static objects won't move past it, and all
	 * calls to addForce(), applyImpulse(), or jump() on this body will do absolutely nothing.
	 *
	 * @since v3000.0
	 */
	isStatic?: boolean;
	/**
	 * If object should move with moving platform (default true).
	 *
	 * @since v3000.0
	 */
	stickToPlatform?: boolean;
	/**
	 * Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).
	 *
	 * @since v3000.0
	 */
	mass?: number;
}
/**
 * The {@link doubleJump `doubleJump()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface DoubleJumpComp extends Comp {
	/**
	 * Number of jumps allowed.
	 */
	numJumps: number;
	/**
	 * Performs double jump (the initial jump only happens if player is grounded).
	 */
	doubleJump(force?: number): void;
	/**
	 * Register an event that runs when the object performs the second jump when double jumping.
	 */
	onDoubleJump(action: () => void): KEventController;
}
export type SurfaceEffectorCompOpt = {
	speed: number;
	speedVariation?: number;
	forceScale?: number;
};
export interface SurfaceEffectorComp extends Comp {
	speed: number;
	speedVariation: number;
	forceScale: number;
}
export type AreaEffectorCompOpt = {
	useGlobalAngle?: boolean;
	force: Vec2;
	linearDrag?: number;
};
export interface AreaEffectorComp extends Comp {
	useGlobalAngle: boolean;
	force: Vec2;
	linearDrag: number;
}
export type ForceMode = "constant" | "inverseLinear" | "inverseSquared";
export type PointEffectorCompOpt = {
	forceMagnitude: number;
	distanceScale?: number;
	forceMode?: ForceMode;
	linearDrag?: number;
};
export interface PointEffectorComp extends Comp {
	forceMagnitude: number;
	distanceScale: number;
	forceMode: ForceMode;
	linearDrag: number;
}
export type ConstantForceCompOpt = {
	force?: Vec2;
	useGlobalAngle?: boolean;
};
export interface ConstantForceComp extends Comp {
	force: Vec2 | undefined;
	useGlobalAngle: boolean;
}
export type PlatformEffectorCompOpt = {
	/**
	 * If the object is about to collide and the collision normal direction is
	 * in here (i.e. the object is moving roughly in this direction), the object won't collide.
	 *
	 * Should be a list of unit vectors `LEFT`, `RIGHT`, `UP`, or `DOWN`.
	 *
	 * Defaults to `[UP]`, i.e. the object will only be able to pass through when it
	 * is jumping upwards, but will collide when it is moving downwards or sideways.
	 */
	ignoreSides?: Vec2[];
	/**
	 * A function that determines whether the object should collide.
	 *
	 * If present, it overrides the `ignoreSides`; if absent, it is
	 * automatically created from `ignoreSides`.
	 */
	shouldCollide?: (this: GameObj<PlatformEffectorComp>, obj: GameObj, normal: Vec2) => boolean;
};
export interface PlatformEffectorComp extends Comp {
	/**
	 * A set of the objects that should not collide with this, because `shouldCollide` returned true.
	 *
	 * Objects in here are automatically removed when they stop colliding, so the casual user shouldn't
	 * need to touch this much. However, if an object is added to this set before the object collides
	 * with the platform effector, it won't collide even if `shouldCollide` returns true.
	 */
	platformIgnore: Set<GameObj>;
}
export type BuoyancyEffectorCompOpt = {
	surfaceLevel: number;
	density?: number;
	linearDrag?: number;
	angularDrag?: number;
	flowAngle?: number;
	flowMagnitude?: number;
	flowVariation?: number;
};
export interface BuoyancyEffectorComp extends Comp {
	surfaceLevel: number;
	density: number;
	linearDrag: number;
	angularDrag: number;
	flowAngle: number;
	flowMagnitude: number;
	flowVariation: number;
	applyBuoyancy(body: GameObj<BodyComp>, submergedArea: Polygon): void;
	applyDrag(body: GameObj<BodyComp>, submergedArea: Polygon): void;
}
/**
 * The serialized {@link anchor `anchor()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedAnchorComp {
	anchor: SerializedVec2;
}
/**
 * The {@link anchor `anchor()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface AnchorComp extends Comp {
	/**
	 * Anchor point for render.
	 */
	anchor: Anchor | Vec2;
	serialize(): SerializedAnchorComp;
}
/**
 * The serialized {@link rotate `rotate()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedRotateComp {
	angle: number;
}
/**
 * The {@link rotate `rotate()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface RotateComp extends Comp {
	/**
	 * Angle in degrees.
	 */
	angle: number;
	/**
	 * Rotate in degrees.
	 */
	rotateBy(angle: number): void;
	/**
	 * Rotate to a degree (like directly assign to .angle)
	 *
	 * @since v3000.0
	 */
	rotateTo(s: number): void;
	serialize(): {
		angle: number;
	};
}
export type BoneOpt = {
	minAngle?: number;
	maxAngle?: number;
};
export interface BoneComp extends Comp {
	minAngle: number;
	maxAngle: number;
	setAngles(minAngle: number, maxAngle: number): void;
}
export interface Constraint extends Comp {
	constraint: {
		target: GameObj;
	};
	apply: () => void;
}
export type DistanceMode = "maximum" | "minimum" | "equal";
export type DistanceConstraintOpt = {
	/**
	 * The desired distance between this and target
	 */
	distance: number;
	/**
	 * If maximum, the distance is maximum distance
	 * If equal, the distance is the desired distance
	 * If minimum, the distance is minimum distance
	 */
	mode: DistanceMode;
	/**
	 * Between 0 and 1. The percentage of the property being overwritten
	 */
	strength?: number;
};
export interface DistanceConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		distance: number;
		mode: DistanceMode;
		strength: number;
	};
}
export type TranslationConstraintOpt = {
	/**
	 * The offset added after applying the constraint
	 */
	offset?: Vec2;
	/**
	 * Between 0 and 1. The percentage of the property being overwritten
	 */
	strength?: number;
};
export interface TranslationConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		offset: Vec2;
		strength: number;
	};
}
export type RotationConstraintOpt = {
	/**
	 * The offset added after applying the constraint
	 */
	offset?: number;
	/**
	 * The factor applied before applying the constraint. For example 0.5 will only apply half of the rotation of the target
	 */
	scale?: number;
	/**
	 * Between 0 and 1. The percentage of the property being overwritten
	 */
	strength?: number;
};
export interface RotationConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		offset: number;
		scale: number;
		strength: number;
	};
}
export type ScaleConstraintOpt = {
	/**
	 * Between 0 and 1. The percentage of the property being overwritten
	 */
	strength?: number;
};
export interface ScaleConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		strength: number;
	};
}
export type TransformConstraintOpt = {
	/**
	 * Between 0 and 1. The percentage of the property being overwritten
	 */
	strength?: number;
};
export interface TransformConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		strength: number;
	};
}
/**
 * "FABRIK": Use Forward And Backward Reaching Inverse Kinematics
 * "CCD" : Use Cyclic Coordinate Descent
 */
export type InverseKinematicsAlgorithm = "FABRIK" | "CCD";
export type IKConstraintOpt = {
	/**
	 * The algorithm to use. Default is FABRIK.
	 */
	algorithm?: InverseKinematicsAlgorithm;
	/**
	 * Amount of bones. Default is 1.
	 */
	depth: number;
	/**
	 * Amount of ik iterations. Default is 10.
	 */
	iterations?: number;
	/**
	 * Between 0 and 1. The percentage of the property being overwritten. Default is 1.
	 */
	strength?: number;
};
export interface IKConstraintComp extends Constraint {
	constraint: {
		target: GameObj;
		iterations: number;
		strength: number;
	};
}
declare const constraint: {
	/**
	 * A distance constraint
	 * @param target - The object to keep within distance off
	 * @param opt - Options
	 *
	 * @returns DistanceConstraintComp
	 */
	distance(target: GameObj, opt: DistanceConstraintOpt): DistanceConstraintComp;
	/**
	 * A translation constraint
	 * @param target - The object to copy the translation from
	 * @param opt - Options
	 *
	 * @returns TranslationConstraintComp
	 */
	translation(target: GameObj, opt: TranslationConstraintOpt): TranslationConstraintComp;
	/**
	 * A rotation constraint
	 * @param target - The object to copy the rotation from
	 * @param opt - Options
	 *
	 * @returns RotationConstraintComp
	 */
	rotation(target: GameObj, opt: RotationConstraintOpt): RotationConstraintComp;
	/**
	 * A scale constraint
	 * @param target - The object to copy the scale from
	 * @param opt - Options
	 *
	 * @returns ScaleConstraintComp
	 */
	scale(target: GameObj, opt: ScaleConstraintOpt): ScaleConstraintComp;
	/**
	 * A transform constraint
	 * @param target - The object to copy the transform from
	 * @param opt - Options
	 *
	 * @returns TransformConstraintComp
	 */
	transform(target: GameObj, opt: TransformConstraintOpt): TransformConstraintComp;
	bone(minAngle?: number, maxAngle?: number, minLength?: number, maxLength?: number): {
		id: string;
		readonly minAngle: number;
		readonly maxAngle: number;
		setAngles(minAngle?: number, maxAngle?: number): void;
		readonly minLength: number | undefined;
		readonly maxLength: number | undefined;
		drawInspect(this: GameObj<IKConstraintComp | RotateComp>): void;
	};
	ik(target: GameObj, opt: IKConstraintOpt): IKConstraintComp;
};
/**
 * The {@link follow `follow()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface FollowComp extends Comp {
	follow: {
		/**
		 * The object to follow.
		 */
		obj: GameObj;
		/**
		 * The offset to follow the object by.
		 */
		offset: Vec2;
	};
}
/**
 * The {@link layer `layer()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface LayerComp extends Comp {
	/**
	 * Get the index of the current layer the object is assigned to.
	 *
	 * Will always be `null` if the game doesn't use layers.
	 */
	get layerIndex(): number | null;
	/**
	 * Get the name of the current layer the object is assigned to.
	 *
	 * Will always be `null` if the game doesn't use layers.
	 */
	get layer(): string | null;
	/**
	 * Set the name of the layer the object should be assigned to.
	 *
	 * Throws an error if the game uses layers and the requested layer
	 * wasn't defined.
	 */
	set layer(name: string);
	serialize(): {
		layer: string | null;
	};
}
/**
 * The serialized {@link move `move()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedMoveComp {
	dir: SerializedVec2 | number;
	speed: number;
}
/**
 * The {@link move `move()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface MoveComp extends Comp {
	serialize: () => SerializedMoveComp;
}
/**
 * The {@link offscreen `offscreen()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface OffScreenComp extends Comp {
	/**
	 * The minimum distance that the object must be off the screen by to be considered "offscreen".
	 *
	 * If it is undefined, it means that the object will be considered to be offscreen when its bounding rectangle
	 * (defined by width and height) is not intersecting with the screen rectangle.
	 */
	offscreenDistance: number | undefined;
	/**
	 * If object is currently out of view.
	 */
	isOffScreen(): boolean;
	/**
	 * Register an event that runs when object goes out of view.
	 */
	onExitScreen(action: () => void): KEventController;
	/**
	 * Register an event that runs when object enters view.
	 */
	onEnterScreen(action: () => void): KEventController;
}
/**
 * Options for {@link offscreen `offscreen()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface OffScreenCompOpt {
	/**
	 * If hide object when out of view.
	 */
	hide?: boolean;
	/**
	 * If pause object when out of view.
	 */
	pause?: boolean;
	/**
	 * If unpause object when back in view.
	 */
	unpause?: boolean;
	/**
	 * If destroy object when out of view.
	 */
	destroy?: boolean;
	/**
	 * The distance when out of view is triggered (default 200).
	 *
	 * @since v3000.0
	 */
	distance?: number;
}
/**
 * The serialized {@link scale `scale()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedScaleComp {
	scale: SerializedVec2;
}
/**
 * The {@link scale `scale()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface ScaleComp extends Comp {
	/**
	 * The current scale of the object
	 *
	 * @returns The current scale of the object as a {@link Vec2 `Vec2`}
	 */
	scale: Vec2;
	/**
	 * Set the scale of the object to a number
	 */
	scaleTo(s: number): void;
	/**
	 * Set the scale of the object to a Vec2
	 */
	scaleTo(s: Vec2): void;
	/**
	 * Set the scale of the object to a number for x and y
	 */
	scaleTo(sx: number, sy: number): void;
	/**
	 * Scale the object by a number
	 */
	scaleBy(s: number): void;
	/**
	 * Scale the object by a Vec2
	 */
	scaleBy(s: Vec2): void;
	/**
	 * Scale the object by a number for x and y
	 */
	scaleBy(sx: number, sy: number): void;
	/**
	 * Serialize the current state comp
	 */
	serialize(): SerializedScaleComp;
}
/**
 * The serialized {@link skew `skew()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedSkewComp {
	skew: SerializedVec2;
}
/**
 * The {@link skew `skew()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SkewComp extends Comp {
	/**
	 * The current skew of the object
	 *
	 * @returns The current skew of the object as a {@link Vec2 `Vec2`}
	 */
	skew: Vec2;
	/**
	 * Serialize the current state comp
	 */
	serialize(): SerializedSkewComp;
}
/**
 * The serialized {@link z `z()`} component.
 *
 * @group Components
 * @subgroup Component Serialization
 */
export interface SerializedZComp {
	z: number;
}
/**
 * The {@link z `z()`} component.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface ZComp extends Comp {
	/**
	 * Defines the z-index of this game obj
	 */
	z: number;
	/**
	 * Serialize the current state comp
	 */
	serialize(): SerializedZComp;
}
/**
 * Convert a union type to an intersection type.
 */
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
/**
 * It removes the properties that are undefined.
 */
export type Defined<T> = T extends any ? Pick<T, {
	[K in keyof T]-?: T[K] extends undefined ? never : K;
}[keyof T]> : never;
/**
 * It obligates to TypeScript to Expand the type.
 *
 * Instead of being `{ id: 1 } | { name: "hi" }`
 * makes
 * It's `{ id: 1, name: "hi" }`
 *
 * https://www.totaltypescript.com/concepts/the-prettify-helper
 */
export type Expand<T> = T extends infer U ? {
	[K in keyof U]: U[K];
} : never;
/**
 * It merges all the objects into one.
 */
export type MergeObj<T> = Expand<UnionToIntersection<Defined<T>>>;
export type TupleWithoutFirst<T extends any[]> = T extends [
	infer R,
	...infer E
] ? E : never;
declare function onCollide(t1: Tag, t2: Tag, f: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
declare function onCollideUpdate(t1: Tag, t2: Tag, f: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
declare function onCollideEnd(t1: Tag, t2: Tag, f: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
declare function onHover(tag: Tag, action: (obj: GameObj) => void): KEventController;
declare function onHoverEnd(tag: Tag, action: (obj: GameObj) => void): KEventController;
declare function onHoverUpdate(tag: Tag, action: (obj: GameObj) => void): KEventController;
declare function onError(action: (err: Error) => void): KEventController;
declare function onLoading(action: (progress: number) => void): KEventController;
declare function onLoad(cb: () => void): KEventController | undefined;
declare function onLoadError(cb: (name: string, failedAsset: Asset<any>) => void): KEventController | undefined;
declare function onSceneLeave(action: (newScene?: string) => void): KEventController;
export type ScopeHandlers = ReturnType<typeof createScopeHandlers>;
declare const createScopeHandlers: (app: App) => {
	onKeyDown: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyPress: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyPressRepeat: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyRelease: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onCharInput: (action: (ch: string) => void) => KEventController;
	onMouseDown: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMousePress: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMouseRelease: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMouseMove: (f: (pos: Vec2, dpos: Vec2) => void) => KEventController;
	onTouchStart: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onTouchEnd: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onTouchMove: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onScroll: (action: (delta: Vec2) => void) => KEventController;
	onGamepadConnect: (action: (gamepad: KGamepad) => void) => KEventController;
	onGamepadDisconnect: (action: (gamepad: KGamepad) => void) => KEventController;
	onGamepadButtonDown: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton, action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadButtonPress: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadButtonRelease: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadStick: (stick: KGamepadStick, action: (value: Vec2, gp: KGamepad) => void) => KEventController;
	onButtonDown: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	onButtonPress: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	onButtonRelease: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	onTabShow: (action: () => void) => KEventController;
	onTabHide: (action: () => void) => KEventController;
	onUpdate: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
	onFixedUpdate: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
	onDraw: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
	onAdd: ((action: (obj: GameObj) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
	onDestroy: ((action: (obj: GameObj) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
	onUse: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
	onUnuse: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
	onTag: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
	onUntag: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
	on: <Ev extends GameObjEventNames | (string & {})>(event: Ev, tag: Tag, cb: (obj: GameObj, ...args: TupleWithoutFirst<GameObjEvents[Ev]>) => void) => KEventController;
	onClick: (tag: Tag, action: (obj: GameObj) => void) => KEventController;
	onCollide: typeof onCollide;
	onCollideEnd: typeof onCollideEnd;
	onCollideUpdate: typeof onCollideUpdate;
	onHover: typeof onHover;
	onHoverEnd: typeof onHoverEnd;
	onHoverUpdate: typeof onHoverUpdate;
	onResize: (action: () => void) => KEventController;
	onSceneLeave: typeof onSceneLeave;
	onLoad: typeof onLoad;
	onLoading: typeof onLoading;
	onError: typeof onError;
	onLoadError: typeof onLoadError;
	onCleanup: (action: () => void) => void;
	onShow: (action: () => void) => KEventController;
	onHide: (action: () => void) => KEventController;
};
export type SceneScope = ScopeHandlers & {
	(id: string, def: SceneDef): void;
};
export type AppScope = ScopeHandlers;
declare const ingnoredHandlersForObject: readonly [
	"onUpdate",
	"onFixedUpdate",
	"onDraw",
	"onAdd",
	"onDestroy",
	"onUse",
	"onUnuse",
	"onTag",
	"onUntag",
	"onCollide",
	"onCollideEnd",
	"onCollideUpdate",
	"onClick",
	"onHover",
	"onHoverEnd",
	"onHoverUpdate",
	"on"
];
export type EventHandlersInAppButNotAddedInGameObjRaw = typeof ingnoredHandlersForObject[number];
declare enum KeepFlags {
	Pos = 1,
	Angle = 2,
	Scale = 4,
	All = 7
}
export type SetParentOpt = {
	keep: KeepFlags;
};
/**
 * Base interface of all game objects.
 *
 * @since v2000.0
 * @group Game Obj
 * @subgroup Types
 */
export interface GameObjRaw {
	/**
	 * The unique id of the game obj.
	 */
	id: GameObjID;
	/**
	 * Get or set the parent game obj.
	 *
	 * @since v4000.0
	 */
	parent: GameObj | null;
	/**
	 * Get all children game objects.
	 *
	 * @readonly
	 * @since v3000.0
	 */
	children: GameObj[];
	/**
	 * Get the tags of a game object. For update it, use `tag()` and `untag()`.
	 *
	 * @readonly
	 * @since v3001.0
	 */
	tags: string[];
	/**
	 * Calculated transform matrix of a game object.
	 *
	 * @since v3000.0
	 */
	transform: Mat23;
	/**
	 * If draw the game obj (run "draw" event or not).
	 *
	 * @since v2000.0
	 */
	hidden: boolean;
	/**
	 * If update the game obj (run "update" event or not).
	 *
	 * @since v2000.0
	 */
	paused: boolean;
	/**
	 * The canvas to draw this game object on
	 *
	 * @since v3001.0
	 */
	target?: RenderTarget;
	/**
	 * Set the parent game obj with additional options.
	 *
	 * @since v4000.0
	 */
	setParent(p: GameObj, opt: SetParentOpt): void;
	/**
	 * Add a child.
	 *
	 * @param comps - The components to add.
	 *
	 * @returns The added game object.
	 * @since v3000.0
	 */
	add<T extends CompList<unknown>>(comps?: [
		...T
	]): GameObj<T[number]>;
	/**
	 * Add a prefab.
	 *
	 * @param nameOrObject - Name of registered prefab using loadPrefab() or plain obj returned by createPrefab().
	 *
	 * @returns The added game object.
	 * @since v4000.0
	 */
	addPrefab<T extends CompList<unknown>>(nameOrObject: object | string, compList?: [
		...T
	]): GameObj<T[number]>;
	/**
	 * Create a serialized version of this Game Object.
	 *
	 * @returns The serialized game object
	 * @since v4000.0
	 */
	serialize(): SerializedGameObj;
	/**
	 * Remove and re-add the game obj, without triggering add / destroy events.
	 *
	 * @param obj - The game object to re-add.
	 *
	 * @returns The re-added game object.
	 * @since v3000.0
	 */
	readd<T>(obj: GameObj<T>): GameObj<T>;
	/**
	 * Remove a child.
	 *
	 * @param obj - The game object to remove.
	 *
	 * @since v3000.0
	 */
	remove(obj: GameObj): void;
	/**
	 * Remove all children with a certain tag.
	 *
	 * @param tag - The tag to remove.
	 *
	 * @since v3000.0
	 */
	removeAll(tag: Tag): void;
	/**
	 * Remove this game obj from scene.
	 *
	 * @since v2000.0
	 */
	destroy(): void;
	/**
	 * Remove all children.
	 *
	 * @since v3000.0
	 */
	removeAll(): void;
	/**
	 * If game obj is attached to the scene graph.
	 *
	 * @returns true if attached, false otherwise.
	 * @since v2000.0
	 */
	exists(): boolean;
	/**
	 * Check if is an ancestor (recursive parent) of another game object
	 *
	 * @returns true if is ancestor, false otherwise.
	 * @since v3000.0
	 */
	isAncestorOf(obj: GameObj): boolean;
	/**
	 * Get a list of all game objs with certain tag.
	 *
	 * @param tag - The tag to get.
	 *
	 * @since v3000.0
	 */
	get<T = any>(tag: Tag | Tag[], opts?: GetOpt): GameObj<T>[];
	/**
	 * Get a list of all game objs with certain properties.
	 *
	 * @param opt - The properties to get.
	 *
	 * @since v3001.0
	 */
	query(opt: QueryOpt): GameObj[];
	/**
	 * Update this game object and all children game objects.
	 *
	 * @since v3000.0
	 */
	update(): void;
	/**
	 * Update this game object and all children game objects.
	 *
	 * @since v3001.0
	 */
	fixedUpdate(): void;
	/**
	 * Draw this game object and all children game objects.
	 *
	 * @since v3000.0
	 */
	draw(): void;
	drawTree(): void;
	/**
	 * Gather debug info of all comps.
	 *
	 * @since v2000.0
	 */
	inspect(): GameObjInspect;
	/**
	 * Draw debug info in inspect mode
	 *
	 * @since v3000.0
	 */
	drawInspect: () => void;
	/**
	 * This method is called to transform and collect objects which should be drawn layered
	 */
	collect(objects: GameObj<any>[]): void;
	/**
	 * This method is called to transform objects
	 */
	transformTree(force: boolean): void;
	/**
	 * Add a component.
	 *
	 * @example
	 * ```js
	 * const obj = add([
	 *    sprite("bean"),
	 * ]);
	 *
	 * // Add opacity
	 * obj.use(opacity(0.5));
	 * ```
	 *
	 * @since v2000.0
	 */
	use(comp: Comp): void;
	/**
	 * Remove a component with its id (the component name)
	 *
	 * @param comp - The component id to remove. It means the name, if sprite, then it's "sprite".
	 *
	 * @example
	 * ```js
	 * // Remove sprite component
	 * obj.unuse("sprite");
	 * ```
	 *
	 * @since v2000.0
	 */
	unuse(comp: string): void;
	/**
	 * Check if game object has a certain component.
	 *
	 * @param compId - The component id(s) to check.
	 * @param op - The operator to use when searching for multiple components. Default is "and".
	 *
	 * @example
	 * ```js
	 * // Check if game object has sprite component
	 * if(obj.has("sprite")) {
	 *     debug.log("has sprite component");
	 * }
	 *
	 * // Check if game object has tags
	 * obj.has(["tag1", "tag2"]); // AND, it has both tags
	 * obj.has(["tag1", "tag2"], "or"); // OR, it has either tag1 or tag2
	 * ```
	 *
	 * @returns true if has the component(s), false otherwise.
	 * @since v3001.0.5
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	has(compId: string | string[], op?: "and" | "or"): boolean;
	/**
	 * Get state for a specific comp.
	 *
	 * @param id - The component id.
	 *
	 * @since v2000.0
	 */
	c(id: string): Comp | null;
	/**
	 * Add a tag(s) to the game obj.
	 *
	 * @param tag - The tag(s) to add.
	 *
	 * @example
	 * ```js
	 * // add enemy tag
	 * obj.tag("enemy");
	 *
	 * // add multiple tags
	 * obj.tag(["enemy", "boss"]);
	 * ```
	 *
	 * @since v3001.0.5
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	tag(tag: Tag | Tag[]): void;
	/**
	 * Remove a tag(s) from the game obj.
	 *
	 * @param tag - The tag(s) to remove.
	 *
	 * @example
	 * ```js
	 * // remove enemy tag
	 * obj.untag("enemy");
	 *
	 * // remove multiple tags
	 * obj.untag(["enemy", "boss"]);
	 * ```
	 *
	 * @since v3001.0.5
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	untag(tag: Tag | Tag[]): void;
	/**
	 * If there's certain tag(s) on the game obj.
	 *
	 * @param tag - The tag(s) for checking.
	 * @param op - The operator to use when searching for multiple tags. Default is "and".
	 *
	 * @since v3001.0.5
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	is(tag: Tag | Tag[], op?: "and" | "or"): boolean;
	/**
	 * Register an event.
	 *
	 * @param event - The event name.
	 * @param action - The action to run when event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 */
	on(event: GameObjEventNames | (string & {}), action: (...args: any) => void): KEventController;
	/**
	 * Trigger an event.
	 *
	 * @param event - The event name.
	 * @param args - The arguments to pass to the event action.
	 *
	 * @since v2000.0
	 */
	trigger(event: string, ...args: any): void;
	/**
	 * Clear all events.
	 */
	clearEvents: () => void;
	/**
	 * Register an event that runs when the game obj is added to the scene.
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 */
	onAdd(action: () => void): KEventController;
	/**
	 * Register an event that runs every frame as long as the game obj exists.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 */
	onUpdate(action: () => void): KEventController;
	/**
	 * Register an event that runs every frame as long as the game obj exists.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 */
	onFixedUpdate(action: () => void): KEventController;
	/**
	 * Register an event that runs every frame as long as the game obj exists (this is the same as `onUpdate()`, but all draw events are run after all update events).
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 */
	onDraw(action: () => void): KEventController;
	/**
	 * Register an event that runs when the game obj is destroyed.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 */
	onDestroy(action: () => void): KEventController;
	/**
	 * Register an event that runs when a component is used.
	 *
	 * @returns The event controller.
	 * @since v4000.0
	 */
	onUse(action: (id: string) => void): KEventController;
	/**
	 * Register an event that runs when a component is unused.
	 *
	 * @returns The event controller.
	 * @since v4000.0
	 */
	onUnuse(action: (id: string) => void): KEventController;
	/**
	 * Register an event that runs when a tag is added.
	 *
	 * @returns The event controller.
	 * @since v4000.0
	 */
	onTag(action: (tag: string) => void): KEventController;
	/**
	 * Register an event that runs when a tag is removed.
	 *
	 * @returns The event controller.
	 * @since v4000.0
	 */
	onUntag(action: (tag: string) => void): KEventController;
	onKeyDown: KAPLAYCtx["onKeyDown"];
	onKeyPress: KAPLAYCtx["onKeyPress"];
	onKeyPressRepeat: KAPLAYCtx["onKeyPressRepeat"];
	onKeyRelease: KAPLAYCtx["onKeyRelease"];
	onCharInput: KAPLAYCtx["onCharInput"];
	onMouseDown: KAPLAYCtx["onMouseDown"];
	onMousePress: KAPLAYCtx["onMousePress"];
	onMouseRelease: KAPLAYCtx["onMouseRelease"];
	onMouseMove: KAPLAYCtx["onMouseMove"];
	onTouchStart: KAPLAYCtx["onTouchStart"];
	onTouchMove: KAPLAYCtx["onTouchMove"];
	onTouchEnd: KAPLAYCtx["onTouchEnd"];
	onScroll: KAPLAYCtx["onScroll"];
	onGamepadButtonDown: KAPLAYCtx["onGamepadButtonDown"];
	onGamepadButtonPress: KAPLAYCtx["onGamepadButtonPress"];
	onGamepadButtonRelease: KAPLAYCtx["onGamepadButtonRelease"];
	onGamepadStick: KAPLAYCtx["onGamepadStick"];
	onButtonDown: KAPLAYCtx["onButtonDown"];
	onButtonPress: KAPLAYCtx["onButtonPress"];
	onButtonRelease: KAPLAYCtx["onButtonRelease"];
	onTabShow: KAPLAYCtx["onTabShow"];
	onTabHide: KAPLAYCtx["onTabHide"];
	onShow: KAPLAYCtx["onShow"];
	onHide: KAPLAYCtx["onHide"];
}
export type InternalGameObjRaw = GameObjRaw & {
	/** @readonly */
	_parent: GameObj;
	/** @readonly */
	_compsIds: Set<string>;
	/** @readonly */
	_compStates: Map<string, Comp>;
	/** @readonly */
	_anonymousCompStates: Comp[];
	/** @readonly */
	_cleanups: Record<string, (() => any)[]>;
	/** @readonly */
	_events: KEventHandler<any>;
	/** @readonly */
	_fixedUpdateEvents: KEvent<[
	]>;
	/** @readonly */
	_updateEvents: KEvent<[
	]>;
	/** @readonly */
	_drawEvents: KEvent<[
	]>;
	/** @readonly */
	_inputEvents: KEventController[];
	/** @readonly */
	_onCurCompCleanup: Function | null;
	/** @readonly */
	_tags: Set<Tag>;
	/** @readonly */
	_drawLayerIndex: number;
	/** @readonly */
	_treeIndex: number;
	/** @readonly */
	_transformVersion: number;
	/**
	 * Adds a component or anonymous component.
	 */
	_addComp(comp: Comp): void;
	/**
	 * Removes a component without checking for dependencies
	 */
	_removeComp(id: string): void;
	/**
	 * Check if any id of a component's require is not present in `_compsIds`, if
	 * there's, throw an error.
	 *
	 * @param comp - The component for checking.
	 */
	_checkDependencies(comp: Comp): void;
	/**
	 * Check if any component (in `_compStates`) is dependent of compId, if
	 * there's, throw an error.
	 *
	 * @param compId - Component ID for searching.
	 */
	_checkDependents(compId: string): void;
};
/**
 * @group Game Obj
 * @subgroup Types
 */
export interface BoomOpt {
	/**
	 * Animation speed.
	 */
	speed?: number;
	/**
	 * Scale.
	 */
	scale?: number;
	/**
	 * Additional components.
	 *
	 * @since v3000.0
	 */
	comps?: CompList<any>;
}
/**
 * Options for the {@link addLevel `addLevel()`}.
 *
 * @group Game Obj
 * @subgroup Types
 */
export interface AddLevelOpt extends LevelCompOpt {
	/**
	 * Position of the first block.
	 */
	pos?: Vec2;
}
declare function anchorPt(orig: Anchor | Vec2): Vec2;
/**
 * @group Draw
 * @subgroup Types
 */
export type DrawCurveOpt = RenderProps & {
	/**
	 * The amount of line segments to draw.
	 */
	segments?: number;
	/**
	 * The width of the line.
	 */
	width?: number;
};
/**
 * @group Draw
 * @subgroup Types
 */
export type DrawBezierOpt = DrawCurveOpt & {
	/**
	 * The first point.
	 */
	pt1: Vec2;
	/**
	 * The the first control point.
	 */
	pt2: Vec2;
	/**
	 * The the second control point.
	 */
	pt3: Vec2;
	/**
	 * The second point.
	 */
	pt4: Vec2;
};
/**
 * How the UV Quad should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawUVQuadOpt = RenderProps & {
	/**
	 * Width of the UV quad.
	 */
	width: number;
	/**
	 * Height of the UV quad.
	 */
	height: number;
	/**
	 * If flip the texture horizontally.
	 */
	flipX?: boolean;
	/**
	 * If flip the texture vertically.
	 */
	flipY?: boolean;
	/**
	 * The texture to sample for this quad.
	 */
	tex?: Texture;
	/**
	 * The texture sampling area.
	 */
	quad?: Quad;
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
};
/**
 * @group Draw
 * @subgroup Types
 */
export type DrawCanvasOpt = DrawUVQuadOpt & {
	canvas: Canvas;
};
/**
 * How the circle should look like.
 * @group Draw
 * @subgroup Types
 */
export type DrawCircleOpt = Omit<RenderProps, "angle"> & {
	/**
	 * Radius of the circle.
	 */
	radius: number;
	/**
	 * Starting angle.
	 */
	start?: number;
	/**
	 * Ending angle.
	 */
	end?: number;
	/**
	 * If fill the shape with color (set this to false if you only want an outline).
	 */
	fill?: boolean;
	/**
	 * Use gradient instead of solid color.
	 *
	 * @since v3000.0
	 */
	gradient?: [
		Color,
		Color
	];
	/**
	 * Multiplier for circle vertices resolution (default 1)
	 */
	resolution?: number;
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
};
/**
 * How the ellipse should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawEllipseOpt = RenderProps & {
	/**
	 * The horizontal radius.
	 */
	radiusX: number;
	/**
	 * The vertical radius.
	 */
	radiusY: number;
	/**
	 * Starting angle.
	 */
	start?: number;
	/**
	 * Ending angle.
	 */
	end?: number;
	/**
	 * If fill the shape with color (set this to false if you only want an outline).
	 */
	fill?: boolean;
	/**
	 * Use gradient instead of solid color.
	 *
	 * @since v3000.0
	 */
	gradient?: [
		Color,
		Color
	];
	/**
	 * Multiplier for circle vertices resolution (default 1)
	 */
	resolution?: number;
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
};
/**
 * How the rectangle should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawRectOpt = RenderProps & {
	/**
	 * Width of the rectangle.
	 */
	width: number;
	/**
	 * Height of the rectangle.
	 */
	height: number;
	/**
	 * Use gradient instead of solid color.
	 *
	 * @since v3000.0
	 */
	gradient?: [
		Color,
		Color
	];
	/**
	 * If the gradient should be horizontal.
	 *
	 * @since v3000.0
	 */
	horizontal?: boolean;
	/**
	 * If fill the shape with color (set this to false if you only want an outline).
	 */
	fill?: boolean;
	/**
	 * The radius of each corner.
	 */
	radius?: number | number[];
	/**
	 * The anchor point, or the pivot point. Default to "topleft".
	 */
	anchor?: Anchor | Vec2;
};
/**
 * How the triangle should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawTriangleOpt = RenderProps & {
	/**
	 * First point of triangle.
	 */
	p1: Vec2;
	/**
	 * Second point of triangle.
	 */
	p2: Vec2;
	/**
	 * Third point of triangle.
	 */
	p3: Vec2;
	/**
	 * If fill the shape with color (set this to false if you only want an outline).
	 */
	fill?: boolean;
	/**
	 * The radius of each corner.
	 */
	radius?: number;
};
export type Predicate = (value: any) => boolean;
export declare class DecisionNode {
	attribute: string;
	children: DecisionNode[];
	totalWeight: number;
	constructor(attribute: string);
	addValueNode(value: any, attribute: string): DecisionNode;
	addPredicateNode(predicate: Predicate, attribute: string): DecisionNode;
	addWeightNode(weight: any, attribute: string): DecisionNode;
	evaluate(answers: any): string;
	assert(value: any): boolean;
}
export declare class DecisionTree {
	root: DecisionNode;
	constructor(attribute: string);
	evaluate(answers: any): string;
	/**
	 * Computes a decision tree from example data
	 * @param data - Example data, a list of columns, where each column contains values for an attribute in attributes.
	 * @param attributes - The names of the columns.
	 * @param outcomes - The outcomes for each row.
	 */
	static learnFromExamples(data: any[][], attributes: string[], outcomes: boolean[]): DecisionTree;
}
type Predicate$1 = (system: RuleSystem) => boolean;
export type Action = (system: RuleSystem) => void;
export declare class Rule {
	predicate: Predicate$1;
	salience: number;
	constructor(predicate: Predicate$1, salience: number);
	evaluate(system: RuleSystem): boolean;
	execute(system: RuleSystem): void;
}
export declare class RuleSystem {
	agenda: Rule[];
	state: any;
	facts: Map<string, number>;
	constructor();
	/**
	 * Adds a rule which runs an action if its predicate evaluates to true.
	 * @param predicate - Predicate to evaluate. A function taking the system as parameter.
	 * @param action - Action to execute. A function taking the system as parameter.
	 * @param salience - Priority of the rule.
	 */
	addRuleExecutingAction(predicate: Predicate$1, action: Action, salience?: number): void;
	/**
	 * Add a rule which asserts a fact if its predicate evaluates to true.
	 * @param predicate - Predicate to evaluate. A function taking the system as parameter.
	 * @param fact - The fact to assert.
	 * @param grade - The optional grade to use when asserting the fact.
	 * @param salience - Priority of the rule.
	 */
	addRuleAssertingFact(predicate: Predicate$1, fact: string, grade?: number, salience?: number): void;
	/**
	 * Add a rule which retracts a fact if its predicate evaluates to true.
	 * @param predicate - Predicate to evaluate. A function taking the system as parameter.
	 * @param fact - The fact to retract.
	 * @param grade - The optional grade to use when retracting the fact.
	 * @param salience - Priority of the rule.
	 */
	addRuleRetractingFact(predicate: Predicate$1, fact: string, grade?: number, salience?: number): void;
	/**
	 * Add a custom rule.
	 * @param rule - The rule to add.
	 */
	addRule(rule: Rule): void;
	/**
	 * Removes all rules.
	 */
	removeAllRules(): void;
	/**
	 * Executes all rules for which the predicate evaluates to true.
	 */
	execute(): void;
	/**
	 * Asserts a fact.
	 * @param fact - The fact to assert.
	 * @param grade - The optional grade to use.
	 */
	assertFact(fact: string, grade?: number): void;
	/**
	 * Retracts a fact.
	 * @param fact - The fact to retract.
	 * @param grade - The optional grade to use.
	 */
	retractFact(fact: string, grade?: number): void;
	/**
	 * Returns the grade for the specified fact.
	 * @param fact - The fact to obtain the grade from.
	 *
	 * @returns The grade for the fact.
	 */
	gradeForFact(fact: string): number;
	/**
	 * Returns the minimum grade for the specified facts.
	 * @param facts - The facts to obtain the minimum grade from.
	 *
	 * @returns The minimum grade for the facts.
	 */
	minimumGradeForFacts(...facts: string[]): number;
	/**
	 * Returns the maximum grade for the specified facts.
	 * @param facts - The facts to obtain the maximum grade from.
	 *
	 * @returns The maximum grade for the facts.
	 */
	maximumGradeForFacts(...facts: string[]): number;
	/**
	 * Resets the facts.
	 */
	reset(): void;
}
export type EnterCallback = (sm: StateMachine, previous: string) => void;
type UpdateCallback$1 = (sm: StateMachine, current: string) => void;
export type DrawCallback = (sm: StateMachine, current: string) => void;
export type ExitCallback = (sm: StateMachine, next: string) => void;
export type TransitionCallback = (sm: StateMachine, from: string, to: string) => void;
export type StateCallbacks = {
	enter?: EnterCallback;
	update?: UpdateCallback$1;
	draw?: DrawCallback;
	exit?: ExitCallback;
};
declare class State {
	name: string;
	callbacks: StateCallbacks;
	transitions: Record<string, TransitionCallback>;
	constructor(name: string, callbacks: StateCallbacks);
}
/**
 * A finite state machine
 */
export declare class StateMachine {
	stateMap: Record<string, State>;
	state: State | undefined;
	/**
	 * Create a machine given the states and initial state
	 * @param states - The states the machine can be in
	 * @param initialState - The initial state it will enter if given
	 */
	constructor(states: string[]);
	/**
	 * Make the machine enter a state
	 * @param name - The new state
	 */
	enterState(name: string): void;
	/**
	 * Set a callback for when the machine enters a state
	 * @param name - The state
	 * @param cb - The callback
	 */
	onStateEnter(name: string, cb: (sm: StateMachine, previous: string) => void): void;
	/**
	 * Set a callback for when the machine updates a state
	 * @param name - The state
	 * @param cb - The callback
	 */
	onStateUpdate(name: string, cb: (sm: StateMachine, current: string) => void): void;
	/**
	 * Set a callback for when the machine draws a state
	 * @param name - The state
	 * @param cb - The callback
	 */
	onStateDraw(name: string, cb: (sm: StateMachine, current: string) => void): void;
	/**
	 * Set a callback for when the machine exits a state
	 * @param name - The state
	 * @param cb - The callback
	 */
	onStateExit(name: string, cb: (sm: StateMachine, next: string) => void): void;
	/**
	 * Set a callback for when the machine transitions from one state to the other state
	 * @param from - The state which is exited
	 * @param to - The state which is entered
	 * @param cb - The callback
	 */
	onStateTransition(from: string, to: string, cb: (sm: StateMachine, from: string, to: string) => void): void;
}
export type GjkCollisionResult = {
	/**
	 * The direction the first shape needs to be moved to resolve the collision
	 */
	normal: Vec2;
	/**
	 * The distance the first shape needs to be moved to resolve the collision
	 */
	distance: number;
};
/**
 * A navigation grid is a graph consisting of connected grid cells
 */
export declare class NavGrid implements Graph {
	private _columns;
	private _rows;
	private _tileWidth;
	private _tileHeight;
	private _diagonals;
	private _connMap;
	private _isConnected;
	/**
	 * @param data - Grid data
	 * @param options - Navigation options
	 */
	constructor(width: number, height: number, isConnected: (a: number, b: number) => boolean, { diagonals, tileWidth, tileHeight }?: {
		diagonals?: boolean | undefined;
		tileWidth?: number | undefined;
		tileHeight?: number | undefined;
	});
	private _buildConnectivityMap;
	private _getTile;
	private _getTileX;
	private _getTileY;
	get nodes(): number[];
	getNeighbors(tile: number): number[];
	getCost(a: number, b: number): number;
	getHeuristic(a: number, b: number): number;
	getPath(start: number, goal: number): number[];
	getWaypointPath(start: Vec2, goal: Vec2): Vec2[];
}
declare class NavEdge {
	a: Vec2;
	b: Vec2;
	polygon: WeakRef<NavPolygon>;
	constructor(a: Vec2, b: Vec2, polygon: NavPolygon);
	isLeft(x: number, y: number): number;
	get middle(): Vec2;
}
declare class NavPolygon {
	private _edges;
	private _centroid;
	private _id;
	constructor(id: number);
	get id(): number;
	set edges(edges: NavEdge[]);
	get edges(): NavEdge[];
	get centroid(): Vec2;
	contains(p: Vec2): boolean;
}
export declare class NavMesh implements Graph {
	private _polygons;
	private _pointCache;
	private _edgeCache;
	constructor();
	private _addPoint;
	private _addEdge;
	private _findEdge;
	private _findCommonEdge;
	get nodes(): number[];
	addPolygon(vertices: Vec2[]): NavPolygon;
	addRect(pos: Vec2, size: Vec2): NavPolygon;
	private _getLocation;
	getNeighbors(index: number): number[];
	getCost(a: number, b: number): number;
	getHeuristic(indexA: number, indexB: number): number;
	getPath(start: number, goal: number): number[];
	getWaypointPath(start: Vec2, goal: Vec2, opt: any): Vec2[];
}
export interface BroadPhaseAlgorithm {
	add(obj: GameObj<AreaComp>): void;
	remove(obj: GameObj<AreaComp>): void;
	clear(): void;
	update(): void;
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
}
/**
 * A quadtree structure
 */
export declare class Quadtree implements BroadPhaseAlgorithm {
	bounds: Rect;
	maxObjects: number;
	maxLevels: number;
	level: number;
	nodes: Quadtree[];
	objects: GameObj<AreaComp>[];
	static versionsForObject: Map<GameObj<AreaComp>, [
		number,
		number,
		number
	]>;
	/**
	 * Creates a new quadtree
	 * @param bounds - The bounds of this node.
	 * @param maxObjects - The maximum amount of objects before triggering a split.
	 * @param maxLevels - The maximum amount of levels before no more splits are made.
	 * @param level - The current level.
	 */
	constructor(bounds: Rect, maxObjects?: number, maxLevels?: number, level?: number);
	/**
	 * True if this node is a leaf node.
	 */
	get isLeaf(): boolean;
	/**
	 * Splits the node, but doesn't redistribute objects
	 */
	subdivide(): void;
	/**
	 * Tries to merge and collapse nodes which are no longer overpopulated.
	 */
	merge(): void;
	/**
	 * Returns the quadrant this rect fits in or -1 if it doesn't fit any quadrant
	 * @param rect - The rect to test with.
	 *
	 * @returns The index of the quadrant fitting the rect completely, or -1 if none.
	 */
	getQuadrant(rect: Rect): 0 | 1 | 2 | -1 | 3;
	/**
	 * Returns the quadrants this rect intersects
	 * @param rect - The rect to test with. Note that this rect is assumed to be within the node.
	 *
	 * @returns the list of quadrant indices
	 */
	getQuadrants(rect: Rect): number[];
	/**
	 * Inserts the object with the given rectangle
	 * @param obj - The object to add
	 * @param bbox - The bounding box of the object
	 */
	insert(obj: GameObj<AreaComp>, bbox: Rect): void;
	/**
	 * Add the object
	 * @param obj - The object to add
	 */
	add(obj: GameObj<AreaComp>): void;
	/**
	 * Retrieves all objects potentially intersecting the rectangle
	 * @param rect - The rect to test with
	 *
	 * @returns A set of objects potentially intersecting the rectangle
	 */
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
	/**
	 * Removes the object
	 * @param obj - The object to remove
	 * @param fast - No node collapse if true
	 */
	remove(obj: GameObj<AreaComp>, fast?: boolean): boolean;
	/**
	 * Updates a single object
	 * Note that no testing is done here. Make sure the object needs to be actually updated.
	 * @param root - The tree root, since insertion happens from the root
	 * @param obj - The object to update
	 * @param bbox - The new bounding box
	 */
	updateObject(root: Quadtree, obj: GameObj<AreaComp>, bbox: Rect): void;
	/**
	 * True if the rectangle is completely outside this node's bounds
	 * @param bbox - The bounding box to test
	 */
	isOutside(bbox: Rect): boolean;
	/**
	 * True if the rectangle is completely outside this node's bounds
	 * @param bbox - The bounding box to test
	 */
	isInside(bbox: Rect): boolean;
	/**
	 * Updates all objects in this node and the objects of its children
	 * @param root - The tree root, since insertion happens from the root
	 */
	updateNode(orphans: [
		GameObj<AreaComp>,
		Rect
	][]): void;
	/**
	 * Update this tree
	 */
	update(): void;
	/**
	 * Clears this node and collapses it
	 */
	clear(): void;
	/**
	 * Gathers all collision pairs in this node and child nodes
	 * @param ancestorObjects - Objects in one of the node's ancestors
	 * @param pairs - The pairs being gathered
	 */
	gatherPairs(ancestorObjects: Array<GameObj<AreaComp>>, pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
}
export declare class ResizingQuadtree implements BroadPhaseAlgorithm {
	root: Quadtree;
	constructor(bounds: Rect, maxObjects?: number, maxLevels?: number);
	add(obj: GameObj<AreaComp>): void;
	remove(obj: GameObj<AreaComp>): void;
	clear(): void;
	update(): void;
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	get bounds(): Rect;
	get nodes(): Quadtree[];
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
}
export declare class BaseQuadtree<T> {
	bounds: Rect;
	maxObjects: number;
	maxLevels: number;
	level: number;
	nodes: BaseQuadtree<T>[];
	objects: T[];
	/**
	 * Creates a new quadtree
	 * @param bounds - The bounds of this node.
	 * @param maxObjects - The maximum amount of objects before triggering a split.
	 * @param maxLevels - The maximum amount of levels before no more splits are made.
	 * @param level - The current level.
	 */
	constructor(bounds: Rect, maxObjects?: number, maxLevels?: number, level?: number);
	/**
	 * True if this node is a leaf node.
	 */
	get isLeaf(): boolean;
	/**
	 * Splits the node, but doesn't redistribute objects
	 */
	subdivide(): void;
	/**
	 * Tries to merge and collapse nodes which are no longer overpopulated.
	 */
	merge(): void;
	/**
	 * Returns the quadrant this rect fits in or -1 if it doesn't fit any quadrant
	 * @param rect - The rect to test with.
	 *
	 * @returns The index of the quadrant fitting the rect completely, or -1 if none.
	 */
	getQuadrant(rect: Rect): 0 | 1 | 2 | -1 | 3;
	/**
	 * Returns the quadrants this rect intersects
	 * @param rect - The rect to test with. Note that this rect is assumed to be within the node.
	 *
	 * @returns the list of quadrant indices
	 */
	getQuadrants(rect: Rect): number[];
	/**
	 * Inserts the object with the given rectangle
	 * @param obj - The object to add
	 * @param bbox - The bounding box of the object
	 */
	insert(obj: T, bbox: Rect): void;
	/**
	 * Retrieves all objects potentially intersecting the rectangle
	 * @param rect - The rect to test with
	 *
	 * @returns A set of objects potentially intersecting the rectangle
	 */
	retrieve(rect: Rect, retrieveCb: (obj: T) => void): void;
	/**
	 * Removes the object
	 * @param obj - The object to remove
	 * @param fast - No node collapse if true
	 */
	remove(obj: T, fast?: boolean): boolean;
	/**
	 * Updates a single object
	 * Note that no testing is done here. Make sure the object needs to be actually updated.
	 * @param obj - The object to update
	 * @param bbox - The new bounding box
	 */
	updateObject(obj: T, bbox: Rect, fast?: boolean): void;
	/**
	 * True if the rectangle is completely outside this node's bounds
	 * @param bbox - The bounding box to test
	 */
	isOutside(bbox: Rect): boolean;
	/**
	 * True if the rectangle is completely outside this node's bounds
	 * @param bbox - The bounding box to test
	 */
	isInside(bbox: Rect): boolean;
	/**
	 * Clears this node and collapses it
	 */
	clear(): void;
	/**
	 * Gathers all collision pairs in this node and child nodes
	 * @param ancestorObjects - Objects in one of the node's ancestors
	 * @param pairs - The pairs being gathered
	 */
	gatherPairs(ancestorObjects: Array<T>, pairCb: (obj1: T, obj2: T) => void): void;
	iterPairs(pairCb: (obj1: T, obj2: T) => void): void;
}
export type Engine = ReturnType<typeof createEngine>;
declare const createEngine: (gopt: KAPLAYOpt) => {
	globalOpt: {
		scale: number;
		spriteAtlasPadding: number;
		defaultLifetimeScope: "scene" | "app";
	} & KAPLAYOpt;
	canvas: HTMLCanvasElement;
	app: {
		state: {
			canvas: HTMLCanvasElement;
			buttons: ButtonsDef;
			buttonHandler: ButtonProcessor;
			loopID: null | number;
			stopped: boolean;
			dt: number;
			fixedDt: number;
			maxStep: number;
			restDt: number;
			time: number;
			realTime: number;
			rawFPSCounter: {
				maxSamples: number;
				history: Float64Array;
				accumulator: number;
				i: number;
				fps: number;
				curNSamples: number;
				timer: number;
				autoRecalculateInterval: number;
				tick(dt: number): void;
				calculate(): number;
				ago(ago: number): number | undefined;
				resize(samples: number): void;
			};
			fpsCounter: {
				maxSamples: number;
				history: Float64Array;
				accumulator: number;
				i: number;
				fps: number;
				curNSamples: number;
				timer: number;
				autoRecalculateInterval: number;
				tick(dt: number): void;
				calculate(): number;
				ago(ago: number): number | undefined;
				resize(samples: number): void;
			};
			timeScale: number;
			skipTime: boolean;
			isHidden: boolean;
			numFrames: number;
			capsOn: boolean;
			mousePos: Vec2;
			mouseDeltaPos: Vec2;
			keyState: ButtonState<Key, never>;
			mouseState: ButtonState<MouseButton, never>;
			mergedGamepadState: {
				buttonState: ButtonState<KGamepadButton, KGamepad>;
				stickState: Map<KGamepadStick, Vec2>;
				analogState: Map<string, number>;
			};
			gamepadStates: Map<number, {
				buttonState: ButtonState<KGamepadButton, KGamepad>;
				stickState: Map<KGamepadStick, Vec2>;
				analogState: Map<string, number>;
			}>;
			lastInputDevice: "mouse" | "keyboard" | "gamepad" | null;
			gamepads: KGamepad[];
			charInputted: string[];
			isMouseMoved: boolean;
			lastWidth: number;
			lastHeight: number;
			events: KEventHandler<AppEventMap>;
		};
		dt: () => number;
		fixedDt: () => number;
		restDt: () => number;
		time: () => number;
		run: (fixedUpdate: () => void, update: (processInput: () => void, resetInput: () => void) => void) => void;
		canvas: HTMLCanvasElement;
		fps: () => number;
		rawFPS: () => number;
		setFixedSpeed: (speed: FixedSpeedOption) => void;
		numFrames: () => number;
		quit: () => void;
		isHidden: () => boolean;
		setFullscreen: (f?: boolean) => void;
		isFullscreen: () => boolean;
		setCursor: (c: Cursor) => void;
		screenshot: () => string;
		screenshotToBlob: () => Promise<Blob>;
		getGamepads: () => KGamepad[];
		getCursor: () => Cursor;
		setCursorLocked: (b: boolean) => void;
		isCursorLocked: () => boolean;
		isTouchscreen: () => boolean;
		mousePos: () => Vec2;
		mouseDeltaPos: () => Vec2;
		isKeyDown: (k?: Key | Key[]) => boolean;
		isKeyPressed: (k?: Key | Key[]) => boolean;
		isKeyPressedRepeat: (k?: Key | Key[]) => boolean;
		isKeyReleased: (k?: Key | Key[]) => boolean;
		isMouseDown: (m?: MouseButton) => boolean;
		isMousePressed: (m?: MouseButton) => boolean;
		isMouseReleased: (m?: MouseButton) => boolean;
		isMouseMoved: () => boolean;
		isGamepadButtonPressed: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
		isGamepadButtonDown: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
		isGamepadButtonReleased: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
		isFocused: () => boolean;
		getGamepadStick: (stick: KGamepadStick) => Vec2;
		getGamepadAnalogButton: (btn: KGamepadButton) => number;
		isButtonPressed: (btn?: string | string[]) => boolean;
		isButtonDown: (btn?: string | string[]) => boolean;
		isButtonReleased: (btn?: string | string[]) => boolean;
		getButton: (btn: string) => ButtonBinding;
		getButtons: () => ButtonsDef;
		setButton: (btn: string, binding: ButtonBinding) => void;
		pressButton: (btn: string) => void;
		releaseButton: (btn: string) => void;
		charInputted: () => string[];
		onResize: (action: () => void) => KEventController;
		onKeyDown: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyPress: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyPressRepeat: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyRelease: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onMouseDown: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMousePress: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMouseRelease: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMouseMove: (f: (pos: Vec2, dpos: Vec2) => void) => KEventController;
		onCharInput: (action: (ch: string) => void) => KEventController;
		onTouchStart: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onTouchMove: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onTouchEnd: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onScroll: (action: (delta: Vec2) => void) => KEventController;
		onHide: (action: () => void) => KEventController;
		onShow: (action: () => void) => KEventController;
		onTabHide: (action: () => void) => KEventController;
		onTabShow: (action: () => void) => KEventController;
		onGamepadButtonDown: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton, action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadButtonPress: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadButtonRelease: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadStick: (stick: KGamepadStick, action: (value: Vec2, gp: KGamepad) => void) => KEventController;
		onGamepadConnect: (action: (gamepad: KGamepad) => void) => KEventController;
		onGamepadDisconnect: (action: (gamepad: KGamepad) => void) => KEventController;
		onButtonPress: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		onButtonDown: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		onButtonRelease: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		getLastInputDeviceType: () => "keyboard" | "gamepad" | "mouse" | null;
		events: KEventHandler<AppEventMap>;
	};
	ggl: {
		gl: WebGLRenderingContext;
		opts: KAPLAYOpt;
		onDestroy: (action: () => unknown) => void;
		destroy: () => void;
		pushTexture2D: (item: WebGLTexture) => void;
		popTexture2D: () => void;
		pushArrayBuffer: (item: WebGLBuffer) => void;
		popArrayBuffer: () => void;
		pushElementArrayBuffer: (item: WebGLBuffer) => void;
		popElementArrayBuffer: () => void;
		pushFramebuffer: (item: WebGLFramebuffer) => void;
		popFramebuffer: () => void;
		pushRenderbuffer: (item: WebGLRenderbuffer) => void;
		popRenderbuffer: () => void;
		pushViewport: (item: {
			x: number;
			y: number;
			w: number;
			h: number;
		}) => void;
		popViewport: () => void;
		pushProgram: (item: WebGLProgram) => void;
		popProgram: () => void;
		setVertexFormat: (fmt: VertexFormat) => void;
	};
	gfx: AppGfxCtx;
	audio: InternalAudioCtx;
	assets: {
		urlPrefix: string;
		sprites: AssetBucket<SpriteData>;
		fonts: AssetBucket<FontData>;
		bitmapFonts: AssetBucket<GfxFont>;
		sounds: AssetBucket<SoundData>;
		shaders: AssetBucket<Shader>;
		custom: AssetBucket<any>;
		prefabAssets: AssetBucket<SerializedGameObj>;
		music: Record<string, string>;
		packer: TexPacker;
		loaded: boolean;
	};
	frameRenderer: {
		frameStart: () => void;
		frameEnd: () => void;
		fixedUpdateFrame: () => void;
		updateFrame: () => void;
	};
	fontCacheC2d: CanvasRenderingContext2D | null;
	fontCacheCanvas: HTMLCanvasElement;
	game: Game;
	debug: Debug;
	gc: (() => void)[];
	sceneScope: SceneScope;
	appScope: {
		onKeyDown: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyPress: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyPressRepeat: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onKeyRelease: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
		onCharInput: (action: (ch: string) => void) => KEventController;
		onMouseDown: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMousePress: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMouseRelease: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
		onMouseMove: (f: (pos: Vec2, dpos: Vec2) => void) => KEventController;
		onTouchStart: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onTouchEnd: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onTouchMove: (f: (pos: Vec2, t: Touch) => void) => KEventController;
		onScroll: (action: (delta: Vec2) => void) => KEventController;
		onGamepadConnect: (action: (gamepad: KGamepad) => void) => KEventController;
		onGamepadDisconnect: (action: (gamepad: KGamepad) => void) => KEventController;
		onGamepadButtonDown: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton, action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadButtonPress: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadButtonRelease: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
		onGamepadStick: (stick: KGamepadStick, action: (value: Vec2, gp: KGamepad) => void) => KEventController;
		onButtonDown: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		onButtonPress: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		onButtonRelease: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
		onTabShow: (action: () => void) => KEventController;
		onTabHide: (action: () => void) => KEventController;
		onUpdate: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
		onFixedUpdate: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
		onDraw: ((action: () => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
		onAdd: ((action: (obj: GameObj) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
		onDestroy: ((action: (obj: GameObj) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj) => void) => KEventController);
		onUse: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
		onUnuse: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
		onTag: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
		onUntag: ((action: (obj: GameObj, compId: string) => void) => KEventController) & ((tag: Tag, action: (obj: GameObj, compId: string) => void) => KEventController);
		on: <Ev extends GameObjEventNames | (string & {})>(event: Ev, tag: Tag, cb: (obj: GameObj, ...args: TupleWithoutFirst<GameObjEvents[Ev]>) => void) => KEventController;
		onClick: (tag: Tag, action: (obj: GameObj) => void) => KEventController;
		onCollide: typeof onCollide;
		onCollideEnd: typeof onCollideEnd;
		onCollideUpdate: typeof onCollideUpdate;
		onHover: typeof onHover;
		onHoverEnd: typeof onHoverEnd;
		onHoverUpdate: typeof onHoverUpdate;
		onResize: (action: () => void) => KEventController;
		onSceneLeave: typeof onSceneLeave;
		onLoad: typeof onLoad;
		onLoading: typeof onLoading;
		onError: typeof onError;
		onLoadError: typeof onLoadError;
		onCleanup: (action: () => void) => void;
		onShow: (action: () => void) => KEventController;
		onHide: (action: () => void) => KEventController;
	};
	k: KAPLAYCtx;
	startLoop(): void;
};
export type InfKAPLAYOpt<T extends KAPLAYOpt = KAPLAYOpt> = {
	buttons: T extends {
		buttons: infer B;
	} ? B : undefined;
	plugins: T extends {
		plugins: infer P;
	} ? P : undefined;
	scenes: T extends {
		types: infer P;
	} ? P extends {
		scenes: infer S;
	} ? S : undefined : undefined;
	tags: T extends {
		types: infer P;
	} ? P extends {
		tags: infer T;
	} ? T : undefined : undefined;
	strictScenes: T extends {
		types: infer P;
	} ? P extends {
		strictScenes: infer S;
	} ? S : undefined : undefined;
	strictTag: T extends {
		types: infer P;
	} ? P extends {
		strictTags: infer T;
	} ? T : undefined : undefined;
};
export type OptionalString<T extends string> = T | {} & string;
/**
 * Type options for the KAPLAY context.
 */
export type TypesOpt = {
	/**
	 * Scene types, made for inference in
	 *
	 * - `go()`
	 * - `scene()`
	 * - `stay()`
	 */
	scenes?: {
		[key in string]?: any[];
	};
	/**
	 * Tag types, made for inference in
	 *
	 * - `get()`
	 * - all `on()` functions
	 */
	/**
	 * If `true`, the scene name must be only the ones defined in `scenes`.
	 */
	strictScenes?: boolean;
};
export type Opt<T extends TypesOpt = TypesOpt> = T;
export type KAPLAYOptTypeOptions = Pick<KAPLAYOpt, "buttons" | "plugins" | "types">;
export type KAPLAYTypeOptWithoutPlugins = Omit<KAPLAYOptTypeOptions, "plugins">;
export type SceneName<O extends KAPLAYOptTypeOptions> = InfKAPLAYOpt<O>["scenes"] extends undefined ? string : InfKAPLAYOpt<O>["strictScenes"] extends true ? keyof InfKAPLAYOpt<O>["scenes"] : OptionalString<Extract<keyof InfKAPLAYOpt<O>["scenes"], string>>;
export type SceneArgs<TScene, TSceneMap> = TScene extends keyof TSceneMap ? TSceneMap[TScene] extends Array<any> ? TSceneMap[TScene] : any[] : any[];
export type ButtonName<TOpt extends KAPLAYOptTypeOptions> = keyof TOpt["buttons"] extends undefined ? string : TOpt["buttons"] extends Record<string, ButtonBinding> ? Extract<keyof TOpt["buttons"], string> : OptionalString<Extract<keyof TOpt["buttons"], string>>;
export type SceneScopeT<O extends KAPLAYOptTypeOptions = any> = ScopeHandlers & {
	<T extends SceneName<O>>(name: T, def: (...args: SceneArgs<T, InfKAPLAYOpt<O>["scenes"]>) => void): void;
};
export interface KAPLAYCtxTMethods<O extends KAPLAYOptTypeOptions = any> {
	scene: SceneScopeT<O>;
	go<T extends SceneName<O>>(name: T, ...args: SceneArgs<T, InfKAPLAYOpt<O>["scenes"]>): void;
	pushScene<T extends SceneName<O>>(T: string, ...args: SceneArgs<T, InfKAPLAYOpt<O>["scenes"]>): void;
	getSceneName(): SceneName<O> | null;
	onButtonPress(btn: ButtonName<O> | ButtonName<O>[], action: (btn: ButtonName<O>) => void): KEventController;
	onButtonPress(action: (btn: ButtonName<O>) => void): KEventController;
	onButtonRelease(btn: ButtonName<O> | ButtonName<O>[], action: (btn: ButtonName<O>) => void): KEventController;
	onButtonRelease(action: (btn: ButtonName<O>) => void): KEventController;
	onButtonDown(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonDown(action: (btn: ButtonName<O>) => void): KEventController;
	isButtonPressed(btn?: ButtonName<O> | ButtonName<O>[]): boolean;
	isButtonDown(btn?: ButtonName<O> | ButtonName<O>[]): boolean;
	isButtonReleased(btn?: ButtonName<O> | ButtonName<O>[]): boolean;
	getButton(btn: ButtonName<O>): ButtonBinding;
	pressButton(btn: ButtonName<O>): void;
	releaseButton(btn: ButtonName<O>): void;
}
export type KAPLAYCtxT<O extends KAPLAYOptTypeOptions = any> = KAPLAYCtxTMethods<O> & Omit<KAPLAYCtx, keyof KAPLAYCtxTMethods<O>>;
/**
 * Context handle that contains every KAPLAY function.
 *
 * @template TButtonDef - The button map
 * @template TButton - The button type
 *
 * @group Start
 */
export interface KAPLAYCtx {
	/**
	 * Internal data that should not be accessed directly.
	 *
	 * @ignore
	 *
	 * @readonly
	 * @group Misc
	 */
	_k: Engine & {
		k: KAPLAYCtx;
	};
	/**
	 * End everything.
	 *
	 * @since v2000.0
	 * @group Start
	 */
	quit(): void;
	/**
	 * Throws a new error and shows the Blue Screen.
	 *
	 * @param msg - The message to be shown on the Blue Screen.
	 *
	 * @since v4000.0
	 * @group Start
	 */
	throwError(msg: string): void;
	/**
	 * Assemble a game object from a list of components, and add it to the game,
	 *
	 * @param comps - List of components to add to the game object.
	 *
	 * @example
	 * ```js
	 * const player = add([
	 *     // List of components, each offers a set of functionalities
	 *     sprite("mark"),
	 *     pos(100, 200),
	 *     area(),
	 *     body(),
	 *     health(8),
	 *     // Plain strings are tags, a quicker way to let us define behaviors for a group
	 *     "player",
	 *     "friendly",
	 *     // Components are just plain objects, you can pass an object literal as a component.
	 *     {
	 *         dir: LEFT,
	 *         dead: false,
	 *         speed: 240,
	 *     },
	 * ]);
	 *
	 * // .jump is provided by body()
	 * player.jump();
	 * // .moveTo is provided by pos()
	 * player.moveTo(300, 200);
	 *
	 * // .onUpdate() is on every game object, it registers an event that runs every frame
	 * player.onUpdate(() => {
	 *     // .move() is provided by pos()
	 *     player.move(player.dir.scale(player.speed));
	 * });
	 *
	 * // .onCollide is provided by area()
	 * player.onCollide("tree", () => {
	 *     destroy(player);
	 * });
	 * ```
	 *
	 * @returns The added game object that contains all properties and methods each component offers.
	 * @group Game Obj
	 */
	add<T extends CompList<unknown>>(comps?: [
		...T
	]): GameObj<T[number]>;
	/**
	 * Assemble a game object from a prefab asset loaded with {@link loadPrefab `loadPrefab()`} or using {@link createPrefab `createPrefab()`}.
	 *
	 * @example
	 * ```js
	 * loadPrefab("bean", "/prefabs/bean.kaprefab");
	 *
	 * addPrefab("bean", [
	 *     pos(40, 40)
	 * ]);
	 * ```
	 *
	 * @returns The added game object that contains all properties and methods each component offers.
	 * @group Game Obj
	 */
	addPrefab<T extends CompList<unknown>>(nameOrObject: SerializedGameObj | string, compList?: [
		...T
	]): GameObj<T[number]>;
	/**
	 * Serialize a game object and register it (like {@link loadPrefab `loadPrefab()`} does).
	 *
	 * @param name - Name to register the prefab.
	 * @param obj - The game object to serialize.
	 *
	 * @example
	 * ```js
	 * const beanObj = add([ sprite("bean") ]);
	 * createPrefab("bean", beanObj);
	 *
	 * addPrefab("bean"); // Now you can use as prefab
	 * ```
	 *
	 * @returns The serialized game object.
	 * @since v4000.0
	 * @group Game Obj
	 */
	createPrefab(name: string, obj: GameObj): SerializedGameObj;
	/**
	 * Serialize a game object.
	 *
	 * @param obj - The game object to serialize.
	 *
	 * @example
	 * ```js
	 * const beanObj = add([ sprite("bean") ]);
	 * const beanPrefab = createPrefab(beanObj);
	 *
	 * addPrefab(beanPrefab); // Now you can use as prefab
	 * ```
	 *
	 * @returns The serialized game object.
	 * @since v4000.0
	 * @group Game Obj
	 * @subgroup Prefabs
	 */
	createPrefab(obj: GameObj): SerializedGameObj;
	/**
	 * Remove and re-add the game obj, without triggering add / destroy events.
	 *
	 * @param obj - The game object to re-add.
	 *
	 * @example
	 * ```js
	 * // Common way to use this is to have one sprite overlap another sprite, and use readd() to have the bottom sprite on top of the other.
	 *
	 * // Create two sprites.
	 * const greenBean = add([
	 *     sprite("bean"),
	 *     pos(200,140),
	 *     color(255, 255, 255),
	 *     area(),
	 * ]);
	 *
	 * // This bean will overlap the green bean.
	 * const purpleBean = add([
	 *     sprite("bean"),
	 *     pos(230,140),
	 *     color(255, 0, 255),
	 *     area(),
	 * ]);
	 *
	 * // Example 1: simply call readd() on the target you want on top.
	 * readd(greenBean);
	 *
	 * // Example 2: using onClick() or other functions with readd().
	 * // If you comment out the first example, and use this readd() with a function like onClick(), you
	 * can keep switching which sprite is above the other ( click on edge of face ).
	 *
	 * purpleBean.onClick(() => {
	 *     readd(greenBean);
	 * });
	 *
	 * greenBean.onClick(() => {
	 *     readd(purpleBean);
	 * });
	 * ```
	 *
	 * @returns The re-added game object.
	 * @since v3001.0
	 * @group Game Obj
	 */
	readd(obj: GameObj): GameObj;
	/**
	 * Retrieves all objects within the given rectangle
	 *
	 * @since v4000
	 * @group Game Obj
	 */
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
	/**
	 * Get a list of all game objs with certain tag.
	 *
	 * @param tag - The tag to search for. Use "*" to get all objects.
	 * @param opts - Additional options.
	 *
	 * @example
	 * ```js
	 * // get a list of all game objs with tag "bomb"
	 * const allBombs = get("bomb");
	 *
	 * // To get all objects use "*"
	 * const allObjs = get("*");
	 *
	 * // Recursively get all children and descendents
	 * const allObjs = get("*", { recursive: true });
	 *
	 * // Get a live query which updates in real-time
	 * const allObjs = get("*", { liveUpdate: true });
	 * ```
	 *
	 * @returns A list of game objects that have the tag.
	 * @since v2000.0
	 * @group Game Obj
	 */
	get<T = any>(tag: Tag | Tag[], opts?: GetOpt): GameObj<T>[];
	/**
	 * Get a list of game objects in an advanced way.
	 *
	 * @param opt - The query options.
	 *
	 * @example
	 * ```js
	 * const bean = k.add(["friend", "bean"]);
	 * const bean2 = k.add(["friend", "bean"]);
	 * const bag = k.add(["friend", "bag"]);
	 *
	 * // get bean
	 * query({
	 *     include: "bean",
	 * }) // will return [bean, bean2];
	 *
	 * // get all friends excluding bean
	 * query({
	 *     include: "friend",
	 *     exclude: "bean",
	 * }); // will return [bag]
	 *
	 * // get all visible friends
	 * query({
	 *     include: "friend",
	 *     visible: true,
	 * });
	 *
	 * // get all friends less than 150 pixels from bean
	 * bean.query({
	 *     include: "friend",
	 *     distance: 150,
	 * });
	 *
	 * ```
	 *
	 * @group Game Obj
	 */
	query(opt: QueryOpt): GameObj[];
	/**
	 * Checks whether the game obj is a valid object.
	 *
	 * @param obj - The game object to check.
	 *
	 * @group Game Obj
	 */
	exists(obj: GameObj): boolean;
	/**
	 * Remove the game obj.
	 *
	 * @param obj - The game object to remove.
	 *
	 * @example
	 * ```js
	 * // every time bean collides with anything with tag "fruit", remove it
	 * bean.onCollide("fruit", (fruit) => {
	 *     destroy(fruit);
	 * });
	 * ```
	 *
	 * @group Game Obj
	 */
	destroy(obj: GameObj): void;
	/**
	 * Remove all game objs with certain tag.
	 *
	 * @param tag - The tag to search for.
	 *
	 * @example
	 * ```js
	 * // destroy all objects with tag "bomb" when you click one
	 * onClick("bomb", () => {
	 *     destroyAll("bomb");
	 * });
	 * ```
	 *
	 * @group Game Obj
	 */
	destroyAll(tag: Tag): void;
	/**
	 * Set the position of a Game Object, relative to its parent.
	 *
	 * @param x - The x position to set.
	 * @param y - The y position to set.
	 *
	 * @example
	 * ```js
	 * // This game object will draw a "bean" sprite at (100, 200)
	 * let bean = add([
	 *     pos(100, 200),
	 *     sprite("bean"),
	 * ]);
	 *
	 * // This game object will draw a rectangle at (105, 205) world coordinate.
	 * // The position will be 5 pixels to the right and 5 pixels down from the parent bean.
	 * let rect = bean.add([
	 *     pos(5, 5),
	 *     rect(100, 100),
	 * ]);
	 * ```
	 *
	 * @returns The position comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Transform
	 */
	pos(x: number, y: number): PosComp;
	pos(xy: number): PosComp;
	pos(p: Vec2): PosComp;
	pos(): PosComp;
	/**
	 * Set the scale of a Game Object.
	 *
	 * @param x - The x scale to set.
	 * @param y - The y scale to set.
	 *
	 * @example
	 * ```js
	 * // scale uniformly with one value
	 * add([
	 *     sprite("bean"),
	 * 	   scale(3),
	 * ]);
	 *
	 * // scale with x & y values. In this case, scales more horizontally.
	 * add([
	 *     sprite("bean"),
	 * 	   scale(3, 1),
	 * ]);
	 *
	 * // scale with vec2(x,y)
	 * bean.scale = vec2(2,4);
	 *
	 * ```
	 *
	 * @returns The scale comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Transform
	 */
	scale(x: number, y: number): ScaleComp;
	scale(xy: number): ScaleComp;
	scale(s: Vec2): ScaleComp;
	scale(): ScaleComp;
	/**
	 * Rotates a Game Object (in degrees).
	 *
	 * @param a - The angle to rotate by. Defaults to 0.
	 *
	 * @example
	 * ```js
	 * let bean = add([
	 *     sprite("bean"),
	 *     rotate(),
	 * ])
	 *
	 * // bean will be upside down!
	 * bean.angle = 180
	 * ```
	 *
	 * @returns The rotate comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Transform
	 */
	rotate(a?: number): RotateComp;
	/**
	 * Set the skew of a Game Object.
	 *
	 * @param x - The x skew to set.
	 * @param y - The y skew to set.
	 *
	 * @example
	 * ```js
	 * // skew x
	 * add([
	 *     sprite("bean"),
	 * 	   skew(45, 0),
	 * ]);
	 * ```
	 *
	 * @returns The skew comp.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Transform
	 */
	skew(x: number, y: number): SkewComp;
	skew(s: Vec2): SkewComp;
	/**
	 * Sets the color of a Game Object (rgb 0-255).
	 *
	 * @param r - The red value to set.
	 * @param g - The green value to set.
	 * @param b - The blue value to set.
	 *
	 * @example
	 * ```js
	 * // blue frog
	 * add([
	 *     sprite("bean"),
	 *     color(0, 0, 255),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(r: number, g: number, b: number): ColorComp;
	/**
	 * Sets the color of a Game Object using a previously created Color Object.
	 *
	 * @param c - The color to clone and set.
	 *
	 * @example
	 * ```js
	 * // blue frog
	 * const blue = rgb(0, 0, 255);
	 *
	 * add([
	 *     sprite("bean"),
	 *     color(blue),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(c: Color): ColorComp;
	/**
	 * Sets the color of a Game Object using an array (rgb 0-255).
	 *
	 * @param rgb - The color array to set [r, g, b].
	 *
	 * @example
	 * ```js
	 * // blue frog
	 * add([
	 *     sprite("bean"),
	 *     color([0, 0, 255]),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(rgb: [
		number,
		number,
		number
	]): ColorComp;
	/**
	 * Sets the color of a Game Object using a CSS color keywords or hexadecimal string.
	 *
	 * @param c - The CSS color keyword or hexadecimal code to set.
	 *
	 * @example
	 * ```js
	 * // blue frog (HEX)
	 * add([
	 *     sprite("bean"),
	 *     color("#0000ff"),
	 * ]);
	 *
	 * // red cheese (CSS)
	 * add([
	 *     sprite("mark"),
	 *     color("red"),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(c: OptionalString<CSSColorKeywords>): ColorComp;
	/**
	 * Sets the color of a Game Object using a hexadecimal literal number.
	 *
	 * @param c - The hexadecimal literal number.
	 *
	 * @example
	 * ```js
	 * // blue frog
	 * add([
	 *     sprite("bean"),
	 *     color(0x0000ff),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(c: number): ColorComp;
	/**
	 * Sets the color of a Game Object to white (no effect).
	 *
	 * @example
	 * ```js
	 * // normal frog
	 * add([
	 *     sprite("bean"),
	 *     color(),
	 * ]);
	 * ```
	 *
	 * @returns The color comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	color(): ColorComp;
	/**
	 * Sets the blend mode of a Game Object.
	 *
	 * @example
	 * ```js
	 * // light
	 * add([
	 *     sprite("light"),
	 *     blend(BlendMode.Add),
	 * ]);
	 * ```
	 *
	 * @returns The blend comp.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	blend(blend: BlendMode): BlendComp;
	/**
	 * Sets the opacity of a Game Object (0.0 - 1.0).
	 *
	 * @param o - The opacity value to set.
	 *
	 * @example
	 * ```js
	 * const bean = add([
	 *     sprite("bean"),
	 *     opacity(0.5), // Make bean 50% transparent
	 * ])
	 *
	 * // Make bean invisible
	 * bean.opacity = 0
	 *
	 * // Make bean fully visible
	 * bean.opacity = 1
	 * ```
	 *
	 * @returns The opacity comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	opacity(o?: number): OpacityComp;
	/**
	 * Sets the fill of a Game Object.
	 *
	 * @param fill - The fill value to set.
	 *
	 * @returns The fill comp.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	fill(fill: boolean): FillComp;
	/**
	 * Attach and render a sprite to a Game Object.
	 *
	 * @param spr - The sprite to render.
	 * @param opt - Options for the sprite component. See {@link SpriteCompOpt `SpriteCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // minimal setup
	 * add([
	 *     sprite("bean"),
	 * ])
	 *
	 * // with options
	 * const bean = add([
	 *     sprite("bean", {
	 *         // start with animation "idle"
	 *         anim: "idle",
	 *     }),
	 * ])
	 *
	 * // play / stop an anim
	 * bean.play("jump")
	 * bean.stop()
	 *
	 * // manually setting a frame
	 * bean.frame = 3
	 * ```
	 *
	 * @returns The sprite comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	sprite(spr: string | SpriteData | Asset<SpriteData>, opt?: SpriteCompOpt): SpriteComp;
	/**
	 * Attach and render a text to a Game Object.
	 *
	 * @param txt - The text to display.
	 * @param opt - Options for the text component. See {@link TextCompOpt}.
	 *
	 * @example
	 * ```js
	 * // a simple score counter
	 * const score = add([
	 *     text("Score: 0"),
	 *     pos(24, 24),
	 *     { value: 0 },
	 * ])
	 *
	 * player.onCollide("coin", () => {
	 *     score.value += 1
	 *     score.text = "Score:" + score.value
	 * })
	 *
	 * // with options
	 * add([
	 *     pos(24, 24),
	 *     text("ohhi", {
	 *         size: 48, // 48 pixels tall
	 *         width: 320, // it'll wrap to next line when width exceeds this value
	 *         font: "sans-serif", // specify any font you loaded or browser built-in
	 *     }),
	 * ])
	 * ```
	 *
	 * @returns The text comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	text(txt?: string, opt?: TextCompOpt): TextComp;
	/**
	 * Attach and render a polygon to a Game Object.
	 *
	 * @param pts - The points to render the polygon.
	 * @param opt - Options for the polygon component. See {@link PolygonCompOpt `PolygonCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // Make a square the hard way
	 * add([
	 *     pos(80, 120),
	 *     polygon([vec2(0,0), vec2(50,0), vec2(50,50), vec2(0,50)]),
	 *     outline(4),
	 *     area(),
	 * ])
	 * ```
	 *
	 * @returns The polygon comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Rendering
	 */
	polygon(pts: Vec2[], opt?: PolygonCompOpt): PolygonComp;
	/**
	 * Create an outline in the form of a polygon from a sprite object
	 *
	 * @param asset - The name of the sprite you want to generate an outline for
	 * @param frame - The frame of the sprite that the outline should be taken from
	 * @param RDP - Should the function return a simplified polygon
	 * @param epsilon - The amount of the polygon that should be reduced
	 *
	 * @example
	 * ```js
	 * // Create a collider from the sprite
	 * onLoad(() => {
	 *     add([
	 *         sprite("apple"),
	 *         area({shape: getSpriteOutline("apple")}),
	 *         pos(120, 80), // optional position
	 *     ]);
	 * });
	 * ```
	 *
	 * @returns A polygon shape.
	 * @since v4000.0
	 */
	getSpriteOutline(asset: string, frame?: number, RDP?: boolean, epsilon?: number): Polygon;
	/**
	 * Attach and render a rectangle to a Game Object.
	 *
	 * @param w - The width of the rectangle.
	 * @param h - The height of the rectangle.
	 * @param opt - Options for the rectangle component. See {@link RectCompOpt `RectCompOpt`}.
	 *
	 * @example
	 * ```js
	 * const obstacle = add([
	 *     pos(80, 120),
	 *     rect(20, 40),
	 *     outline(4),
	 *     area(),
	 * ])
	 * ```
	 *
	 * @returns The rectangle component.
	 * @group Components
	 * @subgroup Rendering
	 */
	rect(w: number, h: number, opt?: RectCompOpt): RectComp;
	/**
	 * Attach and render a circle to a Game Object.
	 *
	 * @param radius - The radius of the circle.
	 * @param opt - Options for the circle component. See {@link CircleCompOpt `CircleCompOpt`}.
	 *
	 * @example
	 * ```js
	 * add([
	 *     pos(80, 120),
	 *     circle(16),
	 * ])
	 * ```
	 *
	 * @returns The circle comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	circle(radius: number, opt?: CircleCompOpt): CircleComp;
	/**
	 * Attach and render an ellipse to a Game Object.
	 *
	 * @param radiusX - The radius of the ellipse on the x-axis.
	 * @param radiusY - The radius of the ellipse on the y-axis.
	 *
	 * @example
	 * ```js
	 * add([
	 *     pos(80, 120),
	 *     ellipse(16, 8),
	 * ])
	 * ```
	 *
	 * @returns The ellipse comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	ellipse(radiusX: number, radiusY: number): EllipseComp;
	/**
	 * Attach and render a UV quad to a Game Object.
	 *
	 * @param w - The width of the quad.
	 * @param h - The height of the quad.
	 *
	 * @example
	 * ```js
	 * add([
	 *     uvquad(width(), height()),
	 *     shader("spiral"),
	 * ])
	 * ```
	 *
	 * @returns The UV quad comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	uvquad(w: number, h: number): UVQuadComp;
	/**
	 * Draws a video.
	 *
	 * @param url - The video to play. Needs to be on the same webserver due to CORS.
	 * @param opt - The video component options
	 *
	 * @returns The video comp.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	video(url: string, opt?: VideoCompOpt): VideoComp;
	/**
	 * Draws a picture, using the Picture API.
	 *
	 * @param picture - The picture to draw.
	 *
	 * @returns The picture comp.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	picture(picture: Picture): PictureComp;
	/**
	 * Attaches a collider area from a shape and enables collision detection on a Game Object.
	 *
	 * @param opt - Options for the area component. See {@link AreaCompOpt `AreaCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // Automatically generate area information from the shape of render
	 * const player = add([
	 *     sprite("bean"),
	 *     area(),
	 * ])
	 *
	 * // Die if player collides with another game obj with tag "tree"
	 * player.onCollide("tree", () => {
	 *     destroy(player)
	 *     go("lose")
	 * })
	 *
	 * // Check for collision manually every frame instead of registering an event
	 * player.onUpdate(() => {
	 *     if (player.isColliding(bomb)) {
	 *         score += 1
	 *     }
	 * })
	 * ```
	 *
	 * @returns The area comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Physics
	 */
	area(opt?: AreaCompOpt): AreaComp;
	/**
	 * Anchor point for render (default "topleft").
	 *
	 * @param o - The anchor point to set.
	 *
	 * @example
	 * ```js
	 * // set anchor to "center" so it'll rotate from center
	 * add([
	 *     rect(40, 10),
	 *     rotate(45),
	 *     anchor("center"),
	 * ])
	 * ```
	 *
	 * @returns The anchor comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	anchor(o: Anchor | Vec2): AnchorComp;
	/**
	 * Determines the draw order for objects on the same layer. Object will be drawn on top if z value is bigger.
	 *
	 * @param z - The z value to set.
	 *
	 * @example
	 * ```js
	 * const bean = add([
	 *    sprite("bean"),
	 *    pos(100, 100),
	 *    z(10), // Bean has a z value of 10
	 * ])
	 *
	 * // Mark has a z value of 20, so he will always be drawn on top of bean
	 * const mark = add([
	 *   sprite("mark"),
	 *   pos(100, 100),
	 *   z(20),
	 * ])
	 *
	 * bean.z = 30 // Bean now has a higher z value, so it will be drawn on top of mark
	 * ```
	 *
	 * @returns The z comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Transform
	 */
	z(z: number): ZComp;
	/**
	 * Determines the layer for objects. Object will be drawn on top if the layer index is higher.
	 *
	 * @param name - The layer name to set.
	 *
	 * @example
	 * ```js
	 * // Define layers
	 * layers(["background", "game", "foreground"], "game")
	 *
	 * const bean = add([
	 *     sprite("bean"),
	 *     pos(100, 100),
	 *     layer("background"),
	 * ])
	 *
	 * // Mark is in a higher layer, so he will be drawn on top of bean
	 * const mark = add([
	 *     sprite("mark"),
	 *     pos(100, 100),
	 *     layer("game"),
	 * ])
	 *
	 * bean.layer("foreground") // Bean is now in the foreground layer and will be drawn on top of mark
	 * ```
	 *
	 * @returns The layer comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Rendering
	 */
	layer(name: string): LayerComp;
	/**
	 * Give an object an outline. Doesn't support sprite or text components.
	 *
	 * @param width - The width of the outline.
	 * @param color - The color of the outline.
	 * @param opacity - The opacity of the outline.
	 * @param join - -The line join style.
	 * @param miterLimit - The miter limit ratio.
	 * @param cap -The line cap style.
	 *
	 * @example
	 * ```js
	 * // Add an outline to a rectangle
	 *
	 * add([
	 *    rect(40, 40),
	 *    outline(4),
	 * ]);
	 * ```
	 *
	 * @returns The outline comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	outline(width?: number, color?: Color, opacity?: number, join?: LineJoin, miterLimit?: number, cap?: LineCap): OutlineComp;
	/**
	 * Attach a particle emitter to a Game Object.
	 *
	 * @param popt - The options for the particles.
	 * @param eopt - The options for the emitter.
	 *
	 * @example
	 * ```js
	 * // beansplosion
	 *
	 * // create the emitter
	 * const emitter = add([
	 *     pos(center()),
	 *     particles({
	 *         max: 100,
	 *         speed: [75, 100],
	 *         lifeTime: [0.75,1.0],
	 *         angle: [0, 360],
	 *         opacities: [1.0, 0.0],
	 *         texture: getSprite("bean").tex,   // texture of a sprite
	 *         quads: getSprite("bean").frames,  // frames of a sprite
	 *     }, {
	 *         direction: 0,
	 *         spread: 360,
	 *     }),
	 * ])
	 *
	 * onUpdate(() => {
	 *     emitter.emit(1)
	 * })
	 * ```
	 *
	 * @returns The particles comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Rendering
	 */
	particles(popt: ParticlesOpt, eopt: EmitterOpt): ParticlesComp;
	/**
	 * Physical body that responds to gravity. Requires "area" and "pos" comp. This also makes the object "solid".
	 *
	 * @param opt - Options for the body component. See {@link BodyCompOpt `BodyCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // bean jumpy
	 * const bean = add([
	 *     sprite("bean"),
	 *     // body() requires "pos" and "area" component
	 *     pos(),
	 *     area(),
	 *     body(),
	 * ])
	 *
	 * // when bean is grounded, press space to jump
	 * // check out #BodyComp for more methods
	 * onKeyPress("space", () => {
	 *     if (bean.isGrounded()) {
	 *         bean.jump()
	 *     }
	 * })
	 *
	 * // run something when bean falls and hits a ground
	 * bean.onGround(() => {
	 *     debug.log("oh no!")
	 * })
	 * ```
	 *
	 * @returns The body comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Physics
	 */
	body(opt?: BodyCompOpt): BodyComp;
	/**
	 * Applies a force on a colliding object in order to make it move along the collision tangent vector.
	 * Good for conveyor belts.
	 *
	 * @param opt - Options for the surface effector component. See {@link SurfaceEffectorCompOpt `SurfaceEffectorCompOpt`}.
	 *
	 * @example
	 * ```js
	 * loadSprite("belt", "/sprites/jumpy.png")
	 *
	 * // conveyor belt
	 * add([
	 *     pos(center()),
	 *     sprite("belt"),
	 *     rotate(90),
	 *     area(),
	 *     body({ isStatic: true }),
	 *     surfaceEffector({
	 *         speed: 50,
	 *     }),
	 * ])
	 * ```
	 *
	 * @returns The surface effector comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	surfaceEffector(opt: SurfaceEffectorCompOpt): SurfaceEffectorComp;
	/**
	 * Applies a force on a colliding object.
	 * Good to apply anti-gravity, wind or water flow.
	 *
	 * @param opt - Options for the area effector component. See {@link AreaEffectorCompOpt `AreaEffectorCompOpt`}.
	 *
	 * @returns The area effector comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	areaEffector(opt: AreaEffectorCompOpt): AreaEffectorComp;
	/**
	 * Applies a force on a colliding object directed towards this object's origin.
	 * Good to apply magnetic attraction or repulsion.
	 *
	 * @param opt - Options for the point effector component. See {@link PointEffectorCompOpt `PointEffectorCompOpt`}.
	 *
	 * @returns The point effector comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	pointEffector(opt: PointEffectorCompOpt): PointEffectorComp;
	/**
	 * The platform effector makes it easier to implement one way platforms
	 * or walls. This effector is typically used with a static body, and it
	 * will only be solid depending on the direction the object is traveling from.
	 *
	 * @param opt - Options for the platform effector component. See {@link PlatformEffectorCompOpt `PlatformEffectorCompOpt`}.
	 *
	 * @returns The platform effector comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	platformEffector(opt?: PlatformEffectorCompOpt): PlatformEffectorComp;
	/**
	 * Applies an upwards force (force against gravity) to colliding objects depending on the fluid density and submerged area.
	 * Good to apply constant thrust.
	 *
	 * @param opt - Options for the buoyancy effector component. See {@link BuoyancyEffectorCompOpt `BuoyancyEffectorCompOpt`}.
	 *
	 * @returns The buoyancy effector comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	buoyancyEffector(opt: BuoyancyEffectorCompOpt): BuoyancyEffectorComp;
	/**
	 * Applies a constant force to the object.
	 * Good to apply constant thrust.
	 *
	 * @param opt - Options for the constant force component. See {@link ConstantForceCompOpt `ConstantForceCompOpt`}.
	 *
	 * @returns The constant force comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Physics
	 */
	constantForce(opt: ConstantForceCompOpt): ConstantForceComp;
	/**
	 * Enables double jump.
	 *
	 * @param numJumps - The number of jumps allowed. Defaults to 1.
	 *
	 * @returns The double jump comp.
	 * @since v3000.0
	 * @group Components
	 * @subgroup Physics
	 *
	 * @requires {@link body `body()`}
	 */
	doubleJump(numJumps?: number): DoubleJumpComp;
	/**
	 * Move towards a direction infinitely, and destroys when it leaves game view.
	 *
	 * @param dir - The direction to move towards.
	 * @param speed - The speed to move at.
	 *
	 * @example
	 * ```js
	 * // enemy throwing feces at player
	 * const projectile = add([
	 *     sprite("feces"),
	 *     pos(enemy.pos),
	 *     area(),
	 *     move(player.pos.angle(enemy.pos), 1200),
	 *     offscreen({ destroy: true }),
	 * ])
	 * ```
	 *
	 * @returns The move comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 *
	 * @requires {@link pos `pos()`}
	 */
	move(dir: number | Vec2, speed: number): MoveComp;
	/**
	 * Constraint components
	 */
	constraint: typeof constraint;
	/**
	 * Control the behavior of object when it goes out of view.
	 *
	 * @param opt - Options for the offscreen component. See {@link OffScreenCompOpt `OffScreenCompOpt`}.
	 *
	 * @example
	 * ```js
	 * add([
	 *     pos(player.pos),
	 *     sprite("bullet"),
	 *     offscreen({ destroy: true }),
	 *     "projectile",
	 * ]);
	 * ```
	 *
	 * @returns The offscreen comp.
	 * @since v2000.2
	 * @group Components
	 * @subgroup Behaviour
	 */
	offscreen(opt?: OffScreenCompOpt): OffScreenComp;
	/**
	 * Follow another game obj's position.
	 *
	 * @param obj - The game obj to follow.
	 * @param offset - The offset to follow at.
	 *
	 * @example
	 * ```js
	 * const bean = add(...);
	 *
	 * add([
	 *     sprite("bag"),
	 *     pos(),
	 *     follow(bean), // Follow bean's position
	 * ]);
	 *
	 * // Using offset
	 * const target = add(...);
	 *
	 * const mark = add([
	 *     sprite("mark"),
	 *     pos(),
	 *     follow(target, vec2(32, 32)), // Follow target's position with an offset
	 * ]);
	 *
	 * mark.follow.offset = vec2(64, 64) // Change the offset
	 * ```
	 *
	 * @returns The follow comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	follow(obj: GameObj | null, offset?: Vec2): FollowComp;
	/**
	 * Custom shader to manipulate sprite.
	 *
	 * @param id - The shader id.
	 * @param uniform - The uniform to pass to the shader.
	 *
	 * @returns The shader comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	shader(id: string, uniform?: Uniform | (() => Uniform)): ShaderComp;
	/**
	 * Get input from the user and store it in the nodes text property, displaying it with the text component and allowing other functions to access it.
	 *
	 * @param hasFocus - Whether the text input should have focus.
	 * @param maxInputLength - The maximum length of the input.
	 *
	 * @example
	 * ```js
	 * const obj = add([
	 *     text(""),
	 *     textInput(),
	 * ])
	 *
	 * obj.hasFocus = false
	 * debug.log(obj.text) // oh no i cant see my new text since it was disabled
	 * ```
	 *
	 * @returns The text input comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup UI
	 */
	textInput(hasFocus?: boolean, maxInputLength?: number): TextInputComp;
	/**
	 * Enable timer related functions like wait(), loop(), tween() on the game object.
	 *
	 * @param maxLoopsPerFrame - The maximum number of loops per frame.
	 *
	 * @example
	 * ```js
	 * const obj = add([
	 *     timer(),
	 * ])
	 *
	 * obj.wait(2, () => { ... })
	 * obj.loop(0.5, () => { ... })
	 * obj.tween(obj.pos, mousePos(), 0.5, (p) => obj.pos = p, easings.easeOutElastic)
	 * ```
	 *
	 * @returns The timer comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	timer(maxLoopsPerFrame?: number): TimerComp;
	/**
	 * Make a game obj unaffected by camera or parent object transforms, and render at last.
	 * Useful for UI elements.
	 *
	 * @param fixed - Default fixed value.
	 *
	 * @example
	 * ```js
	 * // this will be be fixed on top left and not affected by camera
	 * const score = add([
	 *     text(0),
	 *     pos(12, 12),
	 *     fixed(),
	 * ])
	 * ```
	 *
	 * @returns The fixed comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	fixed(fixed?: boolean): FixedComp;
	/**
	 * Don't get destroyed on scene switch. Only works in objects attached to root.
	 *
	 * @param scenesToStay - The scenes to stay in. By default it stays in all scenes.
	 *
	 * @example
	 * ```js
	 * player.onCollide("bomb", () => {
	 *     // spawn an explosion and switch scene, but don't destroy the explosion game obj on scene switch
	 *     add([
	 *         sprite("explosion", { anim: "burst", }),
	 *         stay(),
	 *         lifespan(1),
	 *     ])
	 *     go("lose", score)
	 * })
	 * ```
	 *
	 * @returns The stay comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	stay(scenesToStay?: string[]): StayComp;
	/**
	 * Handles health related logic and events.
	 *
	 * @param hp - The initial health points.
	 * @param maxHP - The maximum health points.
	 *
	 * @example
	 * ```js
	 * const player = add([
	 *     health(3),
	 * ]);
	 *
	 * player.onCollide("bad", (bad) => {
	 *     player.hp--;
	 *     bad.hp--;
	 * });
	 *
	 * player.onCollide("apple", () => {
	 *     player.hp++;
	 * });
	 *
	 * player.onHurt(() => {
	 *     play("ouch");
	 * });
	 *
	 * // triggers when hp reaches 0
	 * player.onDeath(() => {
	 *     destroy(player);
	 *     go("lose");
	 * });
	 * ```
	 *
	 * @returns The health comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	health(hp: number, maxHP?: number): HealthComp;
	/**
	 * Destroy the game obj after certain amount of time
	 *
	 * @param time - The time to live.
	 * @param options - Options for the lifespan component. See {@link LifespanCompOpt `LifespanCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // spawn an explosion, destroy after 1.5 seconds (time + fade)
	 * add([
	 *     sprite("explosion", { anim: "burst", }),
	 *     lifespan(1, {
	 *         fade: 0.5 // it start fading 0.5 second after time
	 *     }),
	 * ]);
	 * ```
	 *
	 * @returns The lifespan comp.
	 * @since v2000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	lifespan(time: number, options?: LifespanCompOpt): EmptyComp;
	/**
	 * Names an game obj.
	 *
	 * @param name - The name to set.
	 *
	 * @returns The named comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	named(name: string): NamedComp;
	/**
	 * Finite state machine.
	 *
	 * @param initialState - The initial state.
	 * @param stateList - The list of states.
	 *
	 * @example
	 * ```js
	 * const enemy = add([
	 *     pos(80, 100),
	 *     sprite("robot"),
	 *     state("idle", ["idle", "attack", "move"]),
	 * ])
	 *
	 * // this callback will run once when enters "attack" state
	 * enemy.onStateEnter("attack", () => {
	 *     // enter "idle" state when the attack animation ends
	 *     enemy.play("attackAnim", {
	 *         // any additional arguments will be passed into the onStateEnter() callback
	 *         onEnd: () => enemy.enterState("idle", rand(1, 3)),
	 *     })
	 *     checkHit(enemy, player)
	 * })
	 *
	 * // this will run once when enters "idle" state
	 * enemy.onStateEnter("idle", (time) => {
	 *     enemy.play("idleAnim")
	 *     wait(time, () => enemy.enterState("move"))
	 * })
	 *
	 * // this will run every frame when current state is "move"
	 * enemy.onStateUpdate("move", () => {
	 *     enemy.follow(player)
	 *     if (enemy.pos.dist(player.pos) < 16) {
	 *         enemy.enterState("attack")
	 *     }
	 * })
	 * ```
	 *
	 * @returns The state comp.
	 * @since v2000.1
	 * @group Components
	 * @subgroup Behaviour
	 */
	state<T extends string>(initialState: T, stateList?: T[]): StateComp<T>;
	/**
	 * state() with pre-defined transitions.
	 *
	 * @param initialState - The initial state.
	 * @param stateList - The list of states.
	 * @param transitions - The transitions between states.
	 *
	 * @example
	 * ```js
	 * const enemy = add([
	 *     pos(80, 100),
	 *     sprite("robot"),
	 *     state("idle", ["idle", "attack", "move"], {
	 *         "idle": "attack",
	 *         "attack": "move",
	 *         "move": [ "idle", "attack" ],
	 *     }),
	 * ])
	 *
	 * // this callback will only run once when enter "attack" state from "idle"
	 * enemy.onStateTransition("idle", "attack", () => {
	 *     checkHit(enemy, player)
	 * })
	 * ```
	 *
	 * @returns The state comp.
	 * @since v2000.2
	 * @group Components
	 * @subgroup Behaviour
	 */
	state<T extends string>(initialState: T, stateList: T[], transitions: Record<T, T | T[]>): StateComp<T>;
	/**
	 * @deprecated since v3001.0
	 *
	 * Fade object in.
	 *
	 * Uses opacity for finding what to fade into and to set opacity during fade animation.
	 *
	 * @returns An empty comp.
	 * @since v3000.0
	 * @group Components
	 * @subgroup Behaviour
	 *
	 * @requires {@link opacity `opacity()`}
	 */
	fadeIn(time: number): Comp;
	/**
	 * Mask all children object render.
	 *
	 * @param maskType - The type of mask to use.
	 *
	 * @returns The mask comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Rendering
	 */
	mask(maskType?: Mask): MaskComp;
	/**
	 * Specifies the FrameBuffer the object should be drawn on.
	 *
	 * @param canvas - The FrameBuffer to draw on.
	 *
	 * @example
	 * ```js
	 * // Draw on another canvas
	 * let canvas = makeCanvas(width(), height());
	 *
	 * let beanOnCanvas = add([
	 *     sprite("bean"),
	 *     drawon(canvas.fb),
	 * ]);
	 * ```
	 *
	 * @returns The drawon comp.
	 * @since v3000.0
	 * @group Components
	 * @subgroup Rendering
	 */
	drawon(canvas: FrameBuffer | Picture, opt?: DrawonCompOpt): DrawonComp;
	/**
	 * A tile on a tile map.
	 *
	 * @param opt - Options for the tile component. See {@link TileCompOpt `TileCompOpt`}.
	 *
	 * @returns The tile comp.
	 * @since v3000.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	tile(opt?: TileCompOpt): TileComp;
	/**
	 * An agent which can find its way on a tilemap.
	 *
	 * @param opt - Options for the agent component. See {@link AgentCompOpt `AgentCompOpt`}.
	 *
	 * @returns The agent comp.
	 * @since v3000.0
	 * @group Components
	 * @subgroup Level
	 */
	agent(opt?: AgentCompOpt): AgentComp;
	/**
	 * A component to animate properties.
	 * This component has an internal clock which starts the moment it is added to an object.
	 *
	 * @param opt - Options for the animate component. See {@link AnimateCompOpt `AnimateCompOpt`}.
	 *
	 * @example
	 * ```js
	 * // First example
	 * let movingBean = add([
	 *       sprite("bean"),
	 *       pos(50, 150),
	 *       anchor("center"),
	 *       animate(),
	 * ]);
	 * // Moving right to left using ping-pong
	 * movingBean.animate("pos", [vec2(50, 150), vec2(150, 150)], {
	 *     duration: 2,
	 *     direction: "ping-pong",
	 * });
	 *
	 * // Second example
	 * const obj = add([
	 *     area(),
	 *     color("#FF0000"),
	 *     animate(),
	 * ]);
	 * // The internal clock starts when the object is added.
	 * // We need to reset the animation when the object is hovered.
	 * obj.onHover(() => {
	 *     obj.animation.seek(0); // reset the animation to the start
	 *     obj.animate(
	 *         "color",
	 *         // We can use the current color property as the start value.
	 *         // It doesn't make sense to have only one value in the array as it's a transition.
	 *         [obj.color, Color.fromHex("#0000FF")],
	 *         { duration: 0.5, loops: 1 },
	 * });
	 *
	 * obj.onHoverEnd(() => {
	 *     // We need to unanimate the color property to reset it to the original value.
	 *     obj.unanimate("color");
	 *     obj.color = Color.fromHex("#FF0000");
	 * });
	 * ```
	 *
	 * @returns The animate comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	animate(opt?: AnimateCompOpt): AnimateComp;
	/**
	 * A fake mouse that follows the mouse position and triggers events.
	 *
	 * [Guide about fake mouse](https://v4000.kaplayjs.com/guides/fake_mouse/)
	 *
	 * @param opt - Options for the fake mouse comp. See {@link FakeMouseOpt `FakeMouseOpt`}.
	 *
	 * @returns The fake mouse comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Behaviour
	 */
	fakeMouse(opt?: FakeMouseOpt): FakeMouseComp;
	/**
	 * Serializes the animation to plain objects
	 *
	 * @param obj - The game obj to serialize.
	 *
	 * @returns The serialized animation.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Component Serialization
	 */
	serializeAnimation(obj: GameObj, name: string): Animation;
	/**
	 * A sentry which reacts to objects coming into view.
	 *
	 * @returns The sentry comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Level
	 */
	sentry(candidates: SentryCandidates, opt?: SentryCompOpt): SentryComp;
	/**
	 * A patrol which can follow waypoints to a goal.
	 *
	 * @param opts - Options for the patrol component. See {@link PatrolCompOpt `PatrolCompOpt`}.
	 *
	 * @example
	 * ```js
	 * const bean = add([
	 *     sprite("bean"),
	 *     pos(40, 30),
	 *     patrol({
	 *         waypoints: [
	 *             vec2(100, 100),
	 *             vec2(120, 170),
	 *             vec2(50, 50),
	 *             vec2(300, 100),
	 *         ],
	 *     }),
	 * ]);
	 *
	 * bean.onPatrolFinished(gb => {
	 *     // Note that the position doesn't exactly match the last waypoint,
	 *     // this is an approximation.
	 *     debug.log(`Bean reached the end of the patrol at ${gb.pos.x}, ${gb.pos.y}`);
	 * });
	 * ```
	 *
	 * @returns The patrol comp.
	 * @since v3001.0
	 * @group Components
	 * @subgroup Level
	 */
	patrol(opts: PatrolCompOpt): PatrolComp;
	/**
	 * A navigator pathfinder which can calculate waypoints to a goal.
	 *
	 * @since v3001.0
	 * @group Components
	 * @subgroup Level
	 */
	pathfinder(opts: PathfinderCompOpt): PathfinderComp;
	/**
	 * Construct a level based on symbols.
	 *
	 * @param map - The map data.
	 * @param opt - The level options.
	 * @param parent - The parent object of the level. Defaults to root.
	 *
	 * @example
	 * ```js
	 * const myLevel = add([
	 *     level([
	 *          "                          $",
	 *          "                          $",
	 *          "           $$         =   $",
	 *          "  %      ====         =   $",
	 *          "                      =    ",
	 *          "       ^^      = >    =   &",
	 *          "===========================",
	 *     ], {
	 *         // define the size of tile block
	 *         tileWidth: 32,
	 *         tileHeight: 32,
	 *         // define what each symbol means, by a function returning a component list (what will be passed to add())
	 *         tiles: {
	 *             "=": () => [
	 *                 sprite("floor"),
	 *                 area(),
	 *                 body({ isStatic: true }),
	 *             ],
	 *             "$": () => [
	 *                 sprite("coin"),
	 *                 area(),
	 *                 pos(0, -9),
	 *             ],
	 *             "^": () => [
	 *                 sprite("spike"),
	 *                 area(),
	 *                 "danger",
	 *             ],
	 *         }
	 *     })
	 * ])
	 * ```
	 *
	 * @returns A game obj with the level.
	 * @since v4000.0
	 * @group Components
	 * @subgroup Level
	 */
	level(map: string[], opt?: LevelCompOpt): LevelComp;
	/**
	 * Create a raycast.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Raycast
	 */
	raycast(origin: Vec2, direction: Vec2, exclude?: string[]): RaycastResult;
	/**
	 * Trigger an event on all game objs with certain tag.
	 *
	 * @param tag - The tag to trigger to.
	 * @param args - Arguments to pass to the `on()` functions
	 *
	 * @example
	 * ```js
	 * trigger("shoot", "target", 140);
	 *
	 * on("shoot", "target", (obj, score) => {
	 *     obj.destroy();
	 *     debug.log(140); // every bomb was 140 score points!
	 * });
	 * ```
	 *
	 * @since v3001.0.6
	 * @group Events
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	trigger(event: string, tag: string, ...args: any): void;
	/**
	 * Register an event that runs when all assets finished loading.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * const bean = add([
	 *     sprite("bean"),
	 * ]);
	 *
	 * // certain assets related data are only available when the game finishes loading
	 * onLoad(() => {
	 *     debug.log(bean.width)
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onLoad(action: () => void): KEventController | undefined;
	/**
	 * Register an event that runs once for each asset that failed to load,
	 * after all others have completed.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // this will not load
	 * loadSprite("bobo", "notavalidURL");
	 *
	 * // process the error
	 * // you decide whether to ignore it, or throw an error and halt the game
	 * onLoadError((name, asset) => {
	 *     debug.error(`${name} failed to load: ${asset.error}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onLoadError(action: (name: string, failedAsset: Asset<any>) => void): KEventController | undefined;
	/**
	 * Register an event that runs every frame when assets are initially loading. Can be used to draw a custom loading screen.
	 *
	 * @param action - The function that runs when assets are loading.
	 *
	 * @example
	 * ```
	 * // progress bar
	 * onLoading((progress) => {
	 *     // Background of the bar
	 *     drawRect({
	 *         width: 240,
	 *         height: 40,
	 *         pos: center().add(-120,0),
	 *         color: BLACK,
	 *         anchor: "left",
	 *     });
	 *     // Progress of the bar
	 *     drawRect({
	 *         width: map(progress, 0, 1, 0, 220),
	 *         height: 32,
	 *         pos: center().add(-116, 0),
	 *         color: BLUE,
	 *         anchor: "left",
	 *     });
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onLoading(action: (progress: number) => void): KEventController;
	/**
	 * Register a custom error handler. Can be used to draw a custom error screen.
	 *
	 * @param action - The function that runs when the program errors.
	 *
	 * @example
	 * ```js
	 * // Create custom error handler
	 * onError((err) => {
	 *     drawRect({
	 *         width: width(),
	 *         height: height(),
	 *         pos: center(),
	 *         color: RED,
	 *         anchor: "center",
	 *     });
	 *
	 *     drawText({
	 *         text: err.message,
	 *         size: 48,
	 *         width: width()/2,
	 *         anchor: "center",
	 *         align: "center",
	 *         pos: center(),
	 *         color: BLACK,
	 *     });
	 * });
	 *
	 * // cause common error
	 * let pos = add([
	 *     pos(),
	 * ]);
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onError(action: (err: Error) => void): KEventController;
	/**
	 * Register an event that runs when the canvas resizes.
	 *
	 * @param action - The function that runs when the canvas resizes.
	 *
	 * @example
	 * ```js
	 * // create a rectangle with screen size
	 * let rectangle = add([
	 *     rect(width(), height()),
	 *     color(GREEN),
	 * ]);
	 *
	 * // resize the rectangle to screen size
	 * onResize(() => {
	 *     debug.log(`Old Size: ${rectangle.width}x${rectangle.height}`);
	 *     rectangle.width = width();
	 *     rectangle.height = height();
	 *     debug.log(`New Size: ${rectangle.width}x${rectangle.height}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onResize(action: () => void): KEventController;
	/**
	 * Cleanup function to run when quit() is called.
	 *
	 * @param action - The function that runs when quit() is called.
	 *
	 * @example
	 * ```js
	 * // useful externally from KAPLAY
	 * onCleanup(() => {
	 *     console.log(`ohbye :(`);
	 * });
	 *
	 * quit();
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onCleanup(action: () => void): void;
	/**
	 * Register an event that runs every frame when a key is held down.
	 *
	 * @param key - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // move left by SPEED pixels per frame every frame when left arrow key is being held down
	 * onKeyDown("left", () => {
	 *     bean.move(-SPEED, 0);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyDown(key: Key | Key[], action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs every frame when any key is held down.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyDown(action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain keys.
	 *
	 * @param k - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // .jump() once when "space" is just being pressed
	 * onKeyPress("space", () => {
	 *     bean.jump();
	 * });
	 *
	 * onKeyPress(["up", "space"], () => {
	 *     bean.jump();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPress(key: Key | Key[], action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses any key.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // Call restart() when player presses any key
	 * onKeyPress((key) => {
	 *     debug.log(`key pressed ${key}`);
	 *     restart();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPress(action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain keys (also fires repeatedly when the keys are being held down).
	 *
	 * @param k - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // delete last character when "backspace" is being pressed and held
	 * onKeyPressRepeat("backspace", () => {
	 *     input.text = input.text.substring(0, input.text.length - 1);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPressRepeat(k: Key | Key[], action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses any key and fires repeatedly when the keys are being held down.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // delete last character when "backspace" is being pressed and held
	 * onKeyPressRepeat((key) => {
	 *     debug.log(`key ${key} is being repeatedly pressed`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPressRepeat(action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user release certain keys.
	 *
	 * @param k - = The key(s) to listen for. See {@link Key `Key`}.
	 * @param action - The function that runs when a user releases certain keys
	 *
	 * @example
	 * ```js
	 * // release `a` or `b` keys
	 * onKeyRelease([`a`, `b`], (k) => {
	 *     debug.log(`Released the ${k} key...`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyRelease(k: Key | Key[], action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user releases a key.
	 *
	 * @param action - The function that runs when a user releases a {@link Key `Key`}.
	 *
	 * @example
	 * ```js
	 * // release a key
	 * onKeyRelease((k) => {
	 *     debug.log(`Released the ${k} key...`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 */
	onKeyRelease(action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user inputs text.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // type into input
	 * onCharInput((ch) => {
	 *     input.text += ch
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onCharInput(action: (ch: string) => void): KEventController;
	/**
	 * Register an event that runs every frame when certain mouse buttons are being held down.
	 *
	 * @param btn - The mouse button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run when certain mouse buttons are being held down.
	 *
	 * @example
	 * ```js
	 * // count time with left mouse button down
	 * let mouseTime = 0;
	 * onMouseDown("left", () => {
	 *     mouseTime += dt();
	 *     debug.log(`Time with mouse down: ${mouseTime});
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseDown(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs every frame when any mouse button is being held down.
	 *
	 * @param action - The function that is run when any mouse button is being held down.
	 *
	 * @example
	 * ```js
	 * // count time with any mouse button down
	 * let mouseTime = 0;
	 * onMouseDown((m) => {
	 *     mouseTime += dt();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseDown(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user clicks mouse.
	 *
	 * @param action - The function that is run when user clicks a mouse button.
	 *
	 * @example
	 * ```js
	 * // gives cookies on left press, remove on right press
	 * let cookies = 0;
	 * onMousePress(["left", "right"], (m) => {
	 *     if (m == "left") {
	 *         cookies++;
	 *     } else {
	 *         cookies--;
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMousePress(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user clicks mouse.
	 *
	 * @param btn - The mouse button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run what the user clicks cetain mouse buttons.
	 *
	 * @example
	 * ```js
	 * // gives cookies on any mouse press
	 * let cookies = 0;
	 * onMousePress((m) => {
	 *     cookies++;
	 *     debug.log(`Cookies: ${cookies}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMousePress(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user releases mouse.
	 *
	 * @param action - The function that is run what the user clicks a provided mouse button.
	 *
	 * @example
	 * ```js
	 * // spawn bean where right mouse is released
	 * onMouseRelease("right", (m) => {
	 *     debug.log(`${m} released, spawning bean...`);
	 *     add([
	 *         pos(mousePos()),
	 *         sprite("bean"),
	 *         anchor("center"),
	 *     ]);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseRelease(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user releases mouse.
	 *
	 * @param btn - The button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run what the user clicks a provided mouse button.
	 *
	 * @example
	 * ```js
	 * // spawn bean where right mouse is released
	 * onMouseRelease((m) => {
	 *     if (m == "right") {
	 *         debug.log(`${m} released, spawning bean...`);
	 *         add([
	 *             pos(mousePos()),
	 *             sprite("bean"),
	 *             anchor("center"),
	 *         ]);
	 *     });
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseRelease(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs whenever user moves the mouse.
	 *
	 * @param action - The function that is run what the user moves the mouse.
	 *
	 * @example
	 * ```js
	 * // runs when the mouse has moved
	 * onMouseMove((p, d) => {
	 *     bean.pos = p; // set bean position to mouse position
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseMove(action: (pos: Vec2, delta: Vec2) => void): KEventController;
	/**
	 * Register an event that runs when a touch starts.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchStart(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs when a touch ends.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchEnd(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs whenever touch moves.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchMove(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs when mouse wheel scrolled.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // Zoom camera on scroll
	 * onScroll((delta) => {
	 *     const zoom = delta.y / 500;
	 *     camScale(camScale().add(zoom));
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onScroll(action: (delta: Vec2) => void): KEventController;
	/**
	 * Register an event that runs when a gamepad is connected.
	 *
	 * @param action - The function that runs when quit() is called.
	 *
	 * @example
	 * ```js
	 * // watch for a controller connecting
	 * onGamepadConnect((gp) => {
	 *     debug.log(`ohhi player ${gp.index + 1}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadConnect(action: (gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when a gamepad is disconnected.
	 *
	 * @param action - The function that runs when quit() is called.
	 *
	 * @example
	 * ```js
	 * // watch for a controller disconnecting
	 * onGamepadDisconnect((gp) => {
	 *     debug.log(`ohbye player ${gp.index + 1}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadDisconnect(action: (gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs every frame when certain gamepad buttons are held down.
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run while certain gamepad buttons are held down.
	 *
	 * @example
	 * ```js
	 * // when button is being held down
	 * onGamepadButtonDown("rtrigger", (gp) => {
	 *     car.addForce(Vec2.fromAngle(car.angle).scale(10));
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonDown(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs every frame when any gamepad buttons are held down.
	 *
	 * @param action - The function that is run while any gamepad buttons are held down.
	 *
	 * @example
	 * ```js
	 * // when button is being held down
	 * onGamepadButtonDown((btn, gp) => {
	 *     if (btn == "rtrigger") {
	 *         car.addForce(Vec2.fromAngle(car.angle).scale(10));
	 *     } else if (btn == "ltrigger") {
	 *         car.addForce(Vec2.fromAngle(car.angle).scale(-5));
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonDown(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain gamepad button.
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run when certain gamepad buttons are pressed.
	 *
	 * @example
	 * ```js
	 * // when user presses button
	 * onGamepadButtonPress("south", (btn, gp) => {
	 *     player.jump(200);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonPress(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user presses any gamepad button.
	 *
	 * @param action - The function that is run when any gamepad buttons is pressed.
	 *
	 * @example
	 * ```js
	 * // when user presses button
	 * onGamepadButtonPress((btn, gp) => {
	 *     if (btn == "south") {
	 *         player.jump(200);     // jump
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonPress(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user releases certain gamepad button
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run when certain gamepad buttons are released.
	 *
	 * @example
	 * ```js
	 * // charged attack
	 * let chargeTime = 0
	 * onGamepadButtonPress("west", (btn, gp) => {
	 *     chargeTime = time();
	 * });
	 *
	 * // when a gamepad button is released, this is run
	 * onGamepadButtonRelease("west", (btn, gp) => {
	 *     let chargedt = time() - chargeTime;
	 *     debug.log(`Used ${chargedt * 1000} power!`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonRelease(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user releases any gamepad button.
	 *
	 * @param action - The function that is run when any gamepad buttons are released.
	 *
	 * @example
	 * ```js
	 * // when a gamepad button is released, this is run
	 * onGamepadButtonRelease((btn, gp) => {
	 *     if (btn == "north") {
	 *         player.jump(500);
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonRelease(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when the gamepad axis exists.
	 *
	 * @param button - The stick to listen for. See {@link KGamepadStick `GamepadStick`}.
	 * @param action - The function that is run when a specific gamepad stick is moved.
	 *
	 * @example
	 * ```js
	 * // player to be moved
	 * let player = add([
	 *     pos(center()),
	 *     sprite("bean"),
	 * ]);
	 *
	 * // when left stick is moved
	 * onGamepadStick("left", (stickVector, gp) => {
	 *     player.move(stickVector.x, 0);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadStick(stick: KGamepadStick, action: (value: Vec2, gameepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user press a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonDown(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonDown(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when user press a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonPress(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonPress(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when user release a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonRelease(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonRelease(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when tab is shown.
	 *
	 * @param action - The function that is run when the tab is shown.
	 *
	 * @example
	 * ```js
	 * // User has returned to this tab
	 * onTabShow(() => {
	 *     burp();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onTabShow(action: () => void): KEventController;
	/**
	 * Register an event that runs when tab is hidden.
	 *
	 * @param action - The function that is run what the tab is hidden.
	 *
	 * @example
	 * ```js
	 * // spooky ghost
	 * let ghosty = add([
	 *     pos(center()),
	 *     sprite("ghosty"),
	 *     anchor("center"),
	 * ]);
	 *
	 * // when switching tabs, this runs
	 * onTabHide(() => {
	 *     destroy(ghosty);
	 *     add([
	 *         text("There was never aa ghosttttt"),
	 *         pos(center()),
	 *         anchor("center"),
	 *     ]);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onTabHide(action: () => void): KEventController;
	/**
	 * @deprecated use `onTabHide` instead
	 *
	 * Register an event that runs when tab is hidden.
	 *
	 * @param action - The function that is run what the tab is hidden.
	 *
	 * @example
	 * ```js
	 * // spooky ghost
	 * let ghosty = add([
	 *     pos(center()),
	 *     sprite("ghosty"),
	 *     anchor("center"),
	 * ]);
	 *
	 * // when switching tabs, this runs
	 * onHide(() => {
	 *     destroy(ghosty);
	 *     add([
	 *         text("There was never aa ghosttttt"),
	 *         pos(center()),
	 *         anchor("center"),
	 *     ]);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onHide(action: () => void): KEventController;
	/**
	 * @deprecated use `onTabShow` instead
	 *
	 * Register an event that runs when tab is shown.
	 *
	 * @param action - The function that is run when the tab is shown.
	 *
	 * @example
	 * ```js
	 * // user has returned to this tab
	 * onShow(() => {
	 *     burp();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onShow(action: () => void): KEventController;
	/**
	 * Register an event that runs at a fixed framerate.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Events
	 */
	onFixedUpdate(action: () => void): KEventController;
	onFixedUpdate(tag: Tag, action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs every frame (~60 times per second) for all game objs with certain tag.
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // move every "tree" 120 pixels per second to the left, destroy it when it leaves screen
	 * // there'll be nothing to run if there's no "tree" obj in the scene
	 * onUpdate("tree", (tree) => {
	 *     tree.move(-120, 0)
	 *     if (tree.pos.x < 0) {
	 *         destroy(tree)
	 *     }
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onUpdate(tag: Tag, action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs every frame (~60 times per second).
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // This will run every frame
	 * onUpdate(() => {
	 *     debug.log("ohhi")
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onUpdate(action: () => void): KEventController;
	/**
	 * Register an event that runs every frame (~60 times per second) for all game objs with certain tag (this is the same as onUpdate but all draw events are run after update events, drawXXX() functions only work in this phase).
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onDraw(tag: Tag, action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs every frame (~60 times per second) (this is the same as onUpdate but all draw events are run after update events, drawXXX() functions only work in this phase).
	 *
	 * @example
	 * ```js
	 * onDraw(() => {
	 *     drawLine({
	 *         p1: vec2(0),
	 *         p2: mousePos(),
	 *         color: rgb(0, 0, 255),
	 *     })
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onDraw(action: () => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag is added.
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function that runs when an object is added.
	 *
	 * @example
	 * ```js
	 * // This will run when the object is added.
	 * onAdd("player", () => {
	 *     debug.log("ohhi");
	 * });
	 *
	 * add([
	 *     pos(),
	 *     "player"
	 * ]);
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	onAdd(tag: Tag, action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs when an object is added
	 *
	 * @param action - The function that runs when an object is added.
	 *
	 * @example
	 * ```js
	 * // This will run when the object is added.
	 * onAdd(() => {
	 *     debug.log("ohhi");
	 * });
	 *
	 * add([
	 *     pos(),
	 * ]);
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	onAdd(action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag is destroyed.
	 *
	 * @param action - The function that runs when an object is destroyed.
	 *
	 * @example
	 * ```js
	 * // This will run when the tagged object is destroyed.
	 * onDestroy("bean", () => {
	 *     debug.log("ohbye");
	 * });
	 *
	 * let player = add([
	 *     pos(),
	 *     "bean"
	 * ])
	 *
	 * // Destroy the tagged object
	 * destroy(player);
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	onDestroy(tag: Tag, action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs when an object is destroyed.
	 *
	 * @param tag - The tag to match, only called for objects with a matching tag.
	 * @param action - The function that runs when an object is destroyed.
	 *
	 * @example
	 * ```js
	 * // This will run when the object is destroyed.
	 * onDestroy(() => {
	 *     debug.log("ohbye");
	 * });
	 *
	 * let ghosty = add([
	 *     pos(),
	 * ]);
	 *
	 * // Destroy the object
	 * destroy(ghosty);
	 * ```
	 *
	 * @returns The event controller.
	 * @group Events
	 */
	onDestroy(action: (obj: GameObj) => void): KEventController;
	/**
	 * Register an event that runs when an object starts using a component.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onUse(action: (obj: GameObj, id: string) => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag starts using a component.
	 *
	 * @param tag - The tag to match, only called for objects with a matching tag.
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * // This will run when the tagged object uses a new component.
	 * onUse("taggedObjTag", (obj, compId) => {
	 *     debug.log(obj, component);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	onUse(tag: Tag, action: (obj: GameObj, compId: string) => void): KEventController;
	/**
	 * Register an event that runs when an object stops using a component.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onUnuse(action: (obj: GameObj, id: string) => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag stops using a component.
	 *
	 * @param tag - The tag to match, only called for objects with a matching tag.
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * // This will run when the tagged object removes a component.
	 * onUnuse("ghost", (obj, compId) => {
	 *     debug.log(obj, component);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	onUnuse(tag: Tag, action: (obj: GameObj, compId: string) => void): KEventController;
	/**
	 * Register an event that runs when an object gains a tag.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * onTag((obj, tag) => {
	 *     debug.log(`A new tag ${tag} was added to the object ${obj.id}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onTag(action: (obj: GameObj, tag: string) => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag gains a tag.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * onTag("elephant", (obj, tag) => {
	 *     debug.log(`A new tag ${tag} was added to the object ${obj.id}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onTag(tag: Tag, action: (obj: GameObj, tag: string) => void): KEventController;
	/**
	 * Register an event that runs when an object loses a tag.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * onUnuse((obj, tag) => {
	 *     debug.log(`A tag ${tag} was removed from the object ${obj.id}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onUntag(action: (obj: GameObj, tag: string) => void): KEventController;
	/**
	 * Register an event that runs when an object with the provided tag loses a tag.
	 *
	 * @param action - The function that runs when the event happens.
	 *
	 * @example
	 * ```js
	 * onUnuse("vegetable", (obj, tag) => {
	 *     debug.log(`A tag ${tag} was removed from the object ${obj.id}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.1
	 * @group Events
	 */
	onUntag(tag: Tag, action: (obj: GameObj, tag: string) => void): KEventController;
	/**
	 * Register an event on all Game Objects with certain tag.
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // a custom event defined by body() comp
	 * // every time an obj with tag "bomb" hits the floor, destroy it and addKaboom()
	 * on("ground", "bomb", (bomb) => {
	 *     destroy(bomb);
	 *     addKaboom(bomb.pos);
	 * });
	 *
	 * // a custom event can be defined manually
	 * // by passing an event name, a tag, and a callback function
	 * // if you want any tag, use a tag of "*"
	 * on("talk", "npc", (npc, message) => {
	 *     npc.add([
	 *         text(message),
	 *         pos(0, -50),
	 *         lifespan(2),
	 *         opacity(),
	 *     ]);
	 * });
	 *
	 * onKeyPress("space", () => {
	 *     // the trigger method on game objs can be used to trigger a custom event
	 *     npc.trigger("talk", "Hello, KAPLAY!");
	 * });
	 *
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.0
	 * @group Events
	 */
	on<Ev extends GameObjEventNames | (string & {})>(event: Ev, tag: Tag, action: (obj: GameObj, ...args: TupleWithoutFirst<GameObjEvents[Ev]>) => void): KEventController;
	/**
	 * Register an event that runs once when 2 game objs with certain tags collides (required to have area() component).
	 *
	 * @param t1 - The tag of the first game obj.
	 * @param t2 - The tag of the second game obj.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * onCollide("sun", "earth", () => {
	 *     addExplosion()
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Events
	 */
	onCollide(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event that runs every frame when 2 game objs with certain tags collides (required to have area() component).
	 *
	 * @param t1 - The tag of the first game obj.
	 * @param t2 - The tag of the second game obj.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * onCollideUpdate("sun", "earth", () => {
	 *     debug.log("okay this is so hot");
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onCollideUpdate(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event that runs once frame when 2 game objs with certain tags stops colliding (required to have area() component).
	 *
	 * @param t1 - The tag of the first game obj.
	 * @param t2 - The tag of the second game obj.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * onCollideEnd("bean", "earth", () => {
	 *     debug.log("destroying world in 3... 2... 1...");
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onCollideEnd(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): KEventController;
	/**
	 * Register an event that runs when game objs with certain tags are clicked (required to have the area() component).
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // click on any "chest" to open
	 * onClick("chest", (chest) => chest.open())
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Mouse
	 */
	onClick(tag: Tag, action: (a: GameObj) => void): KEventController;
	/**
	 * Register an event that runs once when game objs with certain tags are hovered (required to have area() component).
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onHover(tag: Tag, action: (a: GameObj) => void): KEventController;
	/**
	 * Register an event that runs every frame when game objs with certain tags are hovered (required to have area() component).
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // Rotate bean 90 degrees per second when hovered
	 * onHoverUpdate("bean", (bean) => {
	 *   bean.angle += dt() * 90;
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onHoverUpdate(tag: Tag, action: (a: GameObj) => void): KEventController;
	/**
	 * Register an event that runs once when game objs with certain tags are unhovered (required to have area() component).
	 *
	 * @param tag - The tag to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onHoverEnd(tag: Tag, action: (a: GameObj) => void): KEventController;
	/**
	 * Register an event that runs every frame when a key is held down.
	 *
	 * @param key - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // move left by SPEED pixels per frame every frame when left arrow key is being held down
	 * onKeyDown("left", () => {
	 *     bean.move(-SPEED, 0);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyDown(key: Key | Key[], action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs every frame when any key is held down.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyDown(action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain keys.
	 *
	 * @param k - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // .jump() once when "space" is just being pressed
	 * onKeyPress("space", () => {
	 *     bean.jump();
	 * });
	 *
	 * onKeyPress(["up", "space"], () => {
	 *     bean.jump();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPress(key: Key | Key[], action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses any key.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // Call restart() when player presses any key
	 * onKeyPress((key) => {
	 *     debug.log(`key pressed ${key}`);
	 *     restart();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPress(action: (key: Key) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain keys (also fires repeatedly when the keys are being held down).
	 *
	 * @param k - The key(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // delete last character when "backspace" is being pressed and held
	 * onKeyPressRepeat("backspace", () => {
	 *     input.text = input.text.substring(0, input.text.length - 1);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyPressRepeat(k: Key | Key[], action: (k: Key) => void): KEventController;
	onKeyPressRepeat(action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user release certain keys.
	 *
	 * @param k - = The key(s) to listen for. See {@link Key `Key`}.
	 * @param action - The function that runs when a user releases certain keys
	 *
	 * @example
	 * ```js
	 * // release `a` or `b` keys
	 * onKeyRelease([`a`, `b`], (k) => {
	 *     debug.log(`Released the ${k} key...`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onKeyRelease(k: Key | Key[], action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user releases a key.
	 *
	 * @param action - The function that runs when a user releases a {@link Key `Key`}.
	 *
	 * @example
	 * ```js
	 * // release a key
	 * onKeyRelease((k) => {
	 *     debug.log(`Released the ${k} key...`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 */
	onKeyRelease(action: (k: Key) => void): KEventController;
	/**
	 * Register an event that runs when user inputs text.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // type into input
	 * onCharInput((ch) => {
	 *     input.text += ch
	 * })
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Keyboard
	 */
	onCharInput(action: (ch: string) => void): KEventController;
	/**
	 * Register an event that runs every frame when certain mouse buttons are being held down.
	 *
	 * @param btn - The mouse button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run when certain mouse buttons are being held down.
	 *
	 * @example
	 * ```js
	 * // count time with left mouse button down
	 * let mouseTime = 0;
	 * onMouseDown("left", () => {
	 *     mouseTime += dt();
	 *     debug.log(`Time with mouse down: ${mouseTime});
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseDown(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs every frame when any mouse button is being held down.
	 *
	 * @param action - The function that is run when any mouse button is being held down.
	 *
	 * @example
	 * ```js
	 * // count time with any mouse button down
	 * let mouseTime = 0;
	 * onMouseDown((m) => {
	 *     mouseTime += dt();
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseDown(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user clicks mouse.
	 *
	 * @param action - The function that is run when user clicks a mouse button.
	 *
	 * @example
	 * ```js
	 * // gives cookies on left press, remove on right press
	 * let cookies = 0;
	 * onMousePress(["left", "right"], (m) => {
	 *     if (m == "left") {
	 *         cookies++;
	 *     } else {
	 *         cookies--;
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMousePress(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user clicks mouse.
	 *
	 * @param btn - The mouse button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run what the user clicks cetain mouse buttons.
	 *
	 * @example
	 * ```js
	 * // gives cookies on any mouse press
	 * let cookies = 0;
	 * onMousePress((m) => {
	 *     cookies++;
	 *     debug.log(`Cookies: ${cookies}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMousePress(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user releases mouse.
	 *
	 * @param action - The function that is run what the user clicks a provided mouse button.
	 *
	 * @example
	 * ```js
	 * // spawn bean where right mouse is released
	 * onMouseRelease("right", (m) => {
	 *     debug.log(`${m} released, spawning bean...`);
	 *     add([
	 *         pos(mousePos()),
	 *         sprite("bean"),
	 *         anchor("center"),
	 *     ]);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseRelease(action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs when user releases mouse.
	 *
	 * @param btn - The button(s) to listen for. See {@link MouseButton `MouseButton`}.
	 * @param action - The function that is run what the user clicks a provided mouse button.
	 *
	 * @example
	 * ```js
	 * // spawn bean where right mouse is released
	 * onMouseRelease((m) => {
	 *     if (m == "right") {
	 *         debug.log(`${m} released, spawning bean...`);
	 *         add([
	 *             pos(mousePos()),
	 *             sprite("bean"),
	 *             anchor("center"),
	 *         ]);
	 *     });
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseRelease(btn: MouseButton | MouseButton[], action: (m: MouseButton) => void): KEventController;
	/**
	 * Register an event that runs whenever user moves the mouse.
	 *
	 * @param action - The function that is run what the user moves the mouse.
	 *
	 * @example
	 * ```js
	 * // runs when the mouse has moved
	 * onMouseMove((p, d) => {
	 *     bean.pos = p; // set bean position to mouse position
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Mouse
	 */
	onMouseMove(action: (pos: Vec2, delta: Vec2) => void): KEventController;
	/**
	 * Register an event that runs when a touch starts.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchStart(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs whenever touch moves.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchMove(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs when a touch ends.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v2000.1
	 * @group Input
	 * @subgroup Touch
	 */
	onTouchEnd(action: (pos: Vec2, t: Touch) => void): KEventController;
	/**
	 * Register an event that runs when mouse wheel scrolled.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @example
	 * ```js
	 * // Zoom camera on scroll
	 * onScroll((delta) => {
	 *     const zoom = delta.y / 500;
	 *     camScale(camScale().add(zoom));
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	onScroll(action: (delta: Vec2) => void): KEventController;
	/**
	 * Register an event that runs when a gamepad is connected.
	 *
	 * @param action - The function that runs when quit() is called.
	 *
	 * @example
	 * ```js
	 * // watch for a controller connecting
	 * onGamepadConnect((gp) => {
	 *     debug.log(`ohhi player ${gp.index + 1}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadConnect(action: (gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when a gamepad is disconnected.
	 *
	 * @param action - The function that runs when quit() is called.
	 *
	 * @example
	 * ```js
	 * // watch for a controller disconnecting
	 * onGamepadDisconnect((gp) => {
	 *     debug.log(`ohbye player ${gp.index + 1}`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadDisconnect(action: (gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs every frame when certain gamepad buttons are held down.
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run while certain gamepad buttons are held down.
	 *
	 * @example
	 * ```js
	 * // when button is being held down
	 * onGamepadButtonDown("rtrigger", (gp) => {
	 *     car.addForce(Vec2.fromAngle(car.angle).scale(10));
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonDown(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs every frame when any gamepad buttons are held down.
	 *
	 * @param action - The function that is run while any gamepad buttons are held down.
	 *
	 * @example
	 * ```js
	 * // when button is being held down
	 * onGamepadButtonDown((btn, gp) => {
	 *     if (btn == "rtrigger") {
	 *         car.addForce(Vec2.fromAngle(car.angle).scale(10));
	 *     } else if (btn == "ltrigger") {
	 *         car.addForce(Vec2.fromAngle(car.angle).scale(-5));
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonDown(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user presses certain gamepad button.
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run when certain gamepad buttons are pressed.
	 *
	 * @example
	 * ```js
	 * // when user presses button
	 * onGamepadButtonPress("south", (btn, gp) => {
	 *     player.jump(200);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonPress(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user presses any gamepad button.
	 *
	 * @param action - The function that is run when any gamepad buttons is pressed.
	 *
	 * @example
	 * ```js
	 * // when user presses button
	 * onGamepadButtonPress((btn, gp) => {
	 *     if (btn == "south") {
	 *         player.jump(200);
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonPress(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user releases certain gamepad button
	 *
	 * @param btn - The button(s) to listen for. See {@link KGamepadButton `KGamepadButton`}.
	 * @param action - The function that is run when certain gamepad buttons are released.
	 *
	 * @example
	 * ```js
	 * // charged attack
	 * let chargeTime = 0
	 * onGamepadButtonPress("west", (btn, gp) => {
	 *     chargeTime = time();
	 * });
	 *
	 * // when a gamepad button is released, this is run
	 * onGamepadButtonRelease("west", (btn, gp) => {
	 *     let chargedt = time() - chargeTime;
	 *     debug.log(`Used ${chargedt * 1000} power!`);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonRelease(btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user releases any gamepad button.
	 *
	 * @param action - The function that is run when any gamepad buttons are released.
	 *
	 * @example
	 * ```js
	 * // when a gamepad button is released, this is run
	 * onGamepadButtonRelease((btn, gp) => {
	 *     if (btn == "north") {
	 *         player.jump(500);
	 *     }
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadButtonRelease(action: (btn: KGamepadButton, gamepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when the gamepad axis exists.
	 *
	 * @param button - The stick to listen for. See {@link KGamepadStick `GamepadStick`}.
	 * @param action - The function that is run when a specific gamepad stick is moved.
	 *
	 * @example
	 * ```js
	 * // player move
	 * let player = add([
	 *     pos(center()),
	 *     sprite(`bean`),
	 * ]);
	 *
	 * // when left stick is moved
	 * onGamepadStick("left", (stickVector, gp) => {
	 *     player.move(stickVector.x, 0);
	 * });
	 * ```
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	onGamepadStick(stick: KGamepadStick, action: (value: Vec2, gameepad: KGamepad) => void): KEventController;
	/**
	 * Register an event that runs when user press a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonPress(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonPress(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when user release a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonRelease(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonRelease(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when user press a defined button
	 * (like "jump") on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to listen for.
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	onButtonDown(btn: string | string[], action: (btn: string) => void): KEventController;
	onButtonDown(action: (btn: string) => void): KEventController;
	/**
	 * Register an event that runs when current scene ends.
	 *
	 * @param action - The function to run when the event is triggered.
	 *
	 * @returns The event controller.
	 * @since v3000.0
	 * @group Events
	 */
	onSceneLeave(action: (newScene?: string) => void): KEventController;
	/**
	 * Gets the name of the current scene. Returns null if no scene is active.
	 *
	 * @since v3001.0
	 * @group Scenes
	 */
	getSceneName(): string | null;
	/**
	 * Sets the root for all subsequent resource urls.
	 *
	 * This is useful when you want to load assets from a different domain, or setup
	 * a base path for all assets.
	 *
	 * @param path - The root path.
	 *
	 * @example
	 * ```js
	 * loadRoot("https://myassets.com/");
	 * loadSprite("bean", "sprites/bean.png"); // will resolve to "https://myassets.com/sprites/bean.png"
	 *
	 * loadRoot("./"); // useful for Itch.io
	 * ```
	 *
	 * @group Assets
	 * @subgroup Util
	 */
	loadRoot(path?: string): string;
	/**
	 * Load a sprite into asset manager, with name and resource url and optional config.
	 *
	 * @param name - The asset name.
	 * @param src - The resource url.
	 * @param opt - The optional config.
	 *
	 * @example
	 * ```js
	 * // due to browser policies you'll need a static file server to load local files
	 * loadSprite("bean", "bean.png");
	 * loadSprite("apple", "https://play.kaplayjs.com/sprites/apple.png");
	 *
	 * // slice a spritesheet and add anims manually
	 * loadSprite("bean", "bean.png", {
	 *     sliceX: 4,
	 *     sliceY: 1,
	 *     anims: {
	 *         run: {
	 *             from: 0,
	 *             to: 3,
	 *         },
	 *         jump: {
	 *             from: 3,
	 *             to: 3,
	 *         },
	 *     },
	 * });
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Sprites
	 */
	loadSprite(name: string | null, src: LoadSpriteSrc | LoadSpriteSrc[], opt?: LoadSpriteOpt): Asset<SpriteData>;
	/**
	 * Load sprites from a sprite atlas.
	 *
	 * @param src - The image resource url.
	 * @param data - The sprite atlas data.
	 * @param [repack=true] - set to false if you've already packed your spritesheet. See {@link LoadSpriteOpt.repack} for more.
	 *
	 * @example
	 * ```js
	 * // See #SpriteAtlasData type for format spec
	 * loadSpriteAtlas("sprites/dungeon.png", {
	 *     "hero": {
	 *         x: 128,
	 *         y: 68,
	 *         width: 144,
	 *         height: 28,
	 *         sliceX: 9,
	 *         anims: {
	 *             idle: { from: 0, to: 3 },
	 *             run: { from: 4, to: 7 },
	 *             hit: 8,
	 *         },
	 *     },
	 * });
	 *
	 * const player = add([
	 *     sprite("hero"),
	 * ]);
	 *
	 * player.play("run");
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Sprites
	 */
	loadSpriteAtlas(src: LoadSpriteSrc, data: SpriteAtlasData, repack?: boolean): Asset<Record<string, SpriteData>>;
	/**
	 * Load sprites from a sprite atlas with URL.
	 *
	 * @param src - The image resource url.
	 * @param url - The json resource url.
	 * @param [repack=true] - set to false if you've already packed your spritesheet. See {@link LoadSpriteOpt.repack} for more.
	 *
	 * @example
	 * ```js
	 * // Load from json file, see #SpriteAtlasData type for format spec
	 * loadSpriteAtlas("sprites/dungeon.png", "sprites/dungeon.json")
	 *
	 * const player = add([
	 *     sprite("hero"),
	 * ])
	 *
	 * player.play("run")
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Sprites
	 */
	loadSpriteAtlas(src: LoadSpriteSrc, url: string, repack?: boolean): Asset<Record<string, SpriteData>>;
	/**
	 * Load a sprite with Aseprite spritesheet JSON. You should use "array" in the export options and have tags enabled, that way KAPLAY can load tagged frames as animations.
	 *
	 * These are loaded with repacking turned off, since we assume Aseprite is smart enough to pack the frames nicely.
	 *
	 * @param name - The asset name.
	 * @param imgSrc - The image resource url.
	 *
	 * @example
	 * ```js
	 * loadAseprite("car", "sprites/car.png", "sprites/car.json")
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Sprites
	 */
	loadAseprite(name: string | null, imgSrc: LoadSpriteSrc, jsonSrc: string | AsepriteData): Asset<SpriteData>;
	/**
	 * Load default sprite "bean".
	 *
	 * @param name - An optional name for bean.
	 *
	 * @example
	 * ```js
	 * loadBean();
	 *
	 * // use it right away
	 * add([
	 *     sprite("bean"),
	 * ]);
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Sprites
	 */
	loadBean(name?: string): Asset<SpriteData>;
	/**
	 * Load default font "happy".
	 *
	 * @param name - Optional name for happy. Default to happy.
	 * @param opt - Optional config for {@link loadBitmapFont `loadBitmapFont`}.
	 *
	 * @example
	 * ```js
	 * loadHappy();
	 *
	 * add([
	 *     text("ohhi", { font: "happy" }),
	 * ]);
	 * ```
	 *
	 * @returns The asset data.
	 * @since v4000.0
	 * @group Assets
	 * @subgroup Fonts
	 */
	loadHappy(name?: string, opt?: LoadBitmapFontOpt): Asset<BitmapFontData>;
	/**
	 * Load custom JSON data from url.
	 *
	 * @param name - The asset name.
	 * @param url - The resource url.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Util
	 */
	loadJSON(name: string | null, url: string): Asset<any>;
	/**
	 * Load a sound into asset manager, with name and resource url.
	 *
	 * Supported formats: mp3, ogg, wav.
	 *
	 * @param name - The asset name.
	 * @param src - The resource url.
	 *
	 * @example
	 * ```js
	 * loadSound("shoot", "/sounds/horse.ogg");
	 * loadSound("shoot", "/sounds/squeeze.mp3");
	 * loadSound("shoot", "/sounds/shoot.wav");
	 * ```
	 *
	 * @returns  The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Audio
	 */
	loadSound(name: string | null, src: string | ArrayBuffer | AudioBuffer): Asset<SoundData>;
	/**
	 * Like loadSound(), but the audio is streamed and won't block loading. Use this for big audio files like background music.
	 *
	 * @param name - The asset name.
	 * @param url - The resource url.
	 *
	 * @example
	 * ```js
	 * loadMusic("shoot", "/music/bossfight.mp3");
	 * ```
	 *
	 * @returns The asset data.
	 * @since v3001.0
	 * @group Assets
	 * @subgroup Audio
	 */
	loadMusic(name: string | null, url: string): void;
	/**
	 * Load a font (any format supported by the browser, e.g. ttf, otf, woff).
	 *
	 * @param name - The asset name.
	 *
	 * @example
	 * ```js
	 * // load a font from a .ttf file
	 * loadFont("frogblock", "fonts/frogblock.ttf");
	 * ```
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Fonts
	 */
	loadFont(name: string, src: string | ArrayBuffer | ArrayBufferView, opt?: LoadFontOpt): Asset<FontData>;
	/**
	 * Load a bitmap font into asset manager, with name and resource url and information on the layout of the bitmap.
	 *
	 * @param name - The asset name.
	 * @param src - The resource url.
	 * @param gridW - The width of each character on the bitmap.
	 * @param gridH - The height of each character on the bitmap.
	 * @param opt - The options for the bitmap font.
	 *
	 * @example
	 * ```js
	 * // load a bitmap font called "04b03", with bitmap "fonts/04b03.png"
	 * // each character on bitmap has a size of (6, 8), and contains default ASCII_CHARS
	 * loadBitmapFont("04b03", "fonts/04b03.png", 6, 8);
	 *
	 * // load a font with custom characters
	 * loadBitmapFont("myfont", "myfont.png", 6, 8, { chars: "☺☻♥♦♣♠" });
	 * ```
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Fonts
	 */
	loadBitmapFont(name: string | null, src: string, gridW: number, gridH: number, opt?: LoadBitmapFontOpt): Asset<BitmapFontData>;
	/**
	 * Define the frames of an existing sprite as characters that can be used as a font.
	 *
	 * This was primarily intended for use with {@link loadSpriteAtlas} because the sprite in
	 * question usually isn't the whole image and so can't be also passed to {@link loadBitmapFont}
	 * as its own font.
	 *
	 * This waits for the sprite to load before doing anything, but if the sprite doesn't load, the game
	 * will transition to the error screen after a timeout (which is set by {@link KAPLAYOpt["loadTimeout"]|KAPLAYOpt.loadTimeout}).
	 *
	 * @param sprite - The ID of the sprite to use as a font. Must already have frames defined
	 * @param chars - The characters that correspond to each of the frames in the sprite. You can't use
	 * space or newline here because those are hard-coded to special behaviors in the text layout code.
	 *
	 * @returns The generated font data.
	 * @group Assets
	 * @subgroup Fonts
	 *
	 * @see {@link LoadSpriteOpt}
	 */
	loadBitmapFontFromSprite(sprite: string, chars: string): Asset<BitmapFontData>;
	/**
	 * Load a shader with vertex and fragment code.
	 *
	 * @param name - The asset name.
	 * @param vert - The vertex shader code. Null if not needed.
	 * @param frag - The fragment shader code. Null if not needed.
	 *
	 * @example
	 * ```js
	 * // default shaders and custom shader format
	 * loadShader("outline",
	 * `vec4 vert(vec2 pos, vec2 uv, vec4 color) {
	 *     // predefined functions to get the default value by KAPLAY
	 *     return def_vert();
	 * }`,
	 * `vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
	 *     // turn everything blue-ish
	 *     return def_frag() * vec4(0, 0, 1, 1);
	 * }`, false)
	 * ```
	 *
	 * @returns The asset data.
	 * @since v2000.0
	 * @group Assets
	 * @subgroup Shaders
	 */
	loadShader(name: string | null, vert?: string | null, frag?: string | null): Asset<ShaderData>;
	/**
	 * Load a shader with vertex and fragment code file url.
	 *
	 * @param name - The name of the asset.
	 * @param vert - The vertex shader code. Null if not needed.
	 * @param frag - The fragment shader code. Null if not needed.
	 *
	 * @example
	 * ```js
	 * // load only a fragment shader from URL
	 * loadShaderURL("outline", null, "/shaders/outline.glsl")
	 * ```
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Shaders
	 */
	loadShaderURL(name: string | null, vert?: string | null, frag?: string | null): Asset<ShaderData>;
	/**
	 * Add a new loader to wait for before starting the game.
	 *
	 * @param l - The loader to wait for.
	 *
	 * @example
	 * ```js
	 * load(new Promise((resolve, reject) => {
	 *     // anything you want to do that stalls the game in loading state
	 *     resolve("ok")
	 * }))
	 * ```
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Util
	 */
	load<T>(l: Promise<T>): Asset<T>;
	/**
	 * Load a prefab.
	 *
	 * @since v4000.0
	 * @group Assets
	 * @subgroup Util
	 * @experimental
	 */
	loadPrefab: (name: string, url: string) => Asset<SerializedGameObj>;
	/**
	 * Get the global asset loading progress (0.0 - 1.0).
	 *
	 * @returns The loading progress.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Util
	 */
	loadProgress(): number;
	/**
	 * Get SpriteData from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getSprite(name: string): Asset<SpriteData> | null;
	/**
	 * Get SoundData from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getSound(name: string): Asset<SoundData> | null;
	/**
	 * Get FontData from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getFont(name: string): Asset<FontData> | null;
	/**
	 * Get BitmapFontData from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getBitmapFont(name: string): Asset<BitmapFontData> | null;
	/**
	 * Get ShaderData from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getShader(name: string): Asset<ShaderData> | null;
	/**
	 * Get custom data from name.
	 *
	 * @param name - The asset name.
	 *
	 * @returns The asset data.
	 * @since v3000.0
	 * @group Assets
	 * @subgroup Getters
	 */
	getAsset(name: string): Asset<any> | null;
	/**
	 * The asset data.
	 *
	 * @group Assets
	 * @subgroup Data
	 */
	Asset: typeof Asset;
	/**
	 * The sprite data.
	 *
	 * @group Assets
	 * @subgroup Data
	 */
	SpriteData: typeof SpriteData;
	/**
	 * @group Assets
	 * @subgroup Data
	 */
	SoundData: typeof SoundData;
	/**
	 * Get the width of game.
	 *
	 * @returns The width of the game.
	 * @since v2000.0
	 * @group Info
	 */
	width(): number;
	/**
	 * Get the root of all objects.
	 *
	 * @returns The root object.
	 * @since v2000.0
	 * @group Game Obj
	 */
	getTreeRoot(): GameObj;
	/**
	 * Get the height of game.
	 *
	 * @returns The height of the game.
	 * @since v2000.0
	 * @group Info
	 */
	height(): number;
	/**
	 * Get the center point of view.
	 *
	 * @example
	 * ```js
	 * // add bean to the center of the screen
	 * add([
	 *     sprite("bean"),
	 *     pos(center()),
	 *     // ...
	 * ])
	 * ```
	 *
	 * @returns The center point of the view.
	 * @since v2000.0
	 * @group Info
	 */
	center(): Vec2;
	/**
	 * Get the delta time since last frame.
	 *
	 * @example
	 * ```js
	 * // rotate bean 100 deg per second
	 * bean.onUpdate(() => {
	 *     bean.angle += 100 * dt()
	 * })
	 * ```
	 *
	 * @since v2000.0
	 * @group Info
	 */
	dt(): number;
	/**
	 * Get the delta time for the fixed-update loop. This
	 * only changes when you call {@link setFixedSpeed}.
	 *
	 * @since v3000.0
	 * @group Info
	 */
	fixedDt(): number;
	/**
	 * Get the rest delta time since last frame.
	 *
	 * @since v3000.0
	 * @group Info
	 */
	restDt(): number;
	/**
	 * Change the speed that the fixed update loop runs at.
	 * The options (and caveats) are described at {@link KAPLAYOpt["fixedUpdateMode"]|KAPLAYOpt.fixedUpdateMode}.
	 *
	 * @group Physics
	 * @experimental
	 */
	setFixedSpeed(speed: FixedSpeedOption): void;
	/**
	 * Get the total time since beginning.
	 *
	 * @since v3001
	 * @group Info
	 */
	time(): number;
	/**
	 * If the game canvas is currently focused.
	 *
	 * @returns true if focused.
	 * @since v2000.1
	 * @group Info
	 */
	isFocused(): boolean;
	/**
	 * Is currently on a touch screen device.
	 *
	 * @returns true if on a touch screen device.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Touch
	 */
	isTouchscreen(): boolean;
	/**
	 * Get current mouse position (without camera transform).
	 *
	 * @returns The current mouse position.
	 * @since v2000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	mousePos(): Vec2;
	/**
	 * How much mouse moved last frame.
	 *
	 * @returns The delta mouse position.
	 * @since v2000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	mouseDeltaPos(): Vec2;
	/**
	 * If any or certain key(s) are currently down.
	 *
	 * @param k - The key(s) to check.
	 *
	 * @example
	 * ```js
	 * // Any key down
	 *
	 * let lastKeyTime = time()
	 * let triedToWakeUp = false
	 *
	 * onUpdate(() => {
	 *     if (isKeyDown()) {
	 *         lastKeyTime = time()
	 *         triedToWakeUp = false
	 *         return
	 *     }
	 *
	 *     if (triedToWakeUp || time() - lastKeyTime < 5) return
	 *
	 *     debug.log("Wake up!")
	 *     triedToWakeUp = true
	 * })
	 *
	 * // Certain key down
	 * // equivalent to the calling bean.move() in an onKeyDown("left")
	 *
	 * onUpdate(() => {
	 *     if (isKeyDown("left")) {
	 *         bean.move(-SPEED, 0)
	 *     }
	 * })
	 *
	 * // Certain keys down
	 *
	 * let isMoving = false
	 *
	 * onUpdate(() => {
	 *     isMoving = isKeyDown(["left", "right"])
	 * })
	 * ```
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	isKeyDown(k?: Key | Key[]): boolean;
	/**
	 * If any or certain key(s) are just pressed last frame.
	 *
	 * @param k - The key(s) to check.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *     if (!isKeyPressed()) return // early return as no key was pressed
	 *
	 *     if (isKeyPressed("space")) debug.log("Pressed the jump key")
	 *     if (isKeyPressed(["left", "right"])) debug.log("Pressed any of the move keys")
	 * })
	 * ```
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	isKeyPressed(k?: Key | Key[]): boolean;
	/**
	 * If any or certain key(s) are just pressed last frame (also fires repeatedly when the keys are being held down).
	 *
	 * @param k - The key(s) to check.
	 *
	 * @example
	 * ```js
	 * let heldKeys = new Set()
	 *
	 * onUpdate(() => {
	 *     if (isKeyPressedRepeat("space")) {
	 *         pressedOrHeld(["space"], 'the jump key')
	 *     } else if (isKeyPressedRepeat(["left", "right"])) {
	 *         pressedOrHeld(["left", "right"], 'any of the move keys')
	 *     } else if (isKeyPressedRepeat()) {
	 *         pressedOrHeld(["any"], 'any key')
	 *     }
	 * })
	 *
	 * onKeyRelease((key) => wait(0.1, () => {
	 *     heldKeys.delete(key)
	 *     heldKeys.delete("any")
	 * }))
	 *
	 * // log message if pressed only or held as well
	 * function pressedOrHeld(keys, string) {
	 *     debug.log(`Pressed${keys.some(key => heldKeys.has(key)) ? ' and held' : ''} ${string}`)
	 *     keys.forEach((key) => {
	 *         if (key == "any" || isKeyDown(key)) heldKeys.add(key)
	 *     })
	 * }
	 * ```
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	isKeyPressedRepeat(k?: Key | Key[]): boolean;
	/**
	 * If any or certain key(s) are just released last frame.
	 *
	 * @param k - The key(s) to check.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *     if (!isKeyReleased()) return // early return as no key was released
	 *
	 *     if (isKeyReleased("space")) debug.log("Released the jump key")
	 *     if (isKeyReleased(["left", "right"])) debug.log("Released any of the move keys")
	 * })
	 * ```
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	isKeyReleased(k?: Key | Key[]): boolean;
	/**
	 * If mouse buttons are currently down.
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	isMouseDown(btn?: MouseButton | MouseButton[]): boolean;
	/**
	 * If mouse buttons are just clicked last frame
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	isMousePressed(btn?: MouseButton | MouseButton[]): boolean;
	/**
	 * If mouse buttons are just released last frame.
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v2000.0
	 * @group Input
	 * @subgroup Mouse
	 */
	isMouseReleased(btn?: MouseButton | MouseButton[]): boolean;
	/**
	 * If mouse moved last frame.
	 *
	 * @since v2000.1
	 * @group Input
	 * @subgroup Mouse
	 */
	isMouseMoved(): boolean;
	/**
	 * If certain gamepad buttons are just pressed last frame
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	isGamepadButtonPressed(btn?: KGamepadButton | KGamepadButton[]): boolean;
	/**
	 * If certain gamepad buttons are currently held down.
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	isGamepadButtonDown(btn?: KGamepadButton | KGamepadButton): boolean;
	/**
	 * If certain gamepad buttons are just released last frame.
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @since v3000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	isGamepadButtonReleased(btn?: KGamepadButton | KGamepadButton[]): boolean;
	/**
	 * If any or certain bound button(s) are just pressed last frame on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *     if (!isButtonPressed()) return // early return as no button was pressed
	 *
	 *     if (isButtonPressed("jump")) debug.log("Player jumped")
	 *     if (isButtonPressed(["left", "right"])) debug.log("Player moved")
	 * })
	 * ```
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	isButtonPressed(btn?: string | string[]): boolean;
	/**
	 * If any or certain bound button(s) are currently held down on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *     if (!isButtonDown()) return // early return as no button is held down
	 *
	 *     if (isButtonDown("jump")) debug.log("Player is jumping")
	 *     if (isButtonDown(["left", "right"])) debug.log("Player is moving")
	 * })
	 * ```
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	isButtonDown(btn?: string | [
	]): boolean;
	/**
	 * If any or certain bound button(s) are just released last frame on any input (keyboard, gamepad).
	 *
	 * @param btn - The button(s) to check.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *     if (!isButtonReleased()) return // early return as no button was released
	 *
	 *     if (isButtonReleased("jump")) debug.log("Player stopped jumping")
	 *     if (isButtonReleased(["left", "right"])) debug.log("Player stopped moving")
	 * })
	 * ```
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	isButtonReleased(btn?: string | string[]): boolean;
	/**
	 * Get a input binding from a button name.
	 *
	 * @param btn - The button to get binding for.
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	getButton(btn: string): ButtonBinding;
	/**
	 * Get all the input bindings.
	 *
	 * @returns The button definition.
	 * @since v4000.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	getButtons(): ButtonsDef;
	/**
	 * Set a input binding for a button name.
	 *
	 * @param btn - The button to set binding for.
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	setButton(btn: string, def: ButtonBinding): void;
	/**
	 * Press a button virtually.
	 *
	 * @param btn - The button to press.
	 *
	 * @example
	 * ```js
	 * // press "jump" button
	 * pressButton("jump"); // triggers onButtonPress, starts onButtonDown
	 * releaseButton("jump"); // triggers onButtonRelease, stops onButtonDown
	 * ```
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	pressButton(btn: string): void;
	/**
	 * Release a button virtually.
	 *
	 * @param btn - The button to release.
	 *
	 * @example
	 * ```js
	 * // press "jump" button
	 * pressButton("jump"); // triggers onButtonPress, starts onButtonDown
	 * releaseButton("jump"); // triggers onButtonRelease, stops onButtonDown
	 * ```
	 *
	 * @since v3001.0
	 * @group Input
	 * @subgroup Buttons API
	 */
	releaseButton(btn: string): void;
	/**
	 * Get stick axis values from a gamepad.
	 *
	 * @param stick - The stick to get values from.
	 *
	 * @returns The stick axis Vec2.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	getGamepadStick(stick: KGamepadStick): Vec2;
	/**
	 * Get analog button values from a gamepad.
	 *
	 * @param b - The button to read the analog value from.
	 *
	 * @returns The button analog value.
	 * @since v4000.0
	 * @group Input
	 * @subgroup Gamepad
	 */
	getGamepadAnalogButton(b: KGamepadButton): number;
	/**
	 * Get the latest input device type that triggered the input event.
	 *
	 * @returns The last input device type, or null if no input event has been triggered.
	 * @since v3001.0
	 * @group Input
	 * @subgroup Util
	 */
	getLastInputDeviceType(): ButtonBindingDevice | null;
	/**
	 * List of characters inputted since last frame.
	 *
	 * @returns An array of characters inputted.
	 * @since v3000.0
	 * @group Input
	 * @subgroup Keyboard
	 */
	charInputted(): string[];
	/**
	 * Set camera position.
	 *
	 * @param pos - The position to set the camera to.
	 *
	 * @example
	 * ```js
	 * // move camera to (100, 100)
	 * setCamPos(100, 100);
	 * setCamPos(vec2(100, 100));
	 * setCamPos(100); // x and y are the same
	 * ```
	 *
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	setCamPos(pos: Vec2): void;
	setCamPos(x: number, y: number): void;
	setCamPos(xy: number): void;
	/**
	 * Get camera position.
	 *
	 * @returns The current camera position.
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	getCamPos(): Vec2;
	/**
	 * Set camera scale.
	 *
	 * @param scale - The scale to set the camera to.
	 *
	 * @example
	 * ```js
	 * // set camera scale to (2, 2)
	 * setCamScale(2, 2);
	 * setCamScale(vec2(2, 2));
	 * setCamScale(2); // x and y are the same
	 * ```
	 *
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	setCamScale(scale: Vec2): void;
	setCamScale(x: number, y: number): void;
	setCamScale(xy: number): void;
	/**
	 * Get camera scale.
	 *
	 * @returns The current camera scale.
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	getCamScale(): Vec2;
	/**
	 * Set camera rotation.
	 *
	 * @param angle - The angle to rotate the camera.
	 *
	 * @example
	 * ```js
	 * // rotate camera 90 degrees
	 * setCamRot(90);
	 * ```
	 *
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	setCamRot(angle: number): void;
	/**
	 * Get camera rotation.
	 *
	 * @returns The current camera rotation.
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	getCamRot(): number;
	/**
	 * Get camera transform.
	 *
	 * @returns The current camera transform.
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Camera
	 */
	getCamTransform(): Mat23;
	/**
	 * Camera shake.
	 *
	 * @param intensity - The intensity of the shake. Defaults to 12.
	 *
	 * @example
	 * ```js
	 * // shake intensively when bean collides with a "bomb"
	 * bean.onCollide("bomb", () => {
	 *     shake(120)
	 * })
	 * ```
	 *
	 * @since v3000.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	shake(intensity?: number): void;
	/**
	 * Camera flash.
	 *
	 * @param flashColor - The color of the flash.
	 * @param fadeOutTime - The time it takes for the flash to fade out.
	 *
	 * @example
	 * ```js
	 * onMousePress(() => {
	 *     // flashed
	 *     flash(WHITE, 0.5);
	 * });
	 * ```
	 *
	 * @returns A timer controller.
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	flash(flashColor: Color, fadeOutTime: number): TimerController;
	/**
	 * @deprecated Use {@link setCamPos} and {@link getCamPos} instead.
	 *
	 * Get / set camera position.
	 *
	 * @param pos - The position to set the camera to.
	 *
	 * @example
	 * ```js
	 * // camera follows player
	 * player.onUpdate(() => {
	 *     camPos(player.pos)
	 * })
	 * ```
	 *
	 * @returns The current camera position.
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	camPos(pos: Vec2): Vec2;
	/** @deprecated */
	camPos(x: number, y: number): Vec2;
	/** @deprecated */
	camPos(xy: number): Vec2;
	/** @deprecated */
	camPos(): Vec2;
	/**
	 * @deprecated Use {@link setCamScale} and {@link getCamScale} instead.
	 *
	 * Get / set camera scale.
	 *
	 * @param scale - The scale to set the camera to.
	 *
	 * @returns The current camera scale.
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	camScale(scale: Vec2): Vec2;
	/** @deprecated */
	camScale(x: number, y: number): Vec2;
	/** @deprecated */
	camScale(xy: number): Vec2;
	/** @deprecated */
	camScale(): Vec2;
	/**
	 * @deprecated Use {@link setCamRot} and {@link getCamRot} instead.
	 *
	 * Get / set camera rotation.
	 *
	 * @param angle - The angle to rotate the camera.
	 *
	 * @returns The current camera rotation.
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	camRot(angle?: number): number;
	/**
	 * @deprecated use {@link flash} instead.
	 *
	 * Flash the camera.
	 *
	 * @param flashColor - The color of the flash.
	 * @param fadeOutTime - The time it takes for the flash to fade out.
	 *
	 * @example
	 * ```js
	 * onMousePress(() => {
	 *     // flashed
	 *     camFlash(WHITE, 0.5)
	 * })
	 * ```
	 *
	 * @returns A timer controller.
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	camFlash(flashColor: Color, fadeOutTime: number): TimerController;
	/**
	 * @deprecated use {@link getCamTransform} instead.
	 *
	 * Get camera transform.
	 *
	 * @group Rendering
	 * @subgroup Camera
	 */
	camTransform(): Mat23;
	/**
	 * Transform a point from world position (relative to the root) to screen position (relative to the screen).
	 *
	 * @param p - The point to transform.
	 *
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	toScreen(p: Vec2): Vec2;
	/**
	 * Transform a point from screen position (relative to the screen) to world position (relative to the root).
	 *
	 * @param p - The point to transform.
	 *
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Camera
	 */
	toWorld(p: Vec2): Vec2;
	/**
	 * Set gravity.
	 *
	 * @param g - The gravity to set.
	 *
	 * @since v2000.0
	 * @group Physics
	 */
	setGravity(g: number): void;
	/**
	 * Get gravity.
	 *
	 * @since v3001.0
	 * @group Physics
	 */
	getGravity(): number;
	/**
	 * Set gravity direction.
	 *
	 * @since v3001.0
	 * @group Physics
	 */
	setGravityDirection(d: Vec2): void;
	/**
	 * Get gravity direction.
	 *
	 * @returns The gravity direction.
	 * @since v3001.0
	 * @group Physics
	 */
	getGravityDirection(): Vec2;
	/**
	 * An object containing the data for when two objects with area()s
	 * overlap or collide with each other.
	 *
	 * @since v4000.0
	 * @group Physics
	 */
	Collision: typeof Collision;
	/**
	 * Set background color.
	 *
	 * @since v3000.0
	 * @group Info
	 */
	setBackground(color: Color): void;
	setBackground(color: Color, alpha: number): void;
	setBackground(r: number, g: number, b: number): void;
	setBackground(r: number, g: number, b: number, alpha: number): void;
	/**
	 * Get background color.
	 *
	 * @returns The background color.
	 * @since v3000.0
	 * @group Info
	 */
	getBackground(): Color | null;
	/**
	 * Get connected gamepads.
	 *
	 * @returns An array of connected gamepads.
	 * @since v3000.0
	 * @group Info
	 */
	getGamepads(): KGamepad[];
	/**
	 * Set cursor style.
	 *
	 * @param style - The cursor style.
	 *
	 * @example
	 * ```js
	 * // Change between cursor styles
	 *
	 * // Reset cursor to default at start of every frame
	 * onUpdate(() => setCursor("default"));
	 *
	 * button.onHover((c) => {
	 *    // change cursor to pointer when hovering over button
	 *     setCursor("pointer");
	 * });
	 *
	 * // Hide the only cursor at start (useful for fakeMouse)
	 * setCursor("none");
	 * ```
	 *
	 * @since v2000.0
	 * @group Info
	 */
	setCursor(style: Cursor): void;
	/**
	 * Get current cursor style.
	 *
	 * @returns The current cursor style.
	 * @since v2000.0
	 * @group Info
	 */
	getCursor(): Cursor;
	/**
	 * Lock / unlock cursor. Note that you cannot lock cursor within 1 second after user unlocking the cursor with the default unlock gesture (typically the esc key) due to browser policy.
	 *
	 * @since v2000.0
	 * @group Info
	 */
	setCursorLocked(locked: boolean): void;
	/**
	 * Get if cursor is currently locked.
	 *
	 * @returns true if locked, false otherwise.
	 * @since v2000.0
	 * @group Info
	 */
	isCursorLocked(): boolean;
	/**
	 * Enter / exit fullscreen mode.
	 *
	 * @example
	 * ```js
	 * // toggle fullscreen mode with "f" key
	 * onKeyPress("f", () => setFullscreen(!isFullscreen()));
	 * ```
	 *
	 * @since v2000.0
	 * @group Info
	 */
	setFullscreen(f?: boolean): void;
	/**
	 * If currently in fullscreen mode.
	 *
	 * @returns true if fullscreen, false otherwise.
	 * @since v2000.0
	 * @group Info
	 */
	isFullscreen(): boolean;
	/**
	 * Run the function after n seconds.
	 *
	 * @param n - The time to wait in seconds.
	 * @param action - The function to run.
	 *
	 * @example
	 * ```js
	 * // 3 seconds until explosion! Runnn!
	 * wait(3, () => {
	 *     explode()
	 * })
	 *
	 * // wait() returns a PromiseLike that can be used with await
	 * await wait(1)
	 * ```
	 *
	 * @returns A timer controller.
	 * @since v2000.0
	 * @group Timer
	 */
	wait(n: number, action?: () => void): TimerController;
	/**
	 * Run the function every n seconds.
	 *
	 * @param n - The time to wait in seconds.
	 * @param action - The function to run.
	 * @param maxLoops - The maximum number of loops to run. If not provided, it will run forever.
	 * @param waitFirst - Whether to wait for the first loop to start.
	 *
	 * @example
	 * ```js
	 * // spawn a butterfly at random position every 1 second
	 * loop(1, () => {
	 *     add([
	 *         sprite("butterfly"),
	 *         pos(rand(vec2(width(), height()))),
	 *         area(),
	 *         "friend",
	 *     ])
	 * })
	 * ```
	 *
	 * @returns A timer controller.
	 * @since v2000.0
	 * @group Timer
	 */
	loop(t: number, action: () => void, maxLoops?: number, waitFirst?: boolean): TimerController;
	/**
	 * Play a piece of audio.
	 *
	 * @example
	 * ```js
	 * // play a one off sound
	 * play("wooosh")
	 *
	 * // play a looping soundtrack (check out AudioPlayOpt for more options)
	 * const music = play("OverworldlyFoe", {
	 *     volume: 0.8,
	 *     loop: true
	 * })
	 *
	 * // using the handle to control (check out AudioPlay for more controls / info)
	 * music.paused = true
	 * music.speed = 1.2
	 * ```
	 *
	 * @returns A control handle.
	 * @since v2000.0
	 * @group Audio
	 */
	play(src: string | SoundData | Asset<SoundData> | MusicData | Asset<MusicData>, options?: AudioPlayOpt): AudioPlay;
	/**
	 * Yep. Plays a burp sound.
	 *
	 * @returns A control handle.
	 * @since v2000.0
	 * @group Audio
	 */
	burp(options?: AudioPlayOpt): AudioPlay;
	/**
	 * Set the global volume.
	 *
	 * @param v - The volume to set.
	 *
	 * @example
	 * ```js
	 * setVolume(0.5)
	 * ```
	 *
	 * @since v3001.1
	 * @group Audio
	 */
	setVolume(v: number): void;
	/**
	 * Get the global volume.
	 *
	 * @returns The current volume.
	 * @since v3001.1
	 * @group Audio
	 */
	getVolume(): number;
	/**
	 * @deprecated Use {@link setVolume} and {@link getVolume} instead.
	 *
	 * Sets global volume.
	 *
	 * @example
	 * ```js
	 * // makes everything quieter
	 * volume(0.5)
	 * ```
	 *
	 * @returns The new volume or the current volume.
	 * @since v2000.0
	 * @group Audio
	 */
	volume(v?: number): number;
	/**
	 * Get the underlying browser AudioContext.
	 *
	 * @since v2000.0
	 * @group Audio
	 */
	audioCtx: AudioContext;
	/**
	 * Get a random value between the given bound.
	 *
	 * @param a - The lower bound. If not upper bound, this is the upper bound and the lower bound is 0.
	 * @param b - The upper bound.
	 *
	 * @example
	 * ```js
	 * // a random number between 0 - 8
	 * rand(8);
	 *
	 * // a random point on screen
	 * rand(vec2(width(), height()));
	 *
	 * // a random color
	 * rand(rgb(255, 255, 255));
	 *
	 * // a random number between 50 - 100
	 * rand(50, 100);
	 *
	 * // a random point on screen with x between 20 - 100 and y between 20 - 100
	 * rand(vec2(20), vec2(100));
	 *
	 * // spawn something on the right side of the screen but with random y value within screen height
	 * add([
	 *     pos(width(), rand(0, height())),
	 * ]);
	 * ```
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Random
	 */
	rand<T = RNGValue>(a?: T, b?: T): T;
	/**
	 * rand() but floored to integer. If not arguments, returns 0 or 1.
	 *
	 * @param a - The lower bound. If not upper bound, this is the upper bound.
	 * @param b - The upper bound.
	 *
	 * @example
	 * ```js
	 * randi(); // returns either 0 or 1
	 * randi(10); // returns a random integer between 0 and 9
	 * randi(10, 20); // returns a random integer between 10 and 19
	 * ```
	 *
	 * @returns A random integer between 0 and 1.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Random
	 */
	randi(a?: number, b?: number): number;
	/**
	 * Get / set the random number generator seed.
	 *
	 * @param seed - The seed to set.
	 *
	 * @example
	 * ```js
	 * randSeed(Date.now())
	 * ```
	 *
	 * @returns The new seed.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Random
	 */
	randSeed(seed?: number): number;
	/**
	 * Create a 2D vector.
	 *
	 * @example
	 * ```js
	 * // { x: 0, y: 0 }
	 * vec2()
	 *
	 * // { x: 10, y: 10 }
	 * vec2(10)
	 *
	 * // { x: 100, y: 80 }
	 * vec2(100, 80)
	 *
	 * // move to 150 degrees direction with by length 10
	 * player.pos = pos.add(Vec2.fromAngle(150).scale(10))
	 * ```
	 *
	 * @returns The vector.
	 * @since v2000.0
	 * @group Math
	 */
	vec2(x: number, y: number): Vec2;
	vec2(p: Vec2): Vec2;
	vec2(xy: number): Vec2;
	vec2(): Vec2;
	/**
	 * Create a color from RGB values (0 - 255).
	 *
	 * @param r - The red value.
	 * @param g - The green value.
	 * @param b - The blue value.
	 *
	 * @example
	 * ```js
	 * // update the color of the sky to light blue
	 * sky.color = rgb(0, 128, 255)
	 * ```
	 *
	 * @returns The color.
	 * @since v2000.0
	 * @group Math
	 */
	rgb(r: number, g: number, b: number): Color;
	/**
	 * Create a color from hex string.
	 *
	 * @param hex - The hex string.
	 *
	 * @example
	 * ```js
	 * sky.color = rgb("#ef6360")
	 * ```
	 *
	 * @returns The color.
	 * @since v2000.0
	 * @group Math
	 */
	rgb(hex: string): Color;
	/**
	 * Create a color from CSS keyword.
	 *
	 * @param cssColor - The CSS keyword.
	 *
	 * @example
	 * ```js
	 * sea.color = rgb("slateblue");
	 * ```
	 *
	 * @returns The color.
	 * @since v3001.0.10
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1.0
	 */
	rgb(cssColor: CSSColorKeywords): Color;
	/**
	 * Same as rgb(255, 255, 255).
	 */
	rgb(): Color;
	/**
	 * Convert HSL color (all values in 0.0 - 1.0 range) to RGB color.
	 *
	 * @param hue - The hue value.
	 * @param saturation - The saturation value.
	 * @param lightness - The lightness value.
	 *
	 * @example
	 * ```js
	 * // animate rainbow color
	 * onUpdate("rainbow", (obj) => {
	 *     obj.color = hsl2rgb(wave(0, 1, time()), 0.6, 0.6);
	 * });
	 * ```
	 *
	 * @returns The color.
	 * @since v2000.1
	 * @group Math
	 * @subgroup Colors
	 */
	hsl2rgb(hue: number, saturation: number, lightness: number): Color;
	/**
	 * Rectangle area (0.0 - 1.0).
	 *
	 * @param x - The x position of the rectangle.
	 * @param y - The y position of the rectangle.
	 * @param w - The width of the rectangle.
	 * @param h - The height of the rectangle.
	 *
	 * @returns A Quad object.
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	quad(x: number, y: number, w: number, h: number): Quad;
	/**
	 * Choose a random item from a list.
	 *
	 * @param lst - The list to choose from.
	 *
	 * @example
	 * ```js
	 * // decide the best fruit randomly
	 * const bestFruit = choose(["apple", "banana", "pear", "watermelon"]);
	 * ```
	 *
	 * @returns A random item from the list.
	 * @since v3001.0
	 * @group Math
	 * @subgroup Random
	 */
	choose<T>(lst: T[]): T;
	/**
	 * Choose multiple random items from a list.
	 *
	 * @param lst - The list to choose from.
	 * @param count - The number of items to choose.
	 *
	 * @returns An array of random items from the list.
	 * @since v3001.0
	 * @group Math
	 * @subgroup Random
	 */
	chooseMultiple<T>(lst: T[], count: number): T[];
	/**
	 * Shuffle an array.
	 *
	 * @param lst - The list to shuffle.
	 *
	 * @returns A shuffled array.
	 * @since v3001.0
	 * @group Math
	 * @subgroup Random
	 */
	shuffle<T>(lst: T[]): T[];
	/**
	 * rand(1) <= p
	 *
	 * @example
	 * ```js
	 * // every frame all objs with tag "unlucky" have 50% chance to die
	 * onUpdate("unlucky", (o) => {
	 *     if (chance(0.5)) {
	 *         destroy(o)
	 *     }
	 * })
	 * ```
	 *
	 * @group Math
	 * @subgroup Random
	 */
	chance(p: number): boolean;
	/**
	 * Linear interpolation. Can take a number, vector, or color.
	 *
	 * @group Math
	 * @subgroup Tween
	 */
	lerp<V extends LerpValue>(from: V, to: V, t: number): V;
	/**
	 * Linear interpolation for angles. Can take a number or vector.
	 *
	 * @group Math
	 * @subgroup Tween
	 */
	lerpAngle<V extends number | Vec2>(from: V, to: V, t: number): V;
	/**
	 * Tweeeeeeeening!
	 *
	 * @example
	 * ```js
	 * // tween bean to mouse position
	 * tween(bean.pos, mousePos(), 1, (p) => bean.pos = p, easings.easeOutBounce)
	 * ```
	 *
	 * @since v3000.0
	 * @group Math
	 * @subgroup Tween
	 */
	tween<V extends LerpValue>(from: V, to: V, duration: number, setValue: (value: V) => void, easeFunc?: (t: number) => number): TweenController;
	/**
	 * A collection of easing functions for tweening.
	 *
	 * @since v3000.0
	 * @group Math
	 * @subgroup Tween
	 */
	easings: Record<EaseFuncs, EaseFunc>;
	/**
	 * Steps easing. Eases in discontinuous steps.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Tween
	 */
	easingSteps(steps: number, position: StepPosition): (x: number) => number;
	/**
	 * Linear easing with keyframes.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Tween
	 */
	easingLinear(keys: Vec2[]): (x: number) => number;
	/**
	 * Bezier easing. Both control points need x to be within 0 and 1.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Tween
	 */
	easingCubicBezier(p1: Vec2, p2: Vec2): (x: number) => number;
	/**
	 * Map a value from one range to another range.
	 *
	 * If the value overshoots, the source range, the result values will also do.
	 *
	 * For clamping check {@link mapc}
	 *
	 * @param v - The value the function will depend on.
	 * @param l1 - The minimum value of the source range.
	 * @param h1 - The maximum value of the source range.
	 * @param l2 - The minimum result value.
	 * @param h2 - The maximum result value.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *      // Redness will be 0 when the mouse is at the left edge and 255 when the mouse is at the right edge
	 *      const redness = map(mousePos().x, 0, width(), 0, 255)
	 *      setBackground(rgb(redness, 0, 0))
	 * })
	 * ```
	 *
	 * @returns The result value based on the source value.
	 * @since v2000.0
	 * @group Math
	 */
	map(v: number, l1: number, h1: number, l2: number, h2: number): number;
	/**
	 * Map a value from one range to another range, and clamp to the dest range.
	 *
	 * @param v - The value the function will depend on.
	 * @param l1 - The minimum value of the source range.
	 * @param h1 - The maximum value of the source range.
	 * @param l2 - The minimum result value.
	 * @param h2 - The maximum result value.
	 *
	 * @example
	 * ```js
	 * onUpdate(() => {
	 *      // This variable will be 0 when the mouse is at the left edge and 255 when the mouse is at the right edge
	 *      const redness = mapc(mousePos().x, 0, width(), 0, 255)
	 *      setBackground(rgb(redness, 0, 0))
	 * })
	 * ```
	 *
	 * @returns The clamped result value based on the source value.
	 * @since v2000.0
	 * @group Math
	 */
	mapc(v: number, l1: number, h1: number, l2: number, h2: number): number;
	/**
	 * Interpolate back and forth between 2 values.
	 *
	 * (Optionally takes a custom periodic function, which default to a sine wave.).
	 *
	 * @example
	 * ```js
	 * // bounce color between 2 values as time goes on
	 * onUpdate("colorful", (c) => {
	 *     c.color.r = wave(0, 255, time())
	 *     c.color.g = wave(0, 255, time() + 1)
	 *     c.color.b = wave(0, 255, time() + 2)
	 * })
	 * ```
	 *
	 * @group Math
	 */
	wave<V extends LerpValue>(lo: V, hi: V, t: number, func?: (x: number) => number): V;
	/**
	 * Convert degrees to radians.
	 *
	 * @group Math
	 * @subgroup Angle
	 */
	deg2rad(deg: number): number;
	/**
	 * Convert radians to degrees.
	 *
	 * @group Math
	 * @subgroup Angle
	 */
	rad2deg(rad: number): number;
	/**
	 * Return a value clamped to an inclusive range of min and max.
	 *
	 * @group Math
	 */
	clamp(n: number, min: number, max: number): number;
	/**
	 * Evaluate the quadratic Bezier at the given t.
	 *
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateQuadratic(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2;
	/**
	 * Evaluate the first derivative of a quadratic bezier at the given t.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateQuadraticFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2;
	/**
	 * Evaluate the second derivative of a quadratic bezier at the given t
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateQuadraticSecondDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2;
	/**
	 * Evaluate the cubic Bezier at the given t.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateBezier(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2;
	/**
	 * Evaluate the first derivative of a cubic Bezier at the given t.
	 *
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateBezierFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2;
	/**
	 * Evaluate the second derivative of a cubic bezier at the given t.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateBezierSecondDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2;
	/**
	 * Evaluate the Catmull-Rom spline at the given t.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateCatmullRom(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2;
	/**
	 * Evaluate the first derivative of a Catmull-Rom spline at the given t.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	evaluateCatmullRomFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2;
	/**
	 * Returns a function.
	 * entries is the amount of entries in the LUT.
	 * detail is the sampling granularity of each segment recorded in the LUT.
	 * This new function either returns the length for a given t, or t for a given length, depending on the inverse parameter.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	curveLengthApproximation(curve: (t: number) => Vec2, entries: number, detail: number): (t: number, inverse: boolean) => number;
	/**
	 * Returns a new curve which is normalized. This new curve has constant speed
	 * curve is any curve in t (non-constant between 0 and 1)
	 * returns a curve in s (constant between 0 and 1)
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	normalizedCurve(curve: (t: number) => Vec2): (s: number) => Vec2;
	/**
	 * A second order function returning an evaluator for the given 1D Hermite curve.
	 *
	 * @param pt1 - First point.
	 * @param m1 - First control point (tangent).
	 * @param m2 - Second control point (tangent).
	 * @param pt2 - Second point.
	 *
	 * @returns A function which gives the value on the 1D Hermite curve at t.
	 * @group Math
	 * @subgroup Advanced
	 */
	hermite(pt1: number, m1: number, m2: number, pt2: number): (t: number) => number;
	/**
	 * A second order function returning an evaluator for the given 2D Cardinal curve.
	 *
	 * @param pt1 - Previous point.
	 * @param pt2 - First point.
	 * @param pt3 - Second point.
	 * @param pt4 - Next point.
	 * @param tension - The tension of the curve, [0..1] from round to tight.
	 *
	 * @returns A function which gives the value on the 2D Cardinal curve at t.
	 * @group Math
	 * @subgroup Advanced
	 */
	cardinal(pt1: Vec2, m1: Vec2, m2: Vec2, pt2: Vec2, tension: number): (t: number) => Vec2;
	/**
	 * A second order function returning an evaluator for the given 2D Catmull-Rom curve.
	 *
	 * @param pt1 - Previous point.
	 * @param pt2 - First point.
	 * @param pt3 - Second point.
	 * @param pt4 - Next point.
	 *
	 * @returns A function which gives the value on the 2D Catmull-Rom curve at t.
	 * @group Math
	 * @subgroup Advanced
	 */
	catmullRom(pt1: Vec2, m1: Vec2, m2: Vec2, pt2: Vec2): (t: number) => Vec2;
	/**
	 * A second order function returning an evaluator for the given 2D quadratic Bezier curve.
	 *
	 * @param pt1 - First point.
	 * @param pt2 - First control point.
	 * @param pt3 - Second control point.
	 * @param pt4 - Second point.
	 *
	 * @returns A function which gives the value on the 2D quadratic Bezier curve at t.
	 * @group Math
	 * @subgroup Advanced
	 */
	bezier(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2): (t: number) => Vec2;
	/**
	 * A second order function returning an evaluator for the given 2D Kochanek–Bartels curve.
	 *
	 * @param pt1 - Previous point.
	 * @param pt2 - First point.
	 * @param pt3 - Second point.
	 * @param pt4 - Next point.
	 * @param tension - The tension of the curve, [-1..1] from round to tight.
	 * @param continuity - The continuity of the curve, [-1..1] from box corners to inverted corners.
	 * @param bias - The bias of the curve, [-1..1] from pre-shoot to post-shoot.
	 *
	 * @returns A function which gives the value on the 2D Kochanek–Bartels curve at t
	 * @group Math
	 * @subgroup Advanced
	 */
	kochanekBartels(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, tension: number, continuity: number, bias: number): (t: number) => Vec2;
	piecewiseBezier(pts: Vec2[]): (t: number) => Vec2;
	piecewiseCatmullRom(pts: Vec2[]): (t: number) => Vec2;
	createRegularPolygon(radius: number, sides: number, startAngle: number): Vec2[];
	createStarPolygon(radius1: number, radius2: number, sides: number, startAngle: number): Vec2[];
	createCogPolygon(radius1: number, radius2: number, sides: number, startAngle: number): Vec2[];
	floodFill(graph: Graph, start: number | number[], predicate: (node: number) => boolean): number[];
	buildConnectivityMap(graph: Graph): Map<number, number>;
	/**
	 * Check if a line and a point intersect.
	 *
	 * @param l - The line.
	 * @param pt - The point.
	 *
	 * @returns true if the line and point intersect.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testLinePoint(l: Line, pt: Vec2): boolean;
	/**
	 * Check if 2 lines intersect, if yes returns the intersection point.
	 *
	 * @param l1 - The first line.
	 * @param l2 - The second line.
	 *
	 * @returns The intersection point, or null if the lines are parallel.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testLineLine(l1: Line, l2: Line): Vec2 | null;
	/**
	 * Check if a line and a circle intersect.
	 *
	 * @param l - The line.
	 * @param c - The circle.
	 *
	 * @returns true if the line and circle intersect.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testLineCircle(l: Line, c: Circle): boolean;
	/**
	 * Check if 2 rectangle overlap.
	 *
	 * @param r1 - The first rectangle.
	 * @param r2 - The second rectangle.
	 *
	 * @returns true if the rectangles overlap.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testRectRect(r1: Rect, r2: Rect): boolean;
	/**
	 * Check if a line and a rectangle overlap.
	 *
	 * @param l - The line.
	 * @param r - The rectangle.
	 *
	 * @returns true if the line and rectangle overlap.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testRectLine(r: Rect, l: Line): boolean;
	/**
	 * Check if a point is inside a rectangle.
	 *
	 * @param r - The rectangle.
	 * @param pt - The point.
	 *
	 * @returns true if the point is inside the rectangle.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testRectPoint(r: Rect, pt: Vec2): boolean;
	/**
	 * Check if a circle and polygon intersect linewise.
	 *
	 * @param c - The circle.
	 * @param p - The polygon.
	 *
	 * @returns true if the circle and polygon intersect linewise.
	 * @since v2000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	testCirclePolygon(c: Circle, p: Polygon): boolean;
	/**
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	clipLineToRect(r: Rect, l: Line, result: Line): boolean;
	/**
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	clipLineToCircle(c: Circle, l: Line, result: Line): boolean;
	/**
	 * Returns a vector representing the anchor coordinates relative to the object's half-width, half-height, and center.
	 *
	 * For example: `anchorToVec2("right")` returns `vec2(1, 0)`, which means
	 * the anchor is fully to the right horizontally (1), and in-line with the
	 * centerpoint vertically (0).
	 *
	 * Or, `anchorToVec2("botleft")` returns `vec2(-1, 1)`, which means fully to the
	 * left (-1), and fully to the bottom (1).
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup Vectors
	 */
	anchorToVec2: typeof anchorPt;
	/**
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	gjkShapeIntersects(shapeA: Shape, shapeB: Shape): boolean;
	/**
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	gjkShapeIntersection(shapeA: Shape, shapeB: Shape): GjkCollisionResult | null;
	/**
	 * Builds the convex hull of a polygon. Note that even if the polygon is already convex, colinear points will be erased.
	 * @returns true if the given polygon is convex
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	isConvex(pts: Vec2[]): boolean;
	/**
	 * @returns 1 if over the edge, 0 otherwise
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	step(edge: number, x: number): number;
	/**
	 * @returns 1 if over edge1, 0 if under edge0, a smooth hermite curve value otherwise
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	smoothstep(edge0: number, edge1: number, x: number): number;
	/**
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	triangulate(pts: Vec2[]): Vec2[][];
	/**
	 * @returns the convex hull of the given polygon.
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	buildConvexHull(pts: Vec2[]): Vec2[];
	/**
	 * Sorts the array in-place using {@link https://en.wikipedia.org/wiki/Insertion_sort insertion sort}.
	 * This is useful when you have a persistent (not per-frame) array of objects and they change
	 * on each frame but not by much, but the list must remain sorted. (For example, the list could
	 * be returned by {@link get `get`} with the `liveUpdate` option enabled, and then stored somewhere.)
	 *
	 * @param compare - returns true if `[left, right]` is the correct order, false if `[right, left]` is the correct order.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	insertionSort<T>(array: T[], compare: (left: T, right: T) => boolean): void;
	/**
	 * A Navigation Mesh.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	NavMesh: typeof NavMesh;
	/**
	 * A Navigation Grid.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	NavGrid: typeof NavGrid;
	/**
	 * A point.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Point: typeof Point;
	/**
	 * A line shape.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Line: typeof Line;
	/**
	 * A rectangle shape.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Rect: typeof Rect;
	/**
	 * A circle shape.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Circle: typeof Circle;
	/**
	 * An ellipse shape.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Ellipse: typeof Ellipse;
	/**
	 * A polygon shape.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Shapes
	 */
	Polygon: typeof Polygon;
	/**
	 * A 2D vector.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Vectors
	 */
	Vec2: typeof Vec2;
	/**
	 * A color.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Vectors
	 */
	Color: typeof Color;
	/**
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	Mat4: typeof Mat4;
	/**
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	Mat2: typeof Mat2;
	/**
	 * @since v4000.0
	 * @group Math
	 * @subgroup Advanced
	 */
	Mat23: typeof Mat23;
	/**
	 * A 2D quad.
	 *
	 * @since v3001.0
	 * @group Math
	 * @subgroup Advanced
	 */
	Quad: typeof Quad;
	/**
	 * A quadtree
	 *
	 * @since 4000
	 * @group Math
	 * @subgroup Advanced
	 */
	Quadtree: typeof Quadtree;
	/**
	 * Make a new quadtree
	 *
	 * @param pos - The position of the top level node
	 * @param width - The width of the top level node
	 * @param height - The height of the top level node
	 * @param maxObjects - The maximum amount of objects per node before splitting
	 * @param maxLevels - The maximum amount of levels
	 */
	makeQuadtree(pos: Vec2, width: number, height: number, maxObjects: number, maxLevels: number, resizing: boolean): Quadtree | ResizingQuadtree;
	/**
	 * The Random Number Generator.
	 *
	 * @since v2000.0
	 * @group Math
	 * @subgroup Random
	 */
	RNG: typeof RNG;
	/**
	 * A rule in a rule system for AI. Note that this is only for advanced scenarios where the default rules are inadequate.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup AI
	 */
	Rule: typeof Rule;
	/**
	 * A rule system for AI.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup AI
	 */
	RuleSystem: typeof RuleSystem;
	/**
	 * A node in a decision tree for AI.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup AI
	 */
	DecisionNode: typeof DecisionNode;
	/**
	 * A decision tree for AI.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup AI
	 */
	DecisionTree: typeof DecisionTree;
	/**
	 * A state machine for AI.
	 *
	 * @since v4000.0
	 * @group Math
	 * @subgroup AI
	 */
	StateMachine: typeof StateMachine;
	/**
	 * This object serves 2 purposes:
	 *
	 * * When called as a function, it defines a new scene with the
	 *   name and the initializer function.
	 * * It can also be used to register scene-local event handlers
	 *   that will be automatically cancelled when the scene is left.
	 *
	 * @param name - The scene name.
	 * @param def - The scene definition.
	 *
	 * @example
	 * ```js
	 * // define a scene
	 * scene("game", () => {
	 *     // ...
	 * });
	 * // get options
	 * scene("game", (opts) => {
	 *     debug.log(opts.level);
	 * });
	 * ```
	 * @example
	 * ```js
	 * scene("pauseMenu", () => {
	 *     scene.onKeyPress("tab", () => {
	 *         debug.log("go to next menu item");
	 *     });
	 *     scene.onKeyPress("esc", () => {
	 *         // go back to game and cancel menu events
	 *         popScene();
	 *     });
	 * });
	 * ```
	 *
	 * @group Scenes
	 */
	scene: SceneScope;
	/**
	 * Go to a scene, passing all rest args to scene callback.
	 *
	 * @param name - The scene name.
	 * @param args - The rest args to pass to the scene callback.
	 *
	 * @example
	 * ```js
	 * // go to "game" scene
	 * go("game");
	 *
	 * // go with options
	 * go("game", { level: 1 });
	 * ```
	 *
	 * @since v2000.0
	 * @group Scenes
	 */
	go(name: string, ...args: any): void;
	/**
	 * Push the current active scene to a stack and then goes to the new scene
	 *
	 * @param id - The scene name.
	 * @param args - The args passed to the scene definition.
	 *
	 * @example
	 * ```js
	 * scene("mainScene", () => {
	 *     add([
	 *         text("this is the first scene", { size: 32 }),
	 *         pos(center()),
	 *     ]);
	 * });
	 * scene("otherScene", () => {
	 *     add([
	 *         sprite("bean"),
	 *         pos(center()),
	 *     ]);
	 * });
	 *
	 * pushScene("mainScene");
	 * ```
	 *
	 * @since v3001.1
	 * @group Scenes
	 *
	 * @see {@link popScene}
	 */
	pushScene(id: string, ...args: unknown[]): void;
	/**
	 * Pops the scene from the stack and set as current active scene.
	 *
	 * Only works if the current scene was entered using {@link pushScene}.
	 *
	 * @example
	 * ```js
	 * scene("mainScene", () => {
	 *     add([
	 *         text("this is the first scene", { size: 32 }),
	 *         pos(center()),
	 *     ]);
	 * });
	 * scene("otherScene", () => {
	 *     add([
	 *         sprite("bean"),
	 *         pos(center()),
	 *     ]);
	 * });
	 *
	 * pushScene("mainScene");
	 * popScene(); // return to the current scene
	 * ```
	 *
	 * @since v3001.1
	 * @group Scenes
	 */
	popScene(): void;
	/**
	 * Define the layer names. Should be called before any objects are made.
	 *
	 * @param layers - The layer names.
	 * @param defaultLayer - The default layer name.
	 *
	 * @example
	 * ```js
	 * layers(["bg", "obj", "ui"], "obj");
	 *
	 * // no layer specified, will be added to "obj"
	 * add([
	 *      sprite("bean"),
	 * ]);
	 *
	 * // add to "bg" layer
	 * add([
	 *     sprite("bg"),
	 *     layer("bg"),
	 * ]);
	 * ```
	 *
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Layers
	 */
	setLayers(layers: string[], defaultLayer: string): void;
	/**
	 * Get the layer names.
	 *
	 * @returns The layer names or null if not set.
	 * @since v3001.1
	 * @group Rendering
	 * @subgroup Layers
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1
	 */
	getLayers(): string[] | null;
	/**
	 * Get the default layer name.
	 *
	 * @returns The default layer name or null if not set.
	 * @since v3001.0.5
	 * @group Rendering
	 * @subgroup Layers
	 * @experimental This feature is in experimental phase, it will be fully released in v3001.1
	 */
	getDefaultLayer(): string | null;
	/**
	 * @deprecated Use {@link setLayers} instead.
	 *
	 * Define the layer names. Should be called before any objects are made.
	 *
	 * @param layers - The layer names.
	 * @param defaultLayer - The default layer name.
	 *
	 * @example
	 * ```js
	 * setLayers(["bg", "obj", "ui"], "obj")
	 *
	 * // no layer specified, will be added to "obj"
	 * add([
	 *      sprite("bean"),
	 * ]);
	 *
	 * // add to "bg" layer
	 * add([
	 *     sprite("bg"),
	 *     layer("bg"),
	 * ]);
	 * ```
	 *
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Layers
	 */
	layers(layers: string[], defaultLayer: string): void;
	/**
	 * Construct a level based on symbols.
	 *
	 * @param map - The map data.
	 * @param opt - The level options.
	 * @param parent - The parent object of the level. Defaults to root.
	 *
	 * @example
	 * ```js
	 * addLevel([
	 *     "                          $",
	 *     "                          $",
	 *     "           $$         =   $",
	 *     "  %      ====         =   $",
	 *     "                      =    ",
	 *     "       ^^      = >    =   &",
	 *     "===========================",
	 * ], {
	 *     // define the size of tile block
	 *     tileWidth: 32,
	 *     tileHeight: 32,
	 *     // define what each symbol means, by a function returning a component list (what will be passed to add())
	 *     tiles: {
	 *         "=": () => [
	 *             sprite("floor"),
	 *             area(),
	 *             body({ isStatic: true }),
	 *         ],
	 *         "$": () => [
	 *             sprite("coin"),
	 *             area(),
	 *             pos(0, -9),
	 *         ],
	 *         "^": () => [
	 *             sprite("spike"),
	 *             area(),
	 *             "danger",
	 *         ],
	 *     }
	 * })
	 * ```
	 *
	 * @returns A game obj with the level.
	 * @since v2000.0
	 * @group Game Obj
	 *
	 * @see {@link LevelComp `LevelComp`} The level component for more information in level methods.
	 */
	addLevel(map: string[], opt: AddLevelOpt, parent?: GameObj): GameObj<PosComp | LevelComp>;
	/**
	 * Get data from local storage, if not present can set to a default value.
	 *
	 * @param key - The key to get data from.
	 * @param def - The default value to set if not found.
	 *
	 * @returns The data or null if not found.
	 * @since v2000.0
	 * @group Data
	 */
	getData<T>(key: string, def?: T): T | null;
	/**
	 * Set data from local storage.
	 *
	 * @param key - The key to set data to.
	 * @param data - The data to set.
	 *
	 * @since v2000.0
	 * @group Data
	 */
	setData(key: string, data: any): void;
	/**
	 * Draw a sprite.
	 *
	 * @param opt - The draw sprite options.
	 *
	 * @example
	 * ```js
	 * drawSprite({
	 *     sprite: "bean",
	 *     pos: vec2(100, 200),
	 *     frame: 3,
	 * });
	 * ```
	 *
	 * @since v2000.0
	 * @group Draw
	 */
	drawSprite(opt: DrawSpriteOpt): void;
	/**
	 * Draw a piece of text.
	 *
	 * @param opt - The draw text options.
	 *
	 * @example
	 * ```js
	 * drawText({
	 *     text: "oh hi",
	 *     size: 48,
	 *     font: "sans-serif",
	 *     width: 120,
	 *     pos: vec2(100, 200),
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v2000.0
	 * @group Draw
	 */
	drawText(opt: DrawTextOpt): void;
	/**
	 * Draw a rectangle.
	 *
	 * @param opt - The draw rect options.
	 *
	 * @example
	 * ```js
	 * drawRect({
	 *     width: 120,
	 *     height: 240,
	 *     pos: vec2(20, 20),
	 *     color: YELLOW,
	 *     outline: { color: BLACK, width: 4 },
	 * });
	 * ```
	 *
	 * @since v2000.0
	 * @group Draw
	 */
	drawRect(opt: DrawRectOpt): void;
	/**
	 * Draw a line.
	 *
	 * @param opt - The draw line options.
	 *
	 * @example
	 * ```js
	 * drawLine({
	 *     p1: vec2(0),
	 *     p2: mousePos(),
	 *     width: 4,
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawLine(opt: DrawLineOpt): void;
	/**
	 * Draw lines.
	 *
	 * @param opt - The draw lines options.
	 *
	 * @example
	 * ```js
	 * drawLines({
	 *     pts: [ vec2(0), vec2(0, height()), mousePos() ],
	 *     width: 4,
	 *     pos: vec2(100, 200),
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawLines(opt: DrawLinesOpt): void;
	/**
	 * Draw a curve.
	 *
	 * @example
	 * ```js
	 * drawCurve(t => evaluateBezier(a, b, c, d, t), {
	 *     width: 2,
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v3001.0
	 * @group Draw
	 */
	drawCurve(curve: (t: number) => Vec2, opt: DrawCurveOpt): void;
	/**
	 * Draw a cubic Bezier curve.
	 *
	 * @param opt - The draw cubic bezier options.
	 *
	 * @example
	 * ```js
	 * drawBezier({
	 *     pt1: vec2(100, 100),
	 *     pt2: vec2(200, 100),
	 *     pt3: vec2(200, 200),
	 *     pt4: vec2(100, 200),
	 *     width: 2,
	 *     color: GREEN,
	 * });
	 * ```
	 *
	 * @since v3001.0
	 * @group Draw
	 */
	drawBezier(opt: DrawBezierOpt): void;
	/**
	 * Draw a triangle.
	 *
	 * @param opt - The draw triangle options.
	 *
	 * @example
	 * ```js
	 * drawTriangle({
	 *     p1: vec2(0),
	 *     p2: vec2(0, height()),
	 *     p3: mousePos(),
	 *     pos: vec2(100, 200),
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v3001.0
	 * @group Draw
	 */
	drawTriangle(opt: DrawTriangleOpt): void;
	/**
	 * Draw a circle.
	 *
	 * @param opt - The draw circle options.
	 *
	 * @example
	 * ```js
	 * drawCircle({
	 *     pos: vec2(100, 200),
	 *     radius: 120,
	 *     color: rgb(255, 255, 0),
	 * });
	 * ```
	 *
	 * @since v2000.0
	 * @group Draw
	 */
	drawCircle(opt: DrawCircleOpt): void;
	/**
	 * Draw an ellipse.
	 *
	 * @param opt - The draw ellipse options.
	 *
	 * @example
	 * ```js
	 * drawEllipse({
	 *     pos: vec2(100, 200),
	 *     radiusX: 120,
	 *     radiusY: 120,
	 *     color: rgb(255, 255, 0),
	 * });
	 * ```
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawEllipse(opt: DrawEllipseOpt): void;
	/**
	 * Draw a convex polygon from a list of vertices.
	 *
	 * @param opt - The draw polygon options.
	 *
	 * @example
	 * ```js
	 * drawPolygon({
	 *     pts: [
	 *         vec2(-12),
	 *         vec2(0, 16),
	 *         vec2(12, 4),
	 *         vec2(0, -2),
	 *         vec2(-8),
	 *     ],
	 *     pos: vec2(100, 200),
	 *     color: rgb(0, 0, 255),
	 * });
	 * ```
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawPolygon(opt: DrawPolygonOpt): void;
	/**
	 * Draw a rectangle with UV data.
	 *
	 * @param opt - The draw rect with UV options.
	 *
	 * @since v2000.0
	 * @group Draw
	 */
	drawUVQuad(opt: DrawUVQuadOpt): void;
	/**
	 * Draw a piece of formatted text from formatText().
	 *
	 * @param text - The formatted text object.
	 *
	 * @example
	 * ```js
	 * // text background
	 * const txt = formatText({
	 *     text: "oh hi",
	 * });
	 *
	 * drawRect({
	 *     width: txt.width,
	 *     height: txt.height,
	 * });
	 *
	 * drawFormattedText(txt);
	 * ```
	 *
	 * @since v2000.2
	 * @group Draw
	 */
	drawFormattedText(text: FormattedText): void;
	/**
	 * Whatever drawn in content will only be drawn if it's also drawn in mask (mask will not be rendered).
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawMasked(content: () => void, mask: () => void): void;
	/**
	 * Subtract whatever drawn in content by whatever drawn in mask (mask will not be rendered).
	 *
	 * @since v3000.0
	 * @group Draw
	 */
	drawSubtracted(content: () => void, mask: () => void): void;
	/**
	 * The exported Picture class to KAPLAY Context.
	 *
	 * @example
	 * ```js
	 * const k = kaplay();
	 *
	 * // You can use Picture class
	 * new k.Picture()
	 * ```
	 *
	 * @group Draw
	 * @subgroup Picture
	 */
	Picture: typeof Picture;
	/**
	 * Selects the picture for drawing, erases existing data.
	 *
	 * @param picture - The picture to write drawing data to.
	 *
	 * @since v4000.0
	 * @group Draw
	 * @subgroup Picture
	 */
	beginPicture(picture?: Picture): void;
	/**
	 * Selects the picture for drawing, keeps existing data.
	 *
	 * @param picture - The picture to write drawing data to.
	 *
	 * @since v4000.0
	 * @group Draw
	 * @subgroup Picture
	 */
	appendToPicture(picture?: Picture): void;
	/**
	 * Deselects the current picture for drawing, returning the picture.
	 *
	 * @returns The picture which was previously selected.
	 * @since v4000.0
	 * @group Draw
	 * @subgroup Picture
	 */
	endPicture(): Picture;
	/**
	 * Draws a picture to the screen. This function can not be used to draw recursively to a picture.
	 *
	 * @param picture - The picture to draw
	 * @param opt - Drawing
	 *
	 * @since v4000.0
	 * @group Draw
	 * @subgroup Picture
	 */
	drawPicture(picture: Picture, opt: DrawPictureOpt): void;
	/**
	 * Push current transform matrix to the transform stack.
	 *
	 * @example
	 * ```js
	 * pushTransform();
	 *
	 * // These transforms will affect every render until popTransform()
	 * pushTranslate(120, 200);
	 * pushRotate(time() * 120);
	 * pushScale(6);
	 *
	 * drawSprite("bean");
	 * drawCircle(vec2(0), 120);
	 *
	 * // Restore the transformation stack to when last pushed
	 * popTransform();
	 * ```
	 *
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	pushTransform(): void;
	/**
	 * Pop the topmost transform matrix from the transform stack.
	 *
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	popTransform(): void;
	/**
	 * Translate all subsequent draws.
	 *
	 * @example
	 * ```js
	 * pushTranslate(100, 100)
	 *
	 * // this will be drawn at (120, 120)
	 * drawText({
	 *     text: "oh hi",
	 *     pos: vec2(20, 20),
	 * })
	 * ```
	 *
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	pushTranslate(t?: Vec2): void;
	/**
	 * Scale all subsequent draws.
	 *
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	pushScale(s?: Vec2): void;
	/**
	 * Rotate all subsequent draws.
	 *
	 * @since v2000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	pushRotate(angle?: number): void;
	/**
	 * Apply a transform matrix, ignore all prior transforms.
	 *
	 * @since v3000.0
	 * @group Rendering
	 * @subgroup Stack
	 */
	pushMatrix(mat: Mat23): void;
	/**
	 * Apply a post process effect from a shader name.
	 *
	 * @example
	 * ```js
	 * loadShader("invert", null, `
	 * vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
	 *     vec4 c = def_frag();
	 *     return vec4(1.0 - c.r, 1.0 - c.g, 1.0 - c.b, c.a);
	 * }
	 * `)
	 *
	 * usePostEffect("invert")
	 * ```
	 *
	 * @since v3000.0
	 * @group Rendering
	 * @subgroup Shaders
	 */
	usePostEffect(name: string, uniform?: Uniform | (() => Uniform)): void;
	/**
	 * Format a piece of text without drawing (for getting dimensions, etc).
	 *
	 * @example
	 * ```js
	 * // text background
	 * const txt = formatText({
	 *     text: "oh hi",
	 * });
	 *
	 * drawRect({
	 *     width: txt.width,
	 *     height: txt.height,
	 * });
	 *
	 * drawFormattedText(txt);
	 * ```
	 *
	 * @returns The formatted text object.
	 * @since v2000.2
	 * @group Rendering
	 * @subgroup Text
	 */
	formatText(options: DrawTextOpt): FormattedText;
	/**
	 * Parses the text that has formatting tags, and returns the unstyled text
	 * (the actual characters that will be displayed) as well as which styles are
	 * active on each character.
	 *
	 * @since v4000
	 * @group Rendering
	 * @subgroup Text
	 */
	compileStyledText(text: any): StyledTextInfo;
	/**
	 * Create a canvas to draw stuff offscreen.
	 *
	 * @returns The canvas object.
	 * @since v3001.0
	 * @group Rendering
	 * @subgroup Canvas
	 */
	makeCanvas(w: number, h: number): Canvas;
	/**
	 * Draw a canvas.
	 *
	 * @param opt - The canvas object.
	 *
	 * @since v4000.0
	 * @group Draw
	 */
	drawCanvas(opt: DrawCanvasOpt): void;
	/**
	 * The Debug interface for debugging stuff.
	 *
	 * @example
	 * ```js
	 * // pause the whole game
	 * debug.paused = true
	 *
	 * // enter inspect mode
	 * debug.inspect = true
	 * ```
	 *
	 * @returns The debug interface.
	 * @since v2000.0
	 * @group Debug
	 */
	debug: Debug;
	/**
	 * The app scope for creating global events that won't be automatically cancelled
	 * when the scene is changed.
	 *
	 * @example
	 * ```js
	 * app.onKeyPress("f", () => {
	 *     debug.log("i run in every scene from now on");
	 * });
	 *
	 * // will NOT cancel the event
	 * go("someScene");
	 * ```
	 */
	app: AppScope;
	/**
	 * Import a plugin.
	 *
	 * @param plugin - The plugin to import.
	 *
	 * @returns The updated context with the plugin.
	 * @since v2000.0
	 * @group Plugins
	 */
	plug<T extends Record<string, any>>(plugin: KAPLAYPlugin<T>): KAPLAYCtx & T;
	/**
	 * Runs a system at the specified events in the pipeline
	 *
	 * @param name - The name of the system. Overwrites an existing system if the name has been used before.
	 * @param cb - The function to run.
	 * @param when - When to run the function. See {@link SystemPhase} for more info on the 6 phases when the system can be run.
	 *
	 * @since v4000.0
	 * @group Plugins
	 */
	system(name: string, cb: () => void, when: SystemPhase[]): void;
	/**
	 * This enum defines the 6 places where a new system can hook into in KAPLAY's update loop.
	 *
	 * * `BeforeUpdate` and `AfterUpdate` - run once at the start of the frame, before and after all objects' `update()` hooks are run
	 * * `BeforeDraw` and `AfterDraw` - run once per frame while the graphics context is setup, before and after all objects' `draw()` hooks are run
	 * * `BeforeFixedUpdate` and `AfterFixedUpdate` - run 50 times per second independent of graphics/update framerate, before and after all objects' `fixedUpdate()` hooks are run
	 *
	 * @group Plugins
	 */
	SystemPhase: typeof SystemPhase;
	/**
	 * Take a screenshot and get the PNG data url of the image.
	 *
	 * @returns The dataURL of the PNG image.
	 * @since v2000.0
	 * @group Debug
	 */
	screenshot(): string;
	/**
	 * Take a screenshot and get the PNG data as a blob.
	 *
	 * @returns The blob of the image.
	 * @since v4000.0
	 * @group Debug
	 */
	screenshotToBlob(): Promise<Blob>;
	/**
	 * Trigger a file download from a url.
	 *
	 * @since v3000.0
	 * @group Data
	 */
	download(filename: string, dataurl: string): void;
	/**
	 * Trigger a text file download.
	 *
	 * @since v3000.0
	 * @group Data
	 */
	downloadText(filename: string, text: string): void;
	/**
	 * Trigger a json download from a .
	 *
	 * @since v3000.0
	 * @group Data
	 */
	downloadJSON(filename: string, data: any): void;
	/**
	 * Trigger a file download from a blob.
	 *
	 * @since v3000.0
	 * @group Data
	 */
	downloadBlob(filename: string, blob: Blob): void;
	/**
	 * Start recording the canvas into a video.
	 *
	 * Note: This relies on the browser's support using the `MediaRecorder`
	 * API, and support is buggy at best from my (@dragoncoder047)'s testing.
	 * The best results I have gotten are with explicitly specifying `video/webm`
	 * and 60 FPS.
	 *
	 * Results with the default values are usually no good and even if both MIME
	 * type and framerate are specified, dropped frames, truncated videos,
	 * audio desynchronization, and even completely corrupted files have been gotten
	 * from this. `video/mp4` is technically supported by some browsers but I can't
	 * recommend it as MP4 has produced glitched and/or corrupted files much more often
	 * than WebM in my testing.
	 *
	 * If your players want to get a nice clean recording it's probably a better
	 * idea to point them to an external screen-recording program such as
	 * [OBS](https://obsproject.com).
	 *
	 * @param frameRate - Target frame rate for the output video.
	 * If framerate is not specified, a new frame will be captured each
	 * time the canvas changes.
	 * @param mimeTypes - A list of MIME types such as `video/mp4`, `video/webm`.
	 * The browser will select the first one it can do when the recording is started.
	 * If none are supported, an error will be thrown.
	 *
	 * @returns A control handle.
	 * @since v2000.1
	 * @group Debug
	 */
	record(frameRate?: number, mimeTypes?: string[]): Recording;
	/**
	 * Add an explosion effect.
	 *
	 * @param pos - The position of the explosion.
	 * @param opt - The options for the explosion.
	 *
	 * @example
	 * ```js
	 * onMousePress(() => {
	 *     addKaboom(mousePos());
	 * });
	 * ```
	 *
	 * @returns The explosion object.
	 * @since v2000.0
	 * @group Game Obj
	 */
	addKaboom(pos: Vec2, opt?: BoomOpt): GameObj;
	/**
	 * All chars in ASCII.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	ASCII_CHARS: string;
	/**
	 * Left directional vector vec2(-1, 0).
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	LEFT: Vec2;
	/**
	 * Right directional vector vec2(1, 0).
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	RIGHT: Vec2;
	/**
	 * Up directional vector vec2(0, -1).
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	UP: Vec2;
	/**
	 * Down directional vector vec2(0, 1).
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	DOWN: Vec2;
	/**
	 * Red color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	RED: Color;
	/**
	 * Green color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	GREEN: Color;
	/**
	 * Blue color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	BLUE: Color;
	/**
	 * Yellow color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	YELLOW: Color;
	/**
	 * Cyan color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	MAGENTA: Color;
	/**
	 * Cyan color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	CYAN: Color;
	/**
	 * White color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	WHITE: Color;
	/**
	 * Black color.
	 *
	 * @since v2000.0
	 * @group Constants
	 */
	BLACK: Color;
	/**
	 * The canvas DOM KAPLAY is currently using.
	 *
	 * @since v2000.0
	 * @group Info
	 */
	canvas: HTMLCanvasElement;
	/**
	 * EventHandler for one single event.
	 *
	 * @since v3000.0
	 * @group Events
	 */
	KEvent: typeof KEvent;
	/**
	 * EventHandler for multiple events.
	 *
	 * @since v3000.0
	 * @group Events
	 */
	KEventHandler: typeof KEventHandler;
	/**
	 * The object that can pause or cancel an event.
	 *
	 * @since v3000.0
	 * @group Events
	 */
	KEventController: typeof KEventController;
	/**
	 * Cancels the event by returning the cancel symbol.
	 *
	 * @example
	 * ```js
	 * onKeyPress((key) => {
	 *     if (key === "q") return cancel();
	 * });
	 * ```
	 *
	 * @returns The cancel event symbol.
	 * @since v4000.0
	 * @group Events
	 */
	cancel: () => Symbol;
	/**
	 * Flags indicating which transform components to keep. When used, the aspect of the transform will not change visually
	 * even if the parent transform is different. For example a sprite pointing west, will keep pointing west, even if the
	 * parent transform applies a rotation with an angle different from 0. This is only applied once, during switching parents.
	 *
	 * @since v3000.0
	 * @group Game Obj
	 * @subgroup Types
	 */
	KeepFlags: typeof KeepFlags;
	/**
	 * BlendMode.Normal Normal alpha blending
	 * BlendMode.Add Additive blending
	 * BlendMode.Multiply multiplicative blending
	 * BlendMode.Screen Screen blending
	 *
	 * @since v4000.0
	 * @group Constants
	 */
	BlendMode: typeof BlendMode;
	/**
	 * Current KAPLAY library version.
	 *
	 * @since v3000.0
	 * @group Info
	 */
	VERSION: string;
}
export type BroadPhaseType = "sap" | "sapv" | "quadtree" | "grid";
export type NarrowPhaseType = "gjk" | "sat" | "box";
export type Tag = string;
/**
 * The basic unit of object in KAPLAY. The player, a butterfly, a tree, or even a piece of text.
 *
 * @group Game Obj
 * @subgroup Types
 */
export type GameObj<T = any> = GameObjRaw & MergeComps<T>;
export type RemoveCompProps<T> = Defined<{
	[K in keyof T]: K extends keyof Comp ? never : T[K];
}>;
/**
 * A type to merge the components of a game object, omitting the default component properties.
 *
 * @group Components
 * @subgroup Component Types
 */
export type MergeComps<T> = MergeObj<RemoveCompProps<T>>;
export type MergePlugins<T extends PluginList<any>> = MergeObj<ReturnType<T[number]>>;
/**
 * A component list.
 *
 * @group Components
 * @subgroup Component Types
 */
export type CompList<T extends any | undefined> = (T | Tag)[];
export type PluginList<T> = Array<T | KAPLAYPlugin<any>>;
/**
 * A key.
 *
 * @group Input
 * @subgroup Keyboard
 */
export type Key = ("f1" | "f2" | "f3" | "f4" | "f5" | "f6" | "f7" | "f8" | "f9" | "f10" | "f11" | "f12" | "`" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" | "-" | "+" | "=" | "q" | "w" | "e" | "r" | "t" | "y" | "u" | "i" | "o" | "p" | "[" | "]" | "\\" | "a" | "s" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | ";" | "'" | "z" | "x" | "c" | "v" | "b" | "n" | "m" | "," | "." | "/" | "escape" | "backspace" | "enter" | "tab" | "control" | "alt" | "meta" | "space" | " " | "left" | "right" | "up" | "down" | "shift") | (string & {});
/**
 * You can use 3 or more keys (like `control+shift+s`),
 * it just isn't included in the type here because typescript
 * crashes when it tries to expand all 74^3 = 405224 combinations
 * for 3 keys.
 */
export type ChordedKey = Key | `${Key}+${Key}`;
/**
 * A mouse button.
 *
 * @group Input
 * @subgroup Mouse
 */
export type MouseButton = "left" | "right" | "middle" | "back" | "forward";
export type ChordedMouseButton = MouseButton | `${MouseButton}+${MouseButton}`;
/**
 * A gamepad button.
 *
 * @group Input
 * @subgroup Gamepad
 */
export type KGamepadButton = "north" | "east" | "south" | "west" | "ltrigger" | "rtrigger" | "lshoulder" | "rshoulder" | "select" | "start" | "lstick" | "rstick" | "dpad-up" | "dpad-right" | "dpad-down" | "dpad-left" | "home" | "capture" | "touchpad";
export type ChordedKGamepadButton = KGamepadButton | `${KGamepadButton}+${KGamepadButton}` | `${KGamepadButton}+${KGamepadButton}+${KGamepadButton}`;
/**
 * A gamepad stick.
 *
 * @group Input
 * @subgroup Gamepad
 */
export type KGamepadStick = "left" | "right";
/**
 * A gamepad definition. Used in {@link KAPLAYOpt `KAPLAYOpt`}
 *
 * @group Input
 * @subgroup Gamepad
 */
export type GamepadDef = {
	buttons: Record<string, KGamepadButton>;
	sticks: Partial<Record<KGamepadStick, {
		x: number;
		y: number;
	}>>;
};
/**
 *  A KAPLAY gamepad
 *
 * @group Input
 * @subgroup Gamepad
 */
export type KGamepad = {
	/** The order of the gamepad in the gamepad list. */
	index: number;
	/** If certain button is pressed. */
	isPressed(b: KGamepadButton): boolean;
	/** If certain button is held down. */
	isDown(b: KGamepadButton): boolean;
	/** If certain button is released. */
	isReleased(b: KGamepadButton): boolean;
	/** Get the value of a stick. */
	getStick(stick: KGamepadStick): Vec2;
	/** Get the 0-1 analog value of the button
	 * (useful for `ltrigger` and `rtrigger` buttons) */
	getAnalog(b: KGamepadButton): number;
};
/**
 * Inspect info for a game object.
 */
export type GameObjInspect = Record<Tag, string | null>;
export type MustKAPLAYOpt = {
	scale: number;
	spriteAtlasPadding: number;
} & KAPLAYOpt;
/**
 * KAPLAY configurations.
 *
 * @group Start
 */
export interface KAPLAYOpt {
	/**
	 * Width of game.
	 */
	width?: number;
	/**
	 * Height of game.
	 */
	height?: number;
	/**
	 * Pixel scale / size.
	 */
	scale?: number;
	/**
	 * Keep aspect ratio and leave black bars on remaining spaces.
	 */
	letterbox?: boolean;
	/**
	 * If register debug buttons (default true)
	 */
	debug?: boolean;
	/**
	 * Key that toggles debug mode
	 */
	debugKey?: Key;
	/**
	 * Default font (defaults to "monospace").
	 */
	font?: string;
	/**
	 * Device pixel scale (defaults to 1, high pixel density will hurt performance).
	 *
	 * @since v3000.0
	 */
	pixelDensity?: number;
	/**
	 * Disable antialias and enable sharp pixel display. If you see rendering artifacts, set `pixelDensity`
	 * param to `Math.min(devicePixelRatio, 2)` and `scale` to FHD resolution (e.g. 960x540 would need scale 2). Will result in up to 4K.
	 */
	crisp?: boolean;
	/**
	 * The canvas DOM element to use. If empty will create one.
	 */
	canvas?: HTMLCanvasElement;
	/**
	 * The container DOM element to insert the canvas if created. Defaults to document.body.
	 */
	root?: HTMLElement;
	/**
	 * Background color. E.g. [ 0, 0, 255 ] for solid blue background, or [ 0, 0, 0, 0 ] for transparent background. Accepts RGB value array or string hex codes.
	 */
	background?: RGBValue | RGBAValue | string;
	/**
	 * Default sprite texture filter.
	 * @default "nearest"
	 */
	texFilter?: TexFilter;
	/**
	 * Default text rasterization filter.
	 * @default
	 * "linear" for vector fonts (.woff2, .ttf, .otf, etc)
	 * "nearest" for bitmap fonts (loaded from an image)
	 */
	fontFilter?: TexFilter;
	/**
	 * How many log messages can there be on one screen (default 8).
	 */
	logMax?: number;
	/**
	 * How many seconds log messages stay on screen (default 4).
	 *
	 * @since v3000.1
	 */
	logTime?: number;
	/**
	 * Size of the spatial hash grid for collision detection (default 64).
	 *
	 * @since v3000.0
	 */
	hashGridSize?: number;
	/**
	 * If translate touch events as mouse clicks (default true).
	 */
	touchToMouse?: boolean;
	/**
	 * If KAPLAY should render a default loading screen when assets are not fully ready (default true).
	 *
	 * @since v3000.0
	 */
	loadingScreen?: boolean;
	/**
	 * If pause audio when tab is not active (default false).
	 *
	 * @since v3000.0
	 */
	backgroundAudio?: boolean;
	/**
	 * Custom gamepad definitions (see gamepad.json for reference of the format).
	 *
	 * @since v3000.0
	 */
	gamepads?: Record<string, GamepadDef>;
	/**
	 * Defined buttons for input binding.
	 *
	 * @since v30010
	 */
	buttons?: ButtonsDef;
	/**
	 * Limit framerate to an amount per second.
	 *
	 * @since v3000.0
	 */
	maxFPS?: number;
	/**
	 * The number of fixedUpdate() events that should happen per second.
	 * The fixedUpdate() loop is used for physics.
	 * The average user should never need to change this. If you set it too low
	 * then your physics will freak out  due to numerical instability. If you set it too high then
	 * the game will lag.
	 *
	 * The options are:
	 * * friedPotato: 10Hz
	 * * potato: 20Hz
	 * * snail: 25Hz
	 * * normal: 50Hz (default)
	 * * lightspeed: 80Hz
	 * * ridiculous: 125Hz
	 * * ludicrous: 160Hz
	 *
	 * @group Physics
	 * @experimental
	 */
	fixedUpdateMode?: FixedSpeedOption;
	/**
	 * The maximum amount of time the game will simulate passing in order to
	 * limit lag. If the framerate lags low enough that one frame takes
	 * longer than this time, the game will instead use this as the delta time
	 * value, which means that the game will run slower than 100% speed.
	 * The average user should never need to change this. If you set it too
	 * low, the game will slow down with even the slightest lag, and if you
	 * set it too high then the game could try to do too much on each frame
	 * and amplify the lag problem.
	 *
	 * @default 0.1
	 * @group Physics
	 * @experimental
	 */
	maxTimeStep?: number;
	/**
	 * If focus on the canvas on start (default true).
	 *
	 * @since v3001.0
	 */
	focus?: boolean;
	/**
	 * If import all KAPLAY functions to global (default true).
	 */
	global?: boolean;
	/**
	 * List of plugins to import.
	 */
	plugins?: PluginList<any>;
	/**
	 * Enter burp mode.
	 */
	burp?: boolean;
	/**
	 * Make components ids be added as tags.
	 *
	 * That means .is() will return true for components with that id.
	 *
	 * @default true
	 */
	tagComponentIds?: boolean;
	/**
	 * Padding used when adding sprites to texture atlas.
	 *
	 * @default 2
	 */
	spriteAtlasPadding?: number;
	/**
	 * If the debug inspect view should ignore objects that are paused when choosing
	 * the object to show the inspect view on.
	 *
	 * @default false
	 * @experimental
	 */
	inspectOnlyActive?: boolean;
	/**
	 * Which strategy to use for broad phase collision, sap, sapv or quadtree
	 * @default "sap"
	 */
	broadPhaseCollisionAlgorithm?: BroadPhaseType;
	/**
	 * Which strategy to use for narrow phase collision, gjk, sat or box
	 * @default "gjk"
	 */
	narrowPhaseCollisionAlgorithm?: NarrowPhaseType;
	/**
	 * If true, only the topmost object receives clicks
	 * @default false
	 */
	topMostOnlyActivate?: boolean;
	/**
	 * Timeout (in milliseconds) at which other loaders waiting on sprites will give
	 * up and throw an error.
	 *
	 * Currently this is only used by {@link KAPLAYCtx.loadBitmapFontFromSprite}.
	 *
	 * @default 3000
	 */
	loadTimeout?: number;
	/**
	 * The default lifetime scope used for event handlers.
	 *
	 * @default "scene"
	 */
	defaultLifetimeScope?: "scene" | "app";
	/**
	 * TypeScript Advanced Features (TAF) are a series of options for TypeScript
	 * only features.
	 *
	 * It should be created using the helper function `kaplayTypes`.
	 *
	 * ```ts
	 * kaplay({
	 *    types: kaplayTypes<Opt<{
	 *        scenes: {}
	 *    }>>();
	 * });
	 * ```
	 *
	 * @since v4000.0
	 */
	types?: TypesOpt;
}
/**
 * A plugin for KAPLAY.
 *
 * @example
 * ```js
 * // a plugin that adds a new function to KAPLAY
 * const myPlugin = (k) => ({
 *    myFunc: () => {
 *       k.debug.log("hello from my plugin")
 *   }
 * })
 *
 * // use the plugin
 * kaplay({
 *   plugins: [ myPlugin ]
 * })
 *
 * // now you can use the new function
 * myFunc()
 * ```
 *
 * @group Plugins
 */
export type KAPLAYPlugin<T> = (k: KAPLAYCtx) => T | ((...args: any) => (k: KAPLAYCtx) => T);
/**
 * @group Rendering
 * @subgroup Canvas
 */
export type RenderTarget = {
	destination: FrameBuffer | Picture | null;
	childrenOnly?: boolean;
	refreshOnly?: boolean;
	isFresh?: boolean;
};
/**
 * @group Game Obj
 * @subgroup Types
 */
export type GetOpt = {
	/**
	 * Recursively get all children and their descendants.
	 */
	recursive?: boolean;
	/**
	 * Live update the returned list every time object is added / removed.
	 */
	liveUpdate?: boolean;
	/**
	 * Get only by tags or components.
	 */
	only?: "tags" | "comps";
};
/**
 * @group Game Obj
 * @subgroup Types
 */
export type QueryOpt = {
	/**
	 * All objects which include all or any of these tags, depending on includeOp.
	 */
	include?: string | string[];
	/**
	 * Selects the operator to use. Defaults to and.
	 */
	includeOp?: "and" | "or";
	/**
	 * All objects which do not have all or any of these tags, depending on excludeOp.
	 */
	exclude?: string | string[];
	/**
	 * Selects the operator to use. Defaults to and.
	 */
	excludeOp?: "and" | "or";
	/**
	 * All objects which are near or far to the position of this, depending on distanceOp.
	 */
	distance?: number;
	/**
	 * Selects the operator to use. Defaults to near.
	 */
	distanceOp?: "near" | "far";
	/**
	 * All objects visible from this standpoint.
	 */
	visible?: boolean;
	/**
	 * All objects in the given group. Defaults to children.
	 */
	hierarchy?: "children" | "siblings" | "ancestors" | "descendants";
	/**
	 * All objects matching name
	 */
	name?: string;
};
/**
 * Sprite animation configuration when playing.
 *
 * @group Components
 * @subgroup Component Types
 */
export interface SpriteAnimPlayOpt {
	/**
	 * If this anim should be played in loop.
	 */
	loop?: boolean;
	/**
	 * When looping should it move back instead of go to start frame again.
	 */
	pingpong?: boolean;
	/**
	 * This anim's speed in frames per second.
	 */
	speed?: number;
	/**
	 * If the animation should not restart from frame 1 and t=0 if it is already playing.
	 *
	 * @default false
	 */
	preventRestart?: boolean;
	/**
	 * Runs when this animation ends.
	 */
	onEnd?: () => void;
}
/**
 * @group Assets
 * @subgroup Data
 */
export type MusicData = string;
/**
 * @group Assets
 * @subgroup Types
 */
export interface LoadFontOpt {
	outline?: number | Outline;
	/**
	 * The size to load the font in (default 64).
	 *
	 * @since v3001.0
	 */
	size?: number;
	/**
	 * The font filter to use, if different from the global font filter.
	 */
	filter?: TexFilter;
}
/**
 * @group Assets
 * @subgroup Types
 */
export type TextureOpt = {
	filter?: TexFilter;
	wrap?: TexWrap;
};
/**
 * @group Assets
 * @subgroup Types
 */
export type ImageSource = Exclude<TexImageSource, VideoFrame>;
/**
 * @group Rendering
 * @subgroup Canvas
 */
export type Canvas = {
	width: number;
	height: number;
	toImageData(): ImageData;
	toDataURL(): string;
	clear(): void;
	draw(action: () => void): void;
	free(): void;
	readonly fb: FrameBuffer;
};
/**
 * @group Rendering
 * @subgroup Shaders
 */
export interface Vertex {
	pos: Vec2;
	uv: Vec2;
	color: Color;
	opacity: number;
}
declare enum BlendMode {
	Normal = 0,
	Add = 1,
	Multiply = 2,
	Screen = 3,
	Overlay = 4
}
/**
 * @group Rendering
 * @subgroup Shaders
 */
export interface Attributes {
	pos: number[];
	uv: number[];
	color: number[];
	opacity: number[];
}
/**
 * Texture scaling filter. "nearest" is mainly for sharp pixelated scaling, "linear" means linear interpolation.
 */
export type TexFilter = "nearest" | "linear";
export type TexWrap = "repeat" | "clampToEdge";
/**
 * Common render properties.
 */
export interface RenderProps {
	pos?: Vec2;
	scale?: Vec2;
	angle?: number;
	skew?: Vec2;
	color?: Color;
	opacity?: number;
	fixed?: boolean;
	shader?: string | ShaderData | Asset<ShaderData> | null;
	uniform?: Uniform | null;
	blend?: BlendMode;
	outline?: Outline;
}
export interface Outline {
	/**
	 * The width, or thickness of the line.
	 */
	width?: number;
	/**
	 * The color of the line.
	 */
	color?: Color;
	/**
	 * Opacity (overrides fill opacity).
	 *
	 * @since v3001.0
	 */
	opacity?: number;
	/**
	 * Line join.
	 *
	 * @since v3000.0
	 */
	join?: LineJoin;
	/**
	 * Miter limit. If the length of the miter divided by the line width exceeds this limit, the style is converted to a bevel.
	 *
	 * @since v3001.0
	 */
	miterLimit?: number;
	/**
	 * Line cap.
	 *
	 * @since v3001.0
	 */
	cap?: LineCap;
}
/**
 * @group Rendering
 * @subgroup Screen
 */
export type Cursor = string | "auto" | "default" | "none" | "context-menu" | "help" | "pointer" | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text" | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "grab" | "grabbing" | "all-scroll" | "col-resize" | "row-resize" | "n-resize" | "e-resize" | "s-resize" | "w-resize" | "ne-resize" | "nw-resize" | "se-resize" | "sw-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "zoom-int" | "zoom-out";
/**
 * @group Draw
 */
export type Anchor = "topleft" | "top" | "topright" | "left" | "center" | "right" | "botleft" | "bot" | "botright";
/**
 * @group Math
 * @subgroup Random
 */
export type RNGValue = number | Vec2 | Color;
/**
 * @group Components
 * @subgroup Component Types
 */
export interface Comp {
	/**
	 * Component ID (if left out won't be treated as a comp).
	 */
	id?: Tag;
	/**
	 * What other comps this comp depends on.
	 */
	require?: Tag[];
	/**
	 * Event that runs when host game obj is added to scene.
	 */
	add?: () => void;
	/**
	 * Event that runs at a fixed frame rate.
	 */
	fixedUpdate?: () => void;
	/**
	 * Event that runs every frame.
	 */
	update?: () => void;
	/**
	 * Event that runs every frame after update.
	 */
	draw?: () => void;
	/**
	 * Event that runs when obj is removed from scene.
	 */
	destroy?: () => void;
	/**
	 * Debug info for inspect mode.
	 */
	inspect?: () => string | null;
	/**
	 * Draw debug info in inspect mode.
	 *
	 * @since v3000.0
	 */
	drawInspect?: () => void;
	/**
	 * Serializes the component.
	 *
	 * @since v4000.0
	 */
	serialize?: () => any;
}
/**
 * A valid game object id.
 *
 * @group Game Obj
 * @subgroup GameObjID
 */
export type GameObjID = number;
/**
 * A component without own properties.
 *
 * @group Components
 * @subgroup Component Types
 */
export type EmptyComp = {
	id: string;
} & Comp;
/**
 * @group Draw
 */
export type Shape = Rect | Line | Point | Circle | Ellipse | Polygon;
export type Mask = "intersect" | "subtract";
/**
 * @group Math
 * @subgroup Advanced
 */
export type Edge = "left" | "right" | "top" | "bottom";
declare enum EdgeMask {
	None = 0,
	Left = 1,
	Top = 2,
	LeftTop = 3,
	Right = 4,
	Horizontal = 5,
	RightTop = 6,
	HorizontalTop = 7,
	Bottom = 8,
	LeftBottom = 9,
	Vertical = 10,
	LeftVertical = 11,
	RightBottom = 12,
	HorizontalBottom = 13,
	RightVertical = 14,
	All = 15
}
export declare class ButtonState<T = string, A = never> {
	private _pressEv;
	private _pressRepeatEv;
	private _downEv;
	private _releaseEv;
	private _arg?;
	pressed: Set<T>;
	pressedRepeat: Set<T>;
	released: Set<T>;
	down: Set<T>;
	constructor(_pressEv: keyof AppEventMap | null, _pressRepeatEv: keyof AppEventMap | null, _downEv: keyof AppEventMap | null, _releaseEv: keyof AppEventMap | null, _arg?: A | undefined);
	update(): void;
	process(state: AppState): void;
	press(btn: T, state: AppState): void;
	pressRepeat(btn: T, state: AppState): void;
	release(btn: T, state: AppState): void;
}
declare class GamepadState {
	constructor(gp: KGamepad | null);
	buttonState: ButtonState<KGamepadButton, KGamepad>;
	stickState: Map<KGamepadStick, Vec2>;
	analogState: Map<string, number>;
}
declare class FPSCounter {
	/** Window size */
	maxSamples: number;
	history: Float64Array;
	accumulator: number;
	i: number;
	fps: number;
	curNSamples: number;
	timer: number;
	autoRecalculateInterval: number;
	tick(dt: number): void;
	calculate(): number;
	ago(ago: number): number | undefined;
	resize(samples: number): void;
}
export type App = ReturnType<typeof initApp>;
export type AppState = ReturnType<typeof initAppState>;
/**
 * The App method names that will have a helper in GameObjRaw
 */
export type AppEvents = keyof {
	[K in keyof App as K extends `on${any}` ? K : never]: [
		never
	];
};
declare const fixedSpeeds: {
	friedPotato: number;
	potato: number;
	snail: number;
	normal: number;
	lightspeed: number;
	ridiculous: number;
	ludicrous: number;
};
export type FixedSpeedOption = keyof typeof fixedSpeeds;
declare const initAppState: (opt: {
	canvas: HTMLCanvasElement;
	buttons?: ButtonsDef;
	fixedUpdateMode?: FixedSpeedOption;
	maxTimeStep?: number;
}) => {
	canvas: HTMLCanvasElement;
	buttons: ButtonsDef;
	buttonHandler: ButtonProcessor;
	loopID: null | number;
	stopped: boolean;
	dt: number;
	fixedDt: number;
	maxStep: number;
	restDt: number;
	time: number;
	realTime: number;
	rawFPSCounter: FPSCounter;
	fpsCounter: FPSCounter;
	timeScale: number;
	skipTime: boolean;
	isHidden: boolean;
	numFrames: number;
	capsOn: boolean;
	mousePos: Vec2;
	mouseDeltaPos: Vec2;
	keyState: ButtonState<Key, never>;
	mouseState: ButtonState<MouseButton, never>;
	mergedGamepadState: GamepadState;
	gamepadStates: Map<number, GamepadState>;
	lastInputDevice: "mouse" | "keyboard" | "gamepad" | null;
	gamepads: KGamepad[];
	charInputted: string[];
	isMouseMoved: boolean;
	lastWidth: number;
	lastHeight: number;
	events: KEventHandler<AppEventMap>;
};
declare const initApp: (opt: {
	canvas: HTMLCanvasElement;
} & KAPLAYOpt) => {
	state: {
		canvas: HTMLCanvasElement;
		buttons: ButtonsDef;
		buttonHandler: ButtonProcessor;
		loopID: null | number;
		stopped: boolean;
		dt: number;
		fixedDt: number;
		maxStep: number;
		restDt: number;
		time: number;
		realTime: number;
		rawFPSCounter: FPSCounter;
		fpsCounter: FPSCounter;
		timeScale: number;
		skipTime: boolean;
		isHidden: boolean;
		numFrames: number;
		capsOn: boolean;
		mousePos: Vec2;
		mouseDeltaPos: Vec2;
		keyState: ButtonState<Key, never>;
		mouseState: ButtonState<MouseButton, never>;
		mergedGamepadState: GamepadState;
		gamepadStates: Map<number, GamepadState>;
		lastInputDevice: "mouse" | "keyboard" | "gamepad" | null;
		gamepads: KGamepad[];
		charInputted: string[];
		isMouseMoved: boolean;
		lastWidth: number;
		lastHeight: number;
		events: KEventHandler<AppEventMap>;
	};
	dt: () => number;
	fixedDt: () => number;
	restDt: () => number;
	time: () => number;
	run: (fixedUpdate: () => void, update: (processInput: () => void, resetInput: () => void) => void) => void;
	canvas: HTMLCanvasElement;
	fps: () => number;
	rawFPS: () => number;
	setFixedSpeed: (speed: FixedSpeedOption) => void;
	numFrames: () => number;
	quit: () => void;
	isHidden: () => boolean;
	setFullscreen: (f?: boolean) => void;
	isFullscreen: () => boolean;
	setCursor: (c: Cursor) => void;
	screenshot: () => string;
	screenshotToBlob: () => Promise<Blob>;
	getGamepads: () => KGamepad[];
	getCursor: () => Cursor;
	setCursorLocked: (b: boolean) => void;
	isCursorLocked: () => boolean;
	isTouchscreen: () => boolean;
	mousePos: () => Vec2;
	mouseDeltaPos: () => Vec2;
	isKeyDown: (k?: Key | Key[]) => boolean;
	isKeyPressed: (k?: Key | Key[]) => boolean;
	isKeyPressedRepeat: (k?: Key | Key[]) => boolean;
	isKeyReleased: (k?: Key | Key[]) => boolean;
	isMouseDown: (m?: MouseButton) => boolean;
	isMousePressed: (m?: MouseButton) => boolean;
	isMouseReleased: (m?: MouseButton) => boolean;
	isMouseMoved: () => boolean;
	isGamepadButtonPressed: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
	isGamepadButtonDown: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
	isGamepadButtonReleased: (btn?: KGamepadButton | KGamepadButton[]) => boolean;
	isFocused: () => boolean;
	getGamepadStick: (stick: KGamepadStick) => Vec2;
	getGamepadAnalogButton: (btn: KGamepadButton) => number;
	isButtonPressed: (btn?: string | string[]) => boolean;
	isButtonDown: (btn?: string | string[]) => boolean;
	isButtonReleased: (btn?: string | string[]) => boolean;
	getButton: (btn: string) => ButtonBinding;
	getButtons: () => ButtonsDef;
	setButton: (btn: string, binding: ButtonBinding) => void;
	pressButton: (btn: string) => void;
	releaseButton: (btn: string) => void;
	charInputted: () => string[];
	onResize: (action: () => void) => KEventController;
	onKeyDown: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyPress: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyPressRepeat: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onKeyRelease: ((action: (key: Key) => void) => KEventController) & ((key: Key | Key[], action: (key: Key) => void) => KEventController);
	onMouseDown: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMousePress: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMouseRelease: ((action: (m: MouseButton) => void) => KEventController) & ((mouse: MouseButton | MouseButton[], action: (m: MouseButton) => void) => KEventController);
	onMouseMove: (f: (pos: Vec2, dpos: Vec2) => void) => KEventController;
	onCharInput: (action: (ch: string) => void) => KEventController;
	onTouchStart: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onTouchMove: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onTouchEnd: (f: (pos: Vec2, t: Touch) => void) => KEventController;
	onScroll: (action: (delta: Vec2) => void) => KEventController;
	onHide: (action: () => void) => KEventController;
	onShow: (action: () => void) => KEventController;
	onTabHide: (action: () => void) => KEventController;
	onTabShow: (action: () => void) => KEventController;
	onGamepadButtonDown: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton, action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadButtonPress: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadButtonRelease: ((action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController) & ((btn: KGamepadButton | KGamepadButton[], action: (btn: KGamepadButton, gamepad: KGamepad) => void) => KEventController);
	onGamepadStick: (stick: KGamepadStick, action: (value: Vec2, gp: KGamepad) => void) => KEventController;
	onGamepadConnect: (action: (gamepad: KGamepad) => void) => KEventController;
	onGamepadDisconnect: (action: (gamepad: KGamepad) => void) => KEventController;
	onButtonPress: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	onButtonDown: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	onButtonRelease: ((action: (btn: string) => void) => KEventController) & ((btn: string | string, action: (btn: string) => void) => KEventController);
	getLastInputDeviceType: () => "keyboard" | "gamepad" | "mouse" | null;
	events: KEventHandler<AppEventMap>;
};
/**
 * How the texture should look like.
 *
 * @group Draw
 * @subgroup Types
 */
export type DrawTextureOpt = RenderProps & {
	tex: Texture;
	width?: number;
	height?: number;
	tiled?: boolean;
	flipX?: boolean;
	flipY?: boolean;
	quad?: Quad;
	anchor?: Anchor | Vec2;
};
export type SatResult = {
	normal: Vec2;
	distance: number;
};
export type HashGridOpt = {
	hashGridSize?: number;
};
export declare class HashGrid {
	bounds: Rect;
	cellSize: number;
	columns: number;
	grid: Array<Array<GameObj<AreaComp>>>;
	hashesForObject: Map<GameObj<AreaComp>, Array<number>>;
	versionsForObject: Map<GameObj<AreaComp>, [
		number,
		number,
		number
	]>;
	constructor(bounds: Rect, opt: HashGridOpt);
	add(obj: GameObj<AreaComp>): void;
	remove(obj: GameObj<AreaComp>): void;
	clear(): void;
	update(): void;
	/**
	 * Iterates all object pairs which potentially collide
	 */
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	/**
	 * Retrieves all object which potentially collide with the rectangle
	 */
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
	private _hashPoint;
	private _hashRect;
	private _addObjectToGridByHash;
	private _removeObjectFromGridByHash;
	private _isInside;
	private _resizeToFit;
	private _clampBoundsToCellSize;
}
declare class SapEdgeHorizontal {
	obj: GameObj<AreaComp>;
	x: number;
	isLeft: boolean;
	constructor(obj: GameObj<AreaComp>, isLeft: boolean);
}
/**
 * One dimensional horizontal sweep and prune
 *
 * @ignore
 */
export declare class SweepAndPruneHorizontal implements BroadPhaseAlgorithm {
	edges: Array<SapEdgeHorizontal>;
	objects: Map<GameObj<AreaComp>, [
		SapEdgeHorizontal,
		SapEdgeHorizontal
	]>;
	versionsForObject: Map<GameObj<AreaComp>, [
		number,
		number,
		number
	]>;
	constructor();
	/**
	 * Add the object and its edges to the list
	 * @param obj - The object to add
	 */
	add(obj: GameObj<AreaComp>): void;
	/**
	 * Remove the object and its edges from the list
	 * @param obj - The object to remove
	 */
	remove(obj: GameObj<AreaComp>): void;
	clear(): void;
	/**
	 * Update edges and sort
	 */
	update(): void;
	/**
	 * Iterates all object pairs which potentially collide
	 */
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
}
declare class SapEdgeVertical {
	obj: GameObj<AreaComp>;
	y: number;
	isTop: boolean;
	constructor(obj: GameObj<AreaComp>, isTop: boolean);
}
/**
 * One dimensional vertical sweep and prune
 *
 * @ignore
 */
export declare class SweepAndPruneVertical implements BroadPhaseAlgorithm {
	edges: Array<SapEdgeVertical>;
	objects: Map<GameObj<AreaComp>, [
		SapEdgeVertical,
		SapEdgeVertical
	]>;
	versionsForObject: Map<GameObj<AreaComp>, [
		number,
		number,
		number
	]>;
	constructor();
	/**
	 * Add the object and its edges to the list
	 * @param obj - The object to add
	 */
	add(obj: GameObj<AreaComp>): void;
	/**
	 * Remove the object and its edges from the list
	 * @param obj - The object to remove
	 */
	remove(obj: GameObj<AreaComp>): void;
	clear(): void;
	/**
	 * Update edges and sort
	 */
	update(): void;
	/**
	 * Iterates all object pairs which potentially collide
	 */
	iterPairs(pairCb: (obj1: GameObj<AreaComp>, obj2: GameObj<AreaComp>) => void): void;
	retrieve(rect: Rect, retrieveCb: (obj: GameObj<AreaComp>) => void): void;
}
/**
 * A 3D vector.
 *
 * @group Math
 * @subgroup Vectors
 */
export declare class Vec3 {
	x: number;
	y: number;
	z: number;
	static LEFT: Vec3;
	static RIGHT: Vec3;
	static UP: Vec3;
	static DOWN: Vec3;
	static FORWARD: Vec3;
	static BACK: Vec3;
	static ZERO: Vec3;
	static ONE: Vec3;
	constructor(x: number, y: number, z: number);
	dot(other: Vec3): number;
	cross(other: Vec3): Vec3;
	toAxis(): Vec3;
}
export declare class BinaryHeap<T> {
	_items: T[];
	_compareFn: (a: T, b: T) => boolean;
	/**
	 * Creates a binary heap with the given compare function
	 * Not passing a compare function will give a min heap
	 */
	constructor(compareFn?: (a: T, b: T) => boolean);
	/**
	 * Insert an item into the binary heap
	 */
	insert(item: T): void;
	/**
	 * Remove the smallest item from the binary heap in case of a min heap
	 * or the greatest item from the binary heap in case of a max heap
	 */
	remove(): T | null;
	/**
	 * Remove all items
	 */
	clear(): void;
	moveUp(pos: number): void;
	moveDown(pos: number): void;
	swap(index1: number, index2: number): void;
	/**
	 * Returns the amount of items
	 */
	get length(): number;
}
export type HasDefinedKeys<TObj, TCheck> = {
	[K in keyof TCheck & keyof TObj]: TObj[K] extends undefined ? never : K;
}[keyof TCheck & keyof TObj] extends never ? never : TObj;
export type ChooseKAPLAYCtx<O extends KAPLAYOptTypeOptions> = HasDefinedKeys<O, KAPLAYTypeOptWithoutPlugins> extends never ? KAPLAYCtx : KAPLAYCtxT<O>;
export type KAPLAYGame<O extends KAPLAYOptTypeOptions | undefined> = O extends KAPLAYOptTypeOptions ? O["plugins"] extends PluginList<any> ? ChooseKAPLAYCtx<O> & MergePlugins<O["plugins"]> : ChooseKAPLAYCtx<O> : KAPLAYCtx;
/**
 * Initialize KAPLAY context. The starting point of all KAPLAY games.
 *
 * @example
 * ```js
 * // Start KAPLAY with default options (will create a fullscreen canvas under <body>)
 * kaplay()
 *
 * // Init with some options
 * kaplay({
 *     width: 320,
 *     height: 240,
 *     font: "sans-serif",
 *     canvas: document.querySelector("#mycanvas"),
 *     background: [ 0, 0, 255, ],
 * })
 *
 * // All KAPLAY functions are imported to global after calling kaplay()
 * add()
 * onUpdate()
 * onKeyPress()
 * vec2()
 *
 * // If you want to prevent KAPLAY from importing all functions to global and use a context handle for all KAPLAY functions
 * const k = kaplay({ global: false })
 *
 * k.add(...)
 * k.onUpdate(...)
 * k.onKeyPress(...)
 * k.vec2(...)
 * ```
 *
 * @group Start
 */
declare const kaplay: <O extends KAPLAYOpt>(opt?: O) => KAPLAYGame<O>;
export declare const kaplayTypes: <T extends TypesOpt = TypesOpt>() => T;

export {
	kaplay as default,
};

export {};
type KAPLAY = typeof kaplay;declare global {
	const _k: KAPLAYCtx["_k"]
	const quit: KAPLAYCtx["quit"]
	const throwError: KAPLAYCtx["throwError"]
	const add: KAPLAYCtx["add"]
	const addPrefab: KAPLAYCtx["addPrefab"]
	const createPrefab: KAPLAYCtx["createPrefab"]
	const readd: KAPLAYCtx["readd"]
	const retrieve: KAPLAYCtx["retrieve"]
	const get: KAPLAYCtx["get"]
	const query: KAPLAYCtx["query"]
	const exists: KAPLAYCtx["exists"]
	const destroy: KAPLAYCtx["destroy"]
	const destroyAll: KAPLAYCtx["destroyAll"]
	const pos: KAPLAYCtx["pos"]
	const scale: KAPLAYCtx["scale"]
	const rotate: KAPLAYCtx["rotate"]
	const skew: KAPLAYCtx["skew"]
	const color: KAPLAYCtx["color"]
	const blend: KAPLAYCtx["blend"]
	const opacity: KAPLAYCtx["opacity"]
	const fill: KAPLAYCtx["fill"]
	const sprite: KAPLAYCtx["sprite"]
	const text: KAPLAYCtx["text"]
	const polygon: KAPLAYCtx["polygon"]
	const getSpriteOutline: KAPLAYCtx["getSpriteOutline"]
	const rect: KAPLAYCtx["rect"]
	const circle: KAPLAYCtx["circle"]
	const ellipse: KAPLAYCtx["ellipse"]
	const uvquad: KAPLAYCtx["uvquad"]
	const video: KAPLAYCtx["video"]
	const picture: KAPLAYCtx["picture"]
	const area: KAPLAYCtx["area"]
	const anchor: KAPLAYCtx["anchor"]
	const z: KAPLAYCtx["z"]
	const layer: KAPLAYCtx["layer"]
	const outline: KAPLAYCtx["outline"]
	const particles: KAPLAYCtx["particles"]
	const body: KAPLAYCtx["body"]
	const surfaceEffector: KAPLAYCtx["surfaceEffector"]
	const areaEffector: KAPLAYCtx["areaEffector"]
	const pointEffector: KAPLAYCtx["pointEffector"]
	const platformEffector: KAPLAYCtx["platformEffector"]
	const buoyancyEffector: KAPLAYCtx["buoyancyEffector"]
	const constantForce: KAPLAYCtx["constantForce"]
	const doubleJump: KAPLAYCtx["doubleJump"]
	const move: KAPLAYCtx["move"]
	const constraint: KAPLAYCtx["constraint"]
	const offscreen: KAPLAYCtx["offscreen"]
	const follow: KAPLAYCtx["follow"]
	const shader: KAPLAYCtx["shader"]
	const textInput: KAPLAYCtx["textInput"]
	const timer: KAPLAYCtx["timer"]
	const fixed: KAPLAYCtx["fixed"]
	const stay: KAPLAYCtx["stay"]
	const health: KAPLAYCtx["health"]
	const lifespan: KAPLAYCtx["lifespan"]
	const named: KAPLAYCtx["named"]
	const state: KAPLAYCtx["state"]
	const fadeIn: KAPLAYCtx["fadeIn"]
	const mask: KAPLAYCtx["mask"]
	const drawon: KAPLAYCtx["drawon"]
	const tile: KAPLAYCtx["tile"]
	const agent: KAPLAYCtx["agent"]
	const animate: KAPLAYCtx["animate"]
	const fakeMouse: KAPLAYCtx["fakeMouse"]
	const serializeAnimation: KAPLAYCtx["serializeAnimation"]
	const sentry: KAPLAYCtx["sentry"]
	const patrol: KAPLAYCtx["patrol"]
	const pathfinder: KAPLAYCtx["pathfinder"]
	const level: KAPLAYCtx["level"]
	const raycast: KAPLAYCtx["raycast"]
	const trigger: KAPLAYCtx["trigger"]
	const onLoad: KAPLAYCtx["onLoad"]
	const onLoadError: KAPLAYCtx["onLoadError"]
	const onLoading: KAPLAYCtx["onLoading"]
	const onError: KAPLAYCtx["onError"]
	const onResize: KAPLAYCtx["onResize"]
	const onCleanup: KAPLAYCtx["onCleanup"]
	const onKeyDown: KAPLAYCtx["onKeyDown"]
	const onKeyPress: KAPLAYCtx["onKeyPress"]
	const onKeyPressRepeat: KAPLAYCtx["onKeyPressRepeat"]
	const onKeyRelease: KAPLAYCtx["onKeyRelease"]
	const onCharInput: KAPLAYCtx["onCharInput"]
	const onMouseDown: KAPLAYCtx["onMouseDown"]
	const onMousePress: KAPLAYCtx["onMousePress"]
	const onMouseRelease: KAPLAYCtx["onMouseRelease"]
	const onMouseMove: KAPLAYCtx["onMouseMove"]
	const onTouchStart: KAPLAYCtx["onTouchStart"]
	const onTouchEnd: KAPLAYCtx["onTouchEnd"]
	const onTouchMove: KAPLAYCtx["onTouchMove"]
	const onScroll: KAPLAYCtx["onScroll"]
	const onGamepadConnect: KAPLAYCtx["onGamepadConnect"]
	const onGamepadDisconnect: KAPLAYCtx["onGamepadDisconnect"]
	const onGamepadButtonDown: KAPLAYCtx["onGamepadButtonDown"]
	const onGamepadButtonPress: KAPLAYCtx["onGamepadButtonPress"]
	const onGamepadButtonRelease: KAPLAYCtx["onGamepadButtonRelease"]
	const onGamepadStick: KAPLAYCtx["onGamepadStick"]
	const onButtonDown: KAPLAYCtx["onButtonDown"]
	const onButtonPress: KAPLAYCtx["onButtonPress"]
	const onButtonRelease: KAPLAYCtx["onButtonRelease"]
	const onTabShow: KAPLAYCtx["onTabShow"]
	const onTabHide: KAPLAYCtx["onTabHide"]
	const onHide: KAPLAYCtx["onHide"]
	const onShow: KAPLAYCtx["onShow"]
	const onFixedUpdate: KAPLAYCtx["onFixedUpdate"]
	const onUpdate: KAPLAYCtx["onUpdate"]
	const onDraw: KAPLAYCtx["onDraw"]
	const onAdd: KAPLAYCtx["onAdd"]
	const onDestroy: KAPLAYCtx["onDestroy"]
	const onUse: KAPLAYCtx["onUse"]
	const onUnuse: KAPLAYCtx["onUnuse"]
	const onTag: KAPLAYCtx["onTag"]
	const onUntag: KAPLAYCtx["onUntag"]
	const on: KAPLAYCtx["on"]
	const onCollide: KAPLAYCtx["onCollide"]
	const onCollideUpdate: KAPLAYCtx["onCollideUpdate"]
	const onCollideEnd: KAPLAYCtx["onCollideEnd"]
	const onClick: KAPLAYCtx["onClick"]
	const onHover: KAPLAYCtx["onHover"]
	const onHoverUpdate: KAPLAYCtx["onHoverUpdate"]
	const onHoverEnd: KAPLAYCtx["onHoverEnd"]
	const onSceneLeave: KAPLAYCtx["onSceneLeave"]
	const getSceneName: KAPLAYCtx["getSceneName"]
	const loadRoot: KAPLAYCtx["loadRoot"]
	const loadSprite: KAPLAYCtx["loadSprite"]
	const loadSpriteAtlas: KAPLAYCtx["loadSpriteAtlas"]
	const loadAseprite: KAPLAYCtx["loadAseprite"]
	const loadBean: KAPLAYCtx["loadBean"]
	const loadHappy: KAPLAYCtx["loadHappy"]
	const loadJSON: KAPLAYCtx["loadJSON"]
	const loadSound: KAPLAYCtx["loadSound"]
	const loadMusic: KAPLAYCtx["loadMusic"]
	const loadFont: KAPLAYCtx["loadFont"]
	const loadBitmapFont: KAPLAYCtx["loadBitmapFont"]
	const loadBitmapFontFromSprite: KAPLAYCtx["loadBitmapFontFromSprite"]
	const loadShader: KAPLAYCtx["loadShader"]
	const loadShaderURL: KAPLAYCtx["loadShaderURL"]
	const load: KAPLAYCtx["load"]
	const loadPrefab: KAPLAYCtx["loadPrefab"]
	const loadProgress: KAPLAYCtx["loadProgress"]
	const getSprite: KAPLAYCtx["getSprite"]
	const getSound: KAPLAYCtx["getSound"]
	const getFont: KAPLAYCtx["getFont"]
	const getBitmapFont: KAPLAYCtx["getBitmapFont"]
	const getShader: KAPLAYCtx["getShader"]
	const getAsset: KAPLAYCtx["getAsset"]
	const Asset: KAPLAYCtx["Asset"]
	const SpriteData: KAPLAYCtx["SpriteData"]
	const SoundData: KAPLAYCtx["SoundData"]
	const width: KAPLAYCtx["width"]
	const getTreeRoot: KAPLAYCtx["getTreeRoot"]
	const height: KAPLAYCtx["height"]
	const center: KAPLAYCtx["center"]
	const dt: KAPLAYCtx["dt"]
	const fixedDt: KAPLAYCtx["fixedDt"]
	const restDt: KAPLAYCtx["restDt"]
	const setFixedSpeed: KAPLAYCtx["setFixedSpeed"]
	const time: KAPLAYCtx["time"]
	const isFocused: KAPLAYCtx["isFocused"]
	const isTouchscreen: KAPLAYCtx["isTouchscreen"]
	const mousePos: KAPLAYCtx["mousePos"]
	const mouseDeltaPos: KAPLAYCtx["mouseDeltaPos"]
	const isKeyDown: KAPLAYCtx["isKeyDown"]
	const isKeyPressed: KAPLAYCtx["isKeyPressed"]
	const isKeyPressedRepeat: KAPLAYCtx["isKeyPressedRepeat"]
	const isKeyReleased: KAPLAYCtx["isKeyReleased"]
	const isMouseDown: KAPLAYCtx["isMouseDown"]
	const isMousePressed: KAPLAYCtx["isMousePressed"]
	const isMouseReleased: KAPLAYCtx["isMouseReleased"]
	const isMouseMoved: KAPLAYCtx["isMouseMoved"]
	const isGamepadButtonPressed: KAPLAYCtx["isGamepadButtonPressed"]
	const isGamepadButtonDown: KAPLAYCtx["isGamepadButtonDown"]
	const isGamepadButtonReleased: KAPLAYCtx["isGamepadButtonReleased"]
	const isButtonPressed: KAPLAYCtx["isButtonPressed"]
	const isButtonDown: KAPLAYCtx["isButtonDown"]
	const isButtonReleased: KAPLAYCtx["isButtonReleased"]
	const getButton: KAPLAYCtx["getButton"]
	const getButtons: KAPLAYCtx["getButtons"]
	const setButton: KAPLAYCtx["setButton"]
	const pressButton: KAPLAYCtx["pressButton"]
	const releaseButton: KAPLAYCtx["releaseButton"]
	const getGamepadStick: KAPLAYCtx["getGamepadStick"]
	const getGamepadAnalogButton: KAPLAYCtx["getGamepadAnalogButton"]
	const getLastInputDeviceType: KAPLAYCtx["getLastInputDeviceType"]
	const charInputted: KAPLAYCtx["charInputted"]
	const setCamPos: KAPLAYCtx["setCamPos"]
	const getCamPos: KAPLAYCtx["getCamPos"]
	const setCamScale: KAPLAYCtx["setCamScale"]
	const getCamScale: KAPLAYCtx["getCamScale"]
	const setCamRot: KAPLAYCtx["setCamRot"]
	const getCamRot: KAPLAYCtx["getCamRot"]
	const getCamTransform: KAPLAYCtx["getCamTransform"]
	const shake: KAPLAYCtx["shake"]
	const flash: KAPLAYCtx["flash"]
	const camPos: KAPLAYCtx["camPos"]
	const camScale: KAPLAYCtx["camScale"]
	const camRot: KAPLAYCtx["camRot"]
	const camFlash: KAPLAYCtx["camFlash"]
	const camTransform: KAPLAYCtx["camTransform"]
	const toScreen: KAPLAYCtx["toScreen"]
	const toWorld: KAPLAYCtx["toWorld"]
	const setGravity: KAPLAYCtx["setGravity"]
	const getGravity: KAPLAYCtx["getGravity"]
	const setGravityDirection: KAPLAYCtx["setGravityDirection"]
	const getGravityDirection: KAPLAYCtx["getGravityDirection"]
	const Collision: KAPLAYCtx["Collision"]
	const setBackground: KAPLAYCtx["setBackground"]
	const getBackground: KAPLAYCtx["getBackground"]
	const getGamepads: KAPLAYCtx["getGamepads"]
	const setCursor: KAPLAYCtx["setCursor"]
	const getCursor: KAPLAYCtx["getCursor"]
	const setCursorLocked: KAPLAYCtx["setCursorLocked"]
	const isCursorLocked: KAPLAYCtx["isCursorLocked"]
	const setFullscreen: KAPLAYCtx["setFullscreen"]
	const isFullscreen: KAPLAYCtx["isFullscreen"]
	const wait: KAPLAYCtx["wait"]
	const loop: KAPLAYCtx["loop"]
	const play: KAPLAYCtx["play"]
	const burp: KAPLAYCtx["burp"]
	const setVolume: KAPLAYCtx["setVolume"]
	const getVolume: KAPLAYCtx["getVolume"]
	const volume: KAPLAYCtx["volume"]
	const audioCtx: KAPLAYCtx["audioCtx"]
	const rand: KAPLAYCtx["rand"]
	const randi: KAPLAYCtx["randi"]
	const randSeed: KAPLAYCtx["randSeed"]
	const vec2: KAPLAYCtx["vec2"]
	const rgb: KAPLAYCtx["rgb"]
	const hsl2rgb: KAPLAYCtx["hsl2rgb"]
	const quad: KAPLAYCtx["quad"]
	const choose: KAPLAYCtx["choose"]
	const chooseMultiple: KAPLAYCtx["chooseMultiple"]
	const shuffle: KAPLAYCtx["shuffle"]
	const chance: KAPLAYCtx["chance"]
	const lerp: KAPLAYCtx["lerp"]
	const lerpAngle: KAPLAYCtx["lerpAngle"]
	const tween: KAPLAYCtx["tween"]
	const easings: KAPLAYCtx["easings"]
	const easingSteps: KAPLAYCtx["easingSteps"]
	const easingLinear: KAPLAYCtx["easingLinear"]
	const easingCubicBezier: KAPLAYCtx["easingCubicBezier"]
	const map: KAPLAYCtx["map"]
	const mapc: KAPLAYCtx["mapc"]
	const wave: KAPLAYCtx["wave"]
	const deg2rad: KAPLAYCtx["deg2rad"]
	const rad2deg: KAPLAYCtx["rad2deg"]
	const clamp: KAPLAYCtx["clamp"]
	const evaluateQuadratic: KAPLAYCtx["evaluateQuadratic"]
	const evaluateQuadraticFirstDerivative: KAPLAYCtx["evaluateQuadraticFirstDerivative"]
	const evaluateQuadraticSecondDerivative: KAPLAYCtx["evaluateQuadraticSecondDerivative"]
	const evaluateBezier: KAPLAYCtx["evaluateBezier"]
	const evaluateBezierFirstDerivative: KAPLAYCtx["evaluateBezierFirstDerivative"]
	const evaluateBezierSecondDerivative: KAPLAYCtx["evaluateBezierSecondDerivative"]
	const evaluateCatmullRom: KAPLAYCtx["evaluateCatmullRom"]
	const evaluateCatmullRomFirstDerivative: KAPLAYCtx["evaluateCatmullRomFirstDerivative"]
	const curveLengthApproximation: KAPLAYCtx["curveLengthApproximation"]
	const normalizedCurve: KAPLAYCtx["normalizedCurve"]
	const hermite: KAPLAYCtx["hermite"]
	const cardinal: KAPLAYCtx["cardinal"]
	const catmullRom: KAPLAYCtx["catmullRom"]
	const bezier: KAPLAYCtx["bezier"]
	const kochanekBartels: KAPLAYCtx["kochanekBartels"]
	const piecewiseBezier: KAPLAYCtx["piecewiseBezier"]
	const piecewiseCatmullRom: KAPLAYCtx["piecewiseCatmullRom"]
	const createRegularPolygon: KAPLAYCtx["createRegularPolygon"]
	const createStarPolygon: KAPLAYCtx["createStarPolygon"]
	const createCogPolygon: KAPLAYCtx["createCogPolygon"]
	const floodFill: KAPLAYCtx["floodFill"]
	const buildConnectivityMap: KAPLAYCtx["buildConnectivityMap"]
	const testLinePoint: KAPLAYCtx["testLinePoint"]
	const testLineLine: KAPLAYCtx["testLineLine"]
	const testLineCircle: KAPLAYCtx["testLineCircle"]
	const testRectRect: KAPLAYCtx["testRectRect"]
	const testRectLine: KAPLAYCtx["testRectLine"]
	const testRectPoint: KAPLAYCtx["testRectPoint"]
	const testCirclePolygon: KAPLAYCtx["testCirclePolygon"]
	const clipLineToRect: KAPLAYCtx["clipLineToRect"]
	const clipLineToCircle: KAPLAYCtx["clipLineToCircle"]
	const anchorToVec2: KAPLAYCtx["anchorToVec2"]
	const gjkShapeIntersects: KAPLAYCtx["gjkShapeIntersects"]
	const gjkShapeIntersection: KAPLAYCtx["gjkShapeIntersection"]
	const isConvex: KAPLAYCtx["isConvex"]
	const step: KAPLAYCtx["step"]
	const smoothstep: KAPLAYCtx["smoothstep"]
	const triangulate: KAPLAYCtx["triangulate"]
	const buildConvexHull: KAPLAYCtx["buildConvexHull"]
	const insertionSort: KAPLAYCtx["insertionSort"]
	const NavMesh: KAPLAYCtx["NavMesh"]
	const NavGrid: KAPLAYCtx["NavGrid"]
	const Point: KAPLAYCtx["Point"]
	const Line: KAPLAYCtx["Line"]
	const Rect: KAPLAYCtx["Rect"]
	const Circle: KAPLAYCtx["Circle"]
	const Ellipse: KAPLAYCtx["Ellipse"]
	const Polygon: KAPLAYCtx["Polygon"]
	const Vec2: KAPLAYCtx["Vec2"]
	const Color: KAPLAYCtx["Color"]
	const Mat4: KAPLAYCtx["Mat4"]
	const Mat2: KAPLAYCtx["Mat2"]
	const Mat23: KAPLAYCtx["Mat23"]
	const Quad: KAPLAYCtx["Quad"]
	const Quadtree: KAPLAYCtx["Quadtree"]
	const makeQuadtree: KAPLAYCtx["makeQuadtree"]
	const RNG: KAPLAYCtx["RNG"]
	const Rule: KAPLAYCtx["Rule"]
	const RuleSystem: KAPLAYCtx["RuleSystem"]
	const DecisionNode: KAPLAYCtx["DecisionNode"]
	const DecisionTree: KAPLAYCtx["DecisionTree"]
	const StateMachine: KAPLAYCtx["StateMachine"]
	const scene: KAPLAYCtx["scene"]
	const go: KAPLAYCtx["go"]
	const pushScene: KAPLAYCtx["pushScene"]
	const popScene: KAPLAYCtx["popScene"]
	const setLayers: KAPLAYCtx["setLayers"]
	const getLayers: KAPLAYCtx["getLayers"]
	const getDefaultLayer: KAPLAYCtx["getDefaultLayer"]
	const layers: KAPLAYCtx["layers"]
	const addLevel: KAPLAYCtx["addLevel"]
	const getData: KAPLAYCtx["getData"]
	const setData: KAPLAYCtx["setData"]
	const drawSprite: KAPLAYCtx["drawSprite"]
	const drawText: KAPLAYCtx["drawText"]
	const drawRect: KAPLAYCtx["drawRect"]
	const drawLine: KAPLAYCtx["drawLine"]
	const drawLines: KAPLAYCtx["drawLines"]
	const drawCurve: KAPLAYCtx["drawCurve"]
	const drawBezier: KAPLAYCtx["drawBezier"]
	const drawTriangle: KAPLAYCtx["drawTriangle"]
	const drawCircle: KAPLAYCtx["drawCircle"]
	const drawEllipse: KAPLAYCtx["drawEllipse"]
	const drawPolygon: KAPLAYCtx["drawPolygon"]
	const drawUVQuad: KAPLAYCtx["drawUVQuad"]
	const drawFormattedText: KAPLAYCtx["drawFormattedText"]
	const drawMasked: KAPLAYCtx["drawMasked"]
	const drawSubtracted: KAPLAYCtx["drawSubtracted"]
	const Picture: KAPLAYCtx["Picture"]
	const beginPicture: KAPLAYCtx["beginPicture"]
	const appendToPicture: KAPLAYCtx["appendToPicture"]
	const endPicture: KAPLAYCtx["endPicture"]
	const drawPicture: KAPLAYCtx["drawPicture"]
	const pushTransform: KAPLAYCtx["pushTransform"]
	const popTransform: KAPLAYCtx["popTransform"]
	const pushTranslate: KAPLAYCtx["pushTranslate"]
	const pushScale: KAPLAYCtx["pushScale"]
	const pushRotate: KAPLAYCtx["pushRotate"]
	const pushMatrix: KAPLAYCtx["pushMatrix"]
	const usePostEffect: KAPLAYCtx["usePostEffect"]
	const formatText: KAPLAYCtx["formatText"]
	const compileStyledText: KAPLAYCtx["compileStyledText"]
	const makeCanvas: KAPLAYCtx["makeCanvas"]
	const drawCanvas: KAPLAYCtx["drawCanvas"]
	const debug: KAPLAYCtx["debug"]
	const app: KAPLAYCtx["app"]
	const plug: KAPLAYCtx["plug"]
	const system: KAPLAYCtx["system"]
	const SystemPhase: KAPLAYCtx["SystemPhase"]
	const screenshot: KAPLAYCtx["screenshot"]
	const screenshotToBlob: KAPLAYCtx["screenshotToBlob"]
	const download: KAPLAYCtx["download"]
	const downloadText: KAPLAYCtx["downloadText"]
	const downloadJSON: KAPLAYCtx["downloadJSON"]
	const downloadBlob: KAPLAYCtx["downloadBlob"]
	const record: KAPLAYCtx["record"]
	const addKaboom: KAPLAYCtx["addKaboom"]
	const ASCII_CHARS: KAPLAYCtx["ASCII_CHARS"]
	const LEFT: KAPLAYCtx["LEFT"]
	const RIGHT: KAPLAYCtx["RIGHT"]
	const UP: KAPLAYCtx["UP"]
	const DOWN: KAPLAYCtx["DOWN"]
	const RED: KAPLAYCtx["RED"]
	const GREEN: KAPLAYCtx["GREEN"]
	const BLUE: KAPLAYCtx["BLUE"]
	const YELLOW: KAPLAYCtx["YELLOW"]
	const MAGENTA: KAPLAYCtx["MAGENTA"]
	const CYAN: KAPLAYCtx["CYAN"]
	const WHITE: KAPLAYCtx["WHITE"]
	const BLACK: KAPLAYCtx["BLACK"]
	const canvas: KAPLAYCtx["canvas"]
	const KEvent: KAPLAYCtx["KEvent"]
	const KEventHandler: KAPLAYCtx["KEventHandler"]
	const KEventController: KAPLAYCtx["KEventController"]
	const cancel: KAPLAYCtx["cancel"]
	const KeepFlags: KAPLAYCtx["KeepFlags"]
	const BlendMode: KAPLAYCtx["BlendMode"]
	const VERSION: KAPLAYCtx["VERSION"]
const kaplay: KAPLAY;
const kaboom: KAPLAY;
}
