diff --git a/src/staembed.c b/src/staembed.c
index 186c2803..2f493812 100644
--- a/src/staembed.c
+++ b/src/staembed.c
@@ -1,6908 +1 @@
#include "tophat.h"
-const char *th_em_modulesrc[] = {
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"atlas.um\"\n"
-")\n"
-"\n"
-"//~~struct Anim\n"
-"// Anim allows you to animate between individual frames of an atlas.\n"
-"type Anim* = struct {\n"
-"\t// the source atlas\n"
-"\tatl: atlas.Atlas\n"
-"\t// the first cell of the animation\n"
-"\tmin: int\n"
-"\t// the last cell of the animation\n"
-"\tmax: int\n"
-"\tfps: real32\n"
-"\t// offset in time\n"
-"\toffset: int\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"// `Anim` constructor\n"
-"fn mk*(atl: atlas.Atlas, fps: int, min: int = 0, max: int = -1 /* len(atl) - 1 */, offset: int = -1 /* th.time */): Anim {\n"
-"//~~\n"
-"\tif !atl.i.validate() {\n"
-"\t\tth.__error(\"invalid atlas image\")\n"
-"\t}\n"
-"\n"
-"\ta := Anim{}\n"
-"\n"
-"\ta.atl = atl\n"
-"\ta.fps = fps\n"
-"\ta.min = min\n"
-"\tif max == -1 {\n"
-"\t\ta.max = trunc(atl.dm.x * atl.dm.y) - 1\n"
-"\t} else {\n"
-"\t\ta.max = max\n"
-"\t}\n"
-"\n"
-"\tif offset == -1 {\n"
-"\t\ta.offset = th.time\n"
-"\t} else {\n"
-"\t\ta.offset = offset\n"
-"\t}\n"
-"\n"
-"\treturn a\n"
-"}\n"
-"\n"
-"//~~fn Anim.animate\n"
-"// Crops the base atlas to the cell that should be visible at `time`.\n"
-"fn (anm: ^Anim) animate*(time: int) {\n"
-"//~~\n"
-"\tif anm.fps == 0 || anm.max == 0 {\n"
-"\t\t\treturn\n"
-"\t}\n"
-"\n"
-"\tn := (round(real(time-anm.offset)/round((1000.0/anm.fps))) % anm.max) + anm.min\n"
-"\n"
-"\tanm.atl.cropSource(anm.atl.coords(n))\n"
-"}\n"
-"\n"
-"//~~fn Anim.framesPlayed\n"
-"// Returns how many frames were played at `time`.\n"
-"fn (anm: ^Anim) framesPlayed*(time: int): int {\n"
-"//~~\n"
-"\treturn trunc((time - anm.offset) / 1000.0 * anm.fps)\n"
-"}\n"
-"",
-"//~~\n"
-"// Module for audio loading and playback.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~opaque Sound\n"
-"// Represents an instance of a playable sound. It is an opaque structure.\n"
-"type Sound* = struct { _: ^struct{} }\n"
-"//~~\n"
-"\n"
-"var pool: []^Sound\n"
-"\n"
-"type LoadFlag = uint32\n"
-"const (\n"
-"\t// Streams the audio, only saving 2 seconds into memory.\n"
-"\tLoadFlagStream* = LoadFlag(1)\n"
-"\t// Loads the sound in async. Use `audio.waitForLoad` to wait for the\n"
-"\t// sounds to load.\n"
-"\tLoadFlagAsync* = LoadFlag(4)\n"
-")\n"
-"\n"
-"fn umth_sound_load(path: str, flags: uint32): ^struct{}\n"
-"//~~fn load\n"
-"// Loads a sounds at path, if there is an error, the underlying pointer\n"
-"// will be `NULL` and `validate` will return false.\n"
-"fn load*(path: str, flags: LoadFlag = 0): Sound {\n"
-"//~~\n"
-"\treturn Sound{umth_sound_load(path, flags)}\n"
-"}\n"
-"\n"
-"//~~fn Sound.validate\n"
-"// Returns `true` if `s` loaded correctly.\n"
-"fn (s: ^Sound) validate*(): bool {\n"
-"//~~\n"
-"\treturn s._ != null\n"
-"}\n"
-"\n"
-"fn umth_sound_copy(s: Sound): ^struct{}\n"
-"//~~fn Sound.copy\n"
-"// Copies the sound. This will create another sound which can be configured\n"
-"// and played independently from the original sound.\n"
-"fn (s: ^Sound) copy*(): Sound {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"Cannot copy invalid sound.\")\n"
-"\t}\n"
-"\n"
-"\treturn Sound{umth_sound_copy(s^)}\n"
-"}\n"
-"\n"
-"fn umth_sound_is_playing(s: Sound): bool\n"
-"//~~fn Sound.isPlaying\n"
-"// Returns true if the sound is still playing.\n"
-"fn (s: ^Sound) isPlaying*(): bool {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\treturn umth_sound_is_playing(s^)\n"
-"}\n"
-"\n"
-"fn umth_sound_play(s: Sound)\n"
-"//~~fn Sound.play\n"
-"// Plays the sound.\n"
-"fn (s: ^Sound) play*() {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_play(s^)\n"
-"}\n"
-"\n"
-"//~~fn Sound.start\n"
-"// The start function allows you to play a single sound multiple times.\n"
-"// It will create a copy and return a pointer to it, so you can controll it\n"
-"// while it is playing. The returned pointer can be discarded.\n"
-"fn (s: ^Sound) start*(): ^Sound {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tcpy := new(Sound)\n"
-"\tcpy ^= s.copy()\n"
-"\tcpy.play()\n"
-"\n"
-"\tpool = append(pool, cpy)\n"
-"\n"
-"\treturn cpy\n"
-"}\n"
-"\n"
-"fn umth_sound_stop(s: Sound)\n"
-"//~~fn Sound.stop\n"
-"// Stops the sound, but keeps the progress. If you want to start from the\n"
-"// begginning, use `audio.Sound.seekToFrame(0)`.\n"
-"fn (s: ^Sound) stop*() {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_stop(s^)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_volume(s: Sound, vol: real32)\n"
-"//~~fn Sound.setVol\n"
-"// Sets the volume as a multiplier of the base volume.\n"
-"fn (s: ^Sound) setVol*(vol: real32) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_volume(s^, vol)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_pan(s: Sound, pan: real32)\n"
-"//~~fn Sound.setPan\n"
-"// Sets the pan of the sound.\n"
-"fn (s: ^Sound) setPan*(pan: real32) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_pan(s^, pan)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_pitch(s: Sound, pitch: real32)\n"
-"//~~fn Sound.setPitch\n"
-"// Sets the pitch of the sound.\n"
-"fn (s: ^Sound) setPitch*(pitch: real32) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_pitch(s^, pitch)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_looping(s: Sound, looping: bool)\n"
-"//~~fn Sound.setLooping\n"
-"// Sets whether the sound will loop upon finishing.\n"
-"fn (s: ^Sound) setLooping*(looping: bool) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_looping(s^, looping)\n"
-"}\n"
-"\n"
-"fn umth_sound_seek_to_frame(s: Sound, frame: uint)\n"
-"//~~fn Sound.seekToFrame\n"
-"// Seeks to a specified PCM frame.\n"
-"fn (s: ^Sound) seekToFrame*(frame: uint) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_seek_to_frame(s^, frame)\n"
-"}\n"
-"\n"
-"fn umth_sound_frame_count(s: Sound): uint\n"
-"//~~fn Sound.frameCount\n"
-"// Returns length of the sound in PCM frames.\n"
-"fn (s: ^Sound) frameCount*(): uint {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\treturn umth_sound_frame_count(s^)\n"
-"}\n"
-"\n"
-"fn umth_sound_length_ms(s: Sound): uint\n"
-"//~~fn Sound.lengthMs\n"
-"// Returns length of the sound in ms.\n"
-"fn (s: ^Sound) lengthMs*(): uint {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\treturn umth_sound_length_ms(s^)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_start_time_ms(s: Sound, t: uint)\n"
-"//~~fn Sound.setStartTimeMs\n"
-"fn (s: ^Sound) setStartTimeMs*(t: uint) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_start_time_ms(s^, t)\n"
-"}\n"
-"\n"
-"fn umth_sound_set_stop_time_ms(s: Sound, t: uint)\n"
-"//~~fn Sound.setStopTimeMs\n"
-"fn (s: ^Sound) setStopTimeMs*(t: uint) {\n"
-"//~~\n"
-"\tif !s.validate() {\n"
-"\t\tth.__error(\"invalid sound\")\n"
-"\t}\n"
-"\n"
-"\tumth_sound_set_stop_time_ms(s^, t)\n"
-"}\n"
-"\n"
-"// **INTERNAL**\n"
-"fn __setup*() {\n"
-"\tpool = []^Sound{}\n"
-"}\n"
-"\n"
-"// **INTERNAL**\n"
-"fn __cycle*() {\n"
-"\tfor i:=0; i >= 0 && i < len(pool); i++ {\n"
-"\t\tif !pool[i].isPlaying() {\n"
-"\t\t\tpool = delete(pool, i)\n"
-"\t\t\ti--\n"
-"\t\t}\n"
-"\t}\n"
-"}\n"
-"",
-"//~~\n"
-"// A CSV parser, which also works for similar formats. It doesn\'t support\n"
-"// quotes, but you can escape characters using a backslash.\n"
-"//~~\n"
-"\n"
-"//~~fn parse\n"
-"// Parses input into a 2d string array.\n"
-"fn parse*(inp: str, sep: char = \',\'): [][]str {\n"
-"//~~\n"
-"\tout := [][]str{}\n"
-"\trow := []str{}\n"
-"\tstart := 0\n"
-"\tacc := \"\"\n"
-"\tl := len(inp)\n"
-"\tskipnext := false\n"
-"\n"
-"\tfor i,c in inp {\n"
-"\t\tif skipnext { skipnext = false; continue }\n"
-"\n"
-"\t\tif c == \'\\\\\' {\n"
-"\t\t\tacc += slice(inp, start, i)\n"
-"\t\t\tstart = i + 1\n"
-"\t\t\tskipnext = true\n"
-"\t\t} else if c == \'\\r\' {\n"
-"\t\t\tacc += slice(inp, start, i)\n"
-"\t\t\tstart = i + 1\n"
-"\t\t} else if c == \'\\n\' {\n"
-"\t\t\tacc += slice(inp, start, i)\n"
-"\t\t\tstart = i + 1\n"
-"\n"
-"\t\t\trow = append(row, acc)\n"
-"\t\t\tout = append(out, row)\n"
-"\n"
-"\t\t\tacc = \"\"\n"
-"\t\t\trow = []str{}\n"
-"\n"
-"\t\t} else if c == sep {\n"
-"\t\t\tacc += slice(inp, start, i)\n"
-"\t\t\tstart = i + 1\n"
-"\n"
-"\t\t\trow = append(row, acc)\n"
-"\t\t\tacc = \"\"\n"
-"\t\t}\n"
-"\t}\n"
-"\n"
-"\tif start < l {\n"
-"\t\trow = append(row, acc + slice(inp, start, l))\n"
-"\t}\n"
-"\n"
-"\tif len(row) > 0 {\n"
-"\t\tout = append(out, row)\n"
-"\t}\n"
-"\n"
-"\treturn out\n"
-"}\n"
-"\n"
-"fn escapeStr(s: str, sep: char): str {\n"
-"\to := \"\"\n"
-"\n"
-"\tfor i,c in s {\n"
-"\t\tif c == sep || c == \'\\n\' || c == \'\\\\\' {\n"
-"\t\t\to += \"\\\\\"\n"
-"\t\t}\n"
-"\t\to += str(c)\n"
-"\t}\n"
-"\n"
-"\treturn o\n"
-"}\n"
-"\n"
-"//~~fn encode\n"
-"// Converts 2d array to csv string.\n"
-"fn encode*(inp: [][]str, sep: char = \',\'): str {\n"
-"//~~\n"
-"\to := \"\"\n"
-"\n"
-"\tfor i in inp {\n"
-"\t\tfor j in inp[i] {\n"
-"\t\t\to += escapeStr(inp[i][j], sep)\n"
-"\t\t\tif j < len(inp[i]) - 1 { o += sep }\n"
-"\t\t}\n"
-"\t\to += \"\\n\"\n"
-"\t}\n"
-"\n"
-"\treturn o\n"
-"}\n"
-"\n"
-"",
-"\n"
-"import (\n"
-"\t\"rect.um\"\n"
-"\t\"image.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~struct Ent\n"
-"// Entity is the main game object. It features drawing and collisions.\n"
-"// Every entity has an image used for drawing and a rectangle used\n"
-"// for collisions. It also has a transform used for transforming it\'s image\n"
-"// and rectangle.\n"
-"type Ent* = struct {\n"
-"\t// used as a collider, used as backup when invalid image is supplied\n"
-"\tr: rect.Rect\n"
-"\t// used in drawing\n"
-"\ti: image.Image\n"
-"\t// used to transform and translate the image and rect\n"
-"\tt: th.Transform\n"
-"\t// used as a color of the rect and a color filter for the image\n"
-"\tc: uint32\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct Coll\n"
-"// Value returned by get coll. It contains a position where the collision\n"
-"// happened and the index of the entity involved in said collision.\n"
-"type Coll* = struct {\n"
-"\tindex: th.uu\n"
-"\tpos: th.Vf2\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn umth_ent_draw(e: ^Ent)\n"
-"//~~fn Ent.draw\n"
-"// Draws the entity onto the screen.\n"
-"fn (e: ^Ent) draw*() {\n"
-"//~~\n"
-"\tumth_ent_draw(e)\n"
-"}\n"
-"\n"
-"//~~fn mk\n"
-"// ent\'s constructor\n"
-"fn mk*(img: image.Image = image.Image{}, t: th.Transform = th.Transform{ s: th.Vf2{1, 1} }): Ent {\n"
-"//~~\n"
-"\tvar e: Ent\n"
-"\te.i = img\n"
-"\te.t = t\n"
-"\tif img.validate() {\n"
-"\t\tdm := img.getDims()\n"
-"\t\te.r.w = dm.x\n"
-"\t\te.r.h = dm.y\n"
-"\t}\n"
-"\te.c = th.white\n"
-"\n"
-"\tif t.s.x == 0 && t.s.y == 0 {\n"
-"\t\tt.s = th.Vf2{ 1, 1 }\n"
-"\t}\n"
-"\n"
-"\treturn e\n"
-"}\n"
-"\n"
-"fn umth_ent_getcoll(coll: ^Coll, collC: ^int, maxCount: th.uu, count: int32,\n"
-"\te: ^Ent, s: ^^Ent)\n"
-"//~~fn Ent.getColl\n"
-"// Checks collisions of e with entities in s. Checks at max maxColl collisions.\n"
-"// If s contains e, the collision won\'t be returned.\n"
-"fn (e: ^Ent) getColl*(s: []^Ent, maxColls: th.uu): []Coll {\n"
-"//~~\n"
-"\tif len(s) == 0 {\n"
-"\t\treturn []Coll{}\n"
-"\t}\n"
-"\n"
-"\tif maxColls > len(s) {\n"
-"\t\tmaxColls = len(s)\n"
-"\t}\n"
-"\n"
-"\tif maxColls == 0 {\n"
-"\t\tmaxColls = 1\n"
-"\t}\n"
-"\n"
-"\tcolls := make([]Coll, maxColls)\n"
-"\tcount := 0\n"
-"\tumth_ent_getcoll(&colls[0], &count, maxColls, len(s), e, &s[0])\n"
-"\n"
-"\treturn slice(colls, 0, count)\n"
-"}\n"
-"\n"
-"//~~fn Ent.animate\n"
-"// Animates the entity\'s image with one of the `anim` array. Won\'t begin on\n"
-"// the first frame. If you want that, use anim.Anim.\n"
-"fn (e: ^Ent) animate*(fps: int, frames: ^[]image.Image, t: int) {\n"
-"//~~\n"
-"\tif len(frames^) == 0 {\n"
-"\t\treturn\n"
-"\t}\t\n"
-"\n"
-"\te.i = frames^[(round(real(t)/(1000/fps)) % len(frames^))]\n"
-"}\n"
-"\n"
-"",
-"import (\n"
-"\t\"rect.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~opaque Image\n"
-"// Represents a drawable image. It is an opaque structure.\n"
-"// Images support a color filter. It is applied by multiplying the color\n"
-"// of each pixel with the filter.\n"
-"type Image* = struct{ _: ^struct{} }\n"
-"//~~\n"
-"\n"
-"//~~opaque RenderTarget\n"
-"// An image you can render to.\n"
-"type RenderTarget* = struct { _: ^struct{} }\n"
-"//~~\n"
-"\n"
-"fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: int)\n"
-"//~~fn createRenderTarget\n"
-"// Creates a render target you can draw to, like to a window.\n"
-"// Filter specifies specfifies filtering for resulting image.\n"
-"// Image can be retrieved via `toImage`.\n"
-"fn createRenderTarget*(size: th.Vf2, filter: int): RenderTarget {\n"
-"//~~\n"
-"\trt := RenderTarget{}\n"
-"\tumth_image_create_render_target(&rt, trunc(size.x), trunc(size.y), filter)\n"
-"\treturn rt\n"
-"}\n"
-"\n"
-"fn umth_image_render_target_begin(rt: RenderTarget)\n"
-"//~~fn RenderTarget.end\n"
-"// Begins the render target rendering pass.\n"
-"fn (rt: ^RenderTarget) begin*() {\n"
-"//~~\n"
-"\tumth_image_render_target_begin(rt^)\n"
-"}\n"
-"\n"
-"fn umth_image_render_target_end(rt: RenderTarget, wp: th.Vf2)\n"
-"//~~fn RenderTarget.end\n"
-"// Ends the render target rendering pass.\n"
-"fn (rt: ^RenderTarget) end*(wp: th.Vf2) {\n"
-"//~~\n"
-"\tumth_image_render_target_end(rt^, wp)\n"
-"}\n"
-"\n"
-"fn umth_image_render_target_to_image(ret: ^Image, rt: RenderTarget)\n"
-"//~~fn RenderTarget.toImage\n"
-"// Returns the image of the render target.\n"
-"// Do not call `setfilter` on the resulting image.\n"
-"fn (rt: ^RenderTarget) toImage*(): Image {\n"
-"//~~\n"
-"\timg := Image{}\n"
-"\tumth_image_render_target_to_image(&img, rt^)\n"
-"\treturn img\n"
-"}\n"
-"\n"
-"fn umth_image_load(ret: ^Image, path: str)\n"
-"//~~fn load\n"
-"// Loads an image at path.\n"
-"fn load*(path: str): Image {\n"
-"//~~\n"
-"\timg := Image{}\n"
-"\tumth_image_load(&img, path)\n"
-"\treturn img\n"
-"}\n"
-"\n"
-"//~~fn Image.validate\n"
-"// Returns true, if i\'s handle points to an image.\n"
-"fn (i: ^Image) validate*(): bool {\n"
-"//~~\n"
-"\treturn i._ != null\n"
-"}\n"
-"\n"
-"fn umth_image_flipv(i: Image, f: bool)\n"
-"//~~fn Image.flipv\n"
-"// Flips image on it\'s vertical axis.\n"
-"fn (i: ^Image) flipv*(flip: bool) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_flipv(i^, flip)\n"
-"}\n"
-"\n"
-"fn umth_image_fliph(i: Image, f: bool)\n"
-"//~~fn Image.fliph\n"
-"// Flips image on it\'s horizontal axis.\n"
-"fn (i: ^Image) fliph*(flip: bool) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_fliph(i^, flip)\n"
-"}\n"
-"\n"
-"fn umth_image_draw(img: Image, t: ^th.Transform, color: uint32)\n"
-"//~~fn Image.draw\n"
-"// Draws the image in screen coordinates. It transforms it with t and\n"
-"// applies color as a color filter.\n"
-"fn (i: ^Image) draw*(t: th.Transform, color: uint32 = th.white) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_draw(i^, &t, color)\n"
-"}\n"
-"\n"
-"fn umth_image_draw_nine_patch(img: Image, outer, inner, dest: ^rect.Rect,\n"
-"\tcolor: uint32, scale: real)\n"
-"//~~fn Image.drawNinepatch\n"
-"// Draws \"nine-patch\" image.\n"
-"// `outer` specifies the texture coordinates of the outer rect of source image,\n"
-"// `inner` specifies coordinates of inner rect of source image, positioned relative to `outer`.\n"
-"// You can tint with `color`.\n"
-"// \n"
-"fn (i: ^Image) drawNinepatch*(outer, inner, dest: rect.Rect, color: uint32 = th.white, scale: real = 1.0) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_draw_nine_patch(i^, &outer, &inner, &dest, color, scale)\n"
-"}\n"
-"\n"
-"fn umth_image_draw_on_quad(img: Image, color: uint32, q: th.Quad)\n"
-"//~~fn Image.drawOnQuad\n"
-"// Draws the image on top of a quad with corners of the image positioned\n"
-"// on the verticies of the quad.\n"
-"fn (i: ^Image) drawOnQuad*(q: th.Quad, color: uint32 = th.white) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_draw_on_quad(i^, color, q)\n"
-"}\n"
-"\n"
-"fn umth_image_get_dims(dm: ^th.Vf2, i: Image)\n"
-"//~~fn Image.getDims\n"
-"// Returns width and heigth.\n"
-"fn (i: ^Image) getDims*(): th.Vf2 {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tout := th.Vf2{}\n"
-"\tumth_image_get_dims(&out, i^)\n"
-"\n"
-"\treturn out\n"
-"}\n"
-"\n"
-"fn umth_image_crop(img: Image, tl, br: th.Vf2)\n"
-"//~~fn Image.crop\n"
-"// Crops an image. Coordinates are between 0, 0 (top left) and\n"
-"// 1, 1 (bottom right)\n"
-"fn (i: ^Image) crop*(tl, br: th.Vf2) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_crop(i^, tl, br)\n"
-"}\n"
-"\n"
-"//~~fn Image.cropPx\n"
-"// Same as `Image.crop`, but the positions are in pixels.\n"
-"fn (i: ^Image) cropPx*(tr, br: th.Vf2) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tdm := i.getDims()\n"
-"\tumth_image_crop(i^, tr.div(dm), br.div(dm))\n"
-"}\n"
-"\n"
-"//~~fn Image.cropRect\n"
-"// Same as `Image.crop`, but uses a rect instead of two positions.\n"
-"fn (i: ^Image) cropRect*(r: rect.Rect) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_crop(i^, r.getPos(), r.getEnd())\n"
-"}\n"
-"\n"
-"fn umth_image_crop_quad(img: Image, q: ^th.Quad)\n"
-"//~~fn Image.cropQuad\n"
-"// Crop an image using a quad.\n"
-"fn (i: ^Image) cropQuad*(q: th.Quad) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_crop_quad(i^, &q)\n"
-"}\n"
-"\n"
-"fn umth_image_get_crop_quad(img: Image, q: ^th.Quad)\n"
-"//~~fn Image.getCropQuad\n"
-"// Crop an image using a quad.\n"
-"fn (i: ^Image) getCropQuad*(): th.Quad {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tvar (q: th.Quad)\n"
-"\tumth_image_get_crop_quad(i^, &q)\n"
-"\treturn q\n"
-"}\n"
-"\n"
-"fn umth_image_from_data(ret: ^Image, data: ^uint32, dm: th.Vf2)\n"
-"//~~fn mk\n"
-"// Creates an image from raw data.\n"
-"fn mk*(data: []uint32, dm: th.Vf2): Image {\n"
-"//~~\n"
-"\timg := Image{}\n"
-"\tumth_image_from_data(&img, &data[0], dm)\n"
-"\n"
-"\treturn img\n"
-"}\n"
-"\n"
-"fn umth_image_copy(ret: ^Image, data: Image)\n"
-"//~~fn Image.copy\n"
-"// Copies image into a new one.\n"
-"fn (i: ^Image) copy*(): Image {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\timg := Image{}\n"
-"\tumth_image_copy(&img, i^)\n"
-"\n"
-"\treturn img\n"
-"}\n"
-"\n"
-"fn umth_image_set_filter(data: Image, filter: int)\n"
-"//~~fn Image.setfilter\n"
-"// Sets a mag/min filter. 0 is nearest, others are linear.\n"
-"// This function will regenerate the texture. This means it shouldn\'t be\n"
-"// used in a loop.\n"
-"// https://learnopengl.com/img/getting-started/texture_filtering.png\n"
-"// left is nearest, right is linear.\n"
-"fn (i: ^Image) setfilter*(filter: int) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_image_set_filter(i^, filter)\n"
-"}\n"
-"\n"
-"fn umth_image_update_data(img: Image, data: ^uint32, dm: th.Vf2)\n"
-"//~~fn Image.setData\n"
-"// Updates the image data. dm are the dimensions of the new image.\n"
-"// The new image doesn\'t have to be the same size as the old one.\n"
-"fn (i: ^Image) setData*(data: []uint32, dm: th.Vf2) {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tif dm.x * dm.y != len(data) {\n"
-"\t\terror(sprintf(\"setData: incorrect dimensions: %v\" + \"!= %v\", dm.x * dm.y, len(data)))\n"
-"\t}\n"
-"\n"
-"\tif len(data) == 0 {\n"
-"\t\terror(\"setData: can\'t set empty image\")\n"
-"\t}\n"
-"\n"
-"\tumth_image_update_data(i^, &data[0], dm)\n"
-"}\n"
-"\n"
-"fn umth_image_get_data(img: Image, data: ^uint32)\n"
-"//~~fn Image.getData\n"
-"// Gets the image data. This downloads the data from the GPU on **each call**.\n"
-"// Don\'t use in performance critical sections.\n"
-"fn (i: ^Image) getData*(): []uint32 {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"image is invalid\")\n"
-"\t}\t\n"
-"\n"
-"\tbuf := make([]uint32, trunc(i.getDims().x * i.getDims().y))\n"
-"\tif len(buf) == 0 {\n"
-"\t\treturn buf\n"
-"\t}\n"
-"\n"
-"\tumth_image_get_data(i^, &buf[0])\n"
-"\n"
-"\treturn buf\n"
-"}\n"
-"",
-"//~~\n"
-"// Module for getting keyboard and mouse input.\n"
-"// is* functions return info based on a us QWERTY layout. They are supposed to\n"
-"// be used for game controls. For text input use getStr.\n"
-"//~~\n"
-"\n"
-"import (\n"
-" \"rect.um\"\n"
-" \"th.um\"\n"
-" \"window.um\"\n"
-")\n"
-"\n"
-"//~~Keycode constants\n"
-"const (\n"
-" mouse1* = 1 // NOTE: mouse 2 and 3 key codes are swapped\n"
-" mouse2* = 3 // because sokol uses 3 for middle mouse\n"
-" mouse3* = 2 // button.\n"
-"\n"
-" key_ctrl* = 16\n"
-" key_shift* = 17\n"
-" key_alt* = 18\n"
-"\n"
-" key_space* = 32\n"
-" key_apostrophe* = 39 /* \' */\n"
-" key_comma* = 44 /* , */\n"
-" key_minus* = 45 /* - */\n"
-" key_dot* = 46 /* . */\n"
-" key_slash* = 47 /* / */\n"
-" key_0* = 48\n"
-" key_1* = 49\n"
-" key_2* = 50\n"
-" key_3* = 51\n"
-" key_4* = 52\n"
-" key_5* = 53\n"
-" key_6* = 54\n"
-" key_7* = 55\n"
-" key_8* = 56\n"
-" key_9* = 57\n"
-" key_semicolon* = 59 /* ; */\n"
-" key_equal* = 61 /* = */\n"
-" key_a* = 65\n"
-" key_b* = 66\n"
-" key_c* = 67\n"
-" key_d* = 68\n"
-" key_e* = 69\n"
-" key_f* = 70\n"
-" key_g* = 71\n"
-" key_h* = 72\n"
-" key_i* = 73\n"
-" key_j* = 74\n"
-" key_k* = 75\n"
-" key_l* = 76\n"
-" key_m* = 77\n"
-" key_n* = 78\n"
-" key_o* = 79\n"
-" key_p* = 80\n"
-" key_q* = 81\n"
-" key_r* = 82\n"
-" key_s* = 83\n"
-" key_t* = 84\n"
-" key_u* = 85\n"
-" key_v* = 86\n"
-" key_w* = 87\n"
-" key_x* = 88\n"
-" key_y* = 89\n"
-" key_z* = 90\n"
-" key_left_bracket* = 91 /* [ */\n"
-" key_backslash* = 92 /* \\ */\n"
-" key_right_bracket* = 93 /* ] */\n"
-" key_grave_accent* = 96 /* ` */\n"
-" key_world_1* = 161 /* non-US #1 */\n"
-" key_world_2* = 162 /* non-US #2 */\n"
-" key_escape* = 256\n"
-" key_enter* = 257\n"
-" key_tab* = 258\n"
-" key_backspace* = 259\n"
-" key_insert* = 260\n"
-" key_delete* = 261\n"
-" key_right* = 262\n"
-" key_left* = 263\n"
-" key_down* = 264\n"
-" key_up* = 265\n"
-" key_page_up* = 266\n"
-" key_page_down* = 267\n"
-" key_home* = 268\n"
-" key_end* = 269\n"
-" key_caps_lock* = 280\n"
-" key_scroll_lock* = 281\n"
-" key_num_lock* = 282\n"
-" key_print_screen* = 283\n"
-" key_pause* = 284\n"
-"\tkey_fn* = 289\n"
-" key_fn1* = 290\n"
-" key_fn2* = 291\n"
-" key_fn3* = 292\n"
-" key_fn4* = 293\n"
-" key_fn5* = 294\n"
-" key_fn6* = 295\n"
-" key_fn7* = 296\n"
-" key_fn8* = 297\n"
-" key_fn9* = 298\n"
-" key_fn10* = 299\n"
-" key_fn11* = 300\n"
-" key_fn12* = 301\n"
-" key_fn13* = 302\n"
-" key_fn14* = 303\n"
-" key_fn15* = 304\n"
-" key_fn16* = 305\n"
-" key_fn17* = 306\n"
-" key_fn18* = 307\n"
-" key_fn19* = 308\n"
-" key_fn20* = 309\n"
-" key_fn21* = 310\n"
-" key_fn22* = 311\n"
-" key_fn23* = 312\n"
-" key_fn24* = 313\n"
-" key_fn25* = 314\n"
-" key_kp_0* = 320\n"
-" key_kp_1* = 321\n"
-" key_kp_2* = 322\n"
-" key_kp_3* = 323\n"
-" key_kp_4* = 324\n"
-" key_kp_5* = 325\n"
-" key_kp_6* = 326\n"
-" key_kp_7* = 327\n"
-" key_kp_8* = 328\n"
-" key_kp_9* = 329\n"
-" key_kp_decimal* = 330\n"
-" key_kp_divide* = 331\n"
-" key_kp_multiply* = 332\n"
-" key_kp_subtract* = 333\n"
-" key_kp_add* = 334\n"
-" key_kp_enter* = 335\n"
-" key_kp_equal* = 336\n"
-" key_left_shift* = 340\n"
-" key_left_control* = 341\n"
-" key_left_alt* = 342\n"
-" key_left_super* = 343\n"
-" key_right_shift* = 344\n"
-" key_right_control* = 345\n"
-" key_right_alt* = 346\n"
-" key_right_super* = 347\n"
-" key_menu* = 348\n"
-")\n"
-"//~~\n"
-"\n"
-"\n"
-"fn toupper(c: char): int {\n"
-" if c >= \'a\' && c <= \'z\' {\n"
-" return int(c) - 32;\n"
-" }\n"
-" return int(c);\n"
-"}\n"
-"\n"
-"fn umth_input_get_mouse(out: ^th.Vf2)\n"
-"//~~fn getMousePos\n"
-"// Returns the position of mouse cursor in relation to the screen.\n"
-"fn getMousePos*(): th.Vf2 {\n"
-"//~~\n"
-"\tout := th.Vf2{}\n"
-"\tumth_input_get_mouse(&out)\n"
-"\treturn out\n"
-"}\n"
-"\n"
-"//~~fn getGlobalMousePos\n"
-"// Returns the position of mouse cursor in relation to cam.\n"
-"fn getGlobalMousePos*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn getMousePos().add(window.getViewportOffset())\n"
-"}\n"
-"\n"
-"fn umth_input_is_pressed(keycode: int32): int32\n"
-"//~~fn isPressed\n"
-"// Returns true if key is pressed. Either use codes defined in the file above,\n"
-"// or pass lower case char/number.\n"
-"fn isPressed*(code: int): bool {\n"
-"//~~\n"
-"\tval := bool(umth_input_is_pressed(code))\n"
-"\treturn val\n"
-"}\n"
-"\n"
-"//~~fn isPressedc\n"
-"// Like `isPressed`, but you can pass char as the code.\n"
-"fn isPressedc*(code: char): bool {\n"
-"//~~\n"
-"\treturn isPressed(toupper(code))\n"
-"}\n"
-"\n"
-"fn umth_input_is_just_pressed(key: int32): int32\n"
-"//~~fn isJustPressed\n"
-"// Returns, whether code was just pressed this loop.\n"
-"fn isJustPressed*(code: int): bool {\n"
-"//~~\n"
-"\treturn bool(umth_input_is_just_pressed(code))\n"
-"}\n"
-"\n"
-"//~~fn isJustPressedc\n"
-"// Like `isJustPressed`, but you can pass char as the code.\n"
-"fn isJustPressedc*(code: char): bool {\n"
-"//~~\n"
-"\treturn isJustPressed(toupper(code))\n"
-"}\n"
-"\n"
-"fn umth_input_is_pressed_repeat(key: int32): int32\n"
-"//~~fn isPressedRepeat\n"
-"// Returns, whether code was just pressed this loop, with key repeat.\n"
-"fn isPressedRepeat*(code: int): bool {\n"
-"//~~\n"
-" return bool(umth_input_is_pressed_repeat(code))\n"
-"}\n"
-"\n"
-"//~~fn isPressedRepeatc\n"
-"// Like `isPressedRepeat`, but you can pass char as the code.\n"
-"fn isPressedRepeatc*(code: char): bool {\n"
-"//~~\n"
-" return isPressedRepeat(toupper(code))\n"
-"}\n"
-"\n"
-"\n"
-"fn umth_input_is_just_released(key: int32): int32\n"
-"//~~fn isJustReleased\n"
-"// Returns true if a key was just released.\n"
-"fn isJustReleased*(code: int): bool {\n"
-"//~~\n"
-"\treturn bool(umth_input_is_just_released(code))\n"
-"}\n"
-"//~~fn isJustReleasedc\n"
-"// Like `isJustReleased`, but you can pass char as the code.\n"
-"fn isJustReleasedc*(code: char): bool {\n"
-"//~~\n"
-"\treturn isJustReleased(toupper(code))\n"
-"}\n"
-"\n"
-"fn umth_input_clear*(code: int)\n"
-"//~~fn clear\n"
-"// Clears both the pressed and justPressed state of a code.\n"
-"fn clear*(code: int) {\n"
-"//~~\n"
-"\tumth_input_clear(code)\n"
-"}\n"
-"\n"
-"//~~fn clearc\n"
-"// Like `clear`, but you can pass char as the code.\n"
-"fn clearc*(code: char) {\n"
-"//~~\n"
-" umth_input_clear(toupper(code))\n"
-"}\n"
-"\n"
-"fn umth_input_get_str(): str\n"
-"//~~fn getStr\n"
-"// Returns a string entered by the user in the last cycle.\n"
-"fn getStr*(): str {\n"
-"//~~\n"
-"\treturn umth_input_get_str()\n"
-"}\n"
-"\n"
-"fn umth_input_get_mouse_delta(o: ^th.Vf2)\n"
-"//~~fn getMouseDelta\n"
-"// Returns the difference between mouse positions in the last cycle. Will work\n"
-"// even if `window.freezeCursor` is enabled.\n"
-"fn getMouseDelta*(): th.Vf2 {\n"
-"//~~\n"
-"\to := th.Vf2{}\n"
-"\tumth_input_get_mouse_delta(&o)\n"
-"\treturn o\n"
-"}\n"
-"\n"
-"fn umth_input_get_mouse_scroll(x, y: ^th.fu)\n"
-"//~~fn getMouseScroll\n"
-"// Returns the scroll wheel value\n"
-"fn getMouseScroll*(): th.Vf2 {\n"
-"//~~\n"
-" var x, y: th.fu\n"
-" umth_input_get_mouse_scroll(&x, &y)\n"
-" return th.Vf2{x, y}\n"
-"}",
-"//~~\n"
-"// Misc functions.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"std.um\"\n"
-")\n"
-"\n"
-"//~~fn readall\n"
-"// Reads file content into a string.\n"
-"fn readall*(path: str): str {\n"
-"//~~\n"
-"\tf := std.fopen(path, \"r\")\n"
-"\tconst blockSize = 16\n"
-"\tres := \"\"\n"
-"\n"
-"\tfor ok := true; ok {\n"
-"\t var buff: [blockSize + 1]char\n"
-"\t ok = std.fread(f, ^[blockSize]char(&buff)) == 1\n"
-"\t res += str([]char(buff))\n"
-"\t}\n"
-"\n"
-"\tstd.fclose(f)\n"
-"\treturn res\n"
-"}\n"
-"\n"
-"//~~fn stepify\n"
-"// Snaps a value to step.\n"
-"fn stepify*(val, step: th.fu): th.fu {\n"
-"//~~\n"
-"\tif step != 0 {\n"
-"\t\tval = floor(val / step + 0.5) * step\n"
-"\t}\n"
-"\treturn val\n"
-"}\n"
-"\n"
-"//~~fn maxf\n"
-"fn maxf*(a, b: th.fu): th.fu {\n"
-"//~~\n"
-"\tif a > b { return a }\n"
-"\treturn b\n"
-"}\n"
-"\n"
-"//~~fn minf\n"
-"fn minf*(a, b: th.fu): th.fu {\n"
-"//~~\n"
-"\tif a > b { return b }\n"
-"\treturn a\n"
-"}\n"
-"",
-"//~~\n"
-"// Canvas library allowing for drawing basic shapes. Coordinates are based on\n"
-"// the screen.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"misc.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"fn umth_canvas_draw_text(text: str, pos: th.Vf2, color: uint32, size: th.fu)\n"
-"//~~fn drawText\n"
-"// Draws a basic pixel text. Only ascii is supported.\n"
-"fn drawText*(text: str, pos: th.Vf2, color: uint32, size: th.fu) {\n"
-"//~~\n"
-"\tumth_canvas_draw_text(text, pos, color, size)\n"
-"}\n"
-"\n"
-"//~~fn textSize\n"
-"// Returns the size of text taken by an equivalent drawText call.\n"
-"fn textSize*(text: str, scale: th.fu): th.Vf2 {\n"
-"//~~\n"
-"\tvar w, maxw, h: int\n"
-"\tw = 0\n"
-"\tmaxw = 0\n"
-"\th = 1\n"
-"\n"
-"\tfor i in text {\n"
-"\t\tif text[i] == \"\\n\" {\n"
-"\t\t\th += 1\n"
-"\t\t\tif w > maxw {\n"
-"\t\t\t\tmaxw = w\n"
-"\t\t\t}\n"
-"\n"
-"\t\t\tcontinue\n"
-"\t\t}\n"
-"\n"
-"\t\tw++\n"
-"\t}\n"
-"\n"
-"\tif w > maxw {\n"
-"\t\tmaxw = w\n"
-"\t}\n"
-"\n"
-"\treturn th.Vf2{maxw * scale * 6 - scale, h * 6 * scale}\n"
-"}\n"
-"\n"
-"fn umth_canvas_draw_rect(color: uint32, r: rect.Rect)\n"
-"//~~fn drawRect\n"
-"// Draws a Rectangle.\n"
-"fn drawRect*(color: uint32, r: rect.Rect) {\n"
-"//~~\n"
-"\tumth_canvas_draw_rect(color, r)\n"
-"}\n"
-"\n"
-"fn umth_canvas_draw_line(color: uint32, b, e: th.Vf2, thickness: th.fu)\n"
-"//~~fn drawLine\n"
-"// Draws a line.\n"
-"fn drawLine*(color: uint32, b, e: th.Vf2, thickness: th.fu) {\n"
-"//~~\n"
-"\tumth_canvas_draw_line(color, b, e, thickness)\n"
-"}\n"
-"\n"
-"//~~fn drawRectLines\n"
-"// Draws rect border.\n"
-"fn drawRectLines*(color: uint32, r: rect.Rect, thickness: real32 = 1.0) {\n"
-"//~~\n"
-" // top\n"
-" drawLine(color, th.Vf2{r.x-1, r.y}, th.Vf2{r.x+r.w, r.y}, thickness)\n"
-" // bottom\n"
-" drawLine(color, th.Vf2{r.x, r.y+r.h}, th.Vf2{r.x+r.w, r.y+r.h}, thickness)\n"
-" // left\n"
-" drawLine(color, th.Vf2{r.x, r.y}, th.Vf2{r.x, r.y+r.h}, thickness)\n"
-" // right\n"
-" drawLine(color, th.Vf2{r.x+r.w, r.y}, th.Vf2{r.x+r.w, r.y+r.h}, thickness)\n"
-"}\n"
-"\n"
-"fn umth_canvas_draw_quad(color: uint32, q: ^th.Quad)\n"
-"//~~fn drawQuad\n"
-"// Draws a convex quad.\n"
-"fn drawQuad*(color: uint32, q: th.Quad) {\n"
-"//~~\n"
-"\tumth_canvas_draw_quad(color, &q)\n"
-"}\n"
-"\n"
-"var scissor: []rect.Rect\n"
-"\n"
-"fn umth_canvas_begin_scissor_rect(x, y, w, h: real)\n"
-"fn umth_canvas_end_scissor()\n"
-"\n"
-"fn rectDiff(a, b: rect.Rect): rect.Rect {\n"
-"\tx := misc.maxf(a.x, b.x);\n"
-"\ty := misc.maxf(a.y, b.y);\n"
-"\treturn rect.Rect{\n"
-"\t\tx,y, \n"
-"\t\tmisc.minf(a.x + a.w, b.x + b.w) - x,\n"
-"\t\tmisc.minf(a.y + a.h, b.y + b.h) - y};\n"
-"}\n"
-"\n"
-"//~~fn beginScissorRect\n"
-"// Disable rendering outside of rect `r`\n"
-"fn beginScissorRect*(r: rect.Rect, debug: bool = false) {\n"
-"//~~\n"
-"\tr2 := r\n"
-"\tif len(scissor) == 0 {\n"
-"\t\tscissor = { r }\n"
-"\t} else {\n"
-"\t\ts := scissor[len(scissor) - 1]\n"
-"\t\tr2 = rectDiff(s, r)\n"
-"\t\tscissor = append(scissor, r2)\n"
-"\t}\n"
-"\n"
-"\tif debug {\n"
-"\t\tdrawRectLines(th.red, r2, 0.1) \n"
-"\t}\n"
-"\t\n"
-"\tumth_canvas_begin_scissor_rect(r2.x, r2.y, r2.w, r2.h)\n"
-"}\n"
-"\n"
-"//~~fn endScissor\n"
-"// Stops cropping\n"
-"fn endScissor*() {\n"
-"//~~\n"
-"\tif len(scissor) > 0 {\n"
-"\t\tscissor = delete(scissor, len(scissor) - 1)\n"
-"\t\tif len(scissor) > 0 {\n"
-"\t\t\tlast := scissor[len(scissor)-1]\n"
-"\t\t\tumth_canvas_begin_scissor_rect(last.x, last.y, last.w, last.h)\n"
-"\t\t} else {\n"
-"\t\t\tumth_canvas_end_scissor();\n"
-"\t\t}\n"
-"\t}\n"
-"\t\n"
-"}\n"
-"",
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"ent.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"canvas.um\"\n"
-"\t\"tilemap.um\"\n"
-")\n"
-"\n"
-"//~~struct Ray\n"
-"// Ray is a line specified by an origin, length and a rotation.\n"
-"type Ray* = struct {\n"
-"\tpos: th.Vf2\n"
-"\tl: th.fu // length\n"
-"\tr: th.fu // rotation\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"// Ray constructor\n"
-"fn mk*(pos: th.Vf2, l: th.fu, r: th.fu = 0.0): Ray {\n"
-"//~~\n"
-"\treturn Ray{pos, l, r}\n"
-"}\n"
-"\n"
-"fn umth_ray_getcoll(colls: ^ent.Coll, count: ^int, maxCount,\n"
-"\tsceneLen: int, r: ^Ray, scene: ^^ent.Ent)\n"
-"//~~fn Ray.getColl\n"
-"// Checks the ray\'s collisions with a scene of ents. Similar to\n"
-"// `ent.Ent.getColl`\n"
-"fn (r: ^Ray) getColl*(s: []^ent.Ent, maxColls: th.uu): []ent.Coll {\n"
-"//~~\n"
-"\tif len(s) == 0 {\n"
-"\t\treturn []ent.Coll{}\n"
-"\t}\n"
-"\n"
-"\tif maxColls > len(s) {\n"
-"\t\tmaxColls = len(s)\n"
-"\t}\n"
-"\n"
-"\tcolls := make([]ent.Coll, maxColls)\n"
-"\tcount := 0\n"
-"\tumth_ray_getcoll(&colls[0], &count, maxColls, len(s), r, &s[0])\n"
-"\treturn slice(colls, 0, count)\n"
-"}\n"
-"\n"
-"fn umth_ray_get_tilemap_coll(r: ^Ray, t: ^tilemap.Tilemap, ic: ^th.Vf2): bool\n"
-"//~~fn Ray.getTilemapColl\n"
-"// Gets ray\'s collision to a tilemap.\n"
-"fn (r: ^Ray) getTilemapColl*(t: tilemap.Tilemap, ic: ^th.Vf2): bool {\n"
-"//~~\n"
-"\treturn umth_ray_get_tilemap_coll(r, &t, ic)\n"
-"}\n"
-"\n"
-"//~~fn Ray.getEnd\n"
-"// Returns the other point of the ray.\n"
-"fn (r: ^Ray) getEnd*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn r.pos.add(th.Vf2{ 0, r.l }.rotated(th.Vf2{}, r.r))\n"
-"}\n"
-"\n"
-"//~~fn Ray.draw\n"
-"// Draws the ray to the screen.\n"
-"fn (r: ^Ray) draw*(color: uint32, thickness: th.fu) {\n"
-"//~~\n"
-"\tcanvas.drawLine(color, r.pos, r.getEnd(), thickness)\n"
-"}\n"
-"",
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~struct Rect\n"
-"// A set of points representing a rectangle.\n"
-"type Rect* = struct {\n"
-"\tx, y, w, h: th.fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"fn mk*(x, y, w, h: th.fu): Rect {\n"
-"//~~\n"
-"\tvar r: Rect\n"
-"\n"
-"\tr.x = x\n"
-"\tr.y = y\n"
-"\tr.w = w\n"
-"\tr.h = h\n"
-"\n"
-"\treturn r\n"
-"}\n"
-"\n"
-"//~~fn mk\n"
-"// Creates a rect from two Vf2s - the position and the dimensions.\n"
-"fn fromVf2*(p: th.Vf2, dm: th.Vf2): Rect {\n"
-"//~~\n"
-"\treturn mk(p.x, p.y, dm.x, dm.y)\n"
-"}\n"
-"\n"
-"//~~fn Rect.getPos\n"
-"fn (r: ^Rect) getPos*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn th.Vf2{r.x, r.y}\n"
-"}\n"
-"\n"
-"//~~fn Rect.getDims\n"
-"fn (r: ^Rect) getDims*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn th.Vf2{r.w, r.h}\n"
-"}\n"
-"\n"
-"//~~fn Rect.getEnd\n"
-"// returns where the second point of the rectangle lies.\n"
-"fn (r: ^Rect) getEnd*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn th.Vf2{r.x+r.w, r.y+r.h}\n"
-"}\n"
-"\n"
-"fn umth_transform_rect(ret: ^th.Quad, r: ^Rect, t: ^th.Transform)\n"
-"//~~fn Rect.transformed\n"
-"// Transforms a rect into a quad.\n"
-"// Order:\n"
-"// \t1. scale\n"
-"// \t2. rotation\n"
-"// \t3. position\n"
-"fn (r: ^Rect) transformed*(t: th.Transform): th.Quad {\n"
-"//~~\n"
-"\tvar ret: th.Quad\n"
-"\tumth_transform_rect(&ret, r, &t)\n"
-"\n"
-"\treturn ret\n"
-"}\n"
-"\n"
-"//~~fn Rect.shrink\n"
-"// Shrink the rectangle by `p` pixels from all sides.\n"
-"fn (r: ^Rect) shrink*(p: th.Vf2): Rect {\n"
-"//~~\n"
-"\treturn Rect{ r.x + p.x, r.y + p.y, r.w - 2*p.x, r.h - 2*p.y }\n"
-"}\n"
-"\n"
-"//~~fn Rect.shift\n"
-"// Shift the rectangle by `p` pixels.\n"
-"fn (r: ^Rect) shift*(p: th.Vf2): Rect {\n"
-"//~~\n"
-"\treturn Rect{ r.x + p.x, r.y + p.y, r.w, r.h }\n"
-"}\n"
-"\n"
-"//~~fn Rect.scale\n"
-"// Multiply the dimensions by `p`\n"
-"fn (r: ^Rect) scale*(p: th.Vf2): Rect {\n"
-"//~~\n"
-"\treturn Rect{ r.x, r.y, r.w * p.x, r.h * p.y }\n"
-"}\n"
-"\n"
-"//~~fn Rect.center\n"
-"// Returns the position, which is the center of the rect.\n"
-"fn (r: ^Rect) center*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn r.getPos().add(r.getDims().divf(2))\n"
-"}\n"
-"\n"
-"//~~fn Rect.centerWithinRect\n"
-"// Centers `child` with the rect `r`.\n"
-"fn (r: ^Rect) centerWithinRect*(child: Rect): Rect {\n"
-"//~~\n"
-"\tchild.x = r.x + (r.w - child.w)/2\n"
-"\tchild.y = r.y + (r.h - child.h)/2\n"
-"\treturn child\n"
-"}\n"
-"\n"
-"",
-"//~~\n"
-"// Tilemaps allow for easy level construction and fast collisions. You can even\n"
-"// use them for some games instead of entities (tetris comes to mind)\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"ent.um\"\n"
-"\t\"atlas.um\"\n"
-")\n"
-"\n"
-"//~~Direction constants used for autotile\n"
-"const (\n"
-"\ttop* = 1\n"
-"\tright* = 2\n"
-"\tbot* = 4\n"
-"\tleft* = 8\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~struct Tilemap\n"
-"// Tilemap struct\n"
-"type Tilemap* = struct {\n"
-"\tatlas: atlas.Atlas\n"
-"\tpos: th.Vf2\n"
-"\tw: th.uu // width of tilemap\n"
-"\tcells: []th.uu // all cells (this will draw the tile in tiles with number in cells - 1)\n"
-"\tcollMask: []bool // if true, the tile collides\n"
-"\tscale: th.fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"fn mk*(cells: []th.uu, w: th.uu, at: atlas.Atlas, scale: th.fu = 1): Tilemap {\n"
-"//~~\n"
-"\tif !at.i.validate() {\n"
-"\t\tth.__error(\"invalid atlas\")\n"
-"\t}\t\n"
-"\n"
-"\tt := Tilemap{}\n"
-"\tt.cells = cells\n"
-"\tt.w = w\n"
-"\tt.atlas = at\n"
-"\tt.collMask = make([]bool, 10) // TODO\n"
-"\tt.scale = scale\n"
-"\n"
-"\treturn t\n"
-"}\n"
-"\n"
-"//~~fn Tilemap.edit\n"
-"// Sets tile at [x, y] to tile.\n"
-"fn (t: ^Tilemap) edit*(x, y, tile: int) {\n"
-"//~~\n"
-"\tt.cells[y*t.w + x] = tile\n"
-"}\n"
-"\n"
-"fn umth_tilemap_draw(ct: ^Tilemap)\n"
-"//~~fn Tilemap.draw\n"
-"// Draws the tilemap.\n"
-"fn (t: ^Tilemap) draw*() {\n"
-"//~~\n"
-"\tif len(t.cells) == 0 { return }\n"
-"\n"
-"\tumth_tilemap_draw(t)\n"
-"}\n"
-"\n"
-"fn umth_tilemap_getcoll(pos: ^th.Vf2, vert: ^th.Vf2, t: ^Tilemap, e: ^ent.Ent): int32\n"
-"//~~fn Tilemap.getColl\n"
-"// Checks whether `e` collides with any of the tiles in `t`, which are in the\n"
-"// collmask.\n"
-"//\n"
-"// * `ic`[out] - the position where a collision occured\n"
-"// * `pos`[out] - coordinates of a tile where a collision occured\n"
-"//\n"
-"// Note: While there may be multiple collisions with a tilemap, this function\n"
-"// will only return one.\n"
-"fn (t: ^Tilemap) getColl*(e: ent.Ent, ic: ^th.Vf2, pos: ^th.Vf2): bool {\n"
-"//~~\n"
-"\tif len(t.cells) == 0 { return false }\n"
-"\n"
-"\t_ := th.Vf2{}\n"
-"\tif ic == null { ic = &_ }\n"
-"\tif pos == null { pos = &_ }\n"
-"\n"
-"\tc := umth_tilemap_getcoll(pos, ic, t, &e)\n"
-"\n"
-"\treturn bool(c)\n"
-"}\n"
-"\n"
-"fn umth_tilemap_autotile(tgt: ^th.uu, w, h: th.uu, src, cfg: ^th.uu, tile: th.uu)\n"
-"//~~fn Tilemap.autotile\n"
-"// Autotile turns all `tile` tiles in `src` into tiles in `tileCfg`, so they\n"
-"// follow up correctly. `tileCfg` is an array of 16 tiles. They are placed in\n"
-"// a way where OR of all the places where the tile continues (top, right bot,\n"
-"// right). The constants for them are defined in this file. Example:\n"
-"// tileCfg[top | bot] = 21\n"
-"// top | bot would look something like this: |\n"
-"fn (t: ^Tilemap) autotile*(src, tileCfg: []th.uu, tile: th.uu) {\n"
-"//~~\n"
-"\tif len(tileCfg) < 16 {\n"
-"\t\terror(\"autotile: tileCfg len isn\'t 16\'\")\n"
-"\t}\n"
-"\n"
-"\tumth_tilemap_autotile(&t.cells[0], t.w, len(t.cells)/t.w, &src[0], &tileCfg[0], tile)\n"
-"}\n"
-"",
-"\n"
-"import (\n"
-"\t\"audio.um\"\n"
-"\t\"canvas.um\"\n"
-"\t\"image.um\"\n"
-"\t\"placeholders.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"signal.um\"\n"
-"\t\"std.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"var (\n"
-"\tstart, clockOffset: real\n"
-"\tfpsLimit: int = 60\n"
-")\n"
-"\n"
-"//~~Cursor types\n"
-"const (\n"
-"\tcursorDefault* = 0\t\t// Default system cursor\n"
-"\tcursorArrow*\t\t\t// Normal cursor; Arrow cursor\n"
-"\tcursorIBeam*\t\t\t// \'I\' text cursor; I-Beam\n"
-"\tcursorCrosshair*\t\t// \'+\' cursor; Select region cursor\n"
-"\tcursorFinger*\t\t\t// Index finger pointing cursor; Click cursor\n"
-"\tcursorSizeEW*\t\t\t// \'<->\' cursor; Resize width cursor; Resize horizontally cursor; East-West resize cursor\n"
-"\tcursorSizeNS*\t\t\t// Resize height cursor; Resize vertically cursor; North-South resize cursor\n"
-"\tcursorSizeNWSE*\t\t\t// Resize width and height from the right side cursor; Northwest-Southeast resize cursor\n"
-"\tcursorSizeSWNE*\t\t\t// Resize width and height from the left side cursor; Southwest-Northeast resize cursor\n"
-"\tcursorSizeAll*\t\t\t// Resize all cursor; Move cursor\n"
-"\tcursorNo*\t\t\t// \'(/)\' cursor; Disabled cursor; Disallowed cursor\n"
-"\tcursorCount_*\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~Window dimensions\n"
-"var (\n"
-"\tw*, h*: int32\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~Viewport size\n"
-"var wp*: th.Vf2\n"
-"//~~\n"
-"\n"
-"//~~signal OnFrame\n"
-"var onFrame*: signal.Signal\n"
-"//~~\n"
-"//~~signal OnDestroy\n"
-"var onDestroy*: signal.Signal\n"
-"//~~\n"
-"\n"
-"fn umth_window_setup(title: str, w, h: int)\n"
-"fn umth_window_get_dimensions(w, h: ^int32)\n"
-"\n"
-"fn umth_window_set_viewport(dm: th.Vf2)\n"
-"//~~fn setViewport\n"
-"// Sets the dimensions of the viewport. The dimensions are saved in the `wp`\n"
-"// variable.\n"
-"//\n"
-"// `dm`\n"
-"// : dimension of the viewport\n"
-"fn setViewport*(dm: th.Vf2) {\n"
-"//~~\n"
-"\twp = dm\n"
-"\tumth_window_set_viewport(dm)\n"
-"}\n"
-"\n"
-"fn setIcon*(img: image.Image)\n"
-"\n"
-"fn umth_window_is_dpi_enabled(): bool\n"
-"\n"
-"//~~fn isDpiEnabled\n"
-"// Returns true if DPI awareness was enabled\n"
-"fn isDpiEnabled*(): bool {\n"
-"//~~\n"
-"\treturn umth_window_is_dpi_enabled()\n"
-"}\n"
-"\n"
-"fn umth_window_get_dpi_scale(): th.fu\n"
-"\n"
-"//~~fn getDpiScaleFactor\n"
-"// Returns the DPI scaling of the current window.\n"
-"// If `dpiAware` was not enabled in window setup, this function will return 1.0 (default scaling).\n"
-"fn getDpiScaleFactor*(): th.fu {\n"
-"//~~\n"
-"\treturn umth_window_get_dpi_scale()\n"
-"}\n"
-"\n"
-"// 0 = other/unknown\n"
-"// 2 = linux\n"
-"// 3 = windows\n"
-"// 4 = macos (unsupported currently)\n"
-"// 5 = emscripten\n"
-"fn umth_window_get_platform_id(): int\n"
-"\n"
-"//~~fn setup\n"
-"// Sets up the engine and opens a window.\n"
-"fn setup*(title: str = \"tophat game\", width: int = 400, height: int32 = 400) {\n"
-"//~~\n"
-"\tw, h = width, height\n"
-"\tumth_window_setup(title, width, height)\n"
-"\n"
-"\tth.platform = umth_window_get_platform_id()\n"
-"\n"
-"\taudio.__setup()\n"
-"\tplaceholders.__setup()\n"
-"\n"
-"\tsetIcon(placeholders.icon)\n"
-"\n"
-"\tclockOffset = std.clock() * 1000\n"
-"\tstart = std.clock() * 1000\n"
-"\n"
-"\tsetViewport(th.Vf2{width, height})\n"
-"}\n"
-"\n"
-"//~~fn cycle\n"
-"// Cycle needs to be called every cycle for the window to work. If the window\n"
-"// was closed, it returns false.\n"
-"fn cycle(delta: real) {\n"
-"//~~\n"
-"\tumth_window_set_viewport(wp)\n"
-"\n"
-"\tth.delta = trunc(delta*1000.0)\n"
-"\tif th.delta == 0 {\n"
-"\t\tth.delta = 1\n"
-"\t}\n"
-"\n"
-"\tstart = std.clock()*1000\n"
-"\tth.time = round(start - clockOffset)\n"
-"\n"
-"\tumth_window_get_dimensions(&w, &h)\n"
-"\n"
-"\taudio.__cycle()\n"
-"\tcanvas.drawRect(th.white, rect.mk(0, 0, wp.x, wp.y))\n"
-"}\n"
-"\n"
-"fn setViewportOffset*(s: th.Vf2)\n"
-"fn getViewportOffset*(): th.Vf2\n"
-"\n"
-"fn drawClear() {\n"
-"\tof := getViewportOffset()\n"
-"\tsetViewportOffset({})\n"
-"\tcanvas.drawRect(th.black, rect.mk(-4 * wp.x, 0, 4 * wp.x, wp.y))\n"
-"\tcanvas.drawRect(th.black, rect.mk(0, -4 * wp.y, wp.x, 4 * wp.y))\n"
-"\tcanvas.drawRect(th.black, rect.mk(wp.x, 0, 4 * wp.x, wp.y))\n"
-"\tcanvas.drawRect(th.black, rect.mk(0, wp.y, wp.x, 4 * wp.y))\n"
-"\tsetViewportOffset(of)\n"
-"}\n"
-"\n"
-"fn umth_frame_callback*(delta: real) {\n"
-"\tcycle(delta)\n"
-"\tonFrame.emit(null)\n"
-"\tdrawClear()\n"
-"}\n"
-"\n"
-"fn umth_destroy_callback*() {\n"
-" onDestroy.emit(null)\n"
-"}\n"
-"\n"
-"fn umth_window_set_fullscreen(fullscreen: bool)\n"
-"fn umth_window_get_fullscreen(): bool\n"
-"\n"
-"//~~fn setFullscreen\n"
-"// Makes window go full screen\n"
-"fn setFullscreen*(fullscreen: bool) {\n"
-"//~~\n"
-"\tumth_window_set_fullscreen(fullscreen)\n"
-"}\n"
-"\n"
-"//~~fn isFullscreen\n"
-"// Returns true if window is fullscreen\n"
-"fn isFullscreen*(): bool {\n"
-"//~~\n"
-"\treturn umth_window_get_fullscreen()\n"
-"}\n"
-"\n"
-"//~~fn getDims\n"
-"// Returns dimensions of the window in screen pixels.\n"
-"fn getDims*(): th.Vf2 {\n"
-"//~~\n"
-"\treturn th.Vf2{w, h}\n"
-"}\n"
-"\n"
-"fn umth_window_set_target_fps(fps: int)\n"
-"\n"
-"//~~fn setTargetFps\n"
-"// Sets the fps limit.\n"
-"//\n"
-"// `fps`\n"
-"// : amount of fps the limit should be set to\n"
-"//\n"
-"fn setTargetFps*(fps: int) {\n"
-"//~~\n"
-"\tfpsLimit = fps\n"
-"\tumth_window_set_target_fps(fps)\n"
-"}\n"
-"\n"
-"fn umth_window_set_dims(dm: th.Vf2)\n"
-"//~~fn setDims\n"
-"// Sets the dimensions of the window.\n"
-"//\n"
-"// `dm`\n"
-"// : the target dimensions in screen pixels\n"
-"fn setDims*(dm: th.Vf2) {\n"
-"//~~\n"
-"\tumth_window_set_dims(dm)\n"
-"}\n"
-"\n"
-"fn umth_window_set_icon(img: image.Image)\n"
-"//~~fn setIcon\n"
-"// Sets the window icon.\n"
-"fn setIcon*(img: image.Image) {\n"
-"//~~\n"
-"\tif !img.validate() {\n"
-"\t\tth.__error(\"invalid image\")\n"
-"\t}\t\n"
-"\n"
-"\tumth_window_set_icon(img)\n"
-"}\n"
-"\n"
-"fn umth_window_show_cursor(show: bool)\n"
-"//~~fn showCursor\n"
-"// Show or hide the cursor, linux only.\n"
-"fn showCursor*(show: bool) {\n"
-"//~~\n"
-"\tumth_window_show_cursor(show)\n"
-"}\n"
-"\n"
-"fn umth_window_freeze_cursor(freeze: bool)\n"
-"//~~fn freezeCursor\n"
-"// Freezes the cursor in place. `input.getMouseDelta` will still report mouse\n"
-"// movements. The cursor will be automatically hidden.\n"
-"fn freezeCursor*(freeze: bool) {\n"
-"//~~\n"
-"\tshowCursor(freeze)\n"
-"\tumth_window_freeze_cursor(freeze)\n"
-"}\n"
-"\n"
-"fn umth_window_set_cursor(cursor: int)\n"
-"//~~fn setCursor\n"
-"// Allows you to set the displaying cursor. Refer to the cursors section for available cursors.\n"
-"fn setCursor*(cursor: int) {\n"
-"//~~\n"
-"\tumth_window_set_cursor(cursor);\n"
-"}\n"
-"\n"
-"\n"
-"fn umth_window_quit()\n"
-"//~~fn quit\n"
-"// Exits the application. Use this instead of umka\'s default `exit`.\n"
-"fn quit*() {\n"
-"//~~\n"
-"\tumth_window_quit()\n"
-"}\n"
-"\n"
-"fn umth_window_set_clipboard(s: str)\n"
-"//~~fn setClipboard\n"
-"// Puts a string to the system clipboard.\n"
-"fn setClipboard*(s: str) {\n"
-"//~~\n"
-"\tumth_window_set_clipboard(s)\n"
-"}\n"
-"\n"
-"fn umth_window_get_clipboard(s: ^char)\n"
-"//~~fn getClipboard\n"
-"// Gets a string from the system clipboard.\n"
-"fn getClipboard*(): str {\n"
-"//~~\n"
-"\tbuf := make([]char, 8192)\n"
-"\tumth_window_get_clipboard(&buf[0])\n"
-"\treturn str(buf)\n"
-"}\n"
-"\n"
-"fn umth_window_set_viewport_shift(s: th.Vf2)\n"
-"//~~fn setViewportOffset\n"
-"// Sets the offset of the viewport.\n"
-"fn setViewportOffset*(s: th.Vf2) {\n"
-"//~~\n"
-"\tumth_window_set_viewport_shift(s)\n"
-"}\n"
-"\n"
-"fn umth_window_get_viewport_shift(s: ^th.Vf2)\n"
-"//~~fn getViewportOffset\n"
-"// Gets the offset of the viewport (as set by `setViewportShift`)\n"
-"fn getViewportOffset*(): th.Vf2 {\n"
-"\to := th.Vf2{}\n"
-"\n"
-"\tumth_window_get_viewport_shift(&o)\n"
-"\treturn o\n"
-"}\n"
-"",
-"//~~\n"
-"// Particles allow for *performant* and random particle systems.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"rect.um\"\n"
-"\t\"std.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~struct Particle\n"
-"// Particle struct. You can tweak the start_time for godot-like explossivness.\n"
-"type Particle* = struct {\n"
-"//~~\n"
-"\tstart_time: uint\n"
-"\tseed: int32\n"
-"}\n"
-"\n"
-"//~~struct Emitter\n"
-"// Emitter. This is where everything is configured.\n"
-"type Emitter* = struct {\n"
-"\tpos: th.Vf2 // position\n"
-"\tdm: th.Vf2 // size of the emittion area\n"
-"\tgravity: th.Vf2 // gravity\n"
-"\trepeat: bool // if false, particle won\'t be renewed\n"
-"\tactive: bool // false, if there aren\'t any active particles anymore\n"
-"\n"
-"\tangle: th.Vf2 // angle in which particles are emitted\n"
-"\n"
-"\tlifetime: th.uu // lifetime of particles\n"
-"\tlifetimeRandomness: th.fu // randomness in %/100\n"
-"\n"
-"\tvelocity: th.fu // velocity\n"
-"\tvelocityRandomness: th.fu // randomness in %/100\n"
-"\n"
-"\tsize: th.fu // size\n"
-"\tsizeRandomness: th.fu // randomness in %/100\n"
-"\tmaxSize: th.fu // size at the end of particles lifetime\n"
-"\n"
-"\trotation: th.fu\n"
-"\trotationRandomness: th.fu\n"
-"\tmaxRotation: th.fu\n"
-"\n"
-"\tcolors: []uint32 // array of colors, which are interpolated between\n"
-"\n"
-"\tparticles: []Particle // list of particles\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn umth_particles_draw(p: ^Emitter, t: int32)\n"
-"//~~fn Emitter.draw\n"
-"// Draws and updates the particles.\n"
-"fn (e: ^Emitter) draw*(t: int32) {\n"
-"//~~\n"
-"\tif len(e.colors) <= 0 || len(e.particles) <= 0 {\n"
-"\t\treturn\n"
-"\t}\n"
-"\n"
-"\tumth_particles_draw(e, t)\n"
-"}\n"
-"\n"
-"//~~fn Emitter.genParticles\n"
-"// Generates particles for an emitter. The time specifies the time the first\n"
-"// particles is emitted. The explosiveness argument specifies the interval at\n"
-"// which particles are emitted using this formula:\n"
-"/// ```umka\n"
-"/// e.lifetime / count * explosiveness\n"
-"/// ```\n"
-"fn (e: ^Emitter) genParticles*(time, count: uint, explosiveness: th.fu = 0.0) {\n"
-"//~~\n"
-"\tp := make([]Particle, count)\n"
-"\n"
-"\tstep := real32(e.lifetime) / count * explosiveness\n"
-"\tt := real32(time)\n"
-"\n"
-"\tfor i in p {\n"
-"\t\tp[i] = { trunc(t), std.rand() }\n"
-"\t\tt += step\n"
-"\t}\n"
-"\n"
-"\te.particles = p\n"
-"}\n"
-"",
-"//~~\n"
-"// Simple linear interpolation module.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\t\t\t\t\t\t\t\t\n"
-")\n"
-"\n"
-"// Lerper queue item. It interpolates between start and end for the duration\n"
-"// of length in ms. Additionally you can enable swap, which instead of\n"
-"// dequeueing swaps start and end and resets the progress.\n"
-"type Item* = struct {\n"
-"\tstart, end: th.fu\n"
-"\tlength: th.uu\n"
-"\tprogress: th.fu\n"
-"\tswap: bool\n"
-"\tctx: any\n"
-"\tcallback: fn(ctx: any)\n"
-"}\n"
-"\n"
-"// Item\'s constructor\n"
-"fn mk*(start, end: th.fu, length: th.uu, swap: bool = false): Item {\n"
-"\treturn Item{\n"
-"\t\tstart, end, length, 0, swap, null, fn(ctx: any) {}}\n"
-"}\n"
-"\n"
-"// Lerper is a queue of items. It will lerp the first one and if it ends\n"
-"// and doesn\'t have swap enabled, it will dequeue it.\n"
-"type Lerper* = []Item\n"
-"\n"
-"// Removes the first lerper item.\n"
-"fn (l: ^Lerper) dequeue*() {\n"
-"\tswitch len(l^) {\n"
-"\tcase 0:\n"
-"\t\treturn\n"
-"\tcase 1:\n"
-"\t\tl^ = Lerper{}\n"
-"\tdefault:\n"
-"\t\tl^ = slice(l^, 1)\n"
-"\t}\n"
-"}\n"
-"\n"
-"// Adds an item to l\'s queue\n"
-"fn (l: ^Lerper) enqueue*(i: Item) {\n"
-"\tl^ = append(l^, i)\n"
-"}\n"
-"\n"
-"// Interpolates the front by delta. And returns it\'s value.\n"
-"fn (l: ^Lerper) byDelta*(delta: th.uu): th.fu {\n"
-"\tif len(l^) == 0 {\n"
-"\t\treturn 0\n"
-"\t}\n"
-"\n"
-"\t/*for l[0].progress >= 1.0 {\n"
-"\t\tl[0].callback(l[0].ctx)\n"
-"\n"
-"\t\tif l[0].swap {\n"
-"\t\t\ttmp := l[0].start\n"
-"\t\t\tl[0].start = l[0].end\n"
-"\t\t\tl[0].end = tmp\n"
-"\n"
-"\t\t\tl[0].progress = 0\n"
-"\t\t\tbreak\n"
-"\t\t}\n"
-"\n"
-"\t\tl.dequeue()\n"
-"\t\tif len(l^) == 0 {\n"
-"\t\t\treturn 0\n"
-"\t\t}\n"
-"\t}*/\n"
-"\n"
-"\tif l[0].progress >= 1 {\n"
-"\t\tend := l[0].end\n"
-"\t\tl.dequeue()\n"
-"\t\treturn end\n"
-"\t}\n"
-"\n"
-"\tl[0].progress += th.fu(delta)/l[0].length\n"
-"\n"
-"\treturn l[0].progress * (l[0].end-l[0].start) + l[0].start\n"
-"}\n"
-"",
-"//~~\n"
-"// Module for font rendering. Unicode is supported, but only left to right.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~Filtering constants\n"
-"const (\n"
-"\tfilterNearest* = 0\n"
-"\tfilterLinear* = 1\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~opaque Font\n"
-"type Font* = struct { _: ^struct{} }\n"
-"//~~\n"
-"\n"
-"fn umth_font_load(path: str, size: th.fu, filter: uint32): ^struct{}\n"
-"//~~fn load\n"
-"fn load*(path: str, size: th.fu, filter: uint32 = filterLinear): Font {\n"
-"//~~\n"
-"\treturn Font{umth_font_load(path, size, filter)}\n"
-"}\n"
-"\n"
-"//~~fn Font.validate\n"
-"fn (f: ^Font) validate*(): bool {\n"
-"//~~\n"
-"\treturn f._ != null\n"
-"}\n"
-"\n"
-"fn umth_font_draw(font: Font, s: str, x: th.fu, y: th.fu, color: uint32, scale: th.fu)\n"
-"//~~fn Font.draw\n"
-"fn (f: ^Font) draw*(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0) {\n"
-"//~~\n"
-"\tif !f.validate() {\n"
-"\t\tth.__error(\"Invalid font\")\n"
-"\t}\n"
-"\tumth_font_draw(f^, text, pos.x, pos.y, color, scale)\n"
-"}\n"
-"\n"
-"fn umth_font_measure(font: Font, s: str, o: ^th.Vf2)\n"
-"//~~fn Font.measure\n"
-"fn (f: ^Font) measure*(text: str): th.Vf2 {\n"
-"//~~\n"
-"\tif !f.validate() {\n"
-"\t\tth.__error(\"Invalid font\")\n"
-"\t\treturn {}\n"
-"\t}\n"
-"\n"
-"\tvar size: th.Vf2\n"
-"\tumth_font_measure(f^, text, &size)\n"
-"\treturn size\n"
-"}\n"
-"",
-"//~~\n"
-"// Module with useful variables and types.\n"
-"// Variables: time, delta, platform\n"
-"// Constants: black, white, red, green, blue, yellow, magenta, cyan.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"std.um\"\n"
-")\n"
-"\n"
-"//~~Tophat type aliases\n"
-"// standard type for real values\n"
-"type fu* = real32\n"
-"// standard type for integer values\n"
-"type iu* = int32\n"
-"// standard type for unsigned values\n"
-"type uu* = uint32\n"
-"//~~\n"
-"\n"
-"//~~struct Vf2\n"
-"// vector 2\n"
-"type Vf2* = struct {\n"
-"\tx, y: fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mkVf2\n"
-"// Vf2 constructor\n"
-"fn mkVf2*(x: fu = 0, y: fu = 0): Vf2 {\n"
-"\treturn Vf2{x, y}\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn Vf2.rotated\n"
-"// rotates `p` around `origin` with `rot` in degrees\n"
-"fn (p: ^Vf2) rotated*(origin: Vf2, rot: fu): Vf2 {\n"
-"//~~\n"
-"\tangle := (rot * std.pi) / 180\n"
-"\n"
-"\tpos := p^\n"
-"\tpos.x -= origin.x\n"
-"\tpos.y -= origin.y\n"
-"\n"
-"\tx := pos.x * cos(angle) - pos.y * sin(angle)\n"
-"\ty := pos.x * sin(angle) + pos.y * cos(angle)\n"
-"\n"
-"\tpos.x = x + origin.x\n"
-"\tpos.y = y + origin.y\n"
-"\n"
-"\treturn pos\n"
-"}\n"
-"\n"
-"//~~fn Vf2.distanceTo\n"
-"// distance between p1 and p2\n"
-"fn (p1: ^Vf2) distanceTo*(p2: Vf2): fu {\n"
-"//~~\n"
-"\treturn sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))\n"
-"}\n"
-"\n"
-"//~~fn Vf2.angleTo\n"
-"// Angle between p1 and p2\n"
-"fn (p1: ^Vf2) angleTo*(p2: Vf2): real {\n"
-"//~~\n"
-"\tif p1.x == p2.x && p1.y == p2.y { return 0 }\n"
-"\treturn atan2(p2.y - p1.y, p2.x - p1.x) * 180 / std.pi + 180\n"
-"}\n"
-"\n"
-"//~~fn Vf2.abs\n"
-"// Absolute value of a vector.\n"
-"fn (p: ^Vf2) abs*(): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{fabs(p.x), fabs(p.y)}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.round\n"
-"// Rounds a vector.\n"
-"fn (p: ^Vf2) round*(): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{round(p.x), round(p.y)}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.trunc\n"
-"// Truncates a vector.\n"
-"fn (p: ^Vf2) trunc*(): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{trunc(p.x), trunc(p.y)}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.floor\n"
-"// Floors a vector.\n"
-"fn (p: ^Vf2) floor*(): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{floor(p.x), floor(p.y)}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.ceil\n"
-"// Ceils a vector.\n"
-"fn (p: ^Vf2) ceil*(): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{ceil(p.x), ceil(p.y)}\n"
-"}\n"
-"\n"
-"//~~fn vf2f\n"
-"// Creates a vector with both x and y set to f\n"
-"fn vf2f*(f: fu): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{f, f}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.sub\n"
-"// Subtracts a vector from another one.\n"
-"fn (p: ^Vf2) sub*(p2: Vf2): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x - p2.x, p.y - p2.y}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.subf\n"
-"// Subtracts a fu from a vector.\n"
-"fn (p: ^Vf2) subf*(f: fu): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x - f, p.y - f}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.add\n"
-"// Adds a vector to another one.\n"
-"fn (p: ^Vf2) add*(p2: Vf2): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x + p2.x, p.y + p2.y}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.addf\n"
-"// Adds a fu to a vector.\n"
-"fn (p: ^Vf2) addf*(f: fu): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x + f, p.y + f}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.div\n"
-"// Divides a vector by another one.\n"
-"fn (p: ^Vf2) div*(p2: Vf2): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x / p2.x, p.y / p2.y}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.divf\n"
-"// Divides a vector by a fu.\n"
-"fn (p: ^Vf2) divf*(f: fu): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x / f, p.y / f}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.mul\n"
-"// Multiplies a vector by another one.\n"
-"fn (p: ^Vf2) mul*(p2: Vf2): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x * p2.x, p.y * p2.y}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.mulf\n"
-"// Multiplies a vector by a fu.\n"
-"fn (p: ^Vf2) mulf*(f: fu): Vf2 {\n"
-"//~~\n"
-"\treturn Vf2{p.x * f, p.y * f}\n"
-"}\n"
-"\n"
-"//~~fn Vf2.mag\n"
-"// Returns the magnitude of a vector p.\n"
-"fn (p: ^Vf2) mag*(): fu {\n"
-"//~~\n"
-"\treturn sqrt(p.x * p.x + p.y * p.y)\n"
-"}\n"
-"\n"
-"//~~fn Vf2.norm\n"
-"// Normalizes a vector.\n"
-"fn (p: ^Vf2) norm*(): Vf2 {\n"
-"//~~\n"
-"\tif p.x == 0 && p.y == 0 {\n"
-"\t\treturn p^\n"
-"\t}\n"
-"\n"
-"\treturn p.divf(p.mag())\n"
-"}\n"
-"\n"
-"//~~fn Vf2.dot\n"
-"// Calculates dot product between 2 vectors.\n"
-"fn (p: ^Vf2) dot*(q: Vf2): fu {\n"
-"//~~\n"
-"\treturn p.x*q.x + p.y*q.y\n"
-"}\n"
-"\n"
-"//~~struct Transform\n"
-"// Struct defining transformation. Used for example by entities.\n"
-"type Transform* = struct {\n"
-"\tp: Vf2 // position\n"
-"\ts: Vf2 // scale\n"
-"\to: Vf2 // origin\n"
-"\tr: fu // rotation\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mkTransform\n"
-"// Transform constructor\n"
-"fn mkTransform*(p: Vf2, s: Vf2 = Vf2{1, 1}, o: Vf2 = Vf2{0, 0}, r: fu = 0.0): Transform {\n"
-"//~~\n"
-"\treturn Transform{p: p, s: s, o: o, r: r}\n"
-"}\n"
-"\n"
-"fn umth_transform_transform(o, t: ^Transform)\n"
-"//~~fn Transform.transformed\n"
-"// Transforms a transform with another transform.\n"
-"fn (o: ^Transform) transformed*(t: Transform): Transform {\n"
-"//~~\n"
-"\tret := o^\n"
-"\tumth_transform_transform(&ret, &t)\n"
-"\n"
-"\treturn ret\n"
-"}\n"
-"\n"
-"fn umth_transform_vf2(v: ^Vf2, t: ^Transform)\n"
-"//~~fn Vf2.transformed\n"
-"// Transforms a vf2 to another vf2.\n"
-"// Order:\n"
-"// \t1. scale\n"
-"// \t2. rotation\n"
-"// \t3. position\n"
-"//\n"
-"// This allows conversion from a relative to an absolute vf2.\n"
-"fn (v: ^Vf2) transformed*(t: Transform): Vf2 {\n"
-"//~~\n"
-"\tret := v^\n"
-"\tumth_transform_vf2(&ret, &t)\n"
-"\treturn ret\n"
-"}\n"
-"\n"
-"//~~type Quad\n"
-"type Quad* = [4]Vf2\n"
-"//~~\n"
-"\n"
-"fn umth_quad_max(o: ^Vf2, q: ^Quad)\n"
-"//~~fn Quad.getMax\n"
-"// Gets the maximum coordinate.\n"
-"fn (q: ^Quad) getMax*(): Vf2 {\n"
-"//~~\n"
-"\to := Vf2{}\n"
-"\tumth_quad_max(&o, q)\n"
-"\treturn o\n"
-"}\n"
-"\n"
-"fn umth_quad_min(o: ^Vf2, q: ^Quad)\n"
-"//~~fn Quad.getMin\n"
-"// Gets the minimum coordinate.\n"
-"fn (q: ^Quad) getMin*(): Vf2 {\n"
-"//~~\n"
-"\to := Vf2{}\n"
-"\tumth_quad_min(&o, q)\n"
-"\treturn o\n"
-"}\n"
-"\n"
-"//~~fn Quad.getDims\n"
-"// Returns the dimensions of the quad\'s bounding box\n"
-"fn (q: ^Quad) getDims*(): Vf2 {\n"
-"//~~\n"
-"\tmax := q[0]\n"
-"\tmin := q[0]\n"
-"\n"
-"\tmaxmag := max.mag()\n"
-"\tminmag := min.mag()\n"
-"\n"
-"\tfor i:=1; i < len(q^); i++ {\n"
-"\t\tqmag := q[i].mag()\n"
-"\n"
-"\t\tif maxmag < qmag {\n"
-"\t\t\tmax = q[i]\n"
-"\t\t\tmaxmag = qmag\n"
-"\t\t}\n"
-"\n"
-"\t\tif minmag > qmag {\n"
-"\t\t\tmin = q[i]\n"
-"\t\t\tminmag = qmag\n"
-"\t\t}\n"
-"\t}\n"
-"\n"
-"\treturn max.sub(min).abs()\n"
-"}\n"
-"\n"
-"fn umth_th_getglobal(): ^struct{}\n"
-"//~~fn getGlobal\n"
-"// returns a pointer to the th_global. Set this as your extensions thg.\n"
-"fn getGlobal*(): ^struct{} {\n"
-"//~~\n"
-"\treturn umth_th_getglobal()\n"
-"}\n"
-"\n"
-"fn umth_th_getfuncs(): ^struct{}\n"
-"//~~fn getFuncs\n"
-"// returns pointer to tophat functions. Pass this to th_ext_set.\n"
-"fn getFuncs*(): ^struct{} {\n"
-"//~~\n"
-"\treturn umth_th_getfuncs()\n"
-"}\n"
-"\n"
-"//~~var enableErrrors\n"
-"// If true, errors will result in a call to error(), otherwise printf is used.\n"
-"var enableErrors*: bool = true\n"
-"//~~\n"
-"fn __error*(msg: str) {\n"
-"\tif enableErrors {\n"
-"\t\terror(msg)\n"
-"\t} else {\n"
-"\t\tprintf(\"error: %s\\n\", msg)\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~Color constants\n"
-"const (\n"
-"\tblack* = 0xff\n"
-"\twhite* = 0xffffffff\n"
-"\tred* = 0xff0000ff\n"
-"\tgreen* = 0x00ff00ff\n"
-"\tblue* = 0x0000ffff\n"
-"\tyellow* = 0xffff00ff\n"
-"\tmagenta* = 0xff00ffff\n"
-"\tcyan* = 0x00ffffff\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~enum Platform\n"
-"type Platform* = int\n"
-"const (\n"
-"\tPlatformUnknown* = 0\n"
-"\tPlatformLinux*\n"
-"\tPlatformWindows*\n"
-"\tPlatformMacOs*\n"
-"\tPlatformWeb*\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~Misc variables\n"
-"var (\n"
-"\t// time in ms from start of the game\n"
-"\ttime*: uint\n"
-"\t// length of the last frame in ms\n"
-"\tdelta*: int\n"
-"\t// platform tophat is running on\n"
-"\tplatform*: Platform\n"
-")\n"
-"//~~\n"
-"",
-"//~~\n"
-"// A module for importless communication between modules. A signal is a set of\n"
-"// callbacks. You can use signals directly in your own structs if you want\n"
-"// them to be instance specific, of you can use global signals which are\n"
-"// adressed by a string name.\n"
-"//~~\n"
-"\n"
-"//~~type Callback\n"
-"// `args` is a list of arguments passed to the `emit` method.\n"
-"type Callback* = fn(args: []any)\n"
-"//~~\n"
-"\n"
-"//~~type Id\n"
-"type Id* = uint\n"
-"//~~\n"
-"\n"
-"//~~type Signal\n"
-"type Signal* = map[Id]Callback\n"
-"//~~\n"
-"\n"
-"var signals: map[str]Signal\n"
-"var idCounter: Id\n"
-"\n"
-"//~~fn mk\n"
-"// `Signal` constructor\n"
-"fn mk*(): Signal {\n"
-"//~~\n"
-"\treturn make(Signal)\n"
-"}\n"
-"\n"
-"//~~fn Signal.register\n"
-"// Registers a callback to a signal and returns the callback id.\n"
-"fn (this: ^Signal) register*(callback: Callback): Id {\n"
-"//~~\n"
-"\tidCounter++\n"
-"\tthis[idCounter] = callback\n"
-"\n"
-"\treturn idCounter\n"
-"}\n"
-"\n"
-"//~~fn Signal.remove\n"
-"// Removes a callback by id.\n"
-"fn (this: ^Signal) remove*(id: Id) {\n"
-"//~~\n"
-"\tdelete(this^, id)\n"
-"}\n"
-"\n"
-"//~~fn Signal.emit\n"
-"// Emits a signal.\n"
-"fn (this: ^Signal) emit*(args: ..any) {\n"
-"//~~\n"
-"\tfor _,c in this {\n"
-"\t\tc(args)\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~fn Signal.clear\n"
-"// Removes all signal handlers.\n"
-"fn (this: ^Signal) clear*() {\n"
-"//~~\n"
-"\tks := keys(this^)\n"
-"\n"
-"\tfor i, k in ks {\n"
-"\t\tthis ^= delete(this^, k)\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~fn register\n"
-"// Registers a callback to a global signal. There is no need to explicitly\n"
-"// create global signals. Returns id of the added callback\n"
-"fn register*(name: str, callback: Callback): Id {\n"
-"//~~\n"
-"\tif !valid(signals) {\n"
-"\t\tsignals = make(map[str]Signal)\n"
-"\t}\n"
-"\n"
-"\treturn signals[name].register(callback)\n"
-"}\n"
-"\n"
-"//~~fn remove\n"
-"// Removes a callback from a global signal by id.\n"
-"fn remove*(name: str, id: Id) {\n"
-"//~~\n"
-"\tsignals[name].remove(id)\n"
-"}\n"
-"\n"
-"//~~fn remove\n"
-"// Removes all signal handlers from a global signal.\n"
-"fn clear*(name: str) {\n"
-"//~~\n"
-"\tsignals[name].clear()\n"
-"}\n"
-"\n"
-"//~~fn emit\n"
-"// Calls all callbacks associated with the passed global signal name.\n"
-"fn emit*(name: str, args: ..any) {\n"
-"//~~\n"
-"\tif !valid(signals) {\n"
-"\t\tsignals = make(map[str]Signal)\n"
-"\t}\n"
-"\n"
-"\tsignals[name].emit(args)\n"
-"}\n"
-"",
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"image.um\"\n"
-")\n"
-"\n"
-"//~~struct Atlas\n"
-"// Atlas is an image containing tiles in a square grid.\n"
-"type Atlas* = struct {\n"
-"\ti: image.Image // source image\n"
-"\tcs: th.Vf2 // size of a cell in pixels\n"
-"\tdm: th.Vf2 // amount of cells in image\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"// i: source image\n"
-"// dm: amount of cells\n"
-"fn mk*(i: image.Image, dm: th.Vf2): Atlas {\n"
-"//~~\n"
-"\tif !i.validate() {\n"
-"\t\tth.__error(\"Image is not valid\")\n"
-"\t}\n"
-"\n"
-"\ta := Atlas{}\n"
-"\n"
-"\ta.i = i\n"
-"\ta.dm = dm\n"
-"\ta.cs = i.getDims().div(dm)\n"
-"\n"
-"\treturn a\n"
-"}\n"
-"\n"
-"//~~fn Atlas.coords\n"
-"// returns the coordinates of the nth tile\n"
-"fn (a: ^Atlas) coords*(n: int): th.Vf2 {\n"
-"//~~\n"
-"\treturn th.Vf2{ n % trunc(a.dm.x), (n - n % trunc(a.dm.x)) / a.dm.x }\n"
-"}\n"
-"\n"
-"//~~fn Atlas.cropSource\n"
-"// Crops the sourse image to only show a wanted tile\n"
-"fn (a: ^Atlas) cropSource*(at: th.Vf2) {\n"
-"//~~\n"
-"\tif (at.x > a.dm.x || at.y > a.dm.y || at.x * at.y < 0) {\n"
-"\t\treturn\n"
-"\t}\n"
-"\n"
-"\ta.i.crop(\n"
-"\t\tth.Vf2{at.x / a.dm.x, at.y / a.dm.y},\n"
-"\t\tth.Vf2{(at.x+1) / a.dm.x, (at.y+1) / a.dm.y})\n"
-"}\n"
-"\n"
-"//~~enum PackStrategy\n"
-"const (\n"
-"\tPackSquare* = 0\n"
-"\tPackRow*\n"
-"\tPackColumn*\n"
-")\n"
-"//~~\n"
-"\n"
-"fn umth_atlas_pack(a: ^Atlas, images: ^[]image.Image, strategy: int)\n"
-"\n"
-"//~~fn pack\n"
-"// Packs an array of images into an atlas\n"
-"fn pack*(images: []image.Image, strategy: int): Atlas {\n"
-"//~~\n"
-"\tvar a: Atlas\n"
-"\tumth_atlas_pack(&a, &images, strategy)\n"
-"\treturn a\n"
-"}\n"
-"\n"
-"//~~fn Atlas.draw\n"
-"// Draws the tile at `at`\n"
-"fn (a: ^Atlas) draw*(at: th.Vf2, t: th.Transform) {\n"
-"//~~\n"
-"\ta.cropSource(at)\n"
-"\ta.i.draw(t, th.white)\n"
-"\ta.i.crop(th.Vf2{}, th.Vf2{1, 1})\n"
-"}\n"
-"",
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~opaque Shader\n"
-"// Shader allows you to define your own vertex and fragment GLSL shaders. This\n"
-"// is a low-level feature, so it\'s very easy to mess up.\n"
-"// \n"
-"// In tophat, instead of a main function, shaders provide th_vertex and\n"
-"// th_fragment. The signature of th_vertex is:\n"
-"// \n"
-"// ```\n"
-"// vec2 th_vertex(vec2 vert);\n"
-"// ```\n"
-"// \n"
-"// where vert is the position of the vertex taken from the vertex buffer.\n"
-"// The output is the vertex shader output.\n"
-"// \n"
-"// As for fragment shaders, there are two types of them. One for canvas\n"
-"// and one for images. In canvas shaders, the fragment function is very simple:\n"
-"// \n"
-"// ```\n"
-"// vec4 th_fragment(vec4 color);\n"
-"// ```\n"
-"// \n"
-"// Image fragment function looks like this:\n"
-"// \n"
-"// ```\n"
-"// vec4 th_fragment(sampler2D tex, vec2 coord);\n"
-"// ```\n"
-"// \n"
-"// where tex is the texture and coord are the texture coordinates. Be aware to\n"
-"// swap the output of the `texture2D` function. Example:\n"
-"// \n"
-"// ```\n"
-"// texture2D(tex, coord).abgr\n"
-"// ```\n"
-"type Shader* = struct {\n"
-"//~~\n"
-"\thandle: int\n"
-"}\n"
-"\n"
-"\n"
-"//~~Default shader constants\n"
-"const (\n"
-"\tdefaultImageShader* = Shader{1}\n"
-"\tdefaultCanvasShader* = Shader{2}\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~struct Uniform\n"
-"// Represents a GLSL uniform.\n"
-"type Uniform* = struct {\n"
-"\ts: Shader\n"
-"\tl: uint\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn umth_shader_compile_canvas(vertex, fragment: str): int\n"
-"//~~fn mkCanvas\n"
-"// Compiles a canvas shader from source. If there is a compilation error, it\n"
-"// will print something to the console.\n"
-"fn mkCanvas*(vertex, fragment: str): Shader {\n"
-"//~~\n"
-"\treturn Shader{umth_shader_compile_canvas(vertex, fragment)}\n"
-"}\n"
-"\n"
-"fn umth_shader_compile_image(vertex, fragment: str): int\n"
-"//~~fn mkImage\n"
-"// Compiles an image shader from source. If there is a compilation error, it\n"
-"// will print something to the console.\n"
-"fn mkImage*(vertex, fragment: str): Shader {\n"
-"//~~\n"
-"\treturn Shader{umth_shader_compile_image(vertex, fragment)}\n"
-"}\n"
-"\n"
-"fn umth_shader_pick_canvas(handle: int)\n"
-"//~~fn Shader.pickForCanvas\n"
-"// Picks the shader to be used for canvas drawing. Flushes the canvas batch.\n"
-"fn (s: ^Shader) pickForCanvas*() {\n"
-"//~~\n"
-"\tumth_shader_pick_canvas(s.handle)\n"
-"}\n"
-"\n"
-"fn umth_shader_pick_image(handle: int)\n"
-"//~~fn Shader.pickForImage\n"
-"// Picks the shader to be used for image drawing. Flushes the image batch.\n"
-"fn (s: ^Shader) pickForImage*() {\n"
-"//~~\n"
-"\tumth_shader_pick_image(s.handle)\n"
-"}\n"
-"\n"
-"fn umth_shader_get_uniform_location(handle: int, name: str): uint\n"
-"//~~fn Shader.getUniformLocation\n"
-"// Retunrs a uniform by name.\n"
-"fn (s: ^Shader) getUniformLocation*(name: str): Uniform {\n"
-"//~~\n"
-"\treturn Uniform{s^, umth_shader_get_uniform_location(s.handle, name)}\n"
-"}\n"
-"\n"
-"fn umth_shader_set_uniform_int(shandle, uhandle: uint, value: int)\n"
-"//~~fn Uniform.setInt\n"
-"// Sets a uniform to an int value. Flushes both batches.\n"
-"fn (u: ^Uniform) setInt*(value: int) {\n"
-"//~~\n"
-"\tumth_shader_set_uniform_int(u.s.handle, u.l, value)\n"
-"}\n"
-"\n"
-"fn umth_shader_set_uniform_vf2(shandle, uhandle: uint, value: th.Vf2)\n"
-"//~~fn Uniform.setVf2\n"
-"// Sets a uniform to a vf2. Flushes both batches.\n"
-"fn (u: ^Uniform) setVf2*(value: th.Vf2) {\n"
-"//~~\n"
-"\tumth_shader_set_uniform_vf2(u.s.handle, u.l, value)\n"
-"}\n"
-"",
-"//~~\n"
-"// Color operations. Operate on RGBA uint32 values.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"fn umth_hsv2rgb_uint32(h, s, v, a: th.fu): uint32\n"
-"\n"
-"// Now this is hard to decide, but in my opinion executing a C function,\n"
-"// for the current Umka VM would be much better than implementing it in umka itself.\n"
-"// It\'s somewhat less trivial than most other operations like alpha.\n"
-"fn umth_rgb_uint32(r, g, b, a: th.fu): uint32\n"
-"\n"
-"//~~fn hsv\n"
-"// Converts HSV values into RGBA uint32 color.\n"
-"// NOTE: Hue is between 0 and 1\n"
-"fn hsv*(h, s, v: th.fu, a: th.fu = 1.0): uint32 {\n"
-"//~~\n"
-"\treturn umth_hsv2rgb_uint32(h, s, v, a);\n"
-"}\n"
-"\n"
-"//~~fn alpha\n"
-"// Sets alpha of the color c to a value in to.\n"
-"fn alpha*(c: uint32, to: th.fu): uint32 {\n"
-"//~~\n"
-"\treturn (c & 0xFFFFFF00) | (trunc(to * 255) & 0xFF)\n"
-"}\n"
-"\n"
-"//~~fn rgb\n"
-"// Constructs RGBA uint32 from RGBA of reals.\n"
-"fn rgb*(r, g, b: th.fu, a: th.fu = 1.0): uint32 {\n"
-"//~~\n"
-"\treturn umth_rgb_uint32(r, g, b, a)\n"
-"}\n"
-"\n"
-"",
-"//~~\n"
-"// Builtin collision functions. The ic argument stores the collision position.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"th.um\"\n"
-"\t\"rect.um\"\n"
-")\n"
-"\n"
-"fn umth_coll_line_to_line(b1, e1, b2, e2, ic: ^th.Vf2): bool\n"
-"//~~fn lineToLine\n"
-"// Checks for a collision between 2 lines specified by their end points.\n"
-"fn lineToLine*(b1, e1, b2, e2: th.Vf2, ic: ^th.Vf2): bool {\n"
-"//~~\n"
-"\treturn umth_coll_line_to_line(&b1, &e1, &b2, &e2, ic)\n"
-"}\n"
-"\n"
-"fn umth_coll_point_to_quad(p: ^th.Vf2, q: ^th.Quad, ic: ^th.Vf2): bool\n"
-"//~~fn vf2ToQuad\n"
-"// Checks for a collision between a vf2 and a quad.\n"
-"fn vf2ToQuad*(p: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n"
-"//~~\n"
-"\treturn umth_coll_point_to_quad(&p, &q, ic)\n"
-"}\n"
-"\n"
-"fn umth_coll_line_to_quad(b, e: ^th.Vf2, q: ^th.Quad, ic: ^th.Vf2): bool\n"
-"//~~fn lineToQuad\n"
-"// Check for a collision between a line and quad edges.\n"
-"fn lineToQuad*(b, e: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n"
-"//~~\n"
-"\treturn umth_coll_line_to_quad(&b, &e, &q, ic)\n"
-"}\n"
-"\n"
-"fn umth_coll_quad_to_quad(q1, q2: ^th.Quad, ic: ^th.Vf2): bool\n"
-"//~~fn quadToQuad\n"
-"// Check for a collision between two quads.\n"
-"fn quadToQuad*(q1, q2: th.Quad, ic: ^th.Vf2): bool {\n"
-"//~~\n"
-"\treturn umth_coll_quad_to_quad(&q1, &q2, ic)\n"
-"}\n"
-"\n"
-"fn umth_coll_point_to_rect(p: th.Vf2, r: ^rect.Rect): bool\n"
-"//~~fn vf2ToRect\n"
-"// Check for a collision between a vf2 and a rectangle.\n"
-"fn vf2ToRect*(p: th.Vf2, r: rect.Rect): bool {\n"
-"//~~\n"
-"\treturn umth_coll_point_to_rect(p, &r)\n"
-"}\n"
-"\n"
-"fn umth_coll_rect_to_rect(r1, r2: ^rect.Rect): bool\n"
-"//~~fn rectToRect\n"
-"// Check for a collision between two rects\n"
-"fn rectToRect*(r1, r2: rect.Rect): bool {\n"
-"//~~\n"
-"\treturn umth_coll_rect_to_rect(&r1, &r2)\n"
-"}\n"
-"\n"
-"",
-"import(\"image.um\"; \"th.um\")\n"
-"\n"
-"//~~Placeholder images\n"
-"// These images are included with tophat and don\'t have to be loaded.\n"
-"var (\n"
-"\t// an image useful for testing\n"
-"\ttest*: image.Image\n"
-"\t// the image used for the app icon\n"
-"\ticon*: image.Image\n"
-"\t// Windows 95 style button, to be used with ninepatch (image.um) \n"
-"\tbutton*: image.Image\n"
-")\n"
-"//~~\n"
-"\n"
-"fn umth_placeholder_fetch(id: uint32): ^struct{}\n"
-"\n"
-"// **INTERNAL**\n"
-"fn __setup*() {\n"
-"\ttest = image.Image{umth_placeholder_fetch(0)}\n"
-"\ticon = image.Image{umth_placeholder_fetch(1)}\n"
-"\tbutton = image.Image{umth_placeholder_fetch(2)}\n"
-"}\n"
-"\n"
-"",
-"\n"
-"import (\n"
-"\t\"canvas.um\"\n"
-"\t\"color.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"th.um\"\n"
-")\n"
-"\n"
-"//~~struct Mesh\n"
-"// Mesh is a 2d array of bool cells. If a cell is true, the cell can be used\n"
-"// in a path. The mesh is located in a world using the `r` field. A cell can\n"
-"// have an arbitrary size as specified by `s`.\n"
-"// \n"
-"// The mesh can be edited using the `addQuad` method, but it should be trivial\n"
-"// to add your own, similar methods.\n"
-"// \n"
-"// Please use the `mk` constructor to construct a `Mesh`, unless you really\n"
-"// know what you\'re doing.\n"
-"type Mesh* = struct {\n"
-"\t// The mesh data.\n"
-"\td: []bool\n"
-"\t// The dimensions and position of the mesh, r.w == w * s\n"
-"\tr: rect.Rect\n"
-"\t// Width of the mesh. Used to adress the mesh data.\n"
-"\tw: th.uu\n"
-"\t// Scale of one cell (cell is a square)\n"
-"\ts: th.fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn mk\n"
-"// Creates a new nav mesh.\n"
-"// `r`\n"
-"// : the rectangle of the mask\n"
-"// \'s\'\n"
-"// : the scale of the mask\n"
-"fn mk*(r: rect.Rect, s: th.fu): Mesh {\n"
-"//~~\n"
-"\n"
-"\tm := Mesh{}\n"
-"\n"
-"\tm.d = make([]bool, ceil(r.w/s) * ceil(r.h/s))\n"
-"\tfor i in m.d {\n"
-"\t\tm.d[i] = true\n"
-"\t}\n"
-"\n"
-"\tm.w = trunc(r.w/s)\n"
-"\tm.s = s\n"
-"\tm.r = r\n"
-"\n"
-"\treturn m\n"
-"}\n"
-"\n"
-"fn umth_nav_mesh_add_quad(m: ^Mesh, q: ^th.Quad)\n"
-"//~~fn Mesh.addQuad\n"
-"// Sets mask\'s fields overlapping `q` to `false`.\n"
-"fn (m: ^Mesh) addQuad*(q: th.Quad) {\n"
-"//~~\n"
-"\tumth_nav_mesh_add_quad(m, &q)\n"
-"}\n"
-"\n"
-"fn umth_nav_mesh_nav(cameFrom: ^[]th.Vf2, cameFromType: ^void, m: ^Mesh, p1, p2: th.Vf2)\n"
-"//~~fn Mesh.nav\n"
-"// Navigates between `p1` and `p2`. Returns the path as an array of `th.Vf2`s.\n"
-"// If it doesn\'t find any path, or one of the points is outside of the mask,\n"
-"// returns an empty array.\n"
-"fn (m: ^Mesh) nav*(p1, p2: th.Vf2): []th.Vf2 {\n"
-"//~~\n"
-"\tvar cameFrom: []th.Vf2\n"
-"\tumth_nav_mesh_nav(&cameFrom, typeptr([]th.Vf2), m, p1, p2)\n"
-"\t\n"
-"\tpath := []th.Vf2{p2}\n"
-"\tp := p2\n"
-"\tp.x = trunc((p.x - m.r.x) / m.s)\n"
-"\tp.y = trunc((p.y - m.r.y) / m.s)\n"
-"\n"
-"\tp1.x = trunc((p1.x - m.r.x) / m.s)\n"
-"\tp1.y = trunc((p1.y - m.r.y) / m.s)\n"
-"\tfor (p.x != p1.x || p.y != p1.y) && p.x >= 0 && p.y >= 0 {\n"
-"\t\tp = cameFrom[trunc(p.x + p.y*m.w)]\n"
-"\n"
-"\t\tpath = append(path, th.Vf2{\n"
-"\t\t\tp.x * m.s + m.r.x + m.s/2,\n"
-"\t\t\tp.y * m.s + m.r.y + m.s/2 })\n"
-"\t}\n"
-"\n"
-"\tfor i:=0; i < len(path)/2; i++ {\n"
-"\t\tt := path[i]\n"
-"\t\tpath[i] = path[len(path) - i - 1]\n"
-"\t\tpath[len(path) - i - 1] = t\n"
-"\t}\n"
-"\n"
-"\t// path not found is the first element is [-1; -1]\n"
-"\tif len(path) > 0 && path[0].x < m.r.x {\n"
-"\t\treturn []th.Vf2{}\n"
-"\t}\n"
-"\n"
-"\treturn path\n"
-"}\n"
-"\n"
-"//~~fn Mesh.draw\n"
-"// Draws the mesh for debugging purposes.\n"
-"fn (m: ^Mesh) draw*(alpha: real32 = 1.0) {\n"
-"//~~\n"
-"\tfor x:=0; x < m.w; x++ {\n"
-"\t\tfor y:=0; y < len(m.d)/m.w; y += 1 {\n"
-"\t\t\tc := th.cyan\n"
-"\t\t\tif m.d[x + y*m.w] {\n"
-"\t\t\t\tc = th.black\n"
-"\t\t\t}\n"
-"\t\t\tc = color.alpha(c, alpha)\n"
-"\t\t\tcanvas.drawRect(c, rect.mk(m.r.x + x*m.s, m.r.y + y*m.s, m.s, m.s))\n"
-"\t\t}\n"
-"\t}\n"
-"}\n"
-"",
-"//~~\n"
-"// `ui.um` offers an immediate GUI library suitable both for simple game menus\n"
-"// and more complex applications. See the [tutorial](/tut/spritesheet.html)\n"
-"// for example usage.\n"
-"//~~\n"
-"\n"
-"import (\n"
-"\t\"canvas.um\"\n"
-"\t\"coll.um\"\n"
-"\t\"image.um\"\n"
-"\t\"input.um\"\n"
-"\t\"placeholders.um\"\n"
-"\t\"rect.um\"\n"
-"\t\"th.um\"\n"
-"\t\"utf8.um\"\n"
-")\n"
-"\n"
-"//~~struct BoxStyle\n"
-"// `BoxStyle` describes how a box within the GUI is styled. In this case box\n"
-"// can be anything, ranging from a button to a container. By default the box\n"
-"// is drawn using the `image.Image.drawNinepatch` method. However if the image\n"
-"// is invalid, a rectangle with color `color` is drawn.\n"
-"type BoxStyle* = struct {\n"
-"\timg: image.Image\n"
-"\touter, inner: rect.Rect\n"
-"\tscale: th.fu\n"
-"\tcolor: uint32\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~interface Font\n"
-"// This interface is used by all elements that draw text. A `font.Font`\n"
-"// implements this interface.\n"
-"type Font* = interface {\n"
-"\tdraw(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0)\n"
-"\tmeasure(test: str): th.Vf2\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct PixelFont\n"
-"// This struct implement the `Font` interface using the `canvas.um` pixel font.\n"
-"type PixelFont* = struct { }\n"
-"//~~\n"
-"\n"
-"fn (this: ^PixelFont) draw*(t: str, p: th.Vf2, c: uint32, s: th.fu = 1.0) {\n"
-"\tcanvas.drawText(t, p, c, s)\n"
-"}\n"
-"\n"
-"fn (this: ^PixelFont) measure*(t: str): th.Vf2 {\n"
-"\treturn canvas.textSize(t, 1)\n"
-"}\n"
-"\n"
-"//~~struct Style\n"
-"// `Style` is used as a global state for styling the GUI.\n"
-"type Style* = struct {\n"
-"\t// current font\n"
-"\tft: Font\n"
-"\t// font scale\n"
-"\tftScale: th.fu\n"
-"\t// text color\n"
-"\tftColor: uint32\n"
-"\n"
-"\t// Positive box - i. e. unpressed button\n"
-"\tposBox: BoxStyle\n"
-"\t// Negative box - i. e. pressed button, text box\n"
-"\tnegBox: BoxStyle\n"
-"\t// Used to draw containers\n"
-"\tcontainerBox: BoxStyle\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~interface Container\n"
-"// Containers are used to layout elements or other containers.\n"
-"type Container* = interface {\n"
-"\t// This adds a rectangle to the container, and returns the rectangle\n"
-"\t// which was actually added (the container can modify the rectangle).\n"
-"\t// See individual containers for further documentation.\n"
-"\tpushRect(r: rect.Rect): rect.Rect\n"
-"\tgetDims(): rect.Rect\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct Gui\n"
-"// This is the main struct of any UI. Styles and containers are in a stack.\n"
-"type Gui* = struct {\n"
-"\t// user context passed to layout functions\n"
-"\tctx: any\n"
-"\n"
-"\t// the index of the current selection. TODO implement properly\n"
-"\tselection: int\n"
-"\t// true, if the layout is being evaluated, not drawn\n"
-"\tisEval: bool\n"
-"\t// contains more unexported fields\n"
-"//~~\n"
-"\tidx: int\n"
-"\n"
-"\tm1Pressed: bool\n"
-"\tm2Pressed: bool\n"
-"\tm3Pressed: bool\n"
-"\n"
-"\tstyle: []Style\n"
-"\tcontainer: []Container\n"
-"}\n"
-"\n"
-"//~~fn mk\n"
-"// Creates a new gui spanning `r`, with style `s`.\n"
-"fn mk*(r: rect.Rect, s: Style): Gui\n"
-"//~~\n"
-"\n"
-"//~~type LayoutFn\n"
-"// The layout function calls different element or container methods to create\n"
-"// the user interface itself. It is called in the `eval` and `draw`.\n"
-"type LayoutFn* = fn(gui: ^Gui)\n"
-"//~~\n"
-"\n"
-"//~~fn BoxStyle.draw\n"
-"// Draws a rectangle using a BoxStyle\n"
-"fn (this: ^BoxStyle) draw*(r: rect.Rect) {\n"
-"//~~\n"
-"\tif !this.img.validate() {\n"
-"\t\tcanvas.drawRect(this.color, r)\n"
-"\t\treturn\n"
-"\t}\n"
-"\n"
-"\tthis.img.drawNinepatch(this.outer, this.inner, r, this.color,\n"
-"\t\tthis.scale)\n"
-"}\n"
-"\n"
-"//~~fn Gui.pushStyle\n"
-"// Pushes a style onto the style stack.\n"
-"fn (this: ^Gui) pushStyle*(s: Style) {\n"
-"//~~\n"
-"\tthis.style = append(this.style, s)\n"
-"}\n"
-"\n"
-"//~~fn Gui.popStyle\n"
-"// Pops a style from the style stack.\n"
-"fn (this: ^Gui) popStyle*() {\n"
-"//~~\n"
-"\tif len(this.style) > 1 {\n"
-"\t\tthis.style = slice(this.style, 0, len(this.style) - 1)\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~fn Gui.getStyle\n"
-"// Returns a pointer to the style atop the style stack.\n"
-"fn (this: ^Gui) getStyle*(): ^Style {\n"
-"//~~\n"
-"\treturn &this.style[len(this.style) - 1]\n"
-"}\n"
-"\n"
-"//~~fn Gui.getContainer\n"
-"// Returns the container atop the container stack.\n"
-"fn (this: ^Gui) getContainer*(): Container {\n"
-"//~~\n"
-"\treturn this.container[len(this.container) - 1]\n"
-"}\n"
-"\n"
-"//~~fn Gui.pushRect\n"
-"// Shortcut to `this.getContainer().pushRect(r)`\n"
-"fn (this: ^Gui) pushRect*(r: rect.Rect): rect.Rect {\n"
-"//~~\n"
-"\treturn this.getContainer().pushRect(r)\n"
-"}\n"
-"\n"
-"//~~fn Gui.getDims\n"
-"// Shortcut to `this.getContainer().getDims(r)`\n"
-"fn (this: ^Gui) getDims*(): rect.Rect {\n"
-"//~~\n"
-"\treturn this.getContainer().getDims()\n"
-"}\n"
-"\n"
-"//~~fn Gui.dupStyle\n"
-"// Duplicates the current style.\n"
-"fn (this: ^Gui) dupStyle*() {\n"
-"//~~\n"
-"\tthis.pushStyle(this.getStyle()^)\n"
-"}\n"
-"\n"
-"//~~fn Gui.pushContainer\n"
-"// Pushes a container onto the container stack.\n"
-"fn (this: ^Gui) pushContainer*(c: Container) {\n"
-"//~~\n"
-"\tthis.container = append(this.container, c)\n"
-"}\n"
-"\n"
-"//~~fn Gui.popContainer\n"
-"// Pops a container from the container stack.\n"
-"fn (this: ^Gui) popContainer*() {\n"
-"//~~\n"
-"\tif len(this.container) > 1 {\n"
-"\t\tthis.container =\n"
-"\t\t\tslice(this.container, 0, len(this.container) - 1)\n"
-"\t}\n"
-"}\n"
-"\n"
-"fn (this: ^Gui) hover(r: rect.Rect): bool {\n"
-"\treturn coll.vf2ToRect(input.getMousePos(), r)\n"
-"}\n"
-"\n"
-"//~~fn Gui.eval\n"
-"// Runs the evaluation phase on `layout`.\n"
-"fn (this: ^Gui) eval*(layout: LayoutFn) {\n"
-"//~~\n"
-"\tif input.isJustPressed(input.mouse1) { this.m1Pressed = true }\n"
-"\tif input.isJustReleased(input.mouse1) { this.m1Pressed = false }\n"
-"\tif input.isJustPressed(input.mouse2) { this.m2Pressed = true }\n"
-"\tif input.isJustReleased(input.mouse2) { this.m2Pressed = false }\n"
-"\tif input.isJustPressed(input.mouse3) { this.m3Pressed = true }\n"
-"\tif input.isJustReleased(input.mouse3) { this.m3Pressed = false }\n"
-"\n"
-"\tthis.idx = 0\n"
-"\tthis.isEval = true\n"
-"\tlayout(this)\n"
-"\n"
-"\tif this.hover(this.container[0].getDims()) {\n"
-"\t\t\tinput.clear(input.mouse1)\n"
-"\t\t\tinput.clear(input.mouse2)\n"
-"\t\t\tinput.clear(input.mouse3)\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~fn Gui.draw\n"
-"// Runs the draw phase on `layout`.\n"
-"fn (this: ^Gui) draw*(layout: LayoutFn) {\n"
-"//~~\n"
-"\tthis.idx = 0\n"
-"\tthis.isEval = false\n"
-"\tlayout(this)\n"
-"}\n"
-"\n"
-"//~~enum BoxGrow\n"
-"// The different types of \"growing\" the box can do.\n"
-"type BoxGrow* = uint\n"
-"const (\n"
-"\t// Increments by an amount set by the user.\n"
-"\tBoxGrowDimension* = BoxGrow(0)\n"
-"\t// Divides the container into `n` equal parts.\n"
-"\tBoxGrowSubdivision* = BoxGrow(1)\n"
-"\t// Grows the box based on values in the span array.\n"
-"\tBoxGrowSpan* = BoxGrow(2)\n"
-"\tBoxGrowPxSpan* = BoxGrow(3)\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~enum BoxDirection\n"
-"// Direction in which the box will grow.\n"
-"type BoxDirection* = uint\n"
-"const (\n"
-"\tBoxDirectionDown* = BoxDirection(0)\n"
-"\tBoxDirectionRight* = BoxDirection(1)\n"
-"\tBoxDirectionUp* = BoxDirection(2)\n"
-"\tBoxDirectionLeft* = BoxDirection(3)\n"
-")\n"
-"//~~\n"
-"\n"
-"//~~struct BoxConfig\n"
-"// Configuration of the `Box` container.\n"
-"type BoxConfig* = struct {\n"
-"\t// dimension to grow by if `BoxGrowDimension` is used\n"
-"\tdimension: th.fu\n"
-"\t// number of subdivisions if `BoxGrowSubdivisions` is used\n"
-"\tsubdivisions: uint\n"
-"\t// the grow type\n"
-"\tgrowType: BoxGrow\n"
-"\t// the grow direction\n"
-"\tdir: BoxDirection\n"
-"\t// Specifies the values used with BoxGrowSpan nad BoxGrowPxSpan.\n"
-"\t// If BoxGrowSpan is used, 1 equals the size of the box divided by the sum\n"
-"\t// of all spans.\n"
-"\t// If BoxGrowPxSpan is used, 1 equals one pixel.\n"
-"\tspan: []th.fu\n"
-"\t// rect passed to the current container\n"
-"\trect: rect.Rect\n"
-"\t// padding inserted after each element\n"
-"\tpadding: th.fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct Box\n"
-"// `Box` is the main layout. It puts the elements next to each other,\n"
-"// according to the config.\n"
-"//\n"
-"// If the dimensions of the rect passed to `pushRect` are non zero, they will\n"
-"// be kept. Position is always forced.\n"
-"type Box* = struct {\n"
-"\tgrow: th.fu\n"
-"\tspanCursor: int\n"
-"\tdm: rect.Rect\n"
-"\tcfg: BoxConfig\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn (this: ^Box) getGrow(): th.fu {\n"
-"\tswitch this.cfg.growType {\n"
-"\t// These values are constant and can therefore be only calculated once.\n"
-"\tcase BoxGrowDimension:\n"
-"\t\treturn this.grow\n"
-"\tcase BoxGrowSubdivision:\n"
-"\t\treturn this.grow\n"
-"\tcase BoxGrowSpan:\n"
-"\t\t// We store the amount of pixels per a span in the grow array.\n"
-"\t\tsp := this.cfg.span[this.spanCursor]\n"
-"\t\tthis.spanCursor = (this.spanCursor + 1) % len(this.cfg.span)\n"
-"\t\treturn sp * this.grow\n"
-"\tcase BoxGrowPxSpan:\n"
-"\t\tsp := this.cfg.span[this.spanCursor]\n"
-"\t\tthis.spanCursor = (this.spanCursor + 1) % len(this.cfg.span)\n"
-"\t\treturn sp\n"
-"\t}\n"
-"\n"
-"\treturn 0\n"
-"}\n"
-"\n"
-"fn (this: ^Box) pushRect(r: rect.Rect): rect.Rect {\n"
-"\tswitch this.cfg.dir {\n"
-"\tcase BoxDirectionDown:\n"
-"\t\tr.x = this.dm.x\n"
-"\t\tr.y = this.dm.y\n"
-"\n"
-"\t\tif r.h == 0 {\n"
-"\t\t\tr.h = this.getGrow()\n"
-"\t\t}\n"
-"\n"
-"\t\tif r.w == 0 {\n"
-"\t\t\tr.w = this.dm.w\n"
-"\t\t}\n"
-"\n"
-"\t\tthis.dm.y += r.h + this.cfg.padding\n"
-"\tcase BoxDirectionRight:\n"
-"\t\tr.x = this.dm.x\n"
-"\t\tr.y = this.dm.y\n"
-"\n"
-"\t\tif r.h == 0 {\n"
-"\t\t\tr.h = this.dm.h\n"
-"\t\t}\n"
-"\n"
-"\t\tif r.w == 0 {\n"
-"\t\t\tr.w = this.getGrow()\n"
-"\t\t}\n"
-"\n"
-"\t\tthis.dm.x += r.w + this.cfg.padding\n"
-"\tcase BoxDirectionUp:\n"
-"\t\tif r.h == 0 {\n"
-"\t\t\tr.h = this.getGrow()\n"
-"\t\t}\n"
-"\n"
-"\t\tif r.w == 0 {\n"
-"\t\t\tr.w = this.dm.w\n"
-"\t\t}\n"
-"\n"
-"\t\tthis.dm.h -= r.h + this.cfg.padding\n"
-"\t\tr.x = this.dm.x\n"
-"\t\tr.y = this.dm.y + this.dm.h\n"
-"\tcase BoxDirectionLeft:\n"
-"\t\tif r.h == 0 {\n"
-"\t\t\tr.h = this.dm.h\n"
-"\t\t}\n"
-"\n"
-"\t\tif r.w == 0 {\n"
-"\t\t\tr.w = this.getGrow()\n"
-"\t\t}\n"
-"\n"
-"\t\tthis.dm.w -= r.w + this.cfg.padding\n"
-"\t\tr.x = this.dm.x + this.dm.w\n"
-"\t\tr.y = this.dm.y\n"
-"\t}\n"
-"\n"
-"\treturn r\n"
-"}\n"
-"\n"
-"fn (this: ^Box) getDims(): rect.Rect {\n"
-"\treturn this.dm\n"
-"}\n"
-"\n"
-"//~~fn Gui.box\n"
-"// Adds the `Box` container to the gui.\n"
-"fn (gui: ^Gui) box*(cfg: BoxConfig = {\n"
-"\tdimension: 30,\n"
-"\tgrowType: BoxGrowDimension,\n"
-"\tdir: BoxDirectionDown }) {\n"
-"//~~\n"
-"\n"
-"\tb := Box{}\n"
-"\tb.dm = gui.pushRect(cfg.rect)\n"
-"\tb.cfg = cfg\n"
-"\n"
-"\tdm := b.dm.h\n"
-"\tif cfg.dir == BoxDirectionRight || cfg.dir == BoxDirectionLeft {\n"
-"\t\tdm = b.dm.w\n"
-"\t}\n"
-"\tdm += b.cfg.padding\n"
-"\n"
-"\tswitch cfg.growType {\n"
-"\tcase BoxGrowDimension:\n"
-"\t\tb.grow = cfg.dimension\n"
-"\tcase BoxGrowSubdivision:\n"
-"\t\tif cfg.subdivisions == 0 {\n"
-"\t\t\terror(\"Invalid subdivision count\")\n"
-"\t\t}\n"
-"\n"
-"\t\tb.grow = dm / cfg.subdivisions\n"
-"\tcase BoxGrowSpan:\n"
-"\t\ts := th.fu(0)\n"
-"\t\tfor _,v in b.cfg.span {\n"
-"\t\t\ts += v\n"
-"\t\t}\n"
-"\n"
-"\t\tb.grow = dm / s\n"
-"\t}\n"
-"\n"
-"\tif !gui.isEval {\n"
-"\t\tgui.getStyle().containerBox.draw(b.dm)\n"
-"\t}\n"
-"\n"
-"\tgui.pushContainer(b)\n"
-"}\n"
-"\n"
-"//~~struct StackConfig\n"
-"// Configuration for the `Stack` container.\n"
-"type StackConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"\tpadding: th.fu\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct Stack\n"
-"// The stack container puts elements on top of each other.\n"
-"// If a property of the rect passed to `pushRect` is zero, it will be changed\n"
-"// to an equivalent property of the containers\' dimensions (minus the padding),\n"
-"// else it will stay the same. This means stack can be used either to put\n"
-"// multiple elements/containers on top of each other, or for absolutely\n"
-"// positioned elements.\n"
-"type Stack* = struct {\n"
-"\tdm: rect.Rect\n"
-"\tcfg: StackConfig\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn (this: ^Stack) pushRect(r: rect.Rect): rect.Rect {\n"
-"\tr.x += this.dm.x + this.cfg.padding\n"
-"\tr.y += this.dm.y + this.cfg.padding\n"
-"\tif r.w == 0 { r.w = this.dm.w - 2*this.cfg.padding }\n"
-"\tif r.h == 0 { r.h = this.dm.h - 2*this.cfg.padding }\n"
-"\n"
-"\treturn r\n"
-"}\n"
-"\n"
-"fn (this: ^Stack) getDims(): rect.Rect {\n"
-"\treturn this.dm\n"
-"}\n"
-"\n"
-"//~~fn Gui.stack\n"
-"// Adds the `Stack` container to the gui.\n"
-"fn (gui: ^Gui) stack*(cfg: StackConfig = {}) {\n"
-"//~~\n"
-"\tgui.pushContainer(Stack{\n"
-"\t\tdm: gui.pushRect(cfg.rect),\n"
-"\t\tcfg: cfg })\n"
-"\n"
-"\tif !gui.isEval {\n"
-"\t\tgui.getStyle().containerBox.draw(gui.getContainer().getDims())\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~struct ScrollAreaConfig\n"
-"// Configuration for the scroll area.\n"
-"type ScrollAreaConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"\t// scroll speed. Default is 1\n"
-"\tspeed: real32\n"
-"\t// if true, scrolling will be horizontal\n"
-"\thorizontal: bool\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct ScrollArea\n"
-"// Scroll area is a container which allows the user to scroll. It acts as a\n"
-"// stack container, but all the elements are shifted by the scroll.\n"
-"type ScrollArea* = struct {\n"
-"\tdm: rect.Rect\n"
-"\tcfg: ScrollAreaConfig\n"
-"\tscroll: ^real32\n"
-"\tmaxScroll: real32\n"
-"}\n"
-"//~~\n"
-"\n"
-"fn (this: ^ScrollArea) pushRect(r: rect.Rect): rect.Rect {\n"
-"\tif r.x == 0 { r.x = this.dm.x }\n"
-"\tif r.y == 0 { r.y = this.dm.y }\n"
-"\tif this.cfg.horizontal {\n"
-"\t\tif r.w == 0 { r.w = this.maxScroll }\n"
-"\t\tif r.h == 0 { r.h = this.dm.h }\n"
-"\t\treturn { r.x - this.scroll^, r.y, r.w, r.h }\n"
-"\t}\n"
-"\n"
-"\tif r.w == 0 { r.w = this.dm.w }\n"
-"\tif r.h == 0 { r.h = this.maxScroll }\n"
-"\treturn { r.x, r.y - this.scroll^, r.w, r.h }\n"
-"}\n"
-"\n"
-"fn (this: ^ScrollArea) getDims(): rect.Rect {\n"
-"\treturn this.dm\n"
-"}\n"
-"\n"
-"//~~fn Gui.scrollArea\n"
-"// Pushes a scroll area. `scroll` is both input and output value. Both `scroll`\n"
-"// and `maxScroll` are in pixels.\n"
-"fn (gui: ^Gui) scrollArea*(scroll: ^real32, maxScroll: real32, cfg: ScrollAreaConfig = {}) {\n"
-"//~~\n"
-"\tif cfg.speed == 0 {\n"
-"\t\tcfg.speed = 1\n"
-"\t}\n"
-"\n"
-"\tthis := ScrollArea{\n"
-"\t\tdm: gui.pushRect(cfg.rect),\n"
-"\t\tcfg: cfg,\n"
-"\t\tscroll: scroll }\n"
-"\tgui.pushContainer(this)\n"
-"\n"
-"\tdm := this.dm.h\n"
-"\tif this.cfg.horizontal {\n"
-"\t\tdm = this.dm.w\n"
-"\t}\n"
-"\n"
-"\tif maxScroll < dm {\n"
-"\t\tscroll ^= 0\n"
-"\t\treturn\n"
-"\t}\n"
-"\n"
-"\tif gui.isEval && gui.hover(this.dm) {\n"
-"\t\tv := input.getMouseScroll().y\n"
-"\t\tif this.cfg.horizontal {\n"
-"\t\t\tv = input.getMouseScroll().x\n"
-"\t\t}\n"
-"\n"
-"\t\tscroll ^= scroll^ - v*th.delta*this.cfg.speed\n"
-"\t\tif scroll^ < 0 { scroll^ = 0 }\n"
-"\t\tif maxScroll > dm && scroll^ >= maxScroll - dm { scroll^ = maxScroll - dm }\n"
-"\t\tif maxScroll < dm && scroll^ >= maxScroll { scroll^ = maxScroll }\n"
-"\t}\n"
-"}\n"
-"\n"
-"//~~struct ButtonConfig\n"
-"// Configuration for the button.\n"
-"type ButtonConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn Gui.button\n"
-"// Adds a button to the gui. The button acts like a `Stack` container, but it\n"
-"// is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
-"// pressed and the gui is in the eval phase, the return value will be true.\n"
-"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
-"//~~\n"
-"\tgui.stack(StackConfig{ rect: cfg.rect })\n"
-"\tr := gui.getContainer().getDims()\n"
-"\n"
-"\tif gui.isEval {\n"
-"\t\tif gui.hover(r) && input.isJustReleased(input.mouse1) {\n"
-"\t\t\treturn true\n"
-"\t\t}\n"
-"\t\treturn false\n"
-"\t} else {\n"
-"\t\tif gui.hover(r) && gui.m1Pressed {\n"
-"\t\t\tgui.getStyle().negBox.draw(r)\n"
-"\t\t} else {\n"
-"\t\t\tgui.getStyle().posBox.draw(r)\n"
-"\t\t}\n"
-"\t}\n"
-"\n"
-"\treturn false\n"
-"}\n"
-"\n"
-"//~~struct LabelConfig\n"
-"type LabelConfig* = struct {\n"
-"\t// centers the label along the X axis, enables `stretchX`\n"
-"\tcenterX: bool\n"
-"\t// centers the label along the Y axis, enables `stretchY`\n"
-"\tcenterY: bool\n"
-"\t// if false, the rect passed to `pushRect` will have the width of\n"
-"\t// the text, else it will be 0\n"
-"\tstretchX: bool\n"
-"\t// if false, the rect passed to `pushRect` will have the height of\n"
-"\t// the text, else it will be 0\n"
-"\tstretchY: bool\n"
-"\t// forces the rectangle the label will use\n"
-"\trect: rect.Rect\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn Gui.label\n"
-"// Draws a label using the current font style.\n"
-"fn (gui: ^Gui) label*(text: str, cfg: LabelConfig = {\n"
-"//~~\n"
-"\tstretchX: true,\n"
-"\tstretchY: true }) {\n"
-"\n"
-"\tif cfg.centerX { cfg.stretchX = true }\n"
-"\tif cfg.centerY { cfg.stretchY = true }\n"
-"\n"
-"\tr := cfg.rect\n"
-"\tstyle := gui.getStyle()\n"
-"\ttxtSize := style.ft.measure(text).mulf(style.ftScale)\n"
-"\tif r.w == 0 { r.w = txtSize.x }\n"
-"\tif r.h == 0 { r.h = txtSize.y }\n"
-"\n"
-"\tif cfg.stretchX { r.w = 0 }\n"
-"\tif cfg.stretchY { r.h = 0 }\n"
-"\tr = gui.pushRect(r)\n"
-"\n"
-"\tif gui.isEval { return }\n"
-"\n"
-"\tx := r.x\n"
-"\ty := r.y\n"
-"\tif cfg.centerX {\n"
-"\t\tx += (r.w-txtSize.x)/2.0\n"
-"\t}\n"
-"\tif cfg.centerY {\n"
-"\t\ty += (r.h-txtSize.y)/2.0\n"
-"\t}\n"
-"\n"
-"\tstyle.ft.draw(text, th.Vf2{x, y},\n"
-"\t\tstyle.ftColor, style.ftScale)\n"
-"}\n"
-"\n"
-"//~~fn Gui.qbutton\n"
-"// Adds a button with a label to gui.\n"
-"fn (gui: ^Gui) qbutton*(text: str, cfg: ButtonConfig = {}): bool {\n"
-"//~~\n"
-"\tpressed := gui.button(cfg)\n"
-"\tgui.label(text, LabelConfig{centerX: true, centerY: true})\n"
-"\tgui.popContainer()\n"
-"\treturn pressed;\n"
-"}\n"
-"\n"
-"//~~struct TextBoxConfig\n"
-"type TextBoxConfig* = struct {\n"
-"\t// force the rect of the text box\n"
-"\trect: rect.Rect\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~struct TextBox\n"
-"type TextBox* = struct {\n"
-"\t// index of the cursor\n"
-"\tcursor: int\n"
-"\t// contains other unexported rules...\n"
-"//~~\n"
-"\tbuffer: []utf8.Rune\n"
-"}\n"
-"\n"
-"//~~fn TextBox.clear\n"
-"// Clears the textbox\n"
-"fn (this: ^TextBox) clear*() {\n"
-"//~~\n"
-"\tthis.buffer = {}\n"
-"\tthis.cursor = 0\n"
-"}\n"
-"\n"
-"//~~fn TextBox.getBuf()\n"
-"// Get the content of the textbox.\n"
-"fn (this: ^TextBox) getBuf*(): str {\n"
-"//~~\n"
-"\treturn utf8.encode(this.buffer)\n"
-"}\n"
-"\n"
-"//~~fn TextBox.setBuf()\n"
-"// Get the content of the textbox.\n"
-"fn (this: ^TextBox) setBuf*(s: str) {\n"
-"//~~\n"
-"\tthis.buffer = utf8.decode(s)\n"
-"\tthis.cursor = len(this.buffer)\n"
-"}\n"
-"\n"
-"//~~fn Gui.textBox\n"
-"// Adds a single line textbox to the gui.\n"
-"// TODO:\n"
-"// * right-to-left unicode is not supported.\n"
-"// * no selection\n"
-"// * multiline\n"
-"// * copy paste\n"
-"// * stuff like home and end\n"
-"fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) {\n"
-"//~~\n"
-"\tgui.idx++\n"
-"\n"
-"\tr := gui.pushRect(cfg.rect)\n"
-"\n"
-"\thover := gui.hover(r)\n"
-"\n"
-"\tif gui.isEval {\n"
-"\t\tif input.isJustPressed(input.mouse1) && hover {\n"
-"\t\t\tgui.selection = gui.idx\n"
-"\t\t}\n"
-"\n"
-"\t\tif input.isJustPressed(input.mouse1) && !hover &&\n"
-"\t\t\tgui.selection == gui.idx {\n"
-"\t\t\t\tgui.selection = 0\n"
-"\t\t}\n"
-"\n"
-"\t\tif input.isJustPressed(input.key_escape) && gui.selection == gui.idx {\n"
-"\t\t\tgui.selection = 0\n"
-"\t\t}\n"
-"\n"
-"\t\tif gui.selection != gui.idx {\n"
-"\t\t\treturn\n"
-"\t\t}\n"
-"\n"
-"\t\tif input.isJustPressed(input.key_left) ||\n"
-"\t\t\tinput.isPressedRepeat(input.key_left) {\n"
-"\t\t\tif tb.cursor > 0 { tb.cursor-- }\n"
-"\t\t}\n"
-"\n"
-"\t\tif input.isJustPressed(input.key_right) ||\n"
-"\t\t\tinput.isPressedRepeat(input.key_right) {\n"
-"\t\t\tif tb.cursor < len(tb.buffer) { tb.cursor++ }\n"
-"\t\t}\n"
-"\n"
-"\t\tif input.isJustPressed(input.key_backspace) ||\n"
-"\t\t\tinput.isPressedRepeat(input.key_backspace) {\n"
-"\n"
-"\t\t\tif tb.cursor > 0 {\n"
-"\t\t\t\ttb.buffer = append(slice(tb.buffer, 0, tb.cursor - 1), slice(tb.buffer, tb.cursor))\n"
-"\t\t\t\ttb.cursor--\n"
-"\t\t\t}\n"
-"\t\t}\n"
-"\n"
-"\t\tv := true\n"
-"\n"
-"\t\tif input.isPressed(input.key_ctrl) && input.isJustPressedc(\'u\') {\n"
-"\t\t\ttb.clear()\n"
-"\t\t\tv = false\n"
-"\t\t}\n"
-"\n"
-"\t\trunes := utf8.decode(input.getStr())\n"
-"\t\tif len(runes) > 0 && v {\n"
-"\t\t\ttb.buffer = append(slice(tb.buffer, 0, tb.cursor), append(slice(tb.buffer, tb.cursor), runes))\n"
-"\t\t\ttb.cursor += len(runes)\n"
-"\t\t}\n"
-"\n"
-"\t\treturn\n"
-"\t}\n"
-"\n"
-"\tstyle := gui.getStyle()\n"
-"\n"
-"\tstyle.negBox.draw(r)\n"
-"\tcanvas.beginScissorRect(r)\n"
-"\n"
-"\tbuf := utf8.encode(tb.buffer)\n"
-"\tdm := style.ft.measure(buf).mulf(style.ftScale)\n"
-"\n"
-"\tp := th.Vf2{}\n"
-"\tp.y = r.y + r.h/2 - dm.y/2\n"
-"\tc := th.Vf2{r.x, p.y}\n"
-"\n"
-"\tcdmx := style.ft.measure(utf8.encode(slice(tb.buffer, 0, tb.cursor))).x * style.ftScale\n"
-"\tif cdmx < r.w - 2 {\n"
-"\t\tp.x = r.x + 1\n"
-"\t\tc.x = p.x + cdmx\n"
-"\t} else {\n"
-"\t\tc.x = r.x + r.w - 1\n"
-"\t\tp.x = c.x - cdmx\n"
-"\t}\n"
-"\n"
-"\taW := style.ft.measure(\"A\").x * style.ftScale\n"
-"\n"
-"\tstyle.ft.draw(buf, p, style.ftColor, style.ftScale)\n"
-"\tif gui.selection == gui.idx {\n"
-"\t\tcanvas.drawRect(style.ftColor, rect.mk(c.x, c.y, aW / 4, dm.y))\n"
-"\t}\n"
-"\n"
-"\tcanvas.endScissor()\n"
-"}\n"
-"\n"
-"//~~struct ImageConfig\n"
-"// Configuration for the images element. Behaves similarly to labels.\n"
-"type ImageConfig* = struct {\n"
-"\tstretchX, stretchY: bool\n"
-"\tcenterX, centerY: bool\n"
-"\tcolor: uint32\n"
-"\tscale: th.Vf2\n"
-"\trect: rect.Rect\n"
-"}\n"
-"//~~\n"
-"\n"
-"//~~fn Gui.image\n"
-"// Draws an image.\n"
-"fn (gui: ^Gui) image*(i: image.Image, cfg: ImageConfig = {\n"
-"\tstretchX: true,\n"
-"\tstretchY: true,\n"
-"\tcolor: th.white,\n"
-"\tscale: { 1, 1 } }) {\n"
-"//~~\n"
-"\n"
-"\tif cfg.centerX { cfg.stretchX = true }\n"
-"\tif cfg.centerY { cfg.stretchY = true }\n"
-"\n"
-"\tr := cfg.rect\n"
-"\tdm := i.getDims().mul(cfg.scale)\n"
-"\tif r.w == 0 { r.w = dm.x }\n"
-"\tif r.h == 0 { r.h = dm.y }\n"
-"\n"
-"\tif cfg.stretchX { r.w = 0 }\n"
-"\tif cfg.stretchY { r.h = 0 }\n"
-"\n"
-"\tr = gui.pushRect(r)\n"
-"\n"
-"\tif gui.isEval { return }\n"
-"\n"
-"\tx := r.x\n"
-"\ty := r.y\n"
-"\tif cfg.centerX {\n"
-"\t\tx += (r.w - dm.x) / 2\n"
-"\t}\n"
-"\n"
-"\tif cfg.centerY {\n"
-"\t\ty += (r.h - dm.y) / 2\n"
-"\t}\n"
-"\n"
-"\ti.draw(th.Transform{\n"
-"\t\tp: { x, y },\n"
-"\t\ts: cfg.scale }, cfg.color)\n"
-"}\n"
-"\n"
-"//~~fn getDefaultStyle\n"
-"// Returns the default tophat ui style.\n"
-"fn getDefaultStyle*(): Style {\n"
-"//~~\n"
-"\treturn {\n"
-"\t\tft: PixelFont{},\n"
-"\t\tftScale: 1,\n"
-"\t\tftColor: th.black,\n"
-"\n"
-"\t\tposBox: {\n"
-"\t\t\timg: placeholders.button,\n"
-"\t\t\touter: { 0, 0, 5, 5 },\n"
-"\t\t\tinner: { 2, 2, 1, 1 },\n"
-"\t\t\tscale: 1,\n"
-"\t\t\tcolor: th.white },\n"
-"\t\tnegBox: {\n"
-"\t\t\timg: placeholders.button,\n"
-"\t\t\touter: { 5, 0, 5, 5 },\n"
-"\t\t\tinner: { 2, 2, 1, 1 },\n"
-"\t\t\tscale: 1,\n"
-"\t\t\tcolor: th.white },\n"
-"\t\tcontainerBox: {\n"
-"\t\t\tcolor: 0x888888ff } }\n"
-"}\n"
-"\n"
-"//~~fn mk\n"
-"// Creates a GUI instance.\n"
-"fn mk*(r: rect.Rect, s: Style): Gui {\n"
-"//~~\n"
-"\tgui := Gui{}\n"
-"\tgui.pushStyle(s)\n"
-"\tgui.container = []Container{ Stack{ dm: r } }\n"
-"\n"
-"\treturn gui\n"
-"}\n"
-"",
-};
-const char *th_em_modulenames[] = { "anim.um", "audio.um", "csv.um", "ent.um", "image.um", "input.um", "misc.um", "canvas.um", "ray.um", "rect.um", "tilemap.um", "window.um", "particles.um", "lerp.um", "font.um", "th.um", "signal.um", "atlas.um", "shader.um", "color.um", "coll.um", "placeholders.um", "nav.um", "ui.um", };
-int th_em_modulenames_count = 24;
-const char *th_em_misc[] = {
-"BSD 3-Clause License\n"
-"\n"
-"Copyright (c) 2023, Marek Maskarinec\n"
-"All rights reserved.\n"
-"\n"
-"Redistribution and use in source and binary forms, with or without\n"
-"modification, are permitted provided that the following conditions are met:\n"
-"\n"
-"1. Redistributions of source code must retain the above copyright notice, this\n"
-" list of conditions and the following disclaimer.\n"
-"\n"
-"2. Redistributions in binary form must reproduce the above copyright notice,\n"
-" this list of conditions and the following disclaimer in the documentation\n"
-" and/or other materials provided with the distribution.\n"
-"\n"
-"3. Neither the name of the copyright holder nor the names of its\n"
-" contributors may be used to endorse or promote products derived from\n"
-" this software without specific prior written permission.\n"
-"\n"
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n"
-"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
-"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
-"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n"
-"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
-"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n"
-"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n"
-"CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n"
-"OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
-"",
-"v1.2\n"
-"",
-};
-const char *th_em_moduledocs[] = {
-"## struct Anim\n"
-"\n"
-"```\n"
-"type Anim* = struct {\n"
-"\t// the source atlas\n"
-"\tatl: atlas.Atlas\n"
-"\t// the first cell of the animation\n"
-"\tmin: int\n"
-"\t// the last cell of the animation\n"
-"\tmax: int\n"
-"\tfps: real32\n"
-"\t// offset in time\n"
-"\toffset: int\n"
-"}\n"
-"```\n"
-"\n"
-"Anim allows you to animate between individual frames of an atlas.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(atl: atlas.Atlas, fps: int, min: int = 0, max: int = -1 /* len(atl) - 1 */, offset: int = -1 /* th.time */): Anim {\n"
-"```\n"
-"\n"
-"`Anim` constructor\n"
-"\n"
-"\n"
-"## fn Anim.animate\n"
-"\n"
-"```\n"
-"fn (anm: ^Anim) animate*(time: int) {\n"
-"```\n"
-"\n"
-"Crops the base atlas to the cell that should be visible at `time`.\n"
-"\n"
-"\n"
-"## fn Anim.framesPlayed\n"
-"\n"
-"```\n"
-"fn (anm: ^Anim) framesPlayed*(time: int): int {\n"
-"```\n"
-"\n"
-"Returns how many frames were played at `time`.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Module for audio loading and playback.\n"
-"\n"
-"\n"
-"## opaque Sound\n"
-"\n"
-"```\n"
-"type Sound* = struct { _: ^struct{} }\n"
-"```\n"
-"\n"
-"Represents an instance of a playable sound. It is an opaque structure.\n"
-"\n"
-"\n"
-"## fn load\n"
-"\n"
-"```\n"
-"fn load*(path: str, flags: LoadFlag = 0): Sound {\n"
-"```\n"
-"\n"
-"Loads a sounds at path, if there is an error, the underlying pointer\n"
-"will be `NULL` and `validate` will return false.\n"
-"\n"
-"\n"
-"## fn Sound.validate\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) validate*(): bool {\n"
-"```\n"
-"\n"
-"Returns `true` if `s` loaded correctly.\n"
-"\n"
-"\n"
-"## fn Sound.copy\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) copy*(): Sound {\n"
-"```\n"
-"\n"
-"Copies the sound. This will create another sound which can be configured\n"
-"and played independently from the original sound.\n"
-"\n"
-"\n"
-"## fn Sound.isPlaying\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) isPlaying*(): bool {\n"
-"```\n"
-"\n"
-"Returns true if the sound is still playing.\n"
-"\n"
-"\n"
-"## fn Sound.play\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) play*() {\n"
-"```\n"
-"\n"
-"Plays the sound.\n"
-"\n"
-"\n"
-"## fn Sound.start\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) start*(): ^Sound {\n"
-"```\n"
-"\n"
-"The start function allows you to play a single sound multiple times.\n"
-"It will create a copy and return a pointer to it, so you can controll it\n"
-"while it is playing. The returned pointer can be discarded.\n"
-"\n"
-"\n"
-"## fn Sound.stop\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) stop*() {\n"
-"```\n"
-"\n"
-"Stops the sound, but keeps the progress. If you want to start from the\n"
-"begginning, use `audio.Sound.seekToFrame(0)`.\n"
-"\n"
-"\n"
-"## fn Sound.setVol\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setVol*(vol: real32) {\n"
-"```\n"
-"\n"
-"Sets the volume as a multiplier of the base volume.\n"
-"\n"
-"\n"
-"## fn Sound.setPan\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setPan*(pan: real32) {\n"
-"```\n"
-"\n"
-"Sets the pan of the sound.\n"
-"\n"
-"\n"
-"## fn Sound.setPitch\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setPitch*(pitch: real32) {\n"
-"```\n"
-"\n"
-"Sets the pitch of the sound.\n"
-"\n"
-"\n"
-"## fn Sound.setLooping\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setLooping*(looping: bool) {\n"
-"```\n"
-"\n"
-"Sets whether the sound will loop upon finishing.\n"
-"\n"
-"\n"
-"## fn Sound.seekToFrame\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) seekToFrame*(frame: uint) {\n"
-"```\n"
-"\n"
-"Seeks to a specified PCM frame.\n"
-"\n"
-"\n"
-"## fn Sound.frameCount\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) frameCount*(): uint {\n"
-"```\n"
-"\n"
-"Returns length of the sound in PCM frames.\n"
-"\n"
-"\n"
-"## fn Sound.lengthMs\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) lengthMs*(): uint {\n"
-"```\n"
-"\n"
-"Returns length of the sound in ms.\n"
-"\n"
-"\n"
-"## fn Sound.setStartTimeMs\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setStartTimeMs*(t: uint) {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Sound.setStopTimeMs\n"
-"\n"
-"```\n"
-"fn (s: ^Sound) setStopTimeMs*(t: uint) {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"A CSV parser, which also works for similar formats. It doesn\'t support\n"
-"quotes, but you can escape characters using a backslash.\n"
-"\n"
-"\n"
-"## fn parse\n"
-"\n"
-"```\n"
-"fn parse*(inp: str, sep: char = \',\'): [][]str {\n"
-"```\n"
-"\n"
-"Parses input into a 2d string array.\n"
-"\n"
-"\n"
-"## fn encode\n"
-"\n"
-"```\n"
-"fn encode*(inp: [][]str, sep: char = \',\'): str {\n"
-"```\n"
-"\n"
-"Converts 2d array to csv string.\n"
-"\n"
-"\n"
-"",
-"## struct Ent\n"
-"\n"
-"```\n"
-"type Ent* = struct {\n"
-"\t// used as a collider, used as backup when invalid image is supplied\n"
-"\tr: rect.Rect\n"
-"\t// used in drawing\n"
-"\ti: image.Image\n"
-"\t// used to transform and translate the image and rect\n"
-"\tt: th.Transform\n"
-"\t// used as a color of the rect and a color filter for the image\n"
-"\tc: uint32\n"
-"}\n"
-"```\n"
-"\n"
-"Entity is the main game object. It features drawing and collisions.\n"
-"Every entity has an image used for drawing and a rectangle used\n"
-"for collisions. It also has a transform used for transforming it\'s image\n"
-"and rectangle.\n"
-"\n"
-"\n"
-"## struct Coll\n"
-"\n"
-"```\n"
-"type Coll* = struct {\n"
-"\tindex: th.uu\n"
-"\tpos: th.Vf2\n"
-"}\n"
-"```\n"
-"\n"
-"Value returned by get coll. It contains a position where the collision\n"
-"happened and the index of the entity involved in said collision.\n"
-"\n"
-"\n"
-"## fn Ent.draw\n"
-"\n"
-"```\n"
-"fn (e: ^Ent) draw*() {\n"
-"```\n"
-"\n"
-"Draws the entity onto the screen.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(img: image.Image = image.Image{}, t: th.Transform = th.Transform{ s: th.Vf2{1, 1} }): Ent {\n"
-"```\n"
-"\n"
-"ent\'s constructor\n"
-"\n"
-"\n"
-"## fn Ent.getColl\n"
-"\n"
-"```\n"
-"fn (e: ^Ent) getColl*(s: []^Ent, maxColls: th.uu): []Coll {\n"
-"```\n"
-"\n"
-"Checks collisions of e with entities in s. Checks at max maxColl collisions.\n"
-"If s contains e, the collision won\'t be returned.\n"
-"\n"
-"\n"
-"## fn Ent.animate\n"
-"\n"
-"```\n"
-"fn (e: ^Ent) animate*(fps: int, frames: ^[]image.Image, t: int) {\n"
-"```\n"
-"\n"
-"Animates the entity\'s image with one of the `anim` array. Won\'t begin on\n"
-"the first frame. If you want that, use anim.Anim.\n"
-"\n"
-"\n"
-"",
-"## opaque Image\n"
-"\n"
-"```\n"
-"type Image* = struct{ _: ^struct{} }\n"
-"```\n"
-"\n"
-"Represents a drawable image. It is an opaque structure.\n"
-"Images support a color filter. It is applied by multiplying the color\n"
-"of each pixel with the filter.\n"
-"\n"
-"\n"
-"## opaque RenderTarget\n"
-"\n"
-"```\n"
-"type RenderTarget* = struct { _: ^struct{} }\n"
-"```\n"
-"\n"
-"An image you can render to.\n"
-"\n"
-"\n"
-"## fn createRenderTarget\n"
-"\n"
-"```\n"
-"fn createRenderTarget*(size: th.Vf2, filter: int): RenderTarget {\n"
-"```\n"
-"\n"
-"Creates a render target you can draw to, like to a window.\n"
-"Filter specifies specfifies filtering for resulting image.\n"
-"Image can be retrieved via `toImage`.\n"
-"\n"
-"\n"
-"## fn RenderTarget.end\n"
-"\n"
-"```\n"
-"fn (rt: ^RenderTarget) begin*() {\n"
-"```\n"
-"\n"
-"Begins the render target rendering pass.\n"
-"\n"
-"\n"
-"## fn RenderTarget.end\n"
-"\n"
-"```\n"
-"fn (rt: ^RenderTarget) end*(wp: th.Vf2) {\n"
-"```\n"
-"\n"
-"Ends the render target rendering pass.\n"
-"\n"
-"\n"
-"## fn RenderTarget.toImage\n"
-"\n"
-"```\n"
-"fn (rt: ^RenderTarget) toImage*(): Image {\n"
-"```\n"
-"\n"
-"Returns the image of the render target.\n"
-"Do not call `setfilter` on the resulting image.\n"
-"\n"
-"\n"
-"## fn load\n"
-"\n"
-"```\n"
-"fn load*(path: str): Image {\n"
-"```\n"
-"\n"
-"Loads an image at path.\n"
-"\n"
-"\n"
-"## fn Image.validate\n"
-"\n"
-"```\n"
-"fn (i: ^Image) validate*(): bool {\n"
-"```\n"
-"\n"
-"Returns true, if i\'s handle points to an image.\n"
-"\n"
-"\n"
-"## fn Image.flipv\n"
-"\n"
-"```\n"
-"fn (i: ^Image) flipv*(flip: bool) {\n"
-"```\n"
-"\n"
-"Flips image on it\'s vertical axis.\n"
-"\n"
-"\n"
-"## fn Image.fliph\n"
-"\n"
-"```\n"
-"fn (i: ^Image) fliph*(flip: bool) {\n"
-"```\n"
-"\n"
-"Flips image on it\'s horizontal axis.\n"
-"\n"
-"\n"
-"## fn Image.draw\n"
-"\n"
-"```\n"
-"fn (i: ^Image) draw*(t: th.Transform, color: uint32 = th.white) {\n"
-"```\n"
-"\n"
-"Draws the image in screen coordinates. It transforms it with t and\n"
-"applies color as a color filter.\n"
-"\n"
-"\n"
-"## fn Image.drawNinepatch\n"
-"\n"
-"```\n"
-"fn (i: ^Image) drawNinepatch*(outer, inner, dest: rect.Rect, color: uint32 = th.white, scale: real = 1.0) {\n"
-"```\n"
-"\n"
-"Draws \"nine-patch\" image.\n"
-"`outer` specifies the texture coordinates of the outer rect of source image,\n"
-"`inner` specifies coordinates of inner rect of source image, positioned relative to `outer`.\n"
-"You can tint with `color`.\n"
-"\n"
-"\n"
-"\n"
-"## fn Image.drawOnQuad\n"
-"\n"
-"```\n"
-"fn (i: ^Image) drawOnQuad*(q: th.Quad, color: uint32 = th.white) {\n"
-"```\n"
-"\n"
-"Draws the image on top of a quad with corners of the image positioned\n"
-"on the verticies of the quad.\n"
-"\n"
-"\n"
-"## fn Image.getDims\n"
-"\n"
-"```\n"
-"fn (i: ^Image) getDims*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns width and heigth.\n"
-"\n"
-"\n"
-"## fn Image.crop\n"
-"\n"
-"```\n"
-"fn (i: ^Image) crop*(tl, br: th.Vf2) {\n"
-"```\n"
-"\n"
-"Crops an image. Coordinates are between 0, 0 (top left) and\n"
-"1, 1 (bottom right)\n"
-"\n"
-"\n"
-"## fn Image.cropPx\n"
-"\n"
-"```\n"
-"fn (i: ^Image) cropPx*(tr, br: th.Vf2) {\n"
-"```\n"
-"\n"
-"Same as `Image.crop`, but the positions are in pixels.\n"
-"\n"
-"\n"
-"## fn Image.cropRect\n"
-"\n"
-"```\n"
-"fn (i: ^Image) cropRect*(r: rect.Rect) {\n"
-"```\n"
-"\n"
-"Same as `Image.crop`, but uses a rect instead of two positions.\n"
-"\n"
-"\n"
-"## fn Image.cropQuad\n"
-"\n"
-"```\n"
-"fn (i: ^Image) cropQuad*(q: th.Quad) {\n"
-"```\n"
-"\n"
-"Crop an image using a quad.\n"
-"\n"
-"\n"
-"## fn Image.getCropQuad\n"
-"\n"
-"```\n"
-"fn (i: ^Image) getCropQuad*(): th.Quad {\n"
-"```\n"
-"\n"
-"Crop an image using a quad.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(data: []uint32, dm: th.Vf2): Image {\n"
-"```\n"
-"\n"
-"Creates an image from raw data.\n"
-"\n"
-"\n"
-"## fn Image.copy\n"
-"\n"
-"```\n"
-"fn (i: ^Image) copy*(): Image {\n"
-"```\n"
-"\n"
-"Copies image into a new one.\n"
-"\n"
-"\n"
-"## fn Image.setfilter\n"
-"\n"
-"```\n"
-"fn (i: ^Image) setfilter*(filter: int) {\n"
-"```\n"
-"\n"
-"Sets a mag/min filter. 0 is nearest, others are linear.\n"
-"This function will regenerate the texture. This means it shouldn\'t be\n"
-"used in a loop.\n"
-"https://learnopengl.com/img/getting-started/texture_filtering.png\n"
-"left is nearest, right is linear.\n"
-"\n"
-"\n"
-"## fn Image.setData\n"
-"\n"
-"```\n"
-"fn (i: ^Image) setData*(data: []uint32, dm: th.Vf2) {\n"
-"```\n"
-"\n"
-"Updates the image data. dm are the dimensions of the new image.\n"
-"The new image doesn\'t have to be the same size as the old one.\n"
-"\n"
-"\n"
-"## fn Image.getData\n"
-"\n"
-"```\n"
-"fn (i: ^Image) getData*(): []uint32 {\n"
-"```\n"
-"\n"
-"Gets the image data. This downloads the data from the GPU on **each call**.\n"
-"Don\'t use in performance critical sections.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Module for getting keyboard and mouse input.\n"
-"is* functions return info based on a us QWERTY layout. They are supposed to\n"
-"be used for game controls. For text input use getStr.\n"
-"\n"
-"\n"
-"## Keycode constants\n"
-"\n"
-"```\n"
-"const (\n"
-" mouse1* = 1 // NOTE: mouse 2 and 3 key codes are swapped\n"
-" mouse2* = 3 // because sokol uses 3 for middle mouse\n"
-" mouse3* = 2 // button.\n"
-"\n"
-" key_ctrl* = 16\n"
-" key_shift* = 17\n"
-" key_alt* = 18\n"
-"\n"
-" key_space* = 32\n"
-" key_apostrophe* = 39 /* \' */\n"
-" key_comma* = 44 /* , */\n"
-" key_minus* = 45 /* - */\n"
-" key_dot* = 46 /* . */\n"
-" key_slash* = 47 /* / */\n"
-" key_0* = 48\n"
-" key_1* = 49\n"
-" key_2* = 50\n"
-" key_3* = 51\n"
-" key_4* = 52\n"
-" key_5* = 53\n"
-" key_6* = 54\n"
-" key_7* = 55\n"
-" key_8* = 56\n"
-" key_9* = 57\n"
-" key_semicolon* = 59 /* ; */\n"
-" key_equal* = 61 /* = */\n"
-" key_a* = 65\n"
-" key_b* = 66\n"
-" key_c* = 67\n"
-" key_d* = 68\n"
-" key_e* = 69\n"
-" key_f* = 70\n"
-" key_g* = 71\n"
-" key_h* = 72\n"
-" key_i* = 73\n"
-" key_j* = 74\n"
-" key_k* = 75\n"
-" key_l* = 76\n"
-" key_m* = 77\n"
-" key_n* = 78\n"
-" key_o* = 79\n"
-" key_p* = 80\n"
-" key_q* = 81\n"
-" key_r* = 82\n"
-" key_s* = 83\n"
-" key_t* = 84\n"
-" key_u* = 85\n"
-" key_v* = 86\n"
-" key_w* = 87\n"
-" key_x* = 88\n"
-" key_y* = 89\n"
-" key_z* = 90\n"
-" key_left_bracket* = 91 /* [ */\n"
-" key_backslash* = 92 /* \\ */\n"
-" key_right_bracket* = 93 /* ] */\n"
-" key_grave_accent* = 96 /* ` */\n"
-" key_world_1* = 161 /* non-US #1 */\n"
-" key_world_2* = 162 /* non-US #2 */\n"
-" key_escape* = 256\n"
-" key_enter* = 257\n"
-" key_tab* = 258\n"
-" key_backspace* = 259\n"
-" key_insert* = 260\n"
-" key_delete* = 261\n"
-" key_right* = 262\n"
-" key_left* = 263\n"
-" key_down* = 264\n"
-" key_up* = 265\n"
-" key_page_up* = 266\n"
-" key_page_down* = 267\n"
-" key_home* = 268\n"
-" key_end* = 269\n"
-" key_caps_lock* = 280\n"
-" key_scroll_lock* = 281\n"
-" key_num_lock* = 282\n"
-" key_print_screen* = 283\n"
-" key_pause* = 284\n"
-"\tkey_fn* = 289\n"
-" key_fn1* = 290\n"
-" key_fn2* = 291\n"
-" key_fn3* = 292\n"
-" key_fn4* = 293\n"
-" key_fn5* = 294\n"
-" key_fn6* = 295\n"
-" key_fn7* = 296\n"
-" key_fn8* = 297\n"
-" key_fn9* = 298\n"
-" key_fn10* = 299\n"
-" key_fn11* = 300\n"
-" key_fn12* = 301\n"
-" key_fn13* = 302\n"
-" key_fn14* = 303\n"
-" key_fn15* = 304\n"
-" key_fn16* = 305\n"
-" key_fn17* = 306\n"
-" key_fn18* = 307\n"
-" key_fn19* = 308\n"
-" key_fn20* = 309\n"
-" key_fn21* = 310\n"
-" key_fn22* = 311\n"
-" key_fn23* = 312\n"
-" key_fn24* = 313\n"
-" key_fn25* = 314\n"
-" key_kp_0* = 320\n"
-" key_kp_1* = 321\n"
-" key_kp_2* = 322\n"
-" key_kp_3* = 323\n"
-" key_kp_4* = 324\n"
-" key_kp_5* = 325\n"
-" key_kp_6* = 326\n"
-" key_kp_7* = 327\n"
-" key_kp_8* = 328\n"
-" key_kp_9* = 329\n"
-" key_kp_decimal* = 330\n"
-" key_kp_divide* = 331\n"
-" key_kp_multiply* = 332\n"
-" key_kp_subtract* = 333\n"
-" key_kp_add* = 334\n"
-" key_kp_enter* = 335\n"
-" key_kp_equal* = 336\n"
-" key_left_shift* = 340\n"
-" key_left_control* = 341\n"
-" key_left_alt* = 342\n"
-" key_left_super* = 343\n"
-" key_right_shift* = 344\n"
-" key_right_control* = 345\n"
-" key_right_alt* = 346\n"
-" key_right_super* = 347\n"
-" key_menu* = 348\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn getMousePos\n"
-"\n"
-"```\n"
-"fn getMousePos*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the position of mouse cursor in relation to the screen.\n"
-"\n"
-"\n"
-"## fn getGlobalMousePos\n"
-"\n"
-"```\n"
-"fn getGlobalMousePos*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the position of mouse cursor in relation to cam.\n"
-"\n"
-"\n"
-"## fn isPressed\n"
-"\n"
-"```\n"
-"fn isPressed*(code: int): bool {\n"
-"```\n"
-"\n"
-"Returns true if key is pressed. Either use codes defined in the file above,\n"
-"or pass lower case char/number.\n"
-"\n"
-"\n"
-"## fn isPressedc\n"
-"\n"
-"```\n"
-"fn isPressedc*(code: char): bool {\n"
-"```\n"
-"\n"
-"Like `isPressed`, but you can pass char as the code.\n"
-"\n"
-"\n"
-"## fn isJustPressed\n"
-"\n"
-"```\n"
-"fn isJustPressed*(code: int): bool {\n"
-"```\n"
-"\n"
-"Returns, whether code was just pressed this loop.\n"
-"\n"
-"\n"
-"## fn isJustPressedc\n"
-"\n"
-"```\n"
-"fn isJustPressedc*(code: char): bool {\n"
-"```\n"
-"\n"
-"Like `isJustPressed`, but you can pass char as the code.\n"
-"\n"
-"\n"
-"## fn isPressedRepeat\n"
-"\n"
-"```\n"
-"fn isPressedRepeat*(code: int): bool {\n"
-"```\n"
-"\n"
-"Returns, whether code was just pressed this loop, with key repeat.\n"
-"\n"
-"\n"
-"## fn isPressedRepeatc\n"
-"\n"
-"```\n"
-"fn isPressedRepeatc*(code: char): bool {\n"
-"```\n"
-"\n"
-"Like `isPressedRepeat`, but you can pass char as the code.\n"
-"\n"
-"\n"
-"## fn isJustReleased\n"
-"\n"
-"```\n"
-"fn isJustReleased*(code: int): bool {\n"
-"```\n"
-"\n"
-"Returns true if a key was just released.\n"
-"\n"
-"\n"
-"## fn isJustReleasedc\n"
-"\n"
-"```\n"
-"fn isJustReleasedc*(code: char): bool {\n"
-"```\n"
-"\n"
-"Like `isJustReleased`, but you can pass char as the code.\n"
-"\n"
-"\n"
-"## fn clear\n"
-"\n"
-"```\n"
-"fn clear*(code: int) {\n"
-"```\n"
-"\n"
-"Clears both the pressed and justPressed state of a code.\n"
-"\n"
-"\n"
-"## fn clearc\n"
-"\n"
-"```\n"
-"fn clearc*(code: char) {\n"
-"```\n"
-"\n"
-"Like `clear`, but you can pass char as the code.\n"
-"\n"
-"\n"
-"## fn getStr\n"
-"\n"
-"```\n"
-"fn getStr*(): str {\n"
-"```\n"
-"\n"
-"Returns a string entered by the user in the last cycle.\n"
-"\n"
-"\n"
-"## fn getMouseDelta\n"
-"\n"
-"```\n"
-"fn getMouseDelta*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the difference between mouse positions in the last cycle. Will work\n"
-"even if `window.freezeCursor` is enabled.\n"
-"\n"
-"\n"
-"## fn getMouseScroll\n"
-"\n"
-"```\n"
-"fn getMouseScroll*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the scroll wheel value\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Misc functions.\n"
-"\n"
-"\n"
-"## fn readall\n"
-"\n"
-"```\n"
-"fn readall*(path: str): str {\n"
-"```\n"
-"\n"
-"Reads file content into a string.\n"
-"\n"
-"\n"
-"## fn stepify\n"
-"\n"
-"```\n"
-"fn stepify*(val, step: th.fu): th.fu {\n"
-"```\n"
-"\n"
-"Snaps a value to step.\n"
-"\n"
-"\n"
-"## fn maxf\n"
-"\n"
-"```\n"
-"fn maxf*(a, b: th.fu): th.fu {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn minf\n"
-"\n"
-"```\n"
-"fn minf*(a, b: th.fu): th.fu {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Canvas library allowing for drawing basic shapes. Coordinates are based on\n"
-"the screen.\n"
-"\n"
-"\n"
-"## fn drawText\n"
-"\n"
-"```\n"
-"fn drawText*(text: str, pos: th.Vf2, color: uint32, size: th.fu) {\n"
-"```\n"
-"\n"
-"Draws a basic pixel text. Only ascii is supported.\n"
-"\n"
-"\n"
-"## fn textSize\n"
-"\n"
-"```\n"
-"fn textSize*(text: str, scale: th.fu): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the size of text taken by an equivalent drawText call.\n"
-"\n"
-"\n"
-"## fn drawRect\n"
-"\n"
-"```\n"
-"fn drawRect*(color: uint32, r: rect.Rect) {\n"
-"```\n"
-"\n"
-"Draws a Rectangle.\n"
-"\n"
-"\n"
-"## fn drawLine\n"
-"\n"
-"```\n"
-"fn drawLine*(color: uint32, b, e: th.Vf2, thickness: th.fu) {\n"
-"```\n"
-"\n"
-"Draws a line.\n"
-"\n"
-"\n"
-"## fn drawRectLines\n"
-"\n"
-"```\n"
-"fn drawRectLines*(color: uint32, r: rect.Rect, thickness: real32 = 1.0) {\n"
-"```\n"
-"\n"
-"Draws rect border.\n"
-"\n"
-"\n"
-"## fn drawQuad\n"
-"\n"
-"```\n"
-"fn drawQuad*(color: uint32, q: th.Quad) {\n"
-"```\n"
-"\n"
-"Draws a convex quad.\n"
-"\n"
-"\n"
-"## fn beginScissorRect\n"
-"\n"
-"```\n"
-"fn beginScissorRect*(r: rect.Rect, debug: bool = false) {\n"
-"```\n"
-"\n"
-"Disable rendering outside of rect `r`\n"
-"\n"
-"\n"
-"## fn endScissor\n"
-"\n"
-"```\n"
-"fn endScissor*() {\n"
-"```\n"
-"\n"
-"Stops cropping\n"
-"\n"
-"\n"
-"",
-"## struct Ray\n"
-"\n"
-"```\n"
-"type Ray* = struct {\n"
-"\tpos: th.Vf2\n"
-"\tl: th.fu // length\n"
-"\tr: th.fu // rotation\n"
-"}\n"
-"```\n"
-"\n"
-"Ray is a line specified by an origin, length and a rotation.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(pos: th.Vf2, l: th.fu, r: th.fu = 0.0): Ray {\n"
-"```\n"
-"\n"
-"Ray constructor\n"
-"\n"
-"\n"
-"## fn Ray.getColl\n"
-"\n"
-"```\n"
-"fn (r: ^Ray) getColl*(s: []^ent.Ent, maxColls: th.uu): []ent.Coll {\n"
-"```\n"
-"\n"
-"Checks the ray\'s collisions with a scene of ents. Similar to\n"
-"`ent.Ent.getColl`\n"
-"\n"
-"\n"
-"## fn Ray.getTilemapColl\n"
-"\n"
-"```\n"
-"fn (r: ^Ray) getTilemapColl*(t: tilemap.Tilemap, ic: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Gets ray\'s collision to a tilemap.\n"
-"\n"
-"\n"
-"## fn Ray.getEnd\n"
-"\n"
-"```\n"
-"fn (r: ^Ray) getEnd*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the other point of the ray.\n"
-"\n"
-"\n"
-"## fn Ray.draw\n"
-"\n"
-"```\n"
-"fn (r: ^Ray) draw*(color: uint32, thickness: th.fu) {\n"
-"```\n"
-"\n"
-"Draws the ray to the screen.\n"
-"\n"
-"\n"
-"",
-"## struct Rect\n"
-"\n"
-"```\n"
-"type Rect* = struct {\n"
-"\tx, y, w, h: th.fu\n"
-"}\n"
-"```\n"
-"\n"
-"A set of points representing a rectangle.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(x, y, w, h: th.fu): Rect {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn fromVf2*(p: th.Vf2, dm: th.Vf2): Rect {\n"
-"```\n"
-"\n"
-"Creates a rect from two Vf2s - the position and the dimensions.\n"
-"\n"
-"\n"
-"## fn Rect.getPos\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) getPos*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Rect.getDims\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) getDims*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Rect.getEnd\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) getEnd*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"returns where the second point of the rectangle lies.\n"
-"\n"
-"\n"
-"## fn Rect.transformed\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) transformed*(t: th.Transform): th.Quad {\n"
-"```\n"
-"\n"
-"Transforms a rect into a quad.\n"
-"Order:\n"
-"1. scale\n"
-"2. rotation\n"
-"3. position\n"
-"\n"
-"\n"
-"## fn Rect.shrink\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) shrink*(p: th.Vf2): Rect {\n"
-"```\n"
-"\n"
-"Shrink the rectangle by `p` pixels from all sides.\n"
-"\n"
-"\n"
-"## fn Rect.shift\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) shift*(p: th.Vf2): Rect {\n"
-"```\n"
-"\n"
-"Shift the rectangle by `p` pixels.\n"
-"\n"
-"\n"
-"## fn Rect.scale\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) scale*(p: th.Vf2): Rect {\n"
-"```\n"
-"\n"
-"Multiply the dimensions by `p`\n"
-"\n"
-"\n"
-"## fn Rect.center\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) center*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns the position, which is the center of the rect.\n"
-"\n"
-"\n"
-"## fn Rect.centerWithinRect\n"
-"\n"
-"```\n"
-"fn (r: ^Rect) centerWithinRect*(child: Rect): Rect {\n"
-"```\n"
-"\n"
-"Centers `child` with the rect `r`.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Tilemaps allow for easy level construction and fast collisions. You can even\n"
-"use them for some games instead of entities (tetris comes to mind)\n"
-"\n"
-"\n"
-"## Direction constants used for autotile\n"
-"\n"
-"```\n"
-"const (\n"
-"\ttop* = 1\n"
-"\tright* = 2\n"
-"\tbot* = 4\n"
-"\tleft* = 8\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## struct Tilemap\n"
-"\n"
-"```\n"
-"type Tilemap* = struct {\n"
-"\tatlas: atlas.Atlas\n"
-"\tpos: th.Vf2\n"
-"\tw: th.uu // width of tilemap\n"
-"\tcells: []th.uu // all cells (this will draw the tile in tiles with number in cells - 1)\n"
-"\tcollMask: []bool // if true, the tile collides\n"
-"\tscale: th.fu\n"
-"}\n"
-"```\n"
-"\n"
-"Tilemap struct\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(cells: []th.uu, w: th.uu, at: atlas.Atlas, scale: th.fu = 1): Tilemap {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Tilemap.edit\n"
-"\n"
-"```\n"
-"fn (t: ^Tilemap) edit*(x, y, tile: int) {\n"
-"```\n"
-"\n"
-"Sets tile at [x, y] to tile.\n"
-"\n"
-"\n"
-"## fn Tilemap.draw\n"
-"\n"
-"```\n"
-"fn (t: ^Tilemap) draw*() {\n"
-"```\n"
-"\n"
-"Draws the tilemap.\n"
-"\n"
-"\n"
-"## fn Tilemap.getColl\n"
-"\n"
-"```\n"
-"fn (t: ^Tilemap) getColl*(e: ent.Ent, ic: ^th.Vf2, pos: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Checks whether `e` collides with any of the tiles in `t`, which are in the\n"
-"collmask.\n"
-"\n"
-"* `ic`[out] - the position where a collision occured\n"
-"* `pos`[out] - coordinates of a tile where a collision occured\n"
-"\n"
-"Note: While there may be multiple collisions with a tilemap, this function\n"
-"will only return one.\n"
-"\n"
-"\n"
-"## fn Tilemap.autotile\n"
-"\n"
-"```\n"
-"fn (t: ^Tilemap) autotile*(src, tileCfg: []th.uu, tile: th.uu) {\n"
-"```\n"
-"\n"
-"Autotile turns all `tile` tiles in `src` into tiles in `tileCfg`, so they\n"
-"follow up correctly. `tileCfg` is an array of 16 tiles. They are placed in\n"
-"a way where OR of all the places where the tile continues (top, right bot,\n"
-"right). The constants for them are defined in this file. Example:\n"
-"tileCfg[top | bot] = 21\n"
-"top | bot would look something like this: |\n"
-"\n"
-"\n"
-"",
-"## Cursor types\n"
-"\n"
-"```\n"
-"const (\n"
-"\tcursorDefault* = 0\t\t// Default system cursor\n"
-"\tcursorArrow*\t\t\t// Normal cursor; Arrow cursor\n"
-"\tcursorIBeam*\t\t\t// \'I\' text cursor; I-Beam\n"
-"\tcursorCrosshair*\t\t// \'+\' cursor; Select region cursor\n"
-"\tcursorFinger*\t\t\t// Index finger pointing cursor; Click cursor\n"
-"\tcursorSizeEW*\t\t\t// \'<->\' cursor; Resize width cursor; Resize horizontally cursor; East-West resize cursor\n"
-"\tcursorSizeNS*\t\t\t// Resize height cursor; Resize vertically cursor; North-South resize cursor\n"
-"\tcursorSizeNWSE*\t\t\t// Resize width and height from the right side cursor; Northwest-Southeast resize cursor\n"
-"\tcursorSizeSWNE*\t\t\t// Resize width and height from the left side cursor; Southwest-Northeast resize cursor\n"
-"\tcursorSizeAll*\t\t\t// Resize all cursor; Move cursor\n"
-"\tcursorNo*\t\t\t// \'(/)\' cursor; Disabled cursor; Disallowed cursor\n"
-"\tcursorCount_*\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## Window dimensions\n"
-"\n"
-"```\n"
-"var (\n"
-"\tw*, h*: int32\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## Viewport size\n"
-"\n"
-"```\n"
-"var wp*: th.Vf2\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## signal OnFrame\n"
-"\n"
-"```\n"
-"var onFrame*: signal.Signal\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## signal OnDestroy\n"
-"\n"
-"```\n"
-"var onDestroy*: signal.Signal\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn setViewport\n"
-"\n"
-"```\n"
-"fn setViewport*(dm: th.Vf2) {\n"
-"```\n"
-"\n"
-"Sets the dimensions of the viewport. The dimensions are saved in the `wp`\n"
-"variable.\n"
-"\n"
-"`dm`\n"
-": dimension of the viewport\n"
-"\n"
-"\n"
-"## fn isDpiEnabled\n"
-"\n"
-"```\n"
-"fn isDpiEnabled*(): bool {\n"
-"```\n"
-"\n"
-"Returns true if DPI awareness was enabled\n"
-"\n"
-"\n"
-"## fn getDpiScaleFactor\n"
-"\n"
-"```\n"
-"fn getDpiScaleFactor*(): th.fu {\n"
-"```\n"
-"\n"
-"Returns the DPI scaling of the current window.\n"
-"If `dpiAware` was not enabled in window setup, this function will return 1.0 (default scaling).\n"
-"\n"
-"\n"
-"## fn setup\n"
-"\n"
-"```\n"
-"fn setup*(title: str = \"tophat game\", width: int = 400, height: int32 = 400) {\n"
-"```\n"
-"\n"
-"Sets up the engine and opens a window.\n"
-"\n"
-"\n"
-"## fn cycle\n"
-"\n"
-"```\n"
-"fn cycle(delta: real) {\n"
-"```\n"
-"\n"
-"Cycle needs to be called every cycle for the window to work. If the window\n"
-"was closed, it returns false.\n"
-"\n"
-"\n"
-"## fn setFullscreen\n"
-"\n"
-"```\n"
-"fn setFullscreen*(fullscreen: bool) {\n"
-"```\n"
-"\n"
-"Makes window go full screen\n"
-"\n"
-"\n"
-"## fn isFullscreen\n"
-"\n"
-"```\n"
-"fn isFullscreen*(): bool {\n"
-"```\n"
-"\n"
-"Returns true if window is fullscreen\n"
-"\n"
-"\n"
-"## fn getDims\n"
-"\n"
-"```\n"
-"fn getDims*(): th.Vf2 {\n"
-"```\n"
-"\n"
-"Returns dimensions of the window in screen pixels.\n"
-"\n"
-"\n"
-"## fn setTargetFps\n"
-"\n"
-"```\n"
-"fn setTargetFps*(fps: int) {\n"
-"```\n"
-"\n"
-"Sets the fps limit.\n"
-"\n"
-"`fps`\n"
-": amount of fps the limit should be set to\n"
-"\n"
-"\n"
-"\n"
-"## fn setDims\n"
-"\n"
-"```\n"
-"fn setDims*(dm: th.Vf2) {\n"
-"```\n"
-"\n"
-"Sets the dimensions of the window.\n"
-"\n"
-"`dm`\n"
-": the target dimensions in screen pixels\n"
-"\n"
-"\n"
-"## fn setIcon\n"
-"\n"
-"```\n"
-"fn setIcon*(img: image.Image) {\n"
-"```\n"
-"\n"
-"Sets the window icon.\n"
-"\n"
-"\n"
-"## fn showCursor\n"
-"\n"
-"```\n"
-"fn showCursor*(show: bool) {\n"
-"```\n"
-"\n"
-"Show or hide the cursor, linux only.\n"
-"\n"
-"\n"
-"## fn freezeCursor\n"
-"\n"
-"```\n"
-"fn freezeCursor*(freeze: bool) {\n"
-"```\n"
-"\n"
-"Freezes the cursor in place. `input.getMouseDelta` will still report mouse\n"
-"movements. The cursor will be automatically hidden.\n"
-"\n"
-"\n"
-"## fn setCursor\n"
-"\n"
-"```\n"
-"fn setCursor*(cursor: int) {\n"
-"```\n"
-"\n"
-"Allows you to set the displaying cursor. Refer to the cursors section for available cursors.\n"
-"\n"
-"\n"
-"## fn quit\n"
-"\n"
-"```\n"
-"fn quit*() {\n"
-"```\n"
-"\n"
-"Exits the application. Use this instead of umka\'s default `exit`.\n"
-"\n"
-"\n"
-"## fn setClipboard\n"
-"\n"
-"```\n"
-"fn setClipboard*(s: str) {\n"
-"```\n"
-"\n"
-"Puts a string to the system clipboard.\n"
-"\n"
-"\n"
-"## fn getClipboard\n"
-"\n"
-"```\n"
-"fn getClipboard*(): str {\n"
-"```\n"
-"\n"
-"Gets a string from the system clipboard.\n"
-"\n"
-"\n"
-"## fn setViewportOffset\n"
-"\n"
-"```\n"
-"fn setViewportOffset*(s: th.Vf2) {\n"
-"```\n"
-"\n"
-"Sets the offset of the viewport.\n"
-"\n"
-"\n"
-"## fn getViewportOffset\n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Gets the offset of the viewport (as set by `setViewportShift`)\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Particles allow for *performant* and random particle systems.\n"
-"\n"
-"\n"
-"## struct Particle\n"
-"\n"
-"```\n"
-"type Particle* = struct {\n"
-"```\n"
-"\n"
-"Particle struct. You can tweak the start_time for godot-like explossivness.\n"
-"\n"
-"\n"
-"## struct Emitter\n"
-"\n"
-"```\n"
-"type Emitter* = struct {\n"
-"\tpos: th.Vf2 // position\n"
-"\tdm: th.Vf2 // size of the emittion area\n"
-"\tgravity: th.Vf2 // gravity\n"
-"\trepeat: bool // if false, particle won\'t be renewed\n"
-"\tactive: bool // false, if there aren\'t any active particles anymore\n"
-"\n"
-"\tangle: th.Vf2 // angle in which particles are emitted\n"
-"\n"
-"\tlifetime: th.uu // lifetime of particles\n"
-"\tlifetimeRandomness: th.fu // randomness in %/100\n"
-"\n"
-"\tvelocity: th.fu // velocity\n"
-"\tvelocityRandomness: th.fu // randomness in %/100\n"
-"\n"
-"\tsize: th.fu // size\n"
-"\tsizeRandomness: th.fu // randomness in %/100\n"
-"\tmaxSize: th.fu // size at the end of particles lifetime\n"
-"\n"
-"\trotation: th.fu\n"
-"\trotationRandomness: th.fu\n"
-"\tmaxRotation: th.fu\n"
-"\n"
-"\tcolors: []uint32 // array of colors, which are interpolated between\n"
-"\n"
-"\tparticles: []Particle // list of particles\n"
-"}\n"
-"```\n"
-"\n"
-"Emitter. This is where everything is configured.\n"
-"\n"
-"\n"
-"## fn Emitter.draw\n"
-"\n"
-"```\n"
-"fn (e: ^Emitter) draw*(t: int32) {\n"
-"```\n"
-"\n"
-"Draws and updates the particles.\n"
-"\n"
-"\n"
-"## fn Emitter.genParticles\n"
-"\n"
-"```\n"
-"fn (e: ^Emitter) genParticles*(time, count: uint, explosiveness: th.fu = 0.0) {\n"
-"```\n"
-"\n"
-"Generates particles for an emitter. The time specifies the time the first\n"
-"particles is emitted. The explosiveness argument specifies the interval at\n"
-"which particles are emitted using this formula:\n"
-"/ ```umka\n"
-"/ e.lifetime / count * explosiveness\n"
-"/ ```\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Simple linear interpolation module.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Module for font rendering. Unicode is supported, but only left to right.\n"
-"\n"
-"\n"
-"## Filtering constants\n"
-"\n"
-"```\n"
-"const (\n"
-"\tfilterNearest* = 0\n"
-"\tfilterLinear* = 1\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## opaque Font\n"
-"\n"
-"```\n"
-"type Font* = struct { _: ^struct{} }\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn load\n"
-"\n"
-"```\n"
-"fn load*(path: str, size: th.fu, filter: uint32 = filterLinear): Font {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Font.validate\n"
-"\n"
-"```\n"
-"fn (f: ^Font) validate*(): bool {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Font.draw\n"
-"\n"
-"```\n"
-"fn (f: ^Font) draw*(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0) {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Font.measure\n"
-"\n"
-"```\n"
-"fn (f: ^Font) measure*(text: str): th.Vf2 {\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Module with useful variables and types.\n"
-"Variables: time, delta, platform\n"
-"Constants: black, white, red, green, blue, yellow, magenta, cyan.\n"
-"\n"
-"\n"
-"## Tophat type aliases\n"
-"\n"
-"```\n"
-"type fu* = real32\n"
-"// standard type for integer values\n"
-"type iu* = int32\n"
-"// standard type for unsigned values\n"
-"type uu* = uint32\n"
-"```\n"
-"\n"
-"standard type for real values\n"
-"\n"
-"\n"
-"## struct Vf2\n"
-"\n"
-"```\n"
-"type Vf2* = struct {\n"
-"\tx, y: fu\n"
-"}\n"
-"```\n"
-"\n"
-"vector 2\n"
-"\n"
-"\n"
-"## fn mkVf2\n"
-"\n"
-"```\n"
-"fn mkVf2*(x: fu = 0, y: fu = 0): Vf2 {\n"
-"\treturn Vf2{x, y}\n"
-"}\n"
-"```\n"
-"\n"
-"Vf2 constructor\n"
-"\n"
-"\n"
-"## fn Vf2.rotated\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) rotated*(origin: Vf2, rot: fu): Vf2 {\n"
-"```\n"
-"\n"
-"rotates `p` around `origin` with `rot` in degrees\n"
-"\n"
-"\n"
-"## fn Vf2.distanceTo\n"
-"\n"
-"```\n"
-"fn (p1: ^Vf2) distanceTo*(p2: Vf2): fu {\n"
-"```\n"
-"\n"
-"distance between p1 and p2\n"
-"\n"
-"\n"
-"## fn Vf2.angleTo\n"
-"\n"
-"```\n"
-"fn (p1: ^Vf2) angleTo*(p2: Vf2): real {\n"
-"```\n"
-"\n"
-"Angle between p1 and p2\n"
-"\n"
-"\n"
-"## fn Vf2.abs\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) abs*(): Vf2 {\n"
-"```\n"
-"\n"
-"Absolute value of a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.round\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) round*(): Vf2 {\n"
-"```\n"
-"\n"
-"Rounds a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.trunc\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) trunc*(): Vf2 {\n"
-"```\n"
-"\n"
-"Truncates a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.floor\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) floor*(): Vf2 {\n"
-"```\n"
-"\n"
-"Floors a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.ceil\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) ceil*(): Vf2 {\n"
-"```\n"
-"\n"
-"Ceils a vector.\n"
-"\n"
-"\n"
-"## fn vf2f\n"
-"\n"
-"```\n"
-"fn vf2f*(f: fu): Vf2 {\n"
-"```\n"
-"\n"
-"Creates a vector with both x and y set to f\n"
-"\n"
-"\n"
-"## fn Vf2.sub\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) sub*(p2: Vf2): Vf2 {\n"
-"```\n"
-"\n"
-"Subtracts a vector from another one.\n"
-"\n"
-"\n"
-"## fn Vf2.subf\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) subf*(f: fu): Vf2 {\n"
-"```\n"
-"\n"
-"Subtracts a fu from a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.add\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) add*(p2: Vf2): Vf2 {\n"
-"```\n"
-"\n"
-"Adds a vector to another one.\n"
-"\n"
-"\n"
-"## fn Vf2.addf\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) addf*(f: fu): Vf2 {\n"
-"```\n"
-"\n"
-"Adds a fu to a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.div\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) div*(p2: Vf2): Vf2 {\n"
-"```\n"
-"\n"
-"Divides a vector by another one.\n"
-"\n"
-"\n"
-"## fn Vf2.divf\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) divf*(f: fu): Vf2 {\n"
-"```\n"
-"\n"
-"Divides a vector by a fu.\n"
-"\n"
-"\n"
-"## fn Vf2.mul\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) mul*(p2: Vf2): Vf2 {\n"
-"```\n"
-"\n"
-"Multiplies a vector by another one.\n"
-"\n"
-"\n"
-"## fn Vf2.mulf\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) mulf*(f: fu): Vf2 {\n"
-"```\n"
-"\n"
-"Multiplies a vector by a fu.\n"
-"\n"
-"\n"
-"## fn Vf2.mag\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) mag*(): fu {\n"
-"```\n"
-"\n"
-"Returns the magnitude of a vector p.\n"
-"\n"
-"\n"
-"## fn Vf2.norm\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) norm*(): Vf2 {\n"
-"```\n"
-"\n"
-"Normalizes a vector.\n"
-"\n"
-"\n"
-"## fn Vf2.dot\n"
-"\n"
-"```\n"
-"fn (p: ^Vf2) dot*(q: Vf2): fu {\n"
-"```\n"
-"\n"
-"Calculates dot product between 2 vectors.\n"
-"\n"
-"\n"
-"## struct Transform\n"
-"\n"
-"```\n"
-"type Transform* = struct {\n"
-"\tp: Vf2 // position\n"
-"\ts: Vf2 // scale\n"
-"\to: Vf2 // origin\n"
-"\tr: fu // rotation\n"
-"}\n"
-"```\n"
-"\n"
-"Struct defining transformation. Used for example by entities.\n"
-"\n"
-"\n"
-"## fn mkTransform\n"
-"\n"
-"```\n"
-"fn mkTransform*(p: Vf2, s: Vf2 = Vf2{1, 1}, o: Vf2 = Vf2{0, 0}, r: fu = 0.0): Transform {\n"
-"```\n"
-"\n"
-"Transform constructor\n"
-"\n"
-"\n"
-"## fn Transform.transformed\n"
-"\n"
-"```\n"
-"fn (o: ^Transform) transformed*(t: Transform): Transform {\n"
-"```\n"
-"\n"
-"Transforms a transform with another transform.\n"
-"\n"
-"\n"
-"## fn Vf2.transformed\n"
-"\n"
-"```\n"
-"fn (v: ^Vf2) transformed*(t: Transform): Vf2 {\n"
-"```\n"
-"\n"
-"Transforms a vf2 to another vf2.\n"
-"Order:\n"
-"1. scale\n"
-"2. rotation\n"
-"3. position\n"
-"\n"
-"This allows conversion from a relative to an absolute vf2.\n"
-"\n"
-"\n"
-"## type Quad\n"
-"\n"
-"```\n"
-"type Quad* = [4]Vf2\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Quad.getMax\n"
-"\n"
-"```\n"
-"fn (q: ^Quad) getMax*(): Vf2 {\n"
-"```\n"
-"\n"
-"Gets the maximum coordinate.\n"
-"\n"
-"\n"
-"## fn Quad.getMin\n"
-"\n"
-"```\n"
-"fn (q: ^Quad) getMin*(): Vf2 {\n"
-"```\n"
-"\n"
-"Gets the minimum coordinate.\n"
-"\n"
-"\n"
-"## fn Quad.getDims\n"
-"\n"
-"```\n"
-"fn (q: ^Quad) getDims*(): Vf2 {\n"
-"```\n"
-"\n"
-"Returns the dimensions of the quad\'s bounding box\n"
-"\n"
-"\n"
-"## fn getGlobal\n"
-"\n"
-"```\n"
-"fn getGlobal*(): ^struct{} {\n"
-"```\n"
-"\n"
-"returns a pointer to the th_global. Set this as your extensions thg.\n"
-"\n"
-"\n"
-"## fn getFuncs\n"
-"\n"
-"```\n"
-"fn getFuncs*(): ^struct{} {\n"
-"```\n"
-"\n"
-"returns pointer to tophat functions. Pass this to th_ext_set.\n"
-"\n"
-"\n"
-"## var enableErrrors\n"
-"\n"
-"```\n"
-"var enableErrors*: bool = true\n"
-"```\n"
-"\n"
-"If true, errors will result in a call to error(), otherwise printf is used.\n"
-"\n"
-"\n"
-"## Color constants\n"
-"\n"
-"```\n"
-"const (\n"
-"\tblack* = 0xff\n"
-"\twhite* = 0xffffffff\n"
-"\tred* = 0xff0000ff\n"
-"\tgreen* = 0x00ff00ff\n"
-"\tblue* = 0x0000ffff\n"
-"\tyellow* = 0xffff00ff\n"
-"\tmagenta* = 0xff00ffff\n"
-"\tcyan* = 0x00ffffff\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## enum Platform\n"
-"\n"
-"```\n"
-"type Platform* = int\n"
-"const (\n"
-"\tPlatformUnknown* = 0\n"
-"\tPlatformLinux*\n"
-"\tPlatformWindows*\n"
-"\tPlatformMacOs*\n"
-"\tPlatformWeb*\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## Misc variables\n"
-"\n"
-"```\n"
-"var (\n"
-"\t// time in ms from start of the game\n"
-"\ttime*: uint\n"
-"\t// length of the last frame in ms\n"
-"\tdelta*: int\n"
-"\t// platform tophat is running on\n"
-"\tplatform*: Platform\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"A module for importless communication between modules. A signal is a set of\n"
-"callbacks. You can use signals directly in your own structs if you want\n"
-"them to be instance specific, of you can use global signals which are\n"
-"adressed by a string name.\n"
-"\n"
-"\n"
-"## type Callback\n"
-"\n"
-"```\n"
-"type Callback* = fn(args: []any)\n"
-"```\n"
-"\n"
-"`args` is a list of arguments passed to the `emit` method.\n"
-"\n"
-"\n"
-"## type Id\n"
-"\n"
-"```\n"
-"type Id* = uint\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## type Signal\n"
-"\n"
-"```\n"
-"type Signal* = map[Id]Callback\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(): Signal {\n"
-"```\n"
-"\n"
-"`Signal` constructor\n"
-"\n"
-"\n"
-"## fn Signal.register\n"
-"\n"
-"```\n"
-"fn (this: ^Signal) register*(callback: Callback): Id {\n"
-"```\n"
-"\n"
-"Registers a callback to a signal and returns the callback id.\n"
-"\n"
-"\n"
-"## fn Signal.remove\n"
-"\n"
-"```\n"
-"fn (this: ^Signal) remove*(id: Id) {\n"
-"```\n"
-"\n"
-"Removes a callback by id.\n"
-"\n"
-"\n"
-"## fn Signal.emit\n"
-"\n"
-"```\n"
-"fn (this: ^Signal) emit*(args: ..any) {\n"
-"```\n"
-"\n"
-"Emits a signal.\n"
-"\n"
-"\n"
-"## fn Signal.clear\n"
-"\n"
-"```\n"
-"fn (this: ^Signal) clear*() {\n"
-"```\n"
-"\n"
-"Removes all signal handlers.\n"
-"\n"
-"\n"
-"## fn register\n"
-"\n"
-"```\n"
-"fn register*(name: str, callback: Callback): Id {\n"
-"```\n"
-"\n"
-"Registers a callback to a global signal. There is no need to explicitly\n"
-"create global signals. Returns id of the added callback\n"
-"\n"
-"\n"
-"## fn remove\n"
-"\n"
-"```\n"
-"fn remove*(name: str, id: Id) {\n"
-"```\n"
-"\n"
-"Removes a callback from a global signal by id.\n"
-"\n"
-"\n"
-"## fn remove\n"
-"\n"
-"```\n"
-"fn clear*(name: str) {\n"
-"```\n"
-"\n"
-"Removes all signal handlers from a global signal.\n"
-"\n"
-"\n"
-"## fn emit\n"
-"\n"
-"```\n"
-"fn emit*(name: str, args: ..any) {\n"
-"```\n"
-"\n"
-"Calls all callbacks associated with the passed global signal name.\n"
-"\n"
-"\n"
-"",
-"## struct Atlas\n"
-"\n"
-"```\n"
-"type Atlas* = struct {\n"
-"\ti: image.Image // source image\n"
-"\tcs: th.Vf2 // size of a cell in pixels\n"
-"\tdm: th.Vf2 // amount of cells in image\n"
-"}\n"
-"```\n"
-"\n"
-"Atlas is an image containing tiles in a square grid.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(i: image.Image, dm: th.Vf2): Atlas {\n"
-"```\n"
-"\n"
-"i: source image\n"
-"dm: amount of cells\n"
-"\n"
-"\n"
-"## fn Atlas.coords\n"
-"\n"
-"```\n"
-"fn (a: ^Atlas) coords*(n: int): th.Vf2 {\n"
-"```\n"
-"\n"
-"returns the coordinates of the nth tile\n"
-"\n"
-"\n"
-"## fn Atlas.cropSource\n"
-"\n"
-"```\n"
-"fn (a: ^Atlas) cropSource*(at: th.Vf2) {\n"
-"```\n"
-"\n"
-"Crops the sourse image to only show a wanted tile\n"
-"\n"
-"\n"
-"## enum PackStrategy\n"
-"\n"
-"```\n"
-"const (\n"
-"\tPackSquare* = 0\n"
-"\tPackRow*\n"
-"\tPackColumn*\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn pack\n"
-"\n"
-"```\n"
-"fn pack*(images: []image.Image, strategy: int): Atlas {\n"
-"```\n"
-"\n"
-"Packs an array of images into an atlas\n"
-"\n"
-"\n"
-"## fn Atlas.draw\n"
-"\n"
-"```\n"
-"fn (a: ^Atlas) draw*(at: th.Vf2, t: th.Transform) {\n"
-"```\n"
-"\n"
-"Draws the tile at `at`\n"
-"\n"
-"\n"
-"",
-"## opaque Shader\n"
-"\n"
-"```\n"
-"type Shader* = struct {\n"
-"```\n"
-"\n"
-"Shader allows you to define your own vertex and fragment GLSL shaders. This\n"
-"is a low-level feature, so it\'s very easy to mess up.\n"
-"\n"
-"In tophat, instead of a main function, shaders provide th_vertex and\n"
-"th_fragment. The signature of th_vertex is:\n"
-"\n"
-"```\n"
-"vec2 th_vertex(vec2 vert);\n"
-"```\n"
-"\n"
-"where vert is the position of the vertex taken from the vertex buffer.\n"
-"The output is the vertex shader output.\n"
-"\n"
-"As for fragment shaders, there are two types of them. One for canvas\n"
-"and one for images. In canvas shaders, the fragment function is very simple:\n"
-"\n"
-"```\n"
-"vec4 th_fragment(vec4 color);\n"
-"```\n"
-"\n"
-"Image fragment function looks like this:\n"
-"\n"
-"```\n"
-"vec4 th_fragment(sampler2D tex, vec2 coord);\n"
-"```\n"
-"\n"
-"where tex is the texture and coord are the texture coordinates. Be aware to\n"
-"swap the output of the `texture2D` function. Example:\n"
-"\n"
-"```\n"
-"texture2D(tex, coord).abgr\n"
-"```\n"
-"\n"
-"\n"
-"## Default shader constants\n"
-"\n"
-"```\n"
-"const (\n"
-"\tdefaultImageShader* = Shader{1}\n"
-"\tdefaultCanvasShader* = Shader{2}\n"
-")\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## struct Uniform\n"
-"\n"
-"```\n"
-"type Uniform* = struct {\n"
-"\ts: Shader\n"
-"\tl: uint\n"
-"}\n"
-"```\n"
-"\n"
-"Represents a GLSL uniform.\n"
-"\n"
-"\n"
-"## fn mkCanvas\n"
-"\n"
-"```\n"
-"fn mkCanvas*(vertex, fragment: str): Shader {\n"
-"```\n"
-"\n"
-"Compiles a canvas shader from source. If there is a compilation error, it\n"
-"will print something to the console.\n"
-"\n"
-"\n"
-"## fn mkImage\n"
-"\n"
-"```\n"
-"fn mkImage*(vertex, fragment: str): Shader {\n"
-"```\n"
-"\n"
-"Compiles an image shader from source. If there is a compilation error, it\n"
-"will print something to the console.\n"
-"\n"
-"\n"
-"## fn Shader.pickForCanvas\n"
-"\n"
-"```\n"
-"fn (s: ^Shader) pickForCanvas*() {\n"
-"```\n"
-"\n"
-"Picks the shader to be used for canvas drawing. Flushes the canvas batch.\n"
-"\n"
-"\n"
-"## fn Shader.pickForImage\n"
-"\n"
-"```\n"
-"fn (s: ^Shader) pickForImage*() {\n"
-"```\n"
-"\n"
-"Picks the shader to be used for image drawing. Flushes the image batch.\n"
-"\n"
-"\n"
-"## fn Shader.getUniformLocation\n"
-"\n"
-"```\n"
-"fn (s: ^Shader) getUniformLocation*(name: str): Uniform {\n"
-"```\n"
-"\n"
-"Retunrs a uniform by name.\n"
-"\n"
-"\n"
-"## fn Uniform.setInt\n"
-"\n"
-"```\n"
-"fn (u: ^Uniform) setInt*(value: int) {\n"
-"```\n"
-"\n"
-"Sets a uniform to an int value. Flushes both batches.\n"
-"\n"
-"\n"
-"## fn Uniform.setVf2\n"
-"\n"
-"```\n"
-"fn (u: ^Uniform) setVf2*(value: th.Vf2) {\n"
-"```\n"
-"\n"
-"Sets a uniform to a vf2. Flushes both batches.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Color operations. Operate on RGBA uint32 values.\n"
-"\n"
-"\n"
-"## fn hsv\n"
-"\n"
-"```\n"
-"fn hsv*(h, s, v: th.fu, a: th.fu = 1.0): uint32 {\n"
-"```\n"
-"\n"
-"Converts HSV values into RGBA uint32 color.\n"
-"NOTE: Hue is between 0 and 1\n"
-"\n"
-"\n"
-"## fn alpha\n"
-"\n"
-"```\n"
-"fn alpha*(c: uint32, to: th.fu): uint32 {\n"
-"```\n"
-"\n"
-"Sets alpha of the color c to a value in to.\n"
-"\n"
-"\n"
-"## fn rgb\n"
-"\n"
-"```\n"
-"fn rgb*(r, g, b: th.fu, a: th.fu = 1.0): uint32 {\n"
-"```\n"
-"\n"
-"Constructs RGBA uint32 from RGBA of reals.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"Builtin collision functions. The ic argument stores the collision position.\n"
-"\n"
-"\n"
-"## fn lineToLine\n"
-"\n"
-"```\n"
-"fn lineToLine*(b1, e1, b2, e2: th.Vf2, ic: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Checks for a collision between 2 lines specified by their end points.\n"
-"\n"
-"\n"
-"## fn vf2ToQuad\n"
-"\n"
-"```\n"
-"fn vf2ToQuad*(p: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Checks for a collision between a vf2 and a quad.\n"
-"\n"
-"\n"
-"## fn lineToQuad\n"
-"\n"
-"```\n"
-"fn lineToQuad*(b, e: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Check for a collision between a line and quad edges.\n"
-"\n"
-"\n"
-"## fn quadToQuad\n"
-"\n"
-"```\n"
-"fn quadToQuad*(q1, q2: th.Quad, ic: ^th.Vf2): bool {\n"
-"```\n"
-"\n"
-"Check for a collision between two quads.\n"
-"\n"
-"\n"
-"## fn vf2ToRect\n"
-"\n"
-"```\n"
-"fn vf2ToRect*(p: th.Vf2, r: rect.Rect): bool {\n"
-"```\n"
-"\n"
-"Check for a collision between a vf2 and a rectangle.\n"
-"\n"
-"\n"
-"## fn rectToRect\n"
-"\n"
-"```\n"
-"fn rectToRect*(r1, r2: rect.Rect): bool {\n"
-"```\n"
-"\n"
-"Check for a collision between two rects\n"
-"\n"
-"\n"
-"",
-"## Placeholder images\n"
-"\n"
-"```\n"
-"var (\n"
-"\t// an image useful for testing\n"
-"\ttest*: image.Image\n"
-"\t// the image used for the app icon\n"
-"\ticon*: image.Image\n"
-"\t// Windows 95 style button, to be used with ninepatch (image.um) \n"
-"\tbutton*: image.Image\n"
-")\n"
-"```\n"
-"\n"
-"These images are included with tophat and don\'t have to be loaded.\n"
-"\n"
-"\n"
-"",
-"## struct Mesh\n"
-"\n"
-"```\n"
-"type Mesh* = struct {\n"
-"\t// The mesh data.\n"
-"\td: []bool\n"
-"\t// The dimensions and position of the mesh, r.w == w * s\n"
-"\tr: rect.Rect\n"
-"\t// Width of the mesh. Used to adress the mesh data.\n"
-"\tw: th.uu\n"
-"\t// Scale of one cell (cell is a square)\n"
-"\ts: th.fu\n"
-"}\n"
-"```\n"
-"\n"
-"Mesh is a 2d array of bool cells. If a cell is true, the cell can be used\n"
-"in a path. The mesh is located in a world using the `r` field. A cell can\n"
-"have an arbitrary size as specified by `s`.\n"
-"\n"
-"The mesh can be edited using the `addQuad` method, but it should be trivial\n"
-"to add your own, similar methods.\n"
-"\n"
-"Please use the `mk` constructor to construct a `Mesh`, unless you really\n"
-"know what you\'re doing.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(r: rect.Rect, s: th.fu): Mesh {\n"
-"```\n"
-"\n"
-"Creates a new nav mesh.\n"
-"`r`\n"
-": the rectangle of the mask\n"
-"\'s\'\n"
-": the scale of the mask\n"
-"\n"
-"\n"
-"## fn Mesh.addQuad\n"
-"\n"
-"```\n"
-"fn (m: ^Mesh) addQuad*(q: th.Quad) {\n"
-"```\n"
-"\n"
-"Sets mask\'s fields overlapping `q` to `false`.\n"
-"\n"
-"\n"
-"## fn Mesh.nav\n"
-"\n"
-"```\n"
-"fn (m: ^Mesh) nav*(p1, p2: th.Vf2): []th.Vf2 {\n"
-"```\n"
-"\n"
-"Navigates between `p1` and `p2`. Returns the path as an array of `th.Vf2`s.\n"
-"If it doesn\'t find any path, or one of the points is outside of the mask,\n"
-"returns an empty array.\n"
-"\n"
-"\n"
-"## fn Mesh.draw\n"
-"\n"
-"```\n"
-"fn (m: ^Mesh) draw*(alpha: real32 = 1.0) {\n"
-"```\n"
-"\n"
-"Draws the mesh for debugging purposes.\n"
-"\n"
-"\n"
-"",
-"## \n"
-"\n"
-"```\n"
-"```\n"
-"\n"
-"`ui.um` offers an immediate GUI library suitable both for simple game menus\n"
-"and more complex applications. See the [tutorial](/tut/spritesheet.html)\n"
-"for example usage.\n"
-"\n"
-"\n"
-"## struct BoxStyle\n"
-"\n"
-"```\n"
-"type BoxStyle* = struct {\n"
-"\timg: image.Image\n"
-"\touter, inner: rect.Rect\n"
-"\tscale: th.fu\n"
-"\tcolor: uint32\n"
-"}\n"
-"```\n"
-"\n"
-"`BoxStyle` describes how a box within the GUI is styled. In this case box\n"
-"can be anything, ranging from a button to a container. By default the box\n"
-"is drawn using the `image.Image.drawNinepatch` method. However if the image\n"
-"is invalid, a rectangle with color `color` is drawn.\n"
-"\n"
-"\n"
-"## interface Font\n"
-"\n"
-"```\n"
-"type Font* = interface {\n"
-"\tdraw(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0)\n"
-"\tmeasure(test: str): th.Vf2\n"
-"}\n"
-"```\n"
-"\n"
-"This interface is used by all elements that draw text. A `font.Font`\n"
-"implements this interface.\n"
-"\n"
-"\n"
-"## struct PixelFont\n"
-"\n"
-"```\n"
-"type PixelFont* = struct { }\n"
-"```\n"
-"\n"
-"This struct implement the `Font` interface using the `canvas.um` pixel font.\n"
-"\n"
-"\n"
-"## struct Style\n"
-"\n"
-"```\n"
-"type Style* = struct {\n"
-"\t// current font\n"
-"\tft: Font\n"
-"\t// font scale\n"
-"\tftScale: th.fu\n"
-"\t// text color\n"
-"\tftColor: uint32\n"
-"\n"
-"\t// Positive box - i. e. unpressed button\n"
-"\tposBox: BoxStyle\n"
-"\t// Negative box - i. e. pressed button, text box\n"
-"\tnegBox: BoxStyle\n"
-"\t// Used to draw containers\n"
-"\tcontainerBox: BoxStyle\n"
-"}\n"
-"```\n"
-"\n"
-"`Style` is used as a global state for styling the GUI.\n"
-"\n"
-"\n"
-"## interface Container\n"
-"\n"
-"```\n"
-"type Container* = interface {\n"
-"\t// This adds a rectangle to the container, and returns the rectangle\n"
-"\t// which was actually added (the container can modify the rectangle).\n"
-"\t// See individual containers for further documentation.\n"
-"\tpushRect(r: rect.Rect): rect.Rect\n"
-"\tgetDims(): rect.Rect\n"
-"}\n"
-"```\n"
-"\n"
-"Containers are used to layout elements or other containers.\n"
-"\n"
-"\n"
-"## struct Gui\n"
-"\n"
-"```\n"
-"type Gui* = struct {\n"
-"\t// user context passed to layout functions\n"
-"\tctx: any\n"
-"\n"
-"\t// the index of the current selection. TODO implement properly\n"
-"\tselection: int\n"
-"\t// true, if the layout is being evaluated, not drawn\n"
-"\tisEval: bool\n"
-"\t// contains more unexported fields\n"
-"```\n"
-"\n"
-"This is the main struct of any UI. Styles and containers are in a stack.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(r: rect.Rect, s: Style): Gui\n"
-"```\n"
-"\n"
-"Creates a new gui spanning `r`, with style `s`.\n"
-"\n"
-"\n"
-"## type LayoutFn\n"
-"\n"
-"```\n"
-"type LayoutFn* = fn(gui: ^Gui)\n"
-"```\n"
-"\n"
-"The layout function calls different element or container methods to create\n"
-"the user interface itself. It is called in the `eval` and `draw`.\n"
-"\n"
-"\n"
-"## fn BoxStyle.draw\n"
-"\n"
-"```\n"
-"fn (this: ^BoxStyle) draw*(r: rect.Rect) {\n"
-"```\n"
-"\n"
-"Draws a rectangle using a BoxStyle\n"
-"\n"
-"\n"
-"## fn Gui.pushStyle\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) pushStyle*(s: Style) {\n"
-"```\n"
-"\n"
-"Pushes a style onto the style stack.\n"
-"\n"
-"\n"
-"## fn Gui.popStyle\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) popStyle*() {\n"
-"```\n"
-"\n"
-"Pops a style from the style stack.\n"
-"\n"
-"\n"
-"## fn Gui.getStyle\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) getStyle*(): ^Style {\n"
-"```\n"
-"\n"
-"Returns a pointer to the style atop the style stack.\n"
-"\n"
-"\n"
-"## fn Gui.getContainer\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) getContainer*(): Container {\n"
-"```\n"
-"\n"
-"Returns the container atop the container stack.\n"
-"\n"
-"\n"
-"## fn Gui.pushRect\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) pushRect*(r: rect.Rect): rect.Rect {\n"
-"```\n"
-"\n"
-"Shortcut to `this.getContainer().pushRect(r)`\n"
-"\n"
-"\n"
-"## fn Gui.getDims\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) getDims*(): rect.Rect {\n"
-"```\n"
-"\n"
-"Shortcut to `this.getContainer().getDims(r)`\n"
-"\n"
-"\n"
-"## fn Gui.dupStyle\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) dupStyle*() {\n"
-"```\n"
-"\n"
-"Duplicates the current style.\n"
-"\n"
-"\n"
-"## fn Gui.pushContainer\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) pushContainer*(c: Container) {\n"
-"```\n"
-"\n"
-"Pushes a container onto the container stack.\n"
-"\n"
-"\n"
-"## fn Gui.popContainer\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) popContainer*() {\n"
-"```\n"
-"\n"
-"Pops a container from the container stack.\n"
-"\n"
-"\n"
-"## fn Gui.eval\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) eval*(layout: LayoutFn) {\n"
-"```\n"
-"\n"
-"Runs the evaluation phase on `layout`.\n"
-"\n"
-"\n"
-"## fn Gui.draw\n"
-"\n"
-"```\n"
-"fn (this: ^Gui) draw*(layout: LayoutFn) {\n"
-"```\n"
-"\n"
-"Runs the draw phase on `layout`.\n"
-"\n"
-"\n"
-"## enum BoxGrow\n"
-"\n"
-"```\n"
-"type BoxGrow* = uint\n"
-"const (\n"
-"\t// Increments by an amount set by the user.\n"
-"\tBoxGrowDimension* = BoxGrow(0)\n"
-"\t// Divides the container into `n` equal parts.\n"
-"\tBoxGrowSubdivision* = BoxGrow(1)\n"
-"\t// Grows the box based on values in the span array.\n"
-"\tBoxGrowSpan* = BoxGrow(2)\n"
-"\tBoxGrowPxSpan* = BoxGrow(3)\n"
-")\n"
-"```\n"
-"\n"
-"The different types of \"growing\" the box can do.\n"
-"\n"
-"\n"
-"## enum BoxDirection\n"
-"\n"
-"```\n"
-"type BoxDirection* = uint\n"
-"const (\n"
-"\tBoxDirectionDown* = BoxDirection(0)\n"
-"\tBoxDirectionRight* = BoxDirection(1)\n"
-"\tBoxDirectionUp* = BoxDirection(2)\n"
-"\tBoxDirectionLeft* = BoxDirection(3)\n"
-")\n"
-"```\n"
-"\n"
-"Direction in which the box will grow.\n"
-"\n"
-"\n"
-"## struct BoxConfig\n"
-"\n"
-"```\n"
-"type BoxConfig* = struct {\n"
-"\t// dimension to grow by if `BoxGrowDimension` is used\n"
-"\tdimension: th.fu\n"
-"\t// number of subdivisions if `BoxGrowSubdivisions` is used\n"
-"\tsubdivisions: uint\n"
-"\t// the grow type\n"
-"\tgrowType: BoxGrow\n"
-"\t// the grow direction\n"
-"\tdir: BoxDirection\n"
-"\t// Specifies the values used with BoxGrowSpan nad BoxGrowPxSpan.\n"
-"\t// If BoxGrowSpan is used, 1 equals the size of the box divided by the sum\n"
-"\t// of all spans.\n"
-"\t// If BoxGrowPxSpan is used, 1 equals one pixel.\n"
-"\tspan: []th.fu\n"
-"\t// rect passed to the current container\n"
-"\trect: rect.Rect\n"
-"\t// padding inserted after each element\n"
-"\tpadding: th.fu\n"
-"}\n"
-"```\n"
-"\n"
-"Configuration of the `Box` container.\n"
-"\n"
-"\n"
-"## struct Box\n"
-"\n"
-"```\n"
-"type Box* = struct {\n"
-"\tgrow: th.fu\n"
-"\tspanCursor: int\n"
-"\tdm: rect.Rect\n"
-"\tcfg: BoxConfig\n"
-"}\n"
-"```\n"
-"\n"
-"`Box` is the main layout. It puts the elements next to each other,\n"
-"according to the config.\n"
-"\n"
-"If the dimensions of the rect passed to `pushRect` are non zero, they will\n"
-"be kept. Position is always forced.\n"
-"\n"
-"\n"
-"## fn Gui.box\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) box*(cfg: BoxConfig = {\n"
-"\tdimension: 30,\n"
-"\tgrowType: BoxGrowDimension,\n"
-"\tdir: BoxDirectionDown }) {\n"
-"```\n"
-"\n"
-"Adds the `Box` container to the gui.\n"
-"\n"
-"\n"
-"## struct StackConfig\n"
-"\n"
-"```\n"
-"type StackConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"\tpadding: th.fu\n"
-"}\n"
-"```\n"
-"\n"
-"Configuration for the `Stack` container.\n"
-"\n"
-"\n"
-"## struct Stack\n"
-"\n"
-"```\n"
-"type Stack* = struct {\n"
-"\tdm: rect.Rect\n"
-"\tcfg: StackConfig\n"
-"}\n"
-"```\n"
-"\n"
-"The stack container puts elements on top of each other.\n"
-"If a property of the rect passed to `pushRect` is zero, it will be changed\n"
-"to an equivalent property of the containers\' dimensions (minus the padding),\n"
-"else it will stay the same. This means stack can be used either to put\n"
-"multiple elements/containers on top of each other, or for absolutely\n"
-"positioned elements.\n"
-"\n"
-"\n"
-"## fn Gui.stack\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) stack*(cfg: StackConfig = {}) {\n"
-"```\n"
-"\n"
-"Adds the `Stack` container to the gui.\n"
-"\n"
-"\n"
-"## struct ScrollAreaConfig\n"
-"\n"
-"```\n"
-"type ScrollAreaConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"\t// scroll speed. Default is 1\n"
-"\tspeed: real32\n"
-"\t// if true, scrolling will be horizontal\n"
-"\thorizontal: bool\n"
-"}\n"
-"```\n"
-"\n"
-"Configuration for the scroll area.\n"
-"\n"
-"\n"
-"## struct ScrollArea\n"
-"\n"
-"```\n"
-"type ScrollArea* = struct {\n"
-"\tdm: rect.Rect\n"
-"\tcfg: ScrollAreaConfig\n"
-"\tscroll: ^real32\n"
-"\tmaxScroll: real32\n"
-"}\n"
-"```\n"
-"\n"
-"Scroll area is a container which allows the user to scroll. It acts as a\n"
-"stack container, but all the elements are shifted by the scroll.\n"
-"\n"
-"\n"
-"## fn Gui.scrollArea\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) scrollArea*(scroll: ^real32, maxScroll: real32, cfg: ScrollAreaConfig = {}) {\n"
-"```\n"
-"\n"
-"Pushes a scroll area. `scroll` is both input and output value. Both `scroll`\n"
-"and `maxScroll` are in pixels.\n"
-"\n"
-"\n"
-"## struct ButtonConfig\n"
-"\n"
-"```\n"
-"type ButtonConfig* = struct {\n"
-"\trect: rect.Rect\n"
-"}\n"
-"```\n"
-"\n"
-"Configuration for the button.\n"
-"\n"
-"\n"
-"## fn Gui.button\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
-"```\n"
-"\n"
-"Adds a button to the gui. The button acts like a `Stack` container, but it\n"
-"is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
-"pressed and the gui is in the eval phase, the return value will be true.\n"
-"\n"
-"\n"
-"## struct LabelConfig\n"
-"\n"
-"```\n"
-"type LabelConfig* = struct {\n"
-"\t// centers the label along the X axis, enables `stretchX`\n"
-"\tcenterX: bool\n"
-"\t// centers the label along the Y axis, enables `stretchY`\n"
-"\tcenterY: bool\n"
-"\t// if false, the rect passed to `pushRect` will have the width of\n"
-"\t// the text, else it will be 0\n"
-"\tstretchX: bool\n"
-"\t// if false, the rect passed to `pushRect` will have the height of\n"
-"\t// the text, else it will be 0\n"
-"\tstretchY: bool\n"
-"\t// forces the rectangle the label will use\n"
-"\trect: rect.Rect\n"
-"}\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn Gui.label\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) label*(text: str, cfg: LabelConfig = {\n"
-"```\n"
-"\n"
-"Draws a label using the current font style.\n"
-"\n"
-"\n"
-"## fn Gui.qbutton\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) qbutton*(text: str, cfg: ButtonConfig = {}): bool {\n"
-"```\n"
-"\n"
-"Adds a button with a label to gui.\n"
-"\n"
-"\n"
-"## struct TextBoxConfig\n"
-"\n"
-"```\n"
-"type TextBoxConfig* = struct {\n"
-"\t// force the rect of the text box\n"
-"\trect: rect.Rect\n"
-"}\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## struct TextBox\n"
-"\n"
-"```\n"
-"type TextBox* = struct {\n"
-"\t// index of the cursor\n"
-"\tcursor: int\n"
-"\t// contains other unexported rules...\n"
-"```\n"
-"\n"
-"\n"
-"\n"
-"## fn TextBox.clear\n"
-"\n"
-"```\n"
-"fn (this: ^TextBox) clear*() {\n"
-"```\n"
-"\n"
-"Clears the textbox\n"
-"\n"
-"\n"
-"## fn TextBox.getBuf()\n"
-"\n"
-"```\n"
-"fn (this: ^TextBox) getBuf*(): str {\n"
-"```\n"
-"\n"
-"Get the content of the textbox.\n"
-"\n"
-"\n"
-"## fn TextBox.setBuf()\n"
-"\n"
-"```\n"
-"fn (this: ^TextBox) setBuf*(s: str) {\n"
-"```\n"
-"\n"
-"Get the content of the textbox.\n"
-"\n"
-"\n"
-"## fn Gui.textBox\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) {\n"
-"```\n"
-"\n"
-"Adds a single line textbox to the gui.\n"
-"TODO:\n"
-"* right-to-left unicode is not supported.\n"
-"* no selection\n"
-"* multiline\n"
-"* copy paste\n"
-"* stuff like home and end\n"
-"\n"
-"\n"
-"## struct ImageConfig\n"
-"\n"
-"```\n"
-"type ImageConfig* = struct {\n"
-"\tstretchX, stretchY: bool\n"
-"\tcenterX, centerY: bool\n"
-"\tcolor: uint32\n"
-"\tscale: th.Vf2\n"
-"\trect: rect.Rect\n"
-"}\n"
-"```\n"
-"\n"
-"Configuration for the images element. Behaves similarly to labels.\n"
-"\n"
-"\n"
-"## fn Gui.image\n"
-"\n"
-"```\n"
-"fn (gui: ^Gui) image*(i: image.Image, cfg: ImageConfig = {\n"
-"\tstretchX: true,\n"
-"\tstretchY: true,\n"
-"\tcolor: th.white,\n"
-"\tscale: { 1, 1 } }) {\n"
-"```\n"
-"\n"
-"Draws an image.\n"
-"\n"
-"\n"
-"## fn getDefaultStyle\n"
-"\n"
-"```\n"
-"fn getDefaultStyle*(): Style {\n"
-"```\n"
-"\n"
-"Returns the default tophat ui style.\n"
-"\n"
-"\n"
-"## fn mk\n"
-"\n"
-"```\n"
-"fn mk*(r: rect.Rect, s: Style): Gui {\n"
-"```\n"
-"\n"
-"Creates a GUI instance.\n"
-"\n"
-"\n"
-"",
-};
-static uint32_t th_em_placeholder_data_2[] = {0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0};
-static uint32_t th_em_placeholder_data_3[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-static uint32_t th_em_placeholder_data_4[] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffc0c0c0, 0xffc0c0c0, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xff808080, 0xff808080, 0xffffffff, 0xffffffff, 0xffc0c0c0, 0xffc0c0c0, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xffc0c0c0, 0xffc0c0c0, 0xffffffff, 0xffffffff, 0xff808080, 0xff808080, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xffc0c0c0, 0xffc0c0c0, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
-th_em_placeholder th_em_placeholders[] = {
-{ th_em_placeholder_data_2, { .w = 12, .h = 12 } },
-{ th_em_placeholder_data_3, { .w = 69, .h = 69 } },
-{ th_em_placeholder_data_4, { .w = 10, .h = 5 } },
-};
diff --git a/tests/uit.um b/tests/uit.um
index 463cd4a6..6b02ce20 100644
--- a/tests/uit.um
+++ b/tests/uit.um
@@ -15,11 +15,11 @@ fn init*() {
window.setup("gui test", 600, 600)
window.setViewport(th.Vf2{ 200, 200 })
- ft := font.load("etc/roboto.ttf", 96, font.filterLinear)
+ ft := font.load("etc/roboto.ttf", 32, font.filterLinear)
gui = ui.mk(rect.mk(0, 0, 200, 200), ui.getDefaultStyle())
gui.getStyle().ft = ft
- gui.getStyle().ftScale = 0.1
+ gui.getStyle().ftScale = 0.3
win = ui.mk(rect.mk(100, 100, 80, 50), ui.getDefaultStyle())
win.getStyle().containerBox.color = 0x88aa88ff
diff --git a/umka/ui.um b/umka/ui.um
index 4b2461a6..fa23ef1a 100644
--- a/umka/ui.um
+++ b/umka/ui.um
@@ -736,7 +736,7 @@ fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) {
runes := utf8.decode(input.getStr())
if len(runes) > 0 && v {
- tb.buffer = append(slice(tb.buffer, 0, tb.cursor), append(slice(tb.buffer, tb.cursor), runes))
+ tb.buffer = append(append(slice(tb.buffer, 0, tb.cursor), runes), slice(tb.buffer, tb.cursor))
tb.cursor += len(runes)
}