@cosmoledo/gleam 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/gleam.d.ts +526 -62
- package/dist/gleam.esm.js +358 -81
- package/dist/gleam.esm.js.map +3 -3
- package/dist/gleam.js +358 -81
- package/dist/gleam.js.map +3 -3
- package/dist/gleam.min.js +7 -7
- package/dist/gleam.min.js.map +4 -4
- package/package.json +13 -11
package/dist/gleam.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/utilities/Functions.ts", "../src/core/EventSystem.ts", "../src/audio/AudioBase.ts", "../src/utilities/Number.ts", "../src/utilities/Easing.ts", "../src/utilities/Array.ts", "../src/audio/Music.ts", "../src/audio/Sound.ts", "../src/utilities/Math.ts", "../src/utilities/Color.ts", "../src/color/Color.ts", "../src/color/ColorShifter.ts", "../src/math/Rect.ts", "../src/math/Vec2.ts", "../src/core/Settings.ts", "../src/utilities/DOM.ts", "../src/utilities/Grid.ts", "../src/utilities/Prototype.ts", "../src/loader/UrlLoaders.ts", "../src/prototypes/HTMLCanvasElement.ts", "../src/utilities/Canvas.ts", "../src/content/Animator.ts", "../src/content/Particle.ts", "../src/content/Projectile.ts", "../src/core/CanvasManager.ts", "../src/core/Gameloop.ts", "../src/input/Keyboard.ts", "../src/input/Pointer.ts", "../src/localization/Translator.ts", "../src/prototypes/Audio.ts", "../src/prototypes/CanvasRenderingContext2D.ts", "../src/prototypes/index.ts", "../src/core/Game.ts", "../src/effects/Screenshake.ts", "../src/input/
|
|
4
|
-
"sourcesContent": ["// generated by scripts/generate-barrel.mjs \u2014 do not edit\n\n// audio\nexport { default as AudioBase } from \"./audio/AudioBase\";\nexport * from \"./audio/AudioBase\";\nexport { default as Music } from \"./audio/Music\";\nexport { default as Sound } from \"./audio/Sound\";\n\n// color\nexport * from \"./color/Color\";\nexport * from \"./color/ColorShifter\";\n\n// content\nexport { default as Animator } from \"./content/Animator\";\nexport * from \"./content/Animator\";\nexport { default as Particle } from \"./content/Particle\";\nexport { default as Projectile } from \"./content/Projectile\";\n\n// core\nexport { default as CanvasManager } from \"./core/CanvasManager\";\nexport * from \"./core/CanvasManager\";\nexport { default as EventSystem } from \"./core/EventSystem\";\nexport * from \"./core/EventSystem\";\nexport { default as Game } from \"./core/Game\";\nexport { default as Gameloop } from \"./core/Gameloop\";\nexport { default as Settings } from \"./core/Settings\";\nexport * from \"./core/Settings\";\n\n// effects\nexport { default as Screenshake } from \"./effects/Screenshake\";\nexport * from \"./effects/Screenshake\";\n\n// input\nexport { default as Controller } from \"./input/Controller\";\nexport * from \"./input/Controller\";\nexport { default as ControllerCursor } from \"./input/ControllerCursor\";\nexport { default as Keyboard } from \"./input/Keyboard\";\nexport * from \"./input/Keyboard\";\nexport { default as Pointer } from \"./input/Pointer\";\nexport * from \"./input/Pointer\";\n\n// loader\nexport * from \"./loader/UrlLoaders\";\n\n// localization\nexport * from \"./localization/Translator\";\n\n// math\nexport { default as Polygon } from \"./math/Polygon\";\nexport * from \"./math/Polygon\";\nexport { default as Rect } from \"./math/Rect\";\nexport { default as Vec2 } from \"./math/Vec2\";\nexport * from \"./math/Vec2\";\n\n// prototypes\n\n// utilities\nexport * from \"./utilities/Array\";\nexport * from \"./utilities/Canvas\";\nexport * from \"./utilities/Color\";\nexport * from \"./utilities/DOM\";\nexport * from \"./utilities/Easing\";\nexport * from \"./utilities/Functions\";\nexport * from \"./utilities/Grid\";\nexport * from \"./utilities/Json\";\nexport * from \"./utilities/Math\";\nexport * from \"./utilities/Number\";\nexport * from \"./utilities/Prototype\";\nexport * from \"./utilities/String\";\n", "/**\n * Returns a debounced wrapper that runs `callback` only after `delay` ms of silence (trailing edge).\n */\nexport function debounce<T extends unknown[]>(\n\tcallback: (...args: T) => void,\n\tdelay: number,\n): (...args: T) => void {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\treturn (...args: T) => {\n\t\tclearTimeout(timer);\n\t\ttimer = setTimeout(() => callback(...args), delay);\n\t};\n}\n\n/**\n * Promise that resolves after `time` milliseconds.\n */\nexport function delay(time: number): Promise<void> {\n\treturn new Promise(res => setTimeout(res, time));\n}\n\n/**\n * Returns `true` when touch is the primary input right now (game-UI question: show touch controls?).\n * Mode-aware: a convertible in laptop mode returns `false`, in tablet mode returns `true`.\n * Snapshot at call time \u2014 won't auto-update if the user switches modes mid-game.\n */\nexport function isTouchPrimary(): boolean {\n\treturn matchMedia(\"(pointer: coarse)\").matches;\n}\n\n/**\n * Run `tick(dt)` on every animation frame; `dt` is seconds since the previous\n * frame (0 on the first call). Returns a cancel function that stops the loop \u2014\n * no further ticks fire after it's called, even if one was already queued.\n */\nexport function rafLoop(tick: (dt: number) => void): () => void {\n\tlet lastTime = 0;\n\tlet running = true;\n\tlet handle = 0;\n\n\tconst wrapped = (now: number): void => {\n\t\tconst dt = lastTime === 0 ? 0 : (now - lastTime) / 1000;\n\t\tlastTime = now;\n\n\t\ttick(dt);\n\n\t\t// `running` covers stop-from-inside-tick: after tick returns, skip the requeue.\n\t\tif (running) {\n\t\t\thandle = requestAnimationFrame(wrapped);\n\t\t}\n\t};\n\n\thandle = requestAnimationFrame(wrapped);\n\n\treturn () => {\n\t\trunning = false;\n\t\tcancelAnimationFrame(handle);\n\t};\n}\n\n/**\n * Returns a throttled wrapper that runs `callback` at most once per `delay` ms (leading edge).\n * The callback receives the number of wrapper calls since the previous firing (inclusive of this one).\n */\nexport function throttle(\n\tcallback: (callCount: number) => void,\n\tdelay: number = 1000,\n): () => void {\n\tlet lastCalled = -Infinity;\n\tlet callCount = 0;\n\n\treturn () => {\n\t\tcallCount++;\n\n\t\tconst now = performance.now();\n\n\t\tif (now - lastCalled > delay) {\n\t\t\tlastCalled = now;\n\t\t\tconst count = callCount;\n\t\t\tcallCount = 0;\n\t\t\tcallback(count);\n\t\t}\n\t};\n}\n\n/**\n * Like `throttle`, but tracks the last firing independently per `key` \u2014\n * different keys never throttle each other. Use for de-duplicating repeated\n * error/warning logs by message identity. When the throttle fires, args from\n * the most recent call for that key are passed through alongside `callCount`.\n */\nexport function throttleByKey<T extends unknown[]>(\n\tcallback: (callCount: number, ...args: T) => void,\n\tdelay: number = 1000,\n): (key: string, ...args: T) => void {\n\tconst wrappers = new Map<string, (...args: T) => void>();\n\n\treturn (key, ...args) => {\n\t\tlet wrapper = wrappers.get(key);\n\n\t\tif (!wrapper) {\n\t\t\tlet latest: T;\n\t\t\tconst throttled = throttle(\n\t\t\t\tcount => callback(count, ...latest),\n\t\t\t\tdelay,\n\t\t\t);\n\t\t\twrapper = (...a: T) => {\n\t\t\t\tlatest = a;\n\t\t\t\tthrottled();\n\t\t\t};\n\t\t\twrappers.set(key, wrapper);\n\t\t}\n\n\t\twrapper(...args);\n\t};\n}\n\n/**\n * Filename component of a URL/path, without directory, extension, or query string.\n * Returns `null` when no usable name can be derived: a path ending in `/`, or a stem containing a malformed percent-escape that `decodeURIComponent` rejects.\n */\nexport function urlBasename(path: string): string | null {\n\tconst url = new URL(path, \"http://_/\");\n\tconst base = url.pathname.split(\"/\").pop()!;\n\tconst dot = base.lastIndexOf(\".\");\n\tconst stem = dot > 0 ? base.slice(0, dot) : base;\n\n\tif (!stem) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn decodeURIComponent(stem);\n\t} catch {\n\t\treturn null;\n\t}\n}\n", "import type Pointer from \"@/input/Pointer\";\nimport { throttleByKey } from \"@/utilities/Functions\";\n\nexport interface GameEventMap {\n\tgameloopStopped: [];\n\tinputControllerConnected: [event: Gamepad];\n\tinputControllerDisconnected: [];\n\tinputKeyboard: [\n\t\tkeys: Record<string, boolean>,\n\t\tcode: string,\n\t\tpressed: boolean,\n\t];\n\tinputPointer: [pointer: Pointer];\n\tresized: [];\n}\n\nexport interface EventSystemOptions {\n\tonce?: boolean;\n\tsignal?: AbortSignal;\n}\n\ntype GameEventListener<K extends keyof GameEventMap> = {\n\tcallback: (...args: GameEventMap[K]) => void;\n\tdispose: () => void;\n\toptions: { once: boolean; signal?: AbortSignal };\n};\n\nexport default class EventSystem {\n\tprivate static eventListener: {\n\t\t[K in keyof GameEventMap]?: Map<number, GameEventListener<K>>;\n\t} = {};\n\n\tprivate static logListenerError = throttleByKey<[string, unknown]>(\n\t\t(count, eventName, err) => {\n\t\t\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\t\t\tconsole.error(\n\t\t\t\t`EventSystem listener for \"${eventName}\" threw${suffix}:`,\n\t\t\t\terr,\n\t\t\t);\n\t\t},\n\t);\n\n\t// Monotonic counter \u2014 each listener gets an id assigned at registration.\n\t// `dispatchEvent` captures the value at start as a boundary so listeners\n\t// registered mid-dispatch (id > maxId) are deferred to the next dispatch.\n\tprivate static nextId = 0;\n\n\tpublic static addEventListener<K extends keyof GameEventMap>(\n\t\teventName: K,\n\t\tcallback: (...args: GameEventMap[K]) => void,\n\t\toptions: EventSystemOptions = {},\n\t): () => void {\n\t\tif (options.signal?.aborted) {\n\t\t\treturn function dispose(): void {};\n\t\t}\n\n\t\tconst id = ++this.nextId;\n\n\t\t// `function` declaration (not arrow) so it's hoisted and can reference\n\t\t// the `listener` constant defined below \u2014 both close over the same id.\n\t\t// Used by: user-returned disposer, the once-path in dispatchEvent, and\n\t\t// the signal's abort handler. Idempotent via Map.delete's false return.\n\t\tfunction dispose(): void {\n\t\t\tconst bucket = EventSystem.eventListener[eventName];\n\n\t\t\tif (!bucket?.delete(id)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Drop the bucket entry when empty so `eventListener` doesn't grow\n\t\t\t// monotonically and `dispatchEvent` can short-circuit on `!bucket`\n\t\t\t// without a per-dispatch size check.\n\t\t\tif (bucket.size === 0) {\n\t\t\t\tdelete EventSystem.eventListener[eventName];\n\t\t\t}\n\n\t\t\tif (listener.options.signal) {\n\t\t\t\tlistener.options.signal.removeEventListener(\"abort\", dispose);\n\t\t\t}\n\t\t}\n\n\t\tconst listener: GameEventListener<K> = {\n\t\t\tcallback,\n\t\t\tdispose,\n\t\t\toptions: { once: options.once ?? false, signal: options.signal },\n\t\t};\n\n\t\tlet bucket = this.eventListener[eventName];\n\n\t\tif (!bucket) {\n\t\t\tbucket = new Map();\n\t\t\tthis.eventListener[eventName] = bucket;\n\t\t}\n\n\t\tbucket.set(id, listener);\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener(\"abort\", dispose, { once: true });\n\t\t}\n\n\t\treturn dispose;\n\t}\n\n\tpublic static dispatchEvent<K extends keyof GameEventMap>(\n\t\teventName: K,\n\t\t...params: GameEventMap[K]\n\t): void {\n\t\tconst bucket = this.eventListener[eventName];\n\n\t\tif (!bucket) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Snapshot the id boundary \u2014 listeners registered during this dispatch\n\t\t// (which would have ids > maxId) are skipped this round.\n\t\tconst maxId = this.nextId;\n\n\t\t// Map.forEach is safe under mid-iteration mutation:\n\t\t// - entries deleted during the walk are skipped natively, so a callback\n\t\t// calling dispose() on itself, a sibling, or via nested dispatch needs\n\t\t// no extra bookkeeping;\n\t\t// - entries added during the walk would otherwise be visited, but the\n\t\t// `id > maxId` filter excludes them;\n\t\t// - nested forEach on the same Map keeps its own position, so recursive\n\t\t// dispatch works without depth tracking.\n\t\tbucket.forEach((entry, id) => {\n\t\t\tif (id > maxId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Remove the once-listener *before* invoking the callback so a nested\n\t\t\t// dispatch of the same event can't fire it a second time, and so a\n\t\t\t// throwing callback still leaves the bucket clean.\n\t\t\tif (entry.options.once) {\n\t\t\t\tentry.dispose();\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tentry.callback(...params);\n\t\t\t} catch (err) {\n\t\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\t\tthis.logListenerError(`${eventName}:${msg}`, eventName, err);\n\t\t\t}\n\t\t});\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport { urlBasename } from \"@/utilities/Functions\";\n\nexport interface RegisterData {\n\tpath: string;\n\tname: string;\n\tvolume?: number;\n}\n\nconst MEDIA_ERROR_CODES: Record<number, string> = {\n\t1: \"ABORTED\",\n\t2: \"NETWORK\",\n\t3: \"DECODE\",\n\t4: \"SRC_NOT_SUPPORTED\",\n};\n\nexport default abstract class AudioBase {\n\tprotected songs: Map<string, HTMLAudioElement> = new Map();\n\tprivate _enabled: boolean;\n\tprivate registered: boolean = false;\n\n\tpublic get enabled(): boolean {\n\t\treturn this._enabled;\n\t}\n\n\tpublic set enabled(value: boolean) {\n\t\tthis._enabled = value;\n\n\t\tif (!value) {\n\t\t\tthis.stop();\n\t\t}\n\t}\n\n\tconstructor(enabled: boolean = true) {\n\t\tthis._enabled = enabled;\n\n\t\tEventSystem.addEventListener(\"gameloopStopped\", () => this.stop());\n\t}\n\n\tpublic register(\n\t\tdefaultVolume: number = 1,\n\t\t...songs: (RegisterData | string)[]\n\t): void {\n\t\tthis.throwOnBadVolume(defaultVolume, \"defaultVolume\");\n\n\t\tif (this.registered) {\n\t\t\tthrow new Error(\"register() can only be called once per instance\");\n\t\t}\n\t\tthis.registered = true;\n\n\t\tsongs.forEach(song => {\n\t\t\tif (typeof song === \"string\") {\n\t\t\t\tsong = { name: urlBasename(song) ?? song, path: song };\n\t\t\t} else if (song.volume !== undefined) {\n\t\t\t\tthis.throwOnBadVolume(song.volume, `Volume of \"${song.name}\"`);\n\t\t\t}\n\n\t\t\tconst audio = new window.Audio();\n\n\t\t\taudio.addEventListener(\"error\", () => {\n\t\t\t\tconst err = audio.error;\n\t\t\t\tconst reason = err\n\t\t\t\t\t? `${MEDIA_ERROR_CODES[err.code] ?? err.code}${err.message ? `: ${err.message}` : \"\"}`\n\t\t\t\t\t: \"unknown\";\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Failed to load audio \"${song.name}\" from \"${audio.src}\": ${reason}`,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\taudio.preload = \"auto\";\n\t\t\taudio.src = song.path;\n\t\t\taudio.id = song.name;\n\t\t\taudio.volume = song.volume ?? defaultVolume;\n\t\t\taudio.defaultVolume = audio.volume;\n\n\t\t\tthis.songs.set(song.name, audio);\n\t\t});\n\t}\n\n\tpublic stop(): void {\n\t\tvoid 0;\n\t}\n\n\tprivate throwOnBadVolume(volume: number, name: string): void {\n\t\tif (!Number.isFinite(volume)) {\n\t\t\tthrow new Error(\n\t\t\t\tname + \" is invalid, it has to be in range of 0 to 1\",\n\t\t\t);\n\t\t}\n\n\t\tif (volume < 0) {\n\t\t\tthrow new Error(\n\t\t\t\tname + \" has to be above 0. What's a negative volume anyway?\",\n\t\t\t);\n\t\t}\n\n\t\tif (volume > 1) {\n\t\t\tthrow new Error(\n\t\t\t\tname +\n\t\t\t\t\t\" has to be lower or equal to 1! If you need a louder volume, you need to update the audio file itself.\",\n\t\t\t);\n\t\t}\n\t}\n}\n", "/**\n * Compare two numbers with float tolerance. Default epsilon absorbs typical accumulated rounding error from normalize/rotate/divide chains.\n */\nexport function approxEqual(a: number, b: number, epsilon = 1e-9): boolean {\n\treturn Math.abs(a - b) <= epsilon;\n}\n\n/**\n * Clamp values between two values\n */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Map value from one range to another. Returns `low2` when the source range is degenerate (`low1 === high1`).\n */\nexport function mapUnclamped(\n\tvalue: number,\n\tlow1: number,\n\thigh1: number,\n\tlow2: number,\n\thigh2: number,\n): number {\n\tif (low1 === high1) {\n\t\treturn low2;\n\t}\n\n\treturn low2 + ((high2 - low2) * (value - low1)) / (high1 - low1);\n}\n\n/**\n * Map value from one range to another (with clamping). Output range allows to be inverted (`high2 < low2`).\n */\nexport function map(\n\tvalue: number,\n\tlow1: number,\n\thigh1: number,\n\tlow2: number,\n\thigh2: number,\n): number {\n\treturn clamp(\n\t\tmapUnclamped(value, low1, high1, low2, high2),\n\t\tMath.min(low2, high2),\n\t\tMath.max(low2, high2),\n\t);\n}\n\n/**\n * Zero out values with `|value| < cutoff`; pass the rest through unchanged.\n */\nexport function threshold(value: number, cutoff: number): number {\n\tif (Math.abs(value) < cutoff) {\n\t\treturn 0;\n\t}\n\n\treturn value;\n}\n\n/**\n * Format number with dot separators (e.g., 1.000.000). Rounds to the nearest integer via `Math.round`; non-finite values pass through as their `toString()` form.\n */\nexport function toDotted(value: number): string {\n\treturn Math.round(value)\n\t\t.toString()\n\t\t.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \".\");\n}\n\n/**\n * Wrap `value` into `[min, max)` modulo the range size. Useful for cyclic ranges like angles.\n * Caller steps via `value + n`; this function handles the wrap-around.\n * Bounds are swapped if passed in reverse order. Throws when `min \u2248 max` (degenerate range, via `approxEqual`).\n */\nexport function wrapValue(value: number, min: number, max: number): number {\n\tif (approxEqual(min, max)) {\n\t\tthrow new RangeError(`wrapValue: min and max must differ (got ${min})`);\n\t}\n\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\tconst range = max - min;\n\treturn ((((value - min) % range) + range) % range) + min;\n}\n", "/**\n * Quadratic ease-in (slow start, accelerates).\n */\nexport function easeIn(t: number): number {\n\treturn t * t;\n}\n\n/**\n * Quadratic ease-in-out (accelerates, then decelerates).\n */\nexport function easeInOut(t: number): number {\n\treturn t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t);\n}\n\n/**\n * Quadratic ease-out (fast start, decelerates).\n */\nexport function easeOut(t: number): number {\n\treturn t * (2 - t);\n}\n\n/**\n * Identity (constant rate of change).\n */\nexport function linear(t: number): number {\n\treturn t;\n}\n\nexport type EasingName = \"ease-in\" | \"ease-in-out\" | \"ease-out\" | \"linear\";\n\nexport const EASINGS: Record<EasingName, (t: number) => number> = {\n\t\"ease-in\": easeIn,\n\t\"ease-in-out\": easeInOut,\n\t\"ease-out\": easeOut,\n\t\"linear\": linear,\n};\n", "/**\n * Split an array into chunks of at most `maxLength` elements each. Throws when `maxLength < 1`.\n */\nexport function chunk<T>(array: ReadonlyArray<T>, maxLength: number): T[][] {\n\tif (!Number.isFinite(maxLength) || maxLength < 1) {\n\t\tthrow new RangeError(\n\t\t\t`chunk: maxLength must be a finite number >= 1 (got ${maxLength})`,\n\t\t);\n\t}\n\n\tconst result: T[][] = [];\n\tlet part: T[] = [];\n\n\tarray.forEach((item, i) => {\n\t\tpart.push(item);\n\n\t\tif (part.length === maxLength || i === array.length - 1) {\n\t\t\tresult.push(part);\n\t\t\tpart = [];\n\t\t}\n\t});\n\n\treturn result;\n}\n\n/**\n * Pick a uniformly random element from `array`. Throws if `array` is empty \u2014 guard at the call site if that's possible.\n */\nexport function randomItem<T>(array: ReadonlyArray<T>): T {\n\tif (array.length === 0) {\n\t\tthrow new Error(\"randomItem called on empty array\");\n\t}\n\n\treturn array[(Math.random() * array.length) | 0];\n}\n\n/**\n * Remove an entry of an Array\n */\nexport function remove<T>(arr: T[], item: T): void {\n\tconst index = arr.indexOf(item);\n\tif (index >= 0) {\n\t\tarr.splice(index, 1);\n\t}\n}\n\n/**\n * Shuffle array using Fisher-Yates algorithm with custom random signer\n */\nexport function shuffle<T>(arr: ReadonlyArray<T>): T[] {\n\tconst result = arr.slice();\n\n\tfor (let i = result.length - 1; i > 0; i--) {\n\t\tconst j = Math.floor(Math.random() * (i + 1));\n\t\t[result[i], result[j]] = [result[j], result[i]];\n\t}\n\n\treturn result;\n}\n", "import AudioBase from \"./AudioBase\";\nimport { clamp } from \"@/utilities/Number\";\nimport { type EasingName, EASINGS } from \"@/utilities/Easing\";\nimport { rafLoop } from \"@/utilities/Functions\";\nimport { randomItem, remove } from \"@/utilities/Array\";\n\nexport default class Music extends AudioBase {\n\tprivate last: HTMLAudioElement | null = null;\n\tprivate current: HTMLAudioElement | null = null;\n\tprivate next: HTMLAudioElement | null = null;\n\tprivate fadeCancel: (() => void) | null = null;\n\n\tpublic get isPlaying(): boolean {\n\t\treturn (\n\t\t\t!!this.fadeCancel ||\n\t\t\t(this.current instanceof window.Audio && !this.current.paused)\n\t\t);\n\t}\n\n\tpublic get enabled(): boolean {\n\t\treturn super.enabled;\n\t}\n\n\tpublic set enabled(value: boolean) {\n\t\tsuper.enabled = value;\n\n\t\tif (value && !this.isPlaying) {\n\t\t\tthis.fade();\n\t\t}\n\t}\n\n\tpublic fade(\n\t\tname: string | null = null,\n\t\tfadeTime: number = 1000,\n\t\teasing: {\n\t\t\tcur: EasingName;\n\t\t\tnext: EasingName;\n\t\t} = {\n\t\t\tcur: \"ease-in\",\n\t\t\tnext: \"ease-out\",\n\t\t},\n\t): void {\n\t\tif (fadeTime <= 0) {\n\t\t\tthrow new Error(`fadeTime must be > 0, got ${fadeTime}`);\n\t\t}\n\n\t\tif (this.songs.size === 0) {\n\t\t\tthrow new Error(\"No music registered!\");\n\t\t}\n\n\t\tif (name && !this.songs.has(name)) {\n\t\t\tthrow new Error(`Music \"${name}\" not registered!`);\n\t\t}\n\n\t\tif (!this.enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.fadeCancel) {\n\t\t\tconsole.warn(\"Stopping current music fading.\");\n\t\t\tthis.fadeCancel();\n\t\t\tthis.fadeCancel = null;\n\t\t\tthis.current?.stop();\n\t\t\tthis.current = this.next;\n\t\t\tthis.next = null;\n\t\t}\n\n\t\tif (this.songs.size === 1) {\n\t\t\tconsole.info(\"Only one music registered, playing that looped.\");\n\t\t\tthis.current = this.songs.values().next().value!;\n\t\t\tthis.current.loop = true;\n\t\t\tthis.current.play();\n\t\t\treturn;\n\t\t}\n\n\t\tif (name) {\n\t\t\tthis.next = this.songs.get(name)!;\n\t\t} else {\n\t\t\tthis.next = this.getRandom();\n\n\t\t\tif (!this.next) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"Not enough songs to pick a fresh one, replaying the previous one.\",\n\t\t\t\t);\n\t\t\t\tthis.next = this.last!;\n\t\t\t}\n\t\t}\n\n\t\tthis.next.onended = (): void => {\n\t\t\tthis.fade();\n\t\t};\n\t\tthis.next.volume = 0;\n\t\tthis.next.play();\n\n\t\tconsole.log(`Start fading to music: \"${this.next.id}\"`);\n\n\t\tif (this.current) {\n\t\t\tthis.current.onended = (): void => void 0;\n\t\t}\n\n\t\tconst curEase = EASINGS[easing.cur];\n\t\tconst nextEase = EASINGS[easing.next];\n\t\tconst fadeTimeSeconds = fadeTime / 1000;\n\n\t\tlet time = 0;\n\t\tconst curStartVolume = this.current?.volume ?? 0;\n\t\tthis.fadeCancel = rafLoop(dt => {\n\t\t\ttime += dt / fadeTimeSeconds;\n\n\t\t\tif (this.current) {\n\t\t\t\tthis.current.volume =\n\t\t\t\t\tcurStartVolume * (1 - clamp(curEase(time), 0, 1));\n\t\t\t}\n\n\t\t\tthis.next!.volume =\n\t\t\t\tthis.next!.defaultVolume! * clamp(nextEase(time), 0, 1);\n\n\t\t\tif (time >= 1) {\n\t\t\t\tthis.fadeCancel?.();\n\t\t\t\tthis.fadeCancel = null;\n\n\t\t\t\tif (this.current) {\n\t\t\t\t\tthis.current.stop();\n\t\t\t\t\tthis.current.volume = this.current.defaultVolume!;\n\t\t\t\t}\n\n\t\t\t\tthis.next!.volume = this.next!.defaultVolume!;\n\n\t\t\t\tthis.last = this.current;\n\t\t\t\tthis.current = this.next;\n\t\t\t\tthis.next = null;\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic stop(): void {\n\t\tsuper.stop();\n\n\t\tthis.fadeCancel?.();\n\t\tthis.fadeCancel = null;\n\n\t\tthis.current?.stop();\n\t\tthis.next?.stop();\n\n\t\tthis.last = this.current;\n\t\tthis.current = this.next;\n\t\tthis.next = null;\n\t}\n\n\tprivate getRandom(): HTMLAudioElement | null {\n\t\tconst allSongs = Array.from(this.songs.values());\n\n\t\tif (this.last) {\n\t\t\tremove(allSongs, this.last);\n\t\t}\n\n\t\tif (this.current) {\n\t\t\tremove(allSongs, this.current);\n\t\t}\n\n\t\tif (allSongs.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn randomItem(allSongs);\n\t}\n}\n", "import AudioBase from \"./AudioBase\";\nimport { remove } from \"@/utilities/Array\";\n\nexport default class Sound extends AudioBase {\n\tprivate currentSounds: HTMLAudioElement[] = [];\n\n\tpublic play(name: string): Promise<void> {\n\t\tif (this.songs.size === 0) {\n\t\t\tthrow new Error(\"No sounds registered!\");\n\t\t}\n\n\t\tif (!this.songs.has(name)) {\n\t\t\tthrow new Error(`Sound \"${name}\" not registered!`);\n\t\t}\n\n\t\tif (!this.enabled) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tconst newSound = this.songs.get(name)!.clone();\n\t\tthis.currentSounds.push(newSound);\n\n\t\tconst cleanup = (): void => remove(this.currentSounds, newSound);\n\t\tnewSound.onended = cleanup;\n\t\tnewSound.onerror = (): void => {\n\t\t\tcleanup();\n\t\t\tconsole.error(\n\t\t\t\t`Playback failed for Sound \"${name}\", reason: ${newSound.error?.message ?? \"unknown\"}`,\n\t\t\t);\n\t\t};\n\n\t\treturn newSound.play().catch((err): void => {\n\t\t\tcleanup();\n\t\t\tthrow err;\n\t\t});\n\t}\n\n\tpublic stop(): void {\n\t\tsuper.stop();\n\n\t\tthis.currentSounds.forEach(audio => audio.stop());\n\t\tthis.currentSounds.length = 0;\n\t}\n}\n", "import { throttle } from \"./Functions\";\nimport { wrapValue } from \"./Number\";\n\nconst NUMERIC_PATTERN = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\n\n/**\n * Check if a value is a finite number or a string holding one. Accepts optional leading sign, decimal forms (`.5`, `5.`, `3.14`), and scientific notation (`1e5`, `-3.14e-2`).\n */\nexport function isNumeric(value: unknown): boolean {\n\tif (typeof value === \"number\") {\n\t\treturn Number.isFinite(value);\n\t}\n\n\tif (typeof value === \"string\") {\n\t\treturn NUMERIC_PATTERN.test(value.trim());\n\t}\n\n\treturn false;\n}\n\n/**\n * Generate a random angle between 0 and 2-PI in radians\n */\nexport function random2Pi(): number {\n\treturn Math.random() * Math.PI * 2;\n}\n\n/**\n * Generate a random float between two values. Bounds may be passed in either order.\n */\nexport function randomBetweenFloat(min: number, max: number): number {\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Generate a random integer in `[min, max]` (both bounds inclusive). Bounds may be passed in either order.\n */\nexport function randomBetweenInt(min: number, max: number): number {\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\treturn Math.floor(min + Math.random() * (max - min + 1));\n}\n\n/**\n * Generate a random boolean value\n */\nexport function randomBoolean(): boolean {\n\treturn Math.random() >= 0.5;\n}\n\n/**\n * Generate a random sign (1 or -1)\n */\nexport function randomSign(): number {\n\treturn randomBoolean() ? 1 : -1;\n}\n\nconst warnInvalidTime = throttle(count => {\n\tconsole.warn(\n\t\t`toHHMMSS() received invalid input (NaN, Infinity, or negative) x${count} since last warning; returning \"00:00\".`,\n\t);\n});\n\n/**\n * Format time in seconds as HH:MM:SS string\n */\nexport function toHHMMSS(time: number): string {\n\tif (!Number.isFinite(time) || time < 0) {\n\t\twarnInvalidTime();\n\t\treturn \"00:00\";\n\t}\n\n\ttime = Math.floor(time);\n\n\tconst h = Math.floor(time / 3600);\n\tconst m = Math.floor((time - h * 3600) / 60);\n\tconst s = time - h * 3600 - m * 60;\n\n\tconst hours = h < 10 ? \"0\" + h : \"\" + h;\n\tconst minutes = m < 10 ? \"0\" + m : \"\" + m;\n\tconst seconds = s < 10 ? \"0\" + s : \"\" + s;\n\n\tif (h === 0) {\n\t\treturn `${minutes}:${seconds}`;\n\t}\n\n\treturn `${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * Convert radians to degrees\n */\nexport function toDegrees(radians: number): number {\n\treturn (radians * 180) / Math.PI;\n}\n\n/**\n * Convert degrees to radians\n */\nexport function toRadians(degrees: number): number {\n\treturn (degrees * Math.PI) / 180;\n}\n\n/**\n * Wrap an angle in radians into `[-PI, PI)`.\n */\nexport function wrapRadians(angle: number): number {\n\treturn wrapValue(angle, -Math.PI, Math.PI);\n}\n\n/**\n * Wrap an angle in degrees into `[-180, 180)`.\n */\nexport function wrapDegrees(angle: number): number {\n\treturn wrapValue(angle, -180, 180);\n}\n\n/**\n * Round a number to a specified number of decimal places\n */\nexport function roundTo(number: number, digitsAfterPoint: number): number {\n\tconst power = Math.pow(10, digitsAfterPoint);\n\n\treturn Math.round(number * power) / power;\n}\n\nconst factorialsCache: Record<number, number> = { 0: 1 };\nlet largestCachedFactorial = 0;\nlet factorialOverflowAt = Infinity;\n\n/**\n * Calculate factorial of a non-negative integer. Memoized \u2014 repeat calls reuse cached intermediates.\n * Returns `Infinity` once `n!` overflows the IEEE 754 double range (around `n = 171`).\n */\nexport function getFactorial(n: number): number {\n\tconst intN = Math.floor(n);\n\n\tif (intN < 0 || !Number.isFinite(intN)) {\n\t\tthrow new Error(\"getFactorial requires non-negative integer\");\n\t}\n\n\tif (intN >= factorialOverflowAt) {\n\t\treturn Infinity;\n\t}\n\n\tif (factorialsCache[intN] !== undefined) {\n\t\treturn factorialsCache[intN];\n\t}\n\n\tlet result = factorialsCache[largestCachedFactorial];\n\tfor (let i = largestCachedFactorial + 1; i <= intN; i++) {\n\t\tresult *= i;\n\n\t\tif (!Number.isFinite(result)) {\n\t\t\tfactorialOverflowAt = i;\n\t\t\treturn Infinity;\n\t\t}\n\n\t\tfactorialsCache[i] = result;\n\t\tlargestCachedFactorial = i;\n\t}\n\n\treturn result;\n}\n", "import { randomBetweenInt } from \"./Math\";\n\nexport type RGB = [number, number, number];\n\n/**\n * Convert an `(r, g, b)` triple (0-255) to a `#rrggbb` hex string.\n * Low-level; prefer `Color.toHex()` outside hot per-pixel loops.\n */\nexport function rgb2hex(red: number, green: number, blue: number): string {\n\treturn \"#\" + (0x1000000 + rgb2Int(red, green, blue)).toString(16).slice(1);\n}\n\n/**\n * Pack `(r, g, b[, a])` channels into a single integer key.\n * RGB are 0-255. Alpha is 0-1 (CSS convention); divide canvas byte-alpha by 255 before passing.\n * Without alpha: 24-bit `RGB`. With alpha: 32-bit `RGBA` (forced unsigned).\n * Useful for fast per-pixel lookups: cheaper than building a hex string.\n */\nexport function rgb2Int(\n\tred: number,\n\tgreen: number,\n\tblue: number,\n\talpha?: number,\n): number {\n\tif (alpha === undefined) {\n\t\treturn (red << 16) | (green << 8) | blue;\n\t}\n\n\tconst a = Math.round(alpha * 255);\n\treturn ((red << 24) | (green << 16) | (blue << 8) | a) >>> 0;\n}\n\n/**\n * Convert a `#rgb` or `#rrggbb` hex string to an `[r, g, b]` integer tuple.\n * Low-level; prefer `Color.fromHex()` outside hot per-pixel loops. Caller must pass a valid hex string.\n */\nexport function hex2rgb(hex: string): RGB {\n\treturn hex\n\t\t.replace(\n\t\t\t/^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n\t\t\t(_: string, r: string, g: string, b: string) =>\n\t\t\t\t\"#\" + r + r + g + g + b + b,\n\t\t)\n\t\t.substring(1)\n\t\t.match(/.{2}/g)!\n\t\t.map((x: string) => parseInt(x, 16)) as RGB;\n}\n\n/**\n * HSL \u2192 RGB channel helper used by `Color.fromHSL`. Inputs are normalized to `[0, 1]`.\n */\nexport function hue2rgb(p: number, q: number, t: number): number {\n\tif (t < 0) {\n\t\tt += 1;\n\t}\n\n\tif (t > 1) {\n\t\tt -= 1;\n\t}\n\n\tif (t < 1 / 6) {\n\t\treturn p + (q - p) * 6 * t;\n\t}\n\n\tif (t < 1 / 2) {\n\t\treturn q;\n\t}\n\n\tif (t < 2 / 3) {\n\t\treturn p + (q - p) * (2 / 3 - t) * 6;\n\t}\n\n\treturn p;\n}\n\n/**\n * Random `#rgb` short hex color.\n */\nexport function randomHex(): string {\n\t// Can in theory return <4 hex digits if Math.random() lands on a value with trailing zeros (probability \u2248 2^-40).\n\treturn \"#\" + Math.random().toString(16).slice(2, 6);\n}\n\n/**\n * Random `[r, g, b]` integer tuple; each channel uniform in `[min, max]`.\n */\nexport function randomRgb(min = 0, max = 255): RGB {\n\treturn [\n\t\trandomBetweenInt(min, max),\n\t\trandomBetweenInt(min, max),\n\t\trandomBetweenInt(min, max),\n\t];\n}\n", "import { approxEqual, clamp, wrapValue } from \"@/utilities/Number\";\nimport { hue2rgb } from \"@/utilities/Color\";\n\nexport class Color {\n\tpublic static fromHex(hex: string): Color {\n\t\tlet cleanHex = hex.replace(\"#\", \"\").toUpperCase();\n\n\t\tif (!/^[0-9A-F]+$/.test(cleanHex)) {\n\t\t\tthrow new Error(`Invalid hex color: ${hex}`);\n\t\t}\n\n\t\tif (cleanHex.length === 3 || cleanHex.length === 4) {\n\t\t\tcleanHex = cleanHex\n\t\t\t\t.split(\"\")\n\t\t\t\t.map(c => c + c)\n\t\t\t\t.join(\"\");\n\t\t}\n\n\t\tif (cleanHex.length !== 6 && cleanHex.length !== 8) {\n\t\t\tthrow new Error(`Invalid hex color: ${hex}`);\n\t\t}\n\n\t\tconst r = parseInt(cleanHex.slice(0, 2), 16);\n\t\tconst g = parseInt(cleanHex.slice(2, 4), 16);\n\t\tconst b = parseInt(cleanHex.slice(4, 6), 16);\n\n\t\tif (cleanHex.length === 8) {\n\t\t\tconst a = parseInt(cleanHex.slice(6, 8), 16);\n\n\t\t\treturn new Color(r, g, b, a / 255);\n\t\t}\n\n\t\treturn new Color(r, g, b);\n\t}\n\n\tpublic static fromHSL(\n\t\th: number,\n\t\ts: number,\n\t\tl: number,\n\t\ta: number = 1,\n\t): Color {\n\t\tconst hNorm = wrapValue(h, 0, 360) / 360;\n\t\tconst sNorm = s / 100;\n\t\tconst lNorm = l / 100;\n\n\t\tlet r, g, b;\n\n\t\tif (sNorm === 0) {\n\t\t\tr = g = b = lNorm;\n\t\t} else {\n\t\t\tconst q =\n\t\t\t\tlNorm < 0.5\n\t\t\t\t\t? lNorm * (1 + sNorm)\n\t\t\t\t\t: lNorm + sNorm - lNorm * sNorm;\n\t\t\tconst p = 2 * lNorm - q;\n\t\t\tr = hue2rgb(p, q, hNorm + 1 / 3);\n\t\t\tg = hue2rgb(p, q, hNorm);\n\t\t\tb = hue2rgb(p, q, hNorm - 1 / 3);\n\t\t}\n\n\t\treturn new Color(r * 255, g * 255, b * 255, a);\n\t}\n\n\tprivate _r!: number;\n\tprivate _g!: number;\n\tprivate _b!: number;\n\tprivate _alpha: number = 1;\n\n\tpublic get r(): number {\n\t\treturn this._r;\n\t}\n\n\tpublic get g(): number {\n\t\treturn this._g;\n\t}\n\n\tpublic get b(): number {\n\t\treturn this._b;\n\t}\n\n\tpublic get alpha(): number {\n\t\treturn this._alpha;\n\t}\n\n\tconstructor(r: number, g: number, b: number, a?: number) {\n\t\tthis.set(r, g, b, a);\n\t}\n\n\tpublic set(r: number, g: number, b: number, a?: number): this {\n\t\tthis._r = clamp(r, 0, 255);\n\t\tthis._g = clamp(g, 0, 255);\n\t\tthis._b = clamp(b, 0, 255);\n\n\t\tif (a !== undefined) {\n\t\t\tconst clamped = clamp(a, 0, 1);\n\t\t\tthis._alpha = approxEqual(clamped, 0)\n\t\t\t\t? 0\n\t\t\t\t: approxEqual(clamped, 1)\n\t\t\t\t\t? 1\n\t\t\t\t\t: clamped;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tpublic applyMatrix(\n\t\tm1: number,\n\t\tm2: number,\n\t\tm3: number,\n\t\tm4: number,\n\t\tm5: number,\n\t\tm6: number,\n\t\tm7: number,\n\t\tm8: number,\n\t\tm9: number,\n\t): this {\n\t\treturn this.set(\n\t\t\tthis.r * m1 + this.g * m2 + this.b * m3,\n\t\t\tthis.r * m4 + this.g * m5 + this.b * m6,\n\t\t\tthis.r * m7 + this.g * m8 + this.b * m9,\n\t\t);\n\t}\n\n\tpublic brightness(factor: number): this {\n\t\treturn this.set(this.r * factor, this.g * factor, this.b * factor);\n\t}\n\n\tpublic contrast(factor: number): this {\n\t\tconst midtone = 127.5;\n\t\treturn this.set(\n\t\t\tmidtone + (this.r - midtone) * factor,\n\t\t\tmidtone + (this.g - midtone) * factor,\n\t\t\tmidtone + (this.b - midtone) * factor,\n\t\t);\n\t}\n\n\tpublic grayscale(value: number = 1): this {\n\t\tconst m1 = 0.2126 + 0.7874 * (1 - value);\n\t\tconst m2 = 0.7152 - 0.7152 * (1 - value);\n\t\tconst m3 = 0.0722 - 0.0722 * (1 - value);\n\t\tconst m4 = 0.2126 - 0.2126 * (1 - value);\n\t\tconst m5 = 0.7152 + 0.2848 * (1 - value);\n\t\tconst m6 = 0.0722 - 0.0722 * (1 - value);\n\t\tconst m7 = 0.2126 - 0.2126 * (1 - value);\n\t\tconst m8 = 0.7152 - 0.7152 * (1 - value);\n\t\tconst m9 = 0.0722 + 0.9278 * (1 - value);\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\tpublic hueRotate(radians: number): this {\n\t\tconst cos = Math.cos(radians);\n\t\tconst sin = Math.sin(radians);\n\n\t\tconst m1 = 0.213 + cos * 0.787 - sin * 0.213;\n\t\tconst m2 = 0.715 - cos * 0.715 - sin * 0.715;\n\t\tconst m3 = 0.072 - cos * 0.072 + sin * 0.928;\n\t\tconst m4 = 0.213 - cos * 0.213 + sin * 0.143;\n\t\tconst m5 = 0.715 + cos * 0.285 + sin * 0.14;\n\t\tconst m6 = 0.072 - cos * 0.072 - sin * 0.283;\n\t\tconst m7 = 0.213 - cos * 0.213 - sin * 0.787;\n\t\tconst m8 = 0.715 - cos * 0.715 + sin * 0.715;\n\t\tconst m9 = 0.072 + cos * 0.928 + sin * 0.072;\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\tpublic invert(factor: number = 1): this {\n\t\treturn this.set(\n\t\t\tthis.r * (1 - factor) + (255 - this.r) * factor,\n\t\t\tthis.g * (1 - factor) + (255 - this.g) * factor,\n\t\t\tthis.b * (1 - factor) + (255 - this.b) * factor,\n\t\t);\n\t}\n\n\tpublic mix(other: Color, amount: number): this {\n\t\tconst inv = 1 - amount;\n\n\t\treturn this.set(\n\t\t\tthis.r * inv + other.r * amount,\n\t\t\tthis.g * inv + other.g * amount,\n\t\t\tthis.b * inv + other.b * amount,\n\t\t\tthis.alpha * inv + other.alpha * amount,\n\t\t);\n\t}\n\n\tpublic round(): this {\n\t\treturn this.set(\n\t\t\tMath.round(this.r),\n\t\t\tMath.round(this.g),\n\t\t\tMath.round(this.b),\n\t\t);\n\t}\n\n\tpublic saturate(value: number = 1): this {\n\t\tconst m1 = 0.213 + 0.787 * value;\n\t\tconst m2 = 0.715 - 0.715 * value;\n\t\tconst m3 = 0.072 - 0.072 * value;\n\t\tconst m4 = 0.213 - 0.213 * value;\n\t\tconst m5 = 0.715 + 0.285 * value;\n\t\tconst m6 = 0.072 - 0.072 * value;\n\t\tconst m7 = 0.213 - 0.213 * value;\n\t\tconst m8 = 0.715 - 0.715 * value;\n\t\tconst m9 = 0.072 + 0.928 * value;\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\tpublic sepia(value: number = 1): this {\n\t\tconst m1 = 0.393 + 0.607 * (1 - value);\n\t\tconst m2 = 0.769 - 0.769 * (1 - value);\n\t\tconst m3 = 0.189 - 0.189 * (1 - value);\n\t\tconst m4 = 0.349 - 0.349 * (1 - value);\n\t\tconst m5 = 0.686 + 0.314 * (1 - value);\n\t\tconst m6 = 0.168 - 0.168 * (1 - value);\n\t\tconst m7 = 0.272 - 0.272 * (1 - value);\n\t\tconst m8 = 0.534 - 0.534 * (1 - value);\n\t\tconst m9 = 0.131 + 0.869 * (1 - value);\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\tpublic shade(percent: number): this {\n\t\tconst target = percent < 0 ? 0 : 255;\n\t\tconst p = Math.abs(percent);\n\n\t\treturn this.set(\n\t\t\tthis.r + (target - this.r) * p,\n\t\t\tthis.g + (target - this.g) * p,\n\t\t\tthis.b + (target - this.b) * p,\n\t\t);\n\t}\n\n\tpublic toHex(): string {\n\t\tconst r = Math.round(this.r).toString(16).padStart(2, \"0\");\n\t\tconst g = Math.round(this.g).toString(16).padStart(2, \"0\");\n\t\tconst b = Math.round(this.b).toString(16).padStart(2, \"0\");\n\t\tconst rgb = `#${r}${g}${b}`;\n\n\t\tif (this.alpha === 1) {\n\t\t\treturn rgb;\n\t\t}\n\n\t\tconst a = Math.round(this.alpha * 255);\n\t\treturn `${rgb}${a.toString(16).padStart(2, \"0\")}`;\n\t}\n\n\tpublic toHSL(): string {\n\t\tconst { h, s, l } = this.toHSLObject();\n\t\tconst cssH = Math.round(h);\n\t\tconst cssS = Math.round(s);\n\t\tconst cssL = Math.round(l);\n\n\t\treturn this.alpha === 1\n\t\t\t? `hsl(${cssH}, ${cssS}%, ${cssL}%)`\n\t\t\t: `hsla(${cssH}, ${cssS}%, ${cssL}%, ${this.alpha.toFixed(2)})`;\n\t}\n\n\tpublic toHSLObject(): { h: number; s: number; l: number; a: number } {\n\t\tconst r = this.r / 255;\n\t\tconst g = this.g / 255;\n\t\tconst b = this.b / 255;\n\n\t\tconst max = Math.max(r, g, b);\n\t\tconst min = Math.min(r, g, b);\n\t\tconst l = (max + min) / 2;\n\t\tlet h = 0;\n\t\tlet s = 0;\n\n\t\tif (max !== min) {\n\t\t\tconst d = max - min;\n\t\t\ts = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n\t\t\tswitch (max) {\n\t\t\t\tcase r:\n\t\t\t\t\th = (g - b) / d + (g < b ? 6 : 0);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase g:\n\t\t\t\t\th = (b - r) / d + 2;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase b:\n\t\t\t\t\th = (r - g) / d + 4;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\th /= 6;\n\t\t}\n\n\t\treturn { h: h * 360, s: s * 100, l: l * 100, a: this.alpha };\n\t}\n\n\tpublic toRGB(): string {\n\t\tconst r = Math.round(this.r);\n\t\tconst g = Math.round(this.g);\n\t\tconst b = Math.round(this.b);\n\n\t\treturn this.alpha === 1\n\t\t\t? `rgb(${r}, ${g}, ${b})`\n\t\t\t: `rgba(${r}, ${g}, ${b}, ${this.alpha.toFixed(2)})`;\n\t}\n\n\tpublic clone(): Color {\n\t\treturn new Color(this.r, this.g, this.b, this.alpha);\n\t}\n\n\tpublic equals(other: Color, compareAlpha: boolean = true): boolean {\n\t\treturn (\n\t\t\tapproxEqual(this.r, other.r) &&\n\t\t\tapproxEqual(this.g, other.g) &&\n\t\t\tapproxEqual(this.b, other.b) &&\n\t\t\t(!compareAlpha || approxEqual(this.alpha, other.alpha))\n\t\t);\n\t}\n}\n", "import { Color } from \"./Color\";\nimport { wrapDegrees } from \"@/utilities/Math\";\nimport { wrapValue } from \"@/utilities/Number\";\nimport type { RGB } from \"@/utilities/Color\";\n\ntype FilterValues = [\n\tinvert: number,\n\tsepia: number,\n\tsaturate: number,\n\thueRotate: number,\n\tbrightness: number,\n\tcontrast: number,\n];\n\ninterface SpsaResult {\n\tvalues: FilterValues;\n\tloss: number;\n}\n\nconst SATURATE = 2;\nconst HUE_ROTATE = 3;\nconst BRIGHTNESS = 4;\nconst CONTRAST = 5;\n\n/**\n * Used when hue-rotate does not work e.g. on dark images\n * Based on https://codepen.io/sosuke/pen/Pjoqqp\n * https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters/43960991#43960991\n *\n * As the result does vary because of a Math.random(),\n * I would suggest console.log some filters, pick nice ones and hardcode them instead:\n * console.log(colorShifter(randomRgb(1, 10)));\n */\nexport function colorShifter(rgb: RGB) {\n\tconst color = new Color(rgb[0], rgb[1], rgb[2]);\n\tconst solver = new Solver(color);\n\tconst result = solver.solve();\n\n\treturn result.filter.replace(\"filter: \", \"\").replace(\";\", \"\");\n}\n\nclass Solver {\n\tprivate reusedColor: Color;\n\tprivate target: Color;\n\tprivate targetHSL: {\n\t\th: number;\n\t\ts: number;\n\t\tl: number;\n\t};\n\n\tconstructor(target: Color) {\n\t\tthis.target = target;\n\t\tthis.targetHSL = target.toHSLObject();\n\t\tthis.reusedColor = new Color(0, 0, 0);\n\t}\n\n\tpublic css(filters: FilterValues): string {\n\t\tconst [invert, sepia, saturate, hueRotate, brightness, contrast] =\n\t\t\tfilters;\n\n\t\treturn `filter: invert(${Math.round(invert)}%) sepia(${Math.round(sepia)}%) saturate(${Math.round(saturate)}%) hue-rotate(${Math.round(hueRotate * 3.6)}deg) brightness(${Math.round(brightness)}%) contrast(${Math.round(contrast)}%);`;\n\t}\n\n\tpublic loss(filters: FilterValues): number {\n\t\tconst [invert, sepia, saturate, hueRotate, brightness, contrast] =\n\t\t\tfilters;\n\t\tconst color = this.reusedColor;\n\t\tcolor.set(0, 0, 0);\n\n\t\tcolor.invert(invert / 100);\n\t\tcolor.sepia(sepia / 100);\n\t\tcolor.saturate(saturate / 100);\n\t\tcolor.hueRotate((hueRotate / 100) * Math.PI * 2);\n\t\tcolor.brightness(brightness / 100);\n\t\tcolor.contrast(contrast / 100);\n\n\t\tconst colorHSL = color.toHSLObject();\n\n\t\treturn (\n\t\t\tMath.abs(color.r - this.target.r) +\n\t\t\tMath.abs(color.g - this.target.g) +\n\t\t\tMath.abs(color.b - this.target.b) +\n\t\t\t// h is cyclic 0-360; wrap diff into \u00B1180 then scale to 0-100 to keep loss balance with the other terms\n\t\t\tMath.abs(wrapDegrees(colorHSL.h - this.targetHSL.h)) / 1.8 +\n\t\t\tMath.abs(colorHSL.s - this.targetHSL.s) +\n\t\t\tMath.abs(colorHSL.l - this.targetHSL.l)\n\t\t);\n\t}\n\n\tpublic solve(): SpsaResult & { filter: string } {\n\t\tconst result = this.solveNarrow(this.solveWide());\n\n\t\treturn {\n\t\t\tvalues: result.values,\n\t\t\tloss: result.loss,\n\t\t\tfilter: this.css(result.values),\n\t\t};\n\t}\n\n\tpublic solveNarrow(wide: SpsaResult): SpsaResult {\n\t\tconst A = wide.loss;\n\t\tconst c = 2;\n\t\tconst A1 = A + 1;\n\t\tconst a: FilterValues = [\n\t\t\t0.25 * A1,\n\t\t\t0.25 * A1,\n\t\t\tA1,\n\t\t\t0.25 * A1,\n\t\t\t0.2 * A1,\n\t\t\t0.2 * A1,\n\t\t];\n\n\t\treturn this.spsa(A, a, c, wide.values, 500);\n\t}\n\n\tpublic solveWide(): SpsaResult {\n\t\tconst A = 5;\n\t\tconst c = 15;\n\t\tconst a: FilterValues = [60, 180, 18000, 600, 1.2, 1.2];\n\n\t\tlet best: SpsaResult = {\n\t\t\tloss: Infinity,\n\t\t\tvalues: [50, 20, 3750, 50, 100, 100],\n\t\t};\n\t\tfor (let i = 0; best.loss > 25 && i < 3; i++) {\n\t\t\tconst initial: FilterValues = [50, 20, 3750, 50, 100, 100];\n\t\t\tconst result = this.spsa(A, a, c, initial, 1000);\n\t\t\tif (result.loss < best.loss) {\n\t\t\t\tbest = result;\n\t\t\t}\n\t\t}\n\n\t\treturn best;\n\t}\n\n\tpublic spsa(\n\t\tA: number,\n\t\ta: FilterValues,\n\t\tc: number,\n\t\tvalues: FilterValues,\n\t\titers: number,\n\t): SpsaResult {\n\t\tvalues = values.slice() as FilterValues;\n\t\tconst alpha = 1;\n\t\tconst gamma = 0.16666666666666666;\n\n\t\tlet best: FilterValues = values.slice() as FilterValues;\n\t\tlet bestLoss = Infinity;\n\t\tconst deltas: FilterValues = [0, 0, 0, 0, 0, 0];\n\t\tconst highArgs: FilterValues = [0, 0, 0, 0, 0, 0];\n\t\tconst lowArgs: FilterValues = [0, 0, 0, 0, 0, 0];\n\n\t\tfor (let k = 0; k < iters; k++) {\n\t\t\tconst ck = c / Math.pow(k + 1, gamma);\n\t\t\tfor (let i = 0; i < 6; i++) {\n\t\t\t\tdeltas[i] = Math.random() > 0.5 ? 1 : -1;\n\t\t\t\thighArgs[i] = values[i] + ck * deltas[i];\n\t\t\t\tlowArgs[i] = values[i] - ck * deltas[i];\n\t\t\t}\n\n\t\t\tconst lossDiff = this.loss(highArgs) - this.loss(lowArgs);\n\t\t\tfor (let i = 0; i < 6; i++) {\n\t\t\t\tconst g = (lossDiff / (2 * ck)) * deltas[i];\n\t\t\t\tconst ak = a[i] / Math.pow(A + k + 1, alpha);\n\t\t\t\tvalues[i] = fix(values[i] - ak * g, i);\n\t\t\t}\n\n\t\t\tconst loss = this.loss(values);\n\t\t\tif (loss < bestLoss) {\n\t\t\t\tbest = values.slice() as FilterValues;\n\t\t\t\tbestLoss = loss;\n\t\t\t}\n\t\t}\n\n\t\treturn { values: best, loss: bestLoss };\n\n\t\tfunction fix(value: number, idx: number): number {\n\t\t\tlet max = 100;\n\t\t\tif (idx === SATURATE) {\n\t\t\t\tmax = 7500;\n\t\t\t} else if (idx === BRIGHTNESS || idx === CONTRAST) {\n\t\t\t\tmax = 200;\n\t\t\t}\n\n\t\t\tif (idx === HUE_ROTATE) {\n\t\t\t\tvalue = wrapValue(value, 0, max);\n\t\t\t} else if (value < 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else if (value > max) {\n\t\t\t\tvalue = max;\n\t\t\t}\n\n\t\t\treturn value;\n\t\t}\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Polygon from \"@/math/Polygon\";\nimport { approxEqual } from \"@/utilities/Number\";\nimport type { Vector2, Vector4 } from \"@/math/Vec2\";\n\ninterface Sides {\n\tbottom: number;\n\tcenterPos: Vec2;\n\thalfSize: Vec2;\n\tright: number;\n}\n\nexport default class Rect {\n\tpublic static fromBoundingClientRect(rect: DOMRect | HTMLElement): Rect {\n\t\tif (rect instanceof HTMLElement) {\n\t\t\trect = rect.getBoundingClientRect();\n\t\t}\n\n\t\treturn new Rect(rect.left, rect.top, rect.width, rect.height);\n\t}\n\n\tpublic static fromPolygon(polygon: Polygon): Rect {\n\t\tif (polygon.points.length === 0) {\n\t\t\tthrow new Error(\"Supplied polygon has no points!\");\n\t\t}\n\n\t\tlet minX = Infinity;\n\t\tlet minY = Infinity;\n\t\tlet maxX = -Infinity;\n\t\tlet maxY = -Infinity;\n\n\t\tpolygon.points.forEach(point => {\n\t\t\tif (point.x < minX) {\n\t\t\t\tminX = point.x;\n\t\t\t}\n\n\t\t\tif (point.x > maxX) {\n\t\t\t\tmaxX = point.x;\n\t\t\t}\n\n\t\t\tif (point.y < minY) {\n\t\t\t\tminY = point.y;\n\t\t\t}\n\n\t\t\tif (point.y > maxY) {\n\t\t\t\tmaxY = point.y;\n\t\t\t}\n\t\t});\n\n\t\treturn new Rect(minX, minY, maxX - minX, maxY - minY);\n\t}\n\n\tprivate _h = 0;\n\tprivate _w = 0;\n\tprivate _x = 0;\n\tprivate _y = 0;\n\tprivate _sides!: Sides;\n\tprivate sideIsDirty: boolean = true;\n\n\tpublic get h(): number {\n\t\treturn this._h;\n\t}\n\n\tpublic set h(value: number) {\n\t\tthis._h = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\tpublic get w(): number {\n\t\treturn this._w;\n\t}\n\n\tpublic set w(value: number) {\n\t\tthis._w = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\tpublic get x(): number {\n\t\treturn this._x;\n\t}\n\n\tpublic set x(value: number) {\n\t\tthis._x = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\tpublic get y(): number {\n\t\treturn this._y;\n\t}\n\n\tpublic set y(value: number) {\n\t\tthis._y = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\tpublic get sides(): Readonly<Sides> {\n\t\tif (this.sideIsDirty) {\n\t\t\tthis._sides = {\n\t\t\t\tbottom: this.y + this.h,\n\t\t\t\tcenterPos: new Vec2(\n\t\t\t\t\tthis.x + this.w * 0.5,\n\t\t\t\t\tthis.y + this.h * 0.5,\n\t\t\t\t),\n\t\t\t\thalfSize: new Vec2(this.w * 0.5, this.h * 0.5),\n\t\t\t\tright: this.x + this.w,\n\t\t\t};\n\n\t\t\tthis.sideIsDirty = false;\n\t\t}\n\n\t\treturn this._sides;\n\t}\n\n\tconstructor(x = 0, y = 0, w = 0, h = 0) {\n\t\tthis.set(x, y, w, h);\n\t}\n\n\tpublic inflate(delta: number): Rect {\n\t\tthis.x -= delta;\n\t\tthis.y -= delta;\n\n\t\tthis.w += 2 * delta;\n\t\tthis.h += 2 * delta;\n\n\t\tthis.sideIsDirty = true;\n\n\t\treturn this;\n\t}\n\n\tpublic round(): Rect {\n\t\tthis.x = Math.round(this.x);\n\t\tthis.y = Math.round(this.y);\n\n\t\tthis.sideIsDirty = true;\n\n\t\treturn this;\n\t}\n\n\tpublic set(\n\t\tx: Vector4 | Vector2 | number = 0,\n\t\ty: number = 0,\n\t\tw?: number,\n\t\th?: number,\n\t): Rect {\n\t\tif (typeof x === \"number\") {\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t} else {\n\t\t\tif (\"w\" in x) {\n\t\t\t\tthis.w = x.w;\n\t\t\t\tthis.h = x.h;\n\t\t\t}\n\n\t\t\tthis.x = x.x;\n\t\t\tthis.y = x.y;\n\t\t}\n\n\t\tif (w !== undefined) {\n\t\t\tthis.w = w;\n\t\t}\n\n\t\tif (h !== undefined) {\n\t\t\tthis.h = h;\n\t\t}\n\n\t\tthis.sideIsDirty = true;\n\t\treturn this;\n\t}\n\n\tpublic collide(rect: Rect): boolean {\n\t\treturn (\n\t\t\tthis.x <= rect.x + rect.w &&\n\t\t\tthis.x + this.w >= rect.x &&\n\t\t\tthis.y <= rect.y + rect.h &&\n\t\t\tthis.y + this.h >= rect.y\n\t\t);\n\t}\n\n\tpublic collideFull(rect: Rect): boolean {\n\t\treturn (\n\t\t\trect.x + rect.w <= this.x + this.w &&\n\t\t\trect.x >= this.x &&\n\t\t\trect.y >= this.y &&\n\t\t\trect.y + rect.h <= this.y + this.h\n\t\t);\n\t}\n\n\tpublic collidePoint(vec: Vector2): boolean {\n\t\treturn (\n\t\t\tthis.x <= vec.x &&\n\t\t\tvec.x <= this.x + this.w &&\n\t\t\tthis.y <= vec.y &&\n\t\t\tvec.y <= this.y + this.h\n\t\t);\n\t}\n\n\tpublic collideSide(\n\t\trect: Rect,\n\t): \"none\" | \"top\" | \"bottom\" | \"left\" | \"right\" {\n\t\tconst dx = this.x + this.w * 0.5 - (rect.x + rect.w * 0.5);\n\t\tconst dy = this.y + this.h * 0.5 - (rect.y + rect.h * 0.5);\n\t\tconst width = (this.w + rect.w) * 0.5;\n\t\tconst height = (this.h + rect.h) * 0.5;\n\t\tconst crossWidth = width * dy;\n\t\tconst crossHeight = height * dx;\n\t\tlet collision: \"none\" | \"top\" | \"bottom\" | \"left\" | \"right\" = \"none\";\n\n\t\tif (Math.abs(dx) <= width && Math.abs(dy) <= height) {\n\t\t\tif (crossWidth > crossHeight) {\n\t\t\t\tcollision = crossWidth > -crossHeight ? \"bottom\" : \"left\";\n\t\t\t} else {\n\t\t\t\tcollision = crossWidth > -crossHeight ? \"right\" : \"top\";\n\t\t\t}\n\t\t}\n\n\t\treturn collision;\n\t}\n\n\tpublic pos(): Vec2 {\n\t\treturn new Vec2(this.x, this.y);\n\t}\n\n\tpublic size(): Vec2 {\n\t\treturn new Vec2(this.w, this.h);\n\t}\n\n\tpublic toString(): string {\n\t\treturn `Rect [x: ${this.x}, y: ${this.y}, w: ${this.w}, h: ${this.h}]`;\n\t}\n\n\tpublic clone(): Rect {\n\t\treturn new Rect(this.x, this.y, this.w, this.h);\n\t}\n\n\tpublic equals(other: Rect, withSize: boolean = true): boolean {\n\t\tlet output =\n\t\t\tapproxEqual(this.x, other.x) && approxEqual(this.y, other.y);\n\n\t\tif (output && withSize) {\n\t\t\toutput =\n\t\t\t\tapproxEqual(this.w, other.w) && approxEqual(this.h, other.h);\n\t\t}\n\n\t\treturn output;\n\t}\n}\n", "import Rect from \"./Rect\";\nimport { approxEqual, clamp } from \"@/utilities/Number\";\nimport { throttle } from \"@/utilities/Functions\";\n\nexport interface Vector2 {\n\tx: number;\n\ty: number;\n}\n\nexport interface Vector4 extends Vector2 {\n\tw: number;\n\th: number;\n}\n\n/**\n * Operation types for vector calculations\n */\nconst Operation = {\n\tAdd: 1,\n\tSub: 2,\n\tMult: 3,\n\tDiv: 4,\n\tRem: 5,\n\tEqual: 6,\n\tMod: 7,\n} as const;\n\nconst warnZeroNormalize = throttle(count =>\n\tconsole.warn(\n\t\t`Vec2.normalize() called on zero vector x${count} since last warning; returning zero.`,\n\t),\n);\n\nconst warnNonFinite = throttle(count =>\n\tconsole.warn(\n\t\t`Vec2 operation produced non-finite value x${count} since last warning; check for zero divisor.`,\n\t),\n);\n\n/**\n * 2D vector. Scalar args to `set`/`add`/`sub`/`mult`/`div`/`rem`/`mod`/`equals`\n * broadcast to both axes: `vec.add(5)` adds 5 to x and y, `vec.mult(-1)` negates\n * both. Pass `(x, y)` or a `Vector2` for per-axis values.\n */\nexport default class Vec2 {\n\tpublic static fromAngle(\n\t\trad: number,\n\t\tscaleX = 1,\n\t\tscaleY: number = scaleX,\n\t): Vec2 {\n\t\treturn new Vec2(Math.cos(rad) * scaleX, Math.sin(rad) * scaleY);\n\t}\n\n\tpublic x = 0;\n\tpublic y = 0;\n\n\tconstructor(x: Vector2 | number = 0, y?: number) {\n\t\tthis.calculate(Operation.Equal, x, y);\n\t}\n\n\tpublic set(v: Vector2): Vec2;\n\tpublic set(x: number, y?: number): Vec2;\n\tpublic set(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Equal, x, y);\n\t}\n\n\tpublic abs(): Vec2 {\n\t\treturn this.map(Math.abs);\n\t}\n\n\tpublic add(v: Vector2): Vec2;\n\tpublic add(x: number, y?: number): Vec2;\n\tpublic add(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Add, x, y);\n\t}\n\n\tpublic ceil(): Vec2 {\n\t\treturn this.map(Math.ceil);\n\t}\n\n\tpublic clamp(x: [number, number], y: [number, number] = x): Vec2 {\n\t\tthis.x = clamp(this.x, x[0], x[1]);\n\t\tthis.y = clamp(this.y, y[0], y[1]);\n\n\t\treturn this;\n\t}\n\n\tpublic div(v: Vector2): Vec2;\n\tpublic div(x: number, y?: number): Vec2;\n\tpublic div(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Div, x, y);\n\t}\n\n\tpublic floor(): Vec2 {\n\t\treturn this.map(Math.floor);\n\t}\n\n\tpublic map(callback: (value: number, index: number) => number): Vec2 {\n\t\tthis.x = callback(this.x, 0);\n\t\tthis.y = callback(this.y, 1);\n\t\treturn this;\n\t}\n\n\tpublic mod(v: Vector2): Vec2;\n\tpublic mod(x: number, y?: number): Vec2;\n\tpublic mod(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Mod, x, y);\n\t}\n\n\tpublic mult(v: Vector2): Vec2;\n\tpublic mult(x: number, y?: number): Vec2;\n\tpublic mult(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Mult, x, y);\n\t}\n\n\tpublic negate(): Vec2 {\n\t\treturn this.mult(-1);\n\t}\n\n\tpublic normalize(): Vec2 {\n\t\tconst length = this.length();\n\n\t\tif (approxEqual(length, 0)) {\n\t\t\twarnZeroNormalize();\n\t\t\treturn this;\n\t\t}\n\n\t\treturn this.map(value => value / length);\n\t}\n\n\tpublic normalizeManhattan(): Vec2 {\n\t\tconst length = this.lengthManhattan();\n\n\t\tif (approxEqual(length, 0)) {\n\t\t\treturn this;\n\t\t}\n\n\t\treturn this.map(value => value / length);\n\t}\n\n\tpublic rem(v: Vector2): Vec2;\n\tpublic rem(x: number, y?: number): Vec2;\n\tpublic rem(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Rem, x, y);\n\t}\n\n\tpublic round(): Vec2 {\n\t\tthis.x = Math.round(this.x);\n\t\tthis.y = Math.round(this.y);\n\t\treturn this;\n\t}\n\n\tpublic sub(v: Vector2): Vec2;\n\tpublic sub(x: number, y?: number): Vec2;\n\tpublic sub(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Sub, x, y);\n\t}\n\n\tpublic angle(other?: Vector2): number {\n\t\tif (!other) {\n\t\t\treturn Math.atan2(this.y, this.x);\n\t\t}\n\n\t\treturn Math.atan2(other.y - this.y, other.x - this.x);\n\t}\n\n\tpublic distance(other: Vector2): number {\n\t\treturn Math.sqrt(\n\t\t\tMath.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2),\n\t\t);\n\t}\n\n\tpublic distanceManhattan(other: Vector2): number {\n\t\treturn Math.abs(other.x - this.x) + Math.abs(other.y - this.y);\n\t}\n\n\tpublic dotProduct(other: Vector2): number {\n\t\treturn this.x * other.x + this.y * other.y;\n\t}\n\n\tpublic isValid(): boolean {\n\t\treturn Number.isFinite(this.x) && Number.isFinite(this.y);\n\t}\n\n\tpublic length(): number {\n\t\treturn Math.sqrt(this.x * this.x + this.y * this.y);\n\t}\n\n\tpublic lengthManhattan(): number {\n\t\treturn Math.abs(this.x) + Math.abs(this.y);\n\t}\n\n\tpublic max(): number {\n\t\treturn Math.max(this.x, this.y);\n\t}\n\n\tpublic min(): number {\n\t\treturn Math.min(this.x, this.y);\n\t}\n\n\tpublic toArray(): [number, number] {\n\t\treturn [this.x, this.y];\n\t}\n\n\tpublic toRectAddPos(v: Vector2): Rect;\n\tpublic toRectAddPos(x: number, y?: number): Rect;\n\tpublic toRectAddPos(x: Vector2 | number, y?: number): Rect {\n\t\treturn this.concat(true, x, y);\n\t}\n\n\tpublic toRectAddSize(v: Vector2): Rect;\n\tpublic toRectAddSize(x: number, y?: number): Rect;\n\tpublic toRectAddSize(width: Vector2 | number, height?: number): Rect {\n\t\treturn this.concat(false, width, height);\n\t}\n\n\tpublic toString(): string {\n\t\treturn `Vec2 [x: ${this.x}, y: ${this.y}]`;\n\t}\n\n\tpublic clone(): Vec2 {\n\t\treturn new Vec2(this.x, this.y);\n\t}\n\n\tpublic equals(v: Vector2): boolean;\n\tpublic equals(x: number, y?: number): boolean;\n\tpublic equals(x: Vector2 | number, y?: number): boolean {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\treturn approxEqual(this.x, x2) && approxEqual(this.y, y2);\n\t}\n\n\tprivate calculate(\n\t\toperation: (typeof Operation)[keyof typeof Operation],\n\t\tx: Vector2 | number,\n\t\ty?: number,\n\t): Vec2 {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\tswitch (operation) {\n\t\t\tcase Operation.Add:\n\t\t\t\tthis.x += x2;\n\t\t\t\tthis.y += y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Sub:\n\t\t\t\tthis.x -= x2;\n\t\t\t\tthis.y -= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Mult:\n\t\t\t\tthis.x *= x2;\n\t\t\t\tthis.y *= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Div:\n\t\t\t\tthis.x /= x2;\n\t\t\t\tthis.y /= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Rem:\n\t\t\t\tthis.x %= x2;\n\t\t\t\tthis.y %= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Equal:\n\t\t\t\tthis.x = x2;\n\t\t\t\tthis.y = y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Mod:\n\t\t\t\tthis.x = ((this.x % x2) + x2) % x2;\n\t\t\t\tthis.y = ((this.y % y2) + y2) % y2;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\toperation satisfies never;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (!this.isValid()) {\n\t\t\twarnNonFinite();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprivate concat(first: boolean, x: Vector2 | number, y?: number): Rect {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\tif (first) {\n\t\t\treturn new Rect(x2, y2, this.x, this.y);\n\t\t}\n\n\t\treturn new Rect(this.x, this.y, x2, y2);\n\t}\n\n\tprivate getValues(x: Vector2 | number, y?: number): number[] {\n\t\tlet inputX = 0;\n\t\tlet inputY = 0;\n\n\t\tif (typeof x === \"number\") {\n\t\t\tinputX = x;\n\t\t\tif (y === undefined) {\n\t\t\t\tinputY = x;\n\t\t\t} else {\n\t\t\t\tinputY = y;\n\t\t\t}\n\t\t} else {\n\t\t\tif (y === undefined) {\n\t\t\t\tinputX = x.x;\n\t\t\t\tinputY = x.y;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"When x is a Vector2, y must be omitted!\");\n\t\t\t}\n\t\t}\n\n\t\treturn [inputX, inputY];\n\t}\n}\n", "import type Game from \"./Game\";\n\nexport type SettingsOverrides = Partial<\n\tOmit<\n\t\ttypeof Settings,\n\t\t\"prototype\" | \"init\" | \"setLocalStorage\" | \"localStorage\"\n\t>\n>;\n\nconst LOCAL_STORAGE_KEY = \"gleam\";\n\nexport default class Settings {\n\tpublic static antialias = false;\n\tpublic static autoloop = true;\n\tpublic static backgroundColor = \"#444\";\n\tpublic static debug = false;\n\tpublic static doNotClear = false;\n\tpublic static enableResize = true;\n\tpublic static font = \"Arial\";\n\tpublic static fps = 1 / 60;\n\tpublic static triedToClose?: () => void;\n\tpublic static useClearRect = true;\n\tpublic static warnBeforeClose = false;\n\tprivate static initialized = false;\n\t// Only mutated via `setLocalStorage` (typed) and via the localStorage\n\t// round-trip in `init()` \u2014 since `setLocalStorage` is the sole writer of\n\t// the persisted blob, the parsed payload is trusted to match the schema.\n\tprivate static readonly _localStorage = {\n\t\tlanguage: \"\",\n\t};\n\n\tpublic static get localStorage(): Readonly<typeof Settings._localStorage> {\n\t\treturn this._localStorage;\n\t}\n\n\tpublic static init(overrides: SettingsOverrides, game: Game): void {\n\t\tif (this.initialized) {\n\t\t\tthrow new Error(\"Settings.init called twice\");\n\t\t}\n\n\t\tObject.assign(this, overrides);\n\n\t\t// fps from `overrides` can be NaN or Infinity; both pass `<= 0`.\n\t\tif (!(Number.isFinite(this.fps) && this.fps > 0)) {\n\t\t\tthrow new Error(`Settings.fps must be > 0, got ${this.fps}`);\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\t// debug-only devtools hook; kept as `any` so the temporary\n\t\t\t// debug surface doesn't leak into any .d.ts file.\n\t\t\t(window as any).game = game;\n\t\t}\n\n\t\tif (this.warnBeforeClose) {\n\t\t\twindow.addEventListener(\n\t\t\t\t\"beforeunload\",\n\t\t\t\t(event: BeforeUnloadEvent) => {\n\t\t\t\t\tthis.triedToClose?.();\n\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.returnValue = true;\n\t\t\t\t\treturn \"Are you sure?\";\n\t\t\t\t},\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\n\t\tthis._localStorage.language = navigator.language.split(\"-\")[0] || \"en\";\n\n\t\tconst storage = localStorage.getItem(LOCAL_STORAGE_KEY);\n\t\tif (storage) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(storage);\n\t\t\t\tObject.assign(this._localStorage, parsed);\n\t\t\t} catch (_e) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"Couldn't parse local storage! Will be cleaned now.\",\n\t\t\t\t\tstorage,\n\t\t\t\t);\n\t\t\t\tlocalStorage.removeItem(LOCAL_STORAGE_KEY);\n\t\t\t}\n\t\t}\n\n\t\tthis.initialized = true;\n\t}\n\n\tpublic static setLocalStorage<K extends keyof typeof this._localStorage>(\n\t\tkey: K,\n\t\tvalue: (typeof this._localStorage)[K],\n\t): void {\n\t\tthis._localStorage[key] = value;\n\n\t\tlocalStorage.setItem(\n\t\t\tLOCAL_STORAGE_KEY,\n\t\t\tJSON.stringify(this._localStorage),\n\t\t);\n\t}\n}\n", "export interface CSSVariables {\n\troot: HTMLElement;\n\tget(name: string): string;\n\tset(name: string, value: string): void;\n}\n\n/**\n * `querySelector` variant that throws when no element matches.\n * Optionally narrow the return type per tag, e.g. `getElement<HTMLCanvasElement>(\"canvas\")`.\n */\nexport function getElement<T extends Element = HTMLElement>(\n\tquery: string,\n\tparent: ParentNode = document,\n): T {\n\tconst el = parent.querySelector<T>(query);\n\tif (!el) {\n\t\tthrow new Error(`Element not found: ${query}`);\n\t}\n\treturn el;\n}\n\n/**\n * Apply a partial `CSSStyleDeclaration` to an element.\n */\nexport function styleElement(\n\telement: HTMLElement,\n\tstyles: Partial<CSSStyleDeclaration>,\n): void {\n\tObject.assign(element.style, styles);\n}\n\n/**\n * Toggle `element.style.display` between `\"\"` (active) and `\"none\"` (inactive).\n */\nexport function setDisplay(element: HTMLElement, active: boolean): void {\n\telement.style.display = active ? \"\" : \"none\";\n}\n\n/**\n * Toggle `element.style.visibility` between `\"\"` (active) and `\"hidden\"` (inactive).\n */\nexport function setVisibility(element: HTMLElement, active: boolean): void {\n\telement.style.visibility = active ? \"\" : \"hidden\";\n}\n\n/**\n * Returns `get` / `set` helpers for CSS custom properties (`--name`) on the `:root` element.\n */\nexport function initCSSVariables(): CSSVariables {\n\tconst root = getElement(\":root\");\n\n\treturn {\n\t\troot,\n\t\tget(name: string): string {\n\t\t\treturn getComputedStyle(root).getPropertyValue(\"--\" + name);\n\t\t},\n\t\tset(name: string, value: string): void {\n\t\t\troot.style.setProperty(\"--\" + name, value);\n\t\t},\n\t};\n}\n\n/**\n * Calls `callback` on pointerdown of the matched element, then keeps calling it every `delay` ms\n * until pointerup or pointercancel. Uses pointer capture so the action persists while the cursor\n * drags off the element (and over descendants). Unifies mouse, touch, and pen. Throws if no element\n * matches. Returns a dispose function that removes the listeners and stops any in-flight interval.\n */\nexport function doWhilePressed(\n\tquerySelector: string,\n\tcallback: () => void,\n\tdelay = 200,\n): () => void {\n\tconst element = getElement(querySelector);\n\n\tlet intervalId: ReturnType<typeof setInterval> | undefined;\n\tlet activePointerId: number | null = null;\n\n\tfunction start(event: PointerEvent): void {\n\t\tif (activePointerId !== null) {\n\t\t\treturn;\n\t\t}\n\n\t\tactivePointerId = event.pointerId;\n\t\telement.setPointerCapture(activePointerId);\n\n\t\tclearInterval(intervalId);\n\t\tcallback();\n\t\tintervalId = setInterval(() => callback(), delay);\n\t}\n\n\tfunction stop(event: PointerEvent): void {\n\t\tif (event.pointerId !== activePointerId) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearInterval(intervalId);\n\t\telement.releasePointerCapture(event.pointerId);\n\t\tactivePointerId = null;\n\t}\n\n\telement.addEventListener(\"pointerdown\", start);\n\telement.addEventListener(\"pointerup\", stop);\n\telement.addEventListener(\"pointercancel\", stop);\n\n\tfunction dispose(): void {\n\t\telement.removeEventListener(\"pointerdown\", start);\n\t\telement.removeEventListener(\"pointerup\", stop);\n\t\telement.removeEventListener(\"pointercancel\", stop);\n\n\t\tclearInterval(intervalId);\n\t\tif (activePointerId !== null) {\n\t\t\telement.releasePointerCapture(activePointerId);\n\t\t\tactivePointerId = null;\n\t\t}\n\t}\n\n\treturn dispose;\n}\n\n/**\n * Resolves the next time `type` fires on `element` (one-shot listener). Pass an `AbortSignal`\n * to cancel \u2014 rejects with `signal.reason` and removes the listener.\n */\nexport async function waitForEvent<K extends keyof HTMLElementEventMap>(\n\telement: HTMLElement,\n\ttype: K,\n\tsignal?: AbortSignal,\n): Promise<void> {\n\tif (signal?.aborted) {\n\t\tthrow signal.reason;\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\telement.addEventListener(type, () => resolve(), {\n\t\t\tonce: true,\n\t\t\tsignal,\n\t\t});\n\t\tsignal?.addEventListener(\"abort\", () => reject(signal.reason), {\n\t\t\tonce: true,\n\t\t});\n\t});\n}\n", "import type { Vector2 } from \"@/math/Vec2\";\n\n/**\n * Clone a 2D grid; the outer array and each row become independent copies.\n * Row cells are kept as-is (suitable for primitive cells; for nested structures use `deepClone`).\n */\nexport function cloneGrid<T>(grid: ReadonlyArray<ReadonlyArray<T>>): T[][] {\n\treturn grid.map(row => row.slice());\n}\n\n/**\n * Convert a 1D index to `{x, y}` for a 2D grid of the given row width.\n */\nexport function convert1DTo2D(index: number, width: number): Vector2 {\n\treturn {\n\t\tx: index % width,\n\t\ty: (index / width) | 0,\n\t};\n}\n\n/**\n * Convert 2D `(x, y)` coordinates to a 1D index for a grid of the given row width.\n */\nexport function convert2DTo1D(\n\tindexX: number,\n\tindexY: number,\n\twidth: number,\n): number {\n\treturn indexX + width * indexY;\n}\n\ntype GridPrimitive =\n\t| string\n\t| number\n\t| boolean\n\t| bigint\n\t| symbol\n\t| null\n\t| undefined;\n\n/**\n * Generate a `height \u00D7 width` 2D grid; every cell holds `defaultValue`. Restricted to primitives at the type level \u2014 for object/array cells use the factory overload to avoid every cell sharing the same reference.\n */\nexport function generateGrid<T extends GridPrimitive>(\n\theight: number,\n\twidth: number,\n\tdefaultValue: T,\n): T[][];\n/**\n * Generate a `height \u00D7 width` 2D grid by invoking `factory(x, y)` for each cell. Use this overload for object/array cells (and for any per-cell computation).\n */\nexport function generateGrid<T>(\n\theight: number,\n\twidth: number,\n\tfactory: (x: number, y: number) => T,\n): T[][];\nexport function generateGrid<T>(\n\theight: number,\n\twidth: number,\n\tvalueOrFactory: T | ((x: number, y: number) => T),\n): T[][] {\n\tconst isFactory = typeof valueOrFactory === \"function\";\n\n\treturn Array.from({ length: height }, (_, y) =>\n\t\tArray.from({ length: width }, (_, x) =>\n\t\t\tisFactory\n\t\t\t\t? (valueOrFactory as (x: number, y: number) => T)(x, y)\n\t\t\t\t: valueOrFactory,\n\t\t),\n\t);\n}\n", "type Method<T, K extends keyof T> = T[K] extends (...args: infer A) => infer R\n\t? (this: T, ...args: A) => R\n\t: never;\n\n/**\n * Define `name` as a non-enumerable method on `proto`. Carries the declared signature so impl `this` and parameters are inferred from the merged declaration.\n */\nexport function defineMethod<T, K extends keyof T>(\n\tproto: T,\n\tname: K,\n\tvalue: Method<T, K>,\n): void {\n\tObject.defineProperty(proto, name, {\n\t\tvalue,\n\t\tconfigurable: true,\n\t\twritable: true,\n\t});\n}\n", "import { createNewCanvas } from \"@/utilities/Canvas\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/**\n * Validates URL format and protocol before any side effects.\n * Throws on invalid URLs or disallowed protocols.\n */\nexport function validateUrl(url: string): void {\n\tconst schemeMatch = url.trim().match(/^([a-z][a-z0-9+.-]*):/i);\n\n\tif (!schemeMatch) {\n\t\t// has no scheme -> relative url -> allow\n\t\treturn;\n\t}\n\n\tconst scheme = schemeMatch[1].toLowerCase();\n\n\tif ([\"blob\", \"data\", \"http\", \"https\"].includes(scheme)) {\n\t\t// has known scheme -> allow\n\t\treturn;\n\t}\n\n\t// well, has unknown scheme -> oh oh\n\tthrow new Error(`Invalid URL protocol: ${url}`);\n}\n\n/**\n * Safe loading wrapper with global timeout and error handling.\n * Use this for any async loading operation that needs timeout protection.\n * Timeout rejects the returned promise but does not cancel the underlying\n * fetch/Image \u2014 the request continues until natural completion. Adding\n * AbortSignal support would require a full rewrite (factory-based API).\n * Maybe a future feature, though.\n */\nexport function safeLoad<T>(\n\tpromise: Promise<T>,\n\turl: string,\n\toperationName: string,\n): Promise<T> {\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\n\tconst timeoutPromise = new Promise<T>((_, reject) => {\n\t\ttimeoutId = setTimeout(() => {\n\t\t\treject(\n\t\t\t\tnew Error(\n\t\t\t\t\t`Timeout (${DEFAULT_TIMEOUT_MS}ms) when loading ${operationName}: ${url}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}, DEFAULT_TIMEOUT_MS);\n\t});\n\n\treturn Promise.race([promise, timeoutPromise])\n\t\t.catch((error: Error) => {\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tconst errorMessage = error?.message || String(error);\n\n\t\t\t// Log detailed error with file path for debugging\n\t\t\tconsole.error(\n\t\t\t\t`${operationName} failed on ${url}\\n ${errorMessage}`,\n\t\t\t);\n\n\t\t\t// Re-throw wrapped error to be caught by caller\n\t\t\tthrow error;\n\t\t})\n\t\t.finally(() => clearTimeout(timeoutId));\n}\n\n/**\n * Loads an image with timeout and error handling\n */\nexport async function loadImage(url: string): Promise<HTMLImageElement> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tnew Promise<HTMLImageElement>((resolve, reject): void => {\n\t\t\tconst image = new Image();\n\n\t\t\timage.onload = () => resolve(image);\n\t\t\timage.onerror = () =>\n\t\t\t\treject(new Error(`Image failed to load: ${url}`));\n\n\t\t\timage.crossOrigin = \"anonymous\";\n\t\t\timage.src = url;\n\t\t}),\n\t\turl,\n\t\t\"image\",\n\t);\n}\n\n/**\n * Loads a canvas from image URL with error handling\n */\nexport async function loadCanvas(url: string): Promise<HTMLCanvasElement> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\t(async () => {\n\t\t\tconst image = await loadImage(url);\n\t\t\tconst cc = createNewCanvas(image.width, image.height);\n\t\t\tcc.canvas.id = url;\n\t\t\tcc.context.drawImage(image, 0, 0);\n\t\t\treturn cc.canvas;\n\t\t})(),\n\t\turl,\n\t\t\"canvas\",\n\t);\n}\n\n/**\n * Loads text content from URL with error handling\n */\nexport async function loadText(url: string): Promise<string> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\t(async () => {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`HTTP ${response.status}: Failed to load text from ${url}\\n Status: ${response.status} ${response.statusText}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.text();\n\t\t})(),\n\t\turl,\n\t\t\"text\",\n\t);\n}\n\n/**\n * Loads JSON data from URL with error handling\n */\nexport async function loadJson<T = unknown>(url: string): Promise<T> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tloadText(url).then(text => JSON.parse(text) as T),\n\t\turl,\n\t\t\"JSON\",\n\t);\n}\n\n/**\n * Loads JSON with inline comments\n */\nexport async function loadJsonCommented<T = unknown>(url: string): Promise<T> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tloadText(url).then(text => {\n\t\t\t// strips lines starting with //\n\t\t\tconst lines = text\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter(line => {\n\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\tif (!trimmed || trimmed.startsWith(\"//\")) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\n\t\t\treturn JSON.parse(lines) as T;\n\t\t}),\n\t\turl,\n\t\t\"JSON (commented)\",\n\t);\n}\n\ninterface SpriteJson {\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n\tname: string;\n\t[key: string]: string | number;\n}\n\ninterface SpriteJsonFile {\n\toptions: { file: string };\n\tsprites: SpriteJson[];\n}\n\n/**\n * Loads image sprites from JSON configuration with error handling\n */\nexport async function loadImageFromJson(\n\tbaseUrl: string,\n\tfilenameOrJson: string,\n\tjsonInput = false,\n): Promise<Record<string, HTMLCanvasElement>> {\n\tif (!baseUrl.endsWith(\"/\")) {\n\t\tbaseUrl += \"/\";\n\t}\n\n\tlet json: SpriteJsonFile;\n\n\t// Handle both inline JSON and file loading cases\n\tif (jsonInput) {\n\t\ttry {\n\t\t\tjson = JSON.parse(filenameOrJson) as SpriteJsonFile;\n\t\t} catch (parseError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to parse inline JSON: ${(parseError as SyntaxError).message}`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tconst url = baseUrl + filenameOrJson + \".json\";\n\n\t\tjson = await loadJson<SpriteJsonFile>(url);\n\t}\n\n\t// Handle JSON parsing errors gracefully\n\tif (!json || !json.options?.file) {\n\t\tconst source = jsonInput\n\t\t\t? \"inline JSON\"\n\t\t\t: `${baseUrl}${filenameOrJson}.json`;\n\n\t\tthrow new Error(\n\t\t\t`JSON missing 'options.file' property\\n Source: ${source}`,\n\t\t);\n\t}\n\n\tconst canvas = await loadCanvas(baseUrl + json.options.file);\n\tconst sprites: Record<string, HTMLCanvasElement> = {};\n\n\tif (!json.sprites || !Array.isArray(json.sprites)) {\n\t\tthrow new Error(\n\t\t\t`JSON missing 'sprites' array\\n Source: ${baseUrl}${filenameOrJson}.json`,\n\t\t);\n\t}\n\n\tjson.sprites.forEach((sprite, i) => {\n\t\tif (\n\t\t\tsprite.x === undefined ||\n\t\t\tsprite.y === undefined ||\n\t\t\t!sprite.w ||\n\t\t\t!sprite.h ||\n\t\t\t!sprite.name\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid sprite data at index ${i}: ${JSON.stringify(sprite, null, 2)}`,\n\t\t\t);\n\t\t}\n\n\t\tconst newSprite = canvas.subImage(\n\t\t\tsprite.x,\n\t\t\tsprite.y,\n\t\t\tsprite.w,\n\t\t\tsprite.h,\n\t\t);\n\n\t\tfor (const key in sprite) {\n\t\t\tnewSprite.dataset[key] = String(sprite[key]);\n\t\t}\n\n\t\tsprites[sprite.name] = newSprite;\n\t});\n\n\treturn sprites;\n}\n\n/**\n * Loads multiple resources concurrently with error handling\n */\nexport async function loadBunch<T extends Record<string, Promise<unknown>>>(\n\tbunch: T,\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> {\n\tconst output = {} as { [K in keyof T]: Awaited<T[K]> };\n\tconst keys = Object.keys(bunch) as (keyof T)[];\n\n\treturn Promise.all(keys.map(k => bunch[k])).then(datas => {\n\t\tkeys.forEach((key, i) => {\n\t\t\toutput[key] = datas[i];\n\t\t});\n\n\t\treturn output;\n\t});\n}\n", "import { convert2DTo1D } from \"@/utilities/Grid\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport { hex2rgb, type RGB, rgb2Int } from \"@/utilities/Color\";\nimport { loadImage } from \"@/loader/UrlLoaders\";\n\nexport {};\n\n// #region hasAnyColor\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** `true` if any pixel has a non-zero RGBA byte. */\n\t\thasAnyColor(): boolean;\n\t}\n}\n\ndefineMethod(HTMLCanvasElement.prototype, \"hasAnyColor\", function (): boolean {\n\tconst pixels = this.getContext(\"2d\")!.getImageData(\n\t\t0,\n\t\t0,\n\t\tthis.width,\n\t\tthis.height,\n\t).data;\n\n\treturn pixels.some(pixel => pixel !== 0);\n});\n// #endregion\n\n// #region getPixelAt\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Read the pixel at `(x, y)`. Out-of-bounds reads return zero/transparent.\n\t\t * Not for hot paths \u2014 each call issues a fresh `getImageData`. For bulk reads, call `getImageData` once and index into the buffer.\n\t\t * @param output return format. Default `\"integer\"`.\n\t\t */\n\t\tgetPixelAt(x: number, y: number, output?: \"integer\"): number;\n\t\tgetPixelAt(x: number, y: number, output: \"array\"): [...RGB, number];\n\t\tgetPixelAt(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\toutput: \"json\",\n\t\t): { r: number; g: number; b: number; a: number };\n\t\tgetPixelAt(x: number, y: number, output: \"string\"): string;\n\t}\n}\n\ndefineMethod(HTMLCanvasElement.prototype, \"getPixelAt\", function (\n\tthis: HTMLCanvasElement,\n\tx: number,\n\ty: number,\n\toutput: \"integer\" | \"array\" | \"json\" | \"string\" = \"integer\",\n) {\n\tlet r = 0;\n\tlet g = 0;\n\tlet b = 0;\n\tlet a = 0;\n\n\tif (x >= 0 && x < this.width && y >= 0 && y < this.height) {\n\t\tconst data = this.getContext(\"2d\")!.getImageData(x, y, 1, 1).data;\n\t\tr = data[0];\n\t\tg = data[1];\n\t\tb = data[2];\n\t\ta = data[3];\n\t}\n\n\tswitch (output) {\n\t\tcase \"array\":\n\t\t\treturn [r, g, b, a];\n\n\t\tcase \"json\":\n\t\t\treturn { r, g, b, a };\n\n\t\tcase \"string\":\n\t\t\treturn `rgba(${r}, ${g}, ${b}, ${a})`;\n\n\t\tcase \"integer\":\n\t\tdefault:\n\t\t\treturn rgb2Int(r, g, b, a / 255);\n\t}\n} as HTMLCanvasElement[\"getPixelAt\"]);\n// #endregion\n\n// #region replaceColors\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Replace pixel colors by RGB hex key. Alpha is ignored \u2014 fully-transparent pixels are skipped, semi-transparent pixels keep their alpha.\n\t\t */\n\t\treplaceColors(replacements: Record<string, string>): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"replaceColors\",\n\tfunction (replacements): HTMLCanvasElement {\n\t\tconst lookup = new Map<number, RGB>();\n\t\tfor (const from in replacements) {\n\t\t\tconst [fr, fg, fb] = hex2rgb(from);\n\t\t\tconst [tr, tg, tb] = hex2rgb(replacements[from]);\n\t\t\tlookup.set(rgb2Int(fr, fg, fb), [tr, tg, tb]);\n\t\t}\n\n\t\tconst context = this.getContext(\"2d\")!;\n\t\tconst image = context.getImageData(0, 0, this.width, this.height);\n\t\tconst { data } = image;\n\n\t\tfor (let i = 0; i < data.length; i += 4) {\n\t\t\tif (data[i + 3] === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst replacement = lookup.get(\n\t\t\t\trgb2Int(data[i], data[i + 1], data[i + 2]),\n\t\t\t);\n\n\t\t\tif (replacement !== undefined) {\n\t\t\t\tdata[i] = replacement[0];\n\t\t\t\tdata[i + 1] = replacement[1];\n\t\t\t\tdata[i + 2] = replacement[2];\n\t\t\t}\n\t\t}\n\n\t\tcontext.putImageData(image, 0, 0);\n\t\treturn this;\n\t},\n);\n// #endregion\n\n// #region rotateBy\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Rotate around the center into a new square canvas sized to fit any rotation (`diam = ceil(sqrt(w\u00B2 + h\u00B2))`). */\n\t\trotateBy(radians: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"rotateBy\",\n\tfunction (radians): HTMLCanvasElement {\n\t\tconst diam = Math.ceil(\n\t\t\tMath.sqrt(this.width * this.width + this.height * this.height),\n\t\t);\n\t\tconst cc = createNewCanvas(diam, diam);\n\n\t\tcc.context.translate(diam * 0.5, diam * 0.5);\n\t\tcc.context.rotate(radians);\n\t\tcc.context.drawImage(this, -this.width * 0.5, -this.height * 0.5);\n\t\tcc.context.translate(-diam * 0.5, -diam * 0.5);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region rotateByAligned\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Rotate around the center within the original `width \u00D7 height`; corners that fall outside are clipped. */\n\t\trotateByAligned(radians: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"rotateByAligned\",\n\tfunction (radians): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(this.width * 0.5, this.height * 0.5);\n\t\tcc.context.rotate(radians);\n\t\tcc.context.translate(-this.width * 0.5, -this.height * 0.5);\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region autoCrop\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Trim fully-transparent borders. Returns a new canvas cropped to the bounding box of opaque pixels. */\n\t\tautoCrop(): HTMLCanvasElement;\n\t}\n}\n\n// https://stackoverflow.com/a/58882518\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"autoCrop\",\n\tfunction (): HTMLCanvasElement {\n\t\tconst topLeft = {\n\t\t\tx: this.width,\n\t\t\ty: this.height,\n\t\t\tupdate(x: number, y: number): void {\n\t\t\t\tthis.x = Math.min(this.x, x);\n\t\t\t\tthis.y = Math.min(this.y, y);\n\t\t\t},\n\t\t};\n\n\t\tconst bottomRight = {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tupdate(x: number, y: number): void {\n\t\t\t\tthis.x = Math.max(this.x, x);\n\t\t\t\tthis.y = Math.max(this.y, y);\n\t\t\t},\n\t\t};\n\n\t\tconst context = this.getContext(\"2d\")!;\n\n\t\tconst imageData = context.getImageData(0, 0, this.width, this.height);\n\n\t\tfor (let y = 0; y < this.height; y++) {\n\t\t\tfor (let x = 0; x < this.width; x++) {\n\t\t\t\tconst alpha =\n\t\t\t\t\timageData.data[convert2DTo1D(x * 4, y * 4, this.width) + 3];\n\n\t\t\t\tif (alpha !== 0) {\n\t\t\t\t\ttopLeft.update(x, y);\n\t\t\t\t\tbottomRight.update(x, y);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// fully-transparent canvas -> nothing to crop to\n\t\tif (topLeft.x > bottomRight.x) {\n\t\t\treturn this.clone();\n\t\t}\n\n\t\tconst width = bottomRight.x - topLeft.x + 1;\n\t\tconst height = bottomRight.y - topLeft.y + 1;\n\n\t\treturn this.subImage(topLeft.x, topLeft.y, width, height);\n\t},\n);\n// #endregion\n\n// #region scaleBy\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Scale into a new canvas. Throws if any factor is `\u2264 0`.\n\t\t * @param scaleX horizontal scale factor. Default `1`.\n\t\t * @param scaleY vertical scale factor. Default = `scaleX`.\n\t\t */\n\t\tscaleBy(scaleX?: number, scaleY?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"scaleBy\",\n\tfunction (scaleX = 1, scaleY = scaleX): HTMLCanvasElement {\n\t\tif (scaleX <= 0 || scaleY <= 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`scaleBy requires positive scale factors, got: ${scaleX} x ${scaleY}`,\n\t\t\t);\n\t\t}\n\n\t\tconst cc = createNewCanvas(this.width * scaleX, this.height * scaleY);\n\n\t\tcc.context.scale(scaleX, scaleY);\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region resize\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Scale into a new canvas so the chosen axis equals `size`, preserving aspect ratio.\n\t\t * @param isWidth match `size` against width when `true`, height when `false`. Default `true`.\n\t\t */\n\t\tresize(size: number, isWidth?: boolean): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"resize\",\n\tfunction (size, isWidth = true): HTMLCanvasElement {\n\t\tif (isWidth) {\n\t\t\treturn this.scaleBy(size / this.width);\n\t\t}\n\n\t\treturn this.scaleBy(size / this.height);\n\t},\n);\n// #endregion\n\n// #region flipX\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Mirror horizontally into a new canvas.\n\t\t * @param offsetX horizontal shift applied after flipping. Default `0`.\n\t\t */\n\t\tflipX(offsetX?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"flipX\",\n\tfunction (offsetX = 0): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(this.width + offsetX, 0);\n\t\tcc.context.scale(-1, 1);\n\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region flipY\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Mirror vertically into a new canvas.\n\t\t * @param offsetY vertical shift applied after flipping. Default `0`.\n\t\t */\n\t\tflipY(offsetY?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"flipY\",\n\tfunction (offsetY = 0): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(0, this.height + offsetY);\n\t\tcc.context.scale(1, -1);\n\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region subImage\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.\n\t\t * @param w default `this.width`\n\t\t * @param h default `this.height`\n\t\t */\n\t\tsubImage(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw?: number,\n\t\t\th?: number,\n\t\t): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"subImage\",\n\tfunction (x, y, w, h): HTMLCanvasElement {\n\t\tif (w === undefined) {\n\t\t\tw = this.width;\n\t\t}\n\n\t\tif (h === undefined) {\n\t\t\th = this.height;\n\t\t}\n\n\t\tconst cc = createNewCanvas(w, h);\n\t\tcc.context.drawImage(this, x, y, w, h, 0, 0, w, h);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region clone\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Copy this canvas (same dimensions, content, `id`, and `dataset`) into a new canvas. */\n\t\tclone(): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"clone\",\n\tfunction (): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\t\tcc.canvas.id = this.id;\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\tfor (const key in this.dataset) {\n\t\t\tcc.canvas.dataset[key] = this.dataset[key];\n\t\t}\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region toImage\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Convert image canvas to `Promise<HTMLImageElement>` via `toDataURL`. */\n\t\ttoImage(): Promise<HTMLImageElement>;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"toImage\",\n\tfunction (): Promise<HTMLImageElement> {\n\t\treturn loadImage(this.toDataURL());\n\t},\n);\n// #endregion\n", "import Settings from \"@/core/Settings\";\nimport { getElement } from \"./DOM\";\nimport { rgb2Int } from \"./Color\";\n\nimport \"@/prototypes/HTMLCanvasElement\"; // splitSpriteSheet relies on the subImage patch\n\nexport interface CanvasConstruct {\n\tcanvas: HTMLCanvasElement;\n\tcontext: CanvasRenderingContext2D;\n}\n\n/**\n * Create a new `<canvas>` of the given size with its 2D context. Antialiasing defaults to `Settings.antialias`.\n */\nexport function createNewCanvas(\n\twidth: number,\n\theight: number,\n\tantialias: boolean = Settings.antialias,\n): CanvasConstruct {\n\tconst canvas = document.createElement(\"canvas\");\n\tcanvas.width = width;\n\tcanvas.height = height;\n\n\tconst context = canvas.getContext(\"2d\")!;\n\tcontext.imageSmoothingEnabled = antialias;\n\n\treturn {\n\t\tcanvas,\n\t\tcontext,\n\t};\n}\n\n/**\n * Look up an existing canvas by CSS selector and return it with its 2D context.\n */\nexport function getCanvasConstruct(selector: string): CanvasConstruct {\n\tconst canvas = getElement<HTMLCanvasElement>(selector);\n\tconst context = canvas.getContext(\"2d\")!;\n\n\treturn {\n\t\tcanvas,\n\t\tcontext,\n\t};\n}\n\n/**\n * Apply a CSS `filter` string to an image and return the result as a new canvas.\n */\nexport function applyFilterOnCanvas(\n\timage: HTMLCanvasElement | HTMLImageElement,\n\tfilter: string,\n\twidth: number = image.width,\n\theight: number = image.height,\n): HTMLCanvasElement {\n\tconst cc = createNewCanvas(width, height);\n\n\tcc.context.filter = filter;\n\tcc.context.drawImage(image, 0, 0);\n\tcc.context.filter = \"none\";\n\n\treturn cc.canvas;\n}\n\n/**\n * Rotate the hue of an image by `hue` degrees via CSS `hue-rotate(...)` filter.\n */\nexport function rotateHue(\n\timage: HTMLCanvasElement | HTMLImageElement,\n\thue: number,\n\twidth?: number,\n\theight?: number,\n): HTMLCanvasElement {\n\treturn applyFilterOnCanvas(\n\t\timage,\n\t\t\"hue-rotate(\" + hue + \"deg)\",\n\t\twidth,\n\t\theight,\n\t);\n}\n\n/**\n * Recolor an opaque canvas in place using composite operations,\n * preserving the alpha mask of the source image. Wraps the body in `save`/`restore`\n * so `fillStyle` / `globalCompositeOperation` writes don't leak to the caller's context.\n * https://stackoverflow.com/a/45201094\n */\nexport function changeColor(\n\tcontext: CanvasRenderingContext2D,\n\toriImg: HTMLCanvasElement,\n\tnewColor: string,\n): void {\n\tcontext.save();\n\n\tcontext.clearRect(0, 0, oriImg.width, oriImg.height);\n\tcontext.globalCompositeOperation = \"source-over\";\n\tcontext.drawImage(oriImg, 0, 0, oriImg.width, oriImg.height);\n\n\tcontext.globalCompositeOperation = \"color\";\n\tcontext.fillStyle = newColor;\n\tcontext.fillRect(0, 0, oriImg.width, oriImg.height);\n\n\tcontext.globalCompositeOperation = \"destination-in\";\n\tcontext.drawImage(oriImg, 0, 0, oriImg.width, oriImg.height);\n\n\tcontext.restore();\n}\n\n/**\n * Split a sprite-sheet image into individual sprite canvases laid out as `elementsX \u00D7 elementsY`.\n * Throws if the image dimensions don't divide evenly \u2014 sheets are expected to be authored that way.\n */\nexport function splitSpriteSheet(\n\timg: HTMLCanvasElement,\n\telementsX: number,\n\telementsY: number,\n): HTMLCanvasElement[] {\n\tif (img.width % elementsX !== 0 || img.height % elementsY !== 0) {\n\t\tthrow new Error(\n\t\t\t`SpriteSheet doesn't divide evenly: ${img.width}x${img.height} / ${elementsX}x${elementsY}`,\n\t\t);\n\t}\n\n\tconst sizeX = img.width / elementsX;\n\tconst sizeY = img.height / elementsY;\n\tconst sprites: HTMLCanvasElement[] = [];\n\n\tArray.from({ length: elementsY }).forEach((_, row) => {\n\t\tArray.from({ length: elementsX }).forEach((_, col) => {\n\t\t\tsprites.push(img.subImage(col * sizeX, row * sizeY, sizeX, sizeY));\n\t\t});\n\t});\n\n\treturn sprites;\n}\n\n/**\n * Count occurrences of each color in an image, keyed by `#rrggbb`.\n * `pixelAmount` multiplies each count and floors to int; values < 1 will drop low-count colors entirely (count rounds to 0).\n * `removeLowerThan` / `removeHigherThan` drop entries outside the range; `0` disables either bound.\n */\nexport function getUsedColors(\n\timage: HTMLCanvasElement,\n\tpixelAmount = 1,\n\tremoveLowerThan = 0,\n\tremoveHigherThan = 0,\n): Map<string, number> {\n\tconst data = image\n\t\t.getContext(\"2d\")!\n\t\t.getImageData(0, 0, image.width, image.height).data;\n\tconst counts = new Map<number, number>();\n\n\tfor (let i = 0; i < data.length; i += 4) {\n\t\tconst key = rgb2Int(data[i], data[i + 1], data[i + 2]);\n\t\tcounts.set(key, (counts.get(key) ?? 0) + 1);\n\t}\n\n\tif (pixelAmount < 1 || removeLowerThan > 0 || removeHigherThan > 0) {\n\t\tcounts.forEach((value, key) => {\n\t\t\tconst newAmount = (value * pixelAmount) | 0;\n\n\t\t\tif (\n\t\t\t\tnewAmount === 0 ||\n\t\t\t\t(removeLowerThan > 0 && newAmount < removeLowerThan) ||\n\t\t\t\t(removeHigherThan > 0 && newAmount > removeHigherThan)\n\t\t\t) {\n\t\t\t\tcounts.delete(key);\n\t\t\t} else {\n\t\t\t\tcounts.set(key, newAmount);\n\t\t\t}\n\t\t});\n\t}\n\n\tconst result = new Map<string, number>();\n\tcounts.forEach((count, rgbInt) => {\n\t\tresult.set(\"#\" + (0x1000000 + rgbInt).toString(16).slice(1), count);\n\t});\n\n\treturn result;\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { randomBetweenFloat } from \"@/utilities/Math\";\n\nexport interface SpriteAnimation {\n\tdefault?: boolean;\n\tname: string;\n\tsprites: HTMLCanvasElement[] | HTMLImageElement[];\n\ttiming: number;\n}\n\ntype onEndType = () => void;\ntype onFrameType = Record<number, () => void>;\n\ninterface BaseEntity {\n\tpos: Vec2;\n\tflipX?: number;\n}\n\nexport default class Animator {\n\tprivate static spriteCache = new Map<\n\t\tstring,\n\t\t{ unflipped: HTMLCanvasElement[]; flipped: HTMLCanvasElement[] }\n\t>();\n\n\t/**\n\t * Drop cached rendered sprites. Pass a namespace to evict only that prefix; omit to clear all.\n\t */\n\tpublic static clearSpriteCache(namespace?: string): void {\n\t\tif (namespace === undefined) {\n\t\t\tAnimator.spriteCache.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tconst prefix = `${namespace}.`;\n\t\tAnimator.spriteCache.forEach((_, key) => {\n\t\t\tif (key.startsWith(prefix)) {\n\t\t\t\tAnimator.spriteCache.delete(key);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic active = true;\n\tpublic image!: HTMLCanvasElement;\n\tpublic imageId = 0;\n\tpublic lookLeft = false;\n\tpublic onEnd: onEndType | undefined;\n\tpublic size: Vec2 = new Vec2();\n\tprivate animations: SpriteAnimation[] = [];\n\tprivate currentAnimation = 0;\n\tprivate entity: BaseEntity;\n\tprivate lastPlayed: string | undefined;\n\tprivate namespace: string;\n\tprivate onFrame?: onFrameType;\n\tprivate playVersion = 0;\n\tprivate timer = 0;\n\n\tpublic get current(): SpriteAnimation {\n\t\treturn this.animations[this.currentAnimation];\n\t}\n\n\t/**\n\t * We store rendered images in a cache.\n\t * So if you have the same entity multiple times, the images get computed once and then shared.\n\t * This reduces overhead and frees time up for other important computations.\n\t *\n\t * `namespace` is the cache key prefix for these rendered images.\n\t * So pass a different key for different Animators; otherwise, you will see wrong images.\n\t */\n\tconstructor(entity: BaseEntity, namespace: string) {\n\t\tthis.entity = entity;\n\t\tthis.namespace = namespace;\n\t}\n\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.drawImage(\n\t\t\tthis.image,\n\t\t\tthis.entity.pos.x + offset.x - this.size.x,\n\t\t\tthis.entity.pos.y + offset.y,\n\t\t);\n\t}\n\n\tpublic update(dt: number): void {\n\t\tif (!this.active) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer += dt;\n\n\t\tif (this.timer <= this.current.timing) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer -= this.current.timing;\n\t\tthis.imageId++;\n\n\t\t// on animation end / no more sprites\n\t\tif (this.imageId >= this.current.sprites.length) {\n\t\t\tconst onEnd = this.onEnd;\n\t\t\tthis.onEnd = undefined;\n\t\t\tthis.onFrame = undefined;\n\t\t\tthis.imageId = 0;\n\n\t\t\tconst versionBefore = this.playVersion;\n\t\t\tonEnd?.();\n\t\t\tif (this.playVersion !== versionBefore) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.lastPlayed) {\n\t\t\t\tthis.play(this.lastPlayed);\n\t\t\t\tthis.lastPlayed = undefined;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.current.sprites.length === 1) {\n\t\t\t\tthis.active = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.onFrame?.[this.imageId]) {\n\t\t\tconst cb = this.onFrame[this.imageId];\n\t\t\tdelete this.onFrame[this.imageId];\n\n\t\t\tconst versionBefore = this.playVersion;\n\t\t\tcb();\n\t\t\tif (this.playVersion !== versionBefore) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.active) {\n\t\t\tthis.setImage();\n\t\t}\n\t}\n\n\tpublic add(\n\t\tname: string,\n\t\tsprites: HTMLCanvasElement[] | HTMLImageElement[],\n\t\ttiming: number,\n\t\tdefaultAnim = false,\n\t): void {\n\t\tif (\n\t\t\tdefaultAnim &&\n\t\t\tthis.animations.some((anim: SpriteAnimation) => anim.default)\n\t\t) {\n\t\t\tconsole.error(\"Only one default animation allowed!\");\n\t\t}\n\n\t\tif (\n\t\t\tthis.animations.some((anim: SpriteAnimation) => anim.name === name)\n\t\t) {\n\t\t\tconsole.error(\"Duplicate animation name!\");\n\t\t}\n\n\t\tthis.animations.push({\n\t\t\tdefault: defaultAnim,\n\t\t\tname,\n\t\t\tsprites,\n\t\t\ttiming,\n\t\t});\n\n\t\tif (defaultAnim) {\n\t\t\tthis.play(name);\n\t\t}\n\t}\n\n\tpublic addAnimation(anim: SpriteAnimation, defaultAnim = false): void {\n\t\tthis.add(\n\t\t\tanim.name,\n\t\t\tanim.sprites,\n\t\t\tanim.timing,\n\t\t\tanim.default || defaultAnim,\n\t\t);\n\t}\n\n\tpublic drawRotated(\n\t\tcontext: CanvasRenderingContext2D,\n\t\tangle: number,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tconst x = this.entity.pos.x + offset.x;\n\t\tconst y = this.entity.pos.y + offset.y;\n\t\tconst w = this.image.width * 0.75;\n\t\tconst h = this.image.height * 0.5;\n\t\tcontext.setTransform(1, 0, 0, 1, x + w - this.size.x, y + h);\n\t\tcontext.rotate(angle);\n\t\tcontext.drawImage(this.image, -w, -h);\n\t\tcontext.setTransform(1, 0, 0, 1, 0, 0);\n\t}\n\n\tpublic play(name: string, onEnd?: onEndType, onFrame?: onFrameType): void {\n\t\tconst index = this.animations.findIndex(\n\t\t\t(anim: SpriteAnimation) => anim.name === name,\n\t\t);\n\n\t\tif (index < 0) {\n\t\t\tthrow new Error(`Animator.play: animation \"${name}\" not found`);\n\t\t}\n\n\t\tthis.playVersion++;\n\t\tconst myVersion = this.playVersion;\n\n\t\tthis.imageId = 0;\n\t\tthis.timer = 0;\n\t\tthis.currentAnimation = index;\n\t\tthis.setImage();\n\n\t\tconst prevOnEnd = this.onEnd;\n\t\tthis.onEnd = onEnd;\n\t\tthis.onFrame = onFrame;\n\t\tprevOnEnd?.();\n\n\t\tif (this.playVersion !== myVersion) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active = true;\n\t}\n\n\tpublic playIfNot(\n\t\tname: string,\n\t\tonEnd?: onEndType,\n\t\tonFrame?: onFrameType,\n\t): boolean {\n\t\tif (!this.isPlaying(name)) {\n\t\t\tthis.play(name, onEnd, onFrame);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tpublic playNextOnce(name: string | undefined): void {\n\t\tthis.lastPlayed = name;\n\t}\n\n\t/**\n\t * Play `name` once, then return to the previously-playing animation. Calling with the currently-playing name re-loops it indefinitely (lastPlayed restores to itself).\n\t */\n\tpublic playOnce(\n\t\tname: string,\n\t\tonEnd?: onEndType,\n\t\tonFrame?: onFrameType,\n\t): void {\n\t\tthis.lastPlayed = this.current?.name;\n\t\tthis.play(name, onEnd, onFrame);\n\t}\n\n\tpublic randomTimer(): void {\n\t\tthis.timer = randomBetweenFloat(0, this.current.timing);\n\t}\n\n\tpublic removeAllAnimations(): void {\n\t\tthis.animations.length = 0;\n\t\tthis.active = true;\n\t\tthis.onEnd = undefined;\n\t\tthis.onFrame = undefined;\n\t\tAnimator.clearSpriteCache(this.namespace);\n\t}\n\n\tpublic reset(): void {\n\t\tconst defaultAnim = this.animations.find(\n\t\t\t(anim: SpriteAnimation) => anim.default,\n\t\t);\n\n\t\tif (defaultAnim) {\n\t\t\tthis.play(defaultAnim.name);\n\t\t\tthis.active = true;\n\t\t} else {\n\t\t\tthis.active = false;\n\t\t}\n\t}\n\n\tpublic isPlaying(name: string): boolean {\n\t\treturn this.current && this.current.name === name;\n\t}\n\n\t/**\n\t * Update `image` and `size` from the current sprite. Assumes uniform sprite size within an animation. Caches rendered canvases per (animation, frame, lookLeft) \u2014 if you mutate `entity.flipX` after first render, call `removeAllAnimations()` or recreate the Animator to invalidate.\n\t */\n\tprotected setImage(): void {\n\t\tconst animation = this.current;\n\t\tconst sprite = animation.sprites[this.imageId];\n\t\tthis.size.set(sprite.width, sprite.height);\n\n\t\tif (this.entity.flipX === undefined) {\n\t\t\tthis.entity.flipX = this.size.x;\n\t\t}\n\n\t\tconst key = `${this.namespace}.${animation.name}`;\n\t\tlet cache = Animator.spriteCache.get(key);\n\t\tif (!cache) {\n\t\t\tcache = { unflipped: [], flipped: [] };\n\t\t\tAnimator.spriteCache.set(key, cache);\n\t\t}\n\n\t\tconst bucket = this.lookLeft ? cache.flipped : cache.unflipped;\n\n\t\tif (!bucket[this.imageId]) {\n\t\t\tconst cc = createNewCanvas(this.size.x * 2, this.size.y);\n\t\t\tcc.context.translate(\n\t\t\t\tthis.size.x + (this.lookLeft ? this.entity.flipX : 0),\n\t\t\t\t0,\n\t\t\t);\n\t\t\tif (this.lookLeft) {\n\t\t\t\tcc.context.scale(-1, 1);\n\t\t\t}\n\t\t\tcc.context.drawImage(sprite, 0, 0);\n\t\t\tbucket[this.imageId] = cc.canvas;\n\t\t}\n\n\t\tthis.image = bucket[this.imageId];\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\nimport { random2Pi, randomBetweenInt } from \"@/utilities/Math\";\n\nexport default class Particle {\n\tprotected color: string;\n\tprotected lifetime: number = 0;\n\tprotected maxLifeTime: number;\n\tprotected pos: Vec2;\n\tprotected size: number;\n\tprotected vel: Vec2;\n\tprotected _rect: Rect;\n\n\tpublic get alive(): boolean {\n\t\treturn this.lifetime < this.maxLifeTime;\n\t}\n\n\tpublic get rect(): Readonly<Rect> {\n\t\treturn this._rect;\n\t}\n\n\tconstructor(pos: Vec2, color: string, size: number = 2) {\n\t\tthis.pos = pos.clone();\n\t\tthis.color = color;\n\t\tthis.size = size;\n\n\t\tthis._rect = pos.toRectAddSize(size);\n\n\t\tthis.vel = Vec2.fromAngle(\n\t\t\trandom2Pi(),\n\t\t\trandomBetweenInt(50, 150),\n\t\t\trandomBetweenInt(50, 150),\n\t\t);\n\n\t\tthis.maxLifeTime = 0.5 + Math.random();\n\t}\n\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.fillStyle = this.color;\n\t\tcontext.drawCircle(\n\t\t\t{\n\t\t\t\tx: this.pos.x + offset.x,\n\t\t\t\ty: this.pos.y + offset.y,\n\t\t\t},\n\t\t\tthis.size,\n\t\t\t\"fill\",\n\t\t);\n\t}\n\n\tpublic update(dt: number): void {\n\t\tthis.lifetime += dt;\n\t\tthis.pos.x += this.vel.x * dt;\n\t\tthis.pos.y += this.vel.y * dt;\n\t\tthis._rect.set(this.pos.x, this.pos.y);\n\t}\n\n\tpublic resetLifetime(): void {\n\t\tthis.lifetime -= this.maxLifeTime;\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\n\nexport default class Projectile<T = unknown> {\n\tpublic maxLifetime = Infinity;\n\tpublic payload?: T;\n\tpublic speed = 1200;\n\tprotected image!: HTMLCanvasElement;\n\tprotected lifetime = 0;\n\tprotected pos: Vec2;\n\tprotected rotation = 0;\n\tprotected vel: Vec2;\n\tprotected _rect: Rect;\n\tprivate originalImage: HTMLCanvasElement;\n\n\tpublic get alive(): boolean {\n\t\treturn this.lifetime < this.maxLifetime;\n\t}\n\n\tpublic get rect(): Readonly<Rect> {\n\t\treturn this._rect;\n\t}\n\n\tconstructor(pos: Vec2, image: HTMLCanvasElement, vel: Vec2 = new Vec2()) {\n\t\tthis.pos = pos.clone();\n\t\tthis.originalImage = image;\n\t\tthis.vel = vel.clone();\n\n\t\tthis._rect = pos.toRectAddSize(image.width, image.height);\n\n\t\tthis.rebuildRotation();\n\t}\n\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.drawImage(\n\t\t\tthis.image,\n\t\t\tthis.pos.x + offset.x,\n\t\t\tthis.pos.y + offset.y,\n\t\t);\n\t}\n\n\tpublic update(dt: number): void {\n\t\tthis.lifetime += dt;\n\n\t\tthis.pos.x += this.vel.x * this.speed * dt;\n\t\tthis.pos.y += this.vel.y * this.speed * dt;\n\n\t\tthis._rect.set(this.pos.x, this.pos.y);\n\t}\n\n\t/**\n\t * Allocates a fresh rotated canvas on each call \u2014 no internal cache.\n\t * Caching by quantized rotation could be a feature when projectiles need to re-aim every tick (homing/seeking).\n\t */\n\tpublic rebuildRotation(): void {\n\t\tthis.rotation = Math.atan2(this.vel.y, this.vel.x);\n\t\tthis.image = this.originalImage.rotateBy(this.rotation);\n\t\tthis._rect.w = this.image.width;\n\t\tthis._rect.h = this.image.height;\n\t}\n\n\tpublic remove(): void {\n\t\tthis.lifetime = this.maxLifetime * 2;\n\t}\n}\n", "import EventSystem from \"./EventSystem\";\nimport Settings from \"@/core/Settings\";\nimport Vec2 from \"@/math/Vec2\";\nimport { type CanvasConstruct, getCanvasConstruct } from \"@/utilities/Canvas\";\n\nexport const CANVAS_TYPES = {\n\tANY: Symbol(\"any\"),\n\tDEFAULT: Symbol(\"default\"),\n\tBACKGROUND: Symbol(\"background\"),\n\tMAIN: Symbol(\"main\"),\n} as const;\n\nexport interface CanvasHolder extends CanvasConstruct {\n\tid: string;\n\tresize: boolean;\n\ttype: symbol;\n}\n\nexport default class CanvasManager {\n\tpublic canvasBoundingClientRect!: DOMRect;\n\tpublic canvasHolder: Record<string, CanvasHolder> = {};\n\tpublic ratio = 1;\n\tpublic resizedSize: Vec2 = new Vec2();\n\tprivate mainHolder!: CanvasHolder;\n\n\tpublic get canvas(): HTMLCanvasElement {\n\t\treturn this.mainHolder.canvas;\n\t}\n\n\tpublic get canvasContext(): CanvasRenderingContext2D {\n\t\treturn this.mainHolder.context;\n\t}\n\n\tpublic get height(): number {\n\t\treturn this.canvas.height;\n\t}\n\n\tpublic set height(height: number) {\n\t\tthis.canvas.height = height;\n\t}\n\n\tpublic get size(): Vec2 {\n\t\treturn new Vec2(this.width, this.height);\n\t}\n\n\tpublic get width(): number {\n\t\treturn this.canvas.width;\n\t}\n\n\tpublic set width(width: number) {\n\t\tthis.canvas.width = width;\n\t}\n\n\tpublic finishSetup(): void {\n\t\tif (this.mainHolder) {\n\t\t\tthrow new Error(\"Already set up.\");\n\t\t}\n\n\t\tconst mainCanvas = Object.values(this.canvasHolder).filter(\n\t\t\tholder => holder.type === CANVAS_TYPES.MAIN,\n\t\t);\n\n\t\tif (mainCanvas.length === 0) {\n\t\t\tthrow new Error(\"No main canvas defined!\");\n\t\t}\n\n\t\tif (mainCanvas.length > 1) {\n\t\t\tthrow new Error(\"Multiple main canvas defined!\");\n\t\t}\n\n\t\tthis.mainHolder = mainCanvas[0];\n\n\t\tif (this.width === 0 || this.height === 0) {\n\t\t\tthrow new Error(\"Main canvas has zero width or height.\");\n\t\t}\n\n\t\tthis.canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\n\t\tif (Settings.enableResize) {\n\t\t\tEventSystem.addEventListener(\"resized\", (): void => this.resize());\n\t\t}\n\t}\n\n\tpublic resize(): void {\n\t\tconst windowRatio = window.innerHeight / window.innerWidth;\n\n\t\tObject.values(this.canvasHolder).forEach(ch => {\n\t\t\tif (!ch.resize) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst canvasRatio = ch.canvas.height / ch.canvas.width;\n\t\t\tlet width: number;\n\t\t\tlet height: number;\n\n\t\t\tif (windowRatio < canvasRatio) {\n\t\t\t\theight = window.innerHeight;\n\t\t\t\twidth = height / canvasRatio;\n\t\t\t} else {\n\t\t\t\twidth = window.innerWidth;\n\t\t\t\theight = width * canvasRatio;\n\t\t\t}\n\n\t\t\tif (ch.canvas === this.canvas) {\n\t\t\t\tthis.resizedSize = new Vec2(width, height);\n\t\t\t\tthis.ratio = width / this.width;\n\t\t\t}\n\n\t\t\tch.canvas.style.width = width + \"px\";\n\t\t\tch.canvas.style.height = height + \"px\";\n\t\t});\n\n\t\tthis.canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t}\n\n\tpublic setFontSize(size: number, font: string = Settings.font): void {\n\t\tthis.canvasContext.font = `${size}px \"${font}\"`;\n\t}\n\n\tpublic setupCanvas(\n\t\tcanvasType: symbol,\n\t\tselector: string,\n\t\tresize: boolean = true,\n\t): CanvasHolder {\n\t\tif (!document.querySelector(selector)) {\n\t\t\tthrow new Error(\"Canvas '\" + selector + \"' does not exist!\");\n\t\t}\n\n\t\tif (this.canvasHolder[selector]) {\n\t\t\tthrow new Error(`Canvas \"${selector}\" was already registered!`);\n\t\t}\n\n\t\tconst newCanvas: CanvasHolder = Object.assign(\n\t\t\t{},\n\t\t\tgetCanvasConstruct(selector),\n\t\t\t{\n\t\t\t\tid: selector,\n\t\t\t\tresize,\n\t\t\t\ttype: canvasType,\n\t\t\t},\n\t\t);\n\t\tnewCanvas.context.fillStyle = \"white\";\n\t\tnewCanvas.context.strokeStyle = \"white\";\n\t\tnewCanvas.context.font = \"12px Arial\";\n\n\t\tthis.canvasHolder[selector] = newCanvas;\n\n\t\treturn newCanvas;\n\t}\n}\n", "import EventSystem from \"./EventSystem\";\nimport Settings from \"./Settings\";\nimport type Game from \"./Game\";\nimport { rafLoop } from \"@/utilities/Functions\";\n\nconst MAX_DT_SECONDS = 0.25;\nconst MAX_STEPS_PER_FRAME = 5;\n\nexport default class Gameloop {\n\tpublic levelTime = 0;\n\tprivate _isLooping = false;\n\tprivate accumulator = 0;\n\tprivate game: Game;\n\tprivate stop = false;\n\n\tpublic get isLooping(): boolean {\n\t\treturn this._isLooping;\n\t}\n\n\tconstructor(game: Game) {\n\t\tthis.game = game;\n\t}\n\n\tpublic startLoop(): void {\n\t\tif (this._isLooping && this.stop) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Gameloop teardown is pending; wait for the \\\"gameloopStopped\\\" event before restarting.\",\n\t\t\t);\n\t\t}\n\n\t\tthis.stop = false;\n\t\tthis.looper();\n\t}\n\n\tpublic stopLoop(): void {\n\t\tthis.stop = true;\n\t}\n\n\tprivate draw(context: CanvasRenderingContext2D): void {\n\t\tif (!Settings.doNotClear) {\n\t\t\tif (Settings.useClearRect) {\n\t\t\t\tcontext.clearRect(\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.game.canman.canvas.width,\n\t\t\t\t\tthis.game.canman.canvas.height,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tcontext.fillStyle = Settings.backgroundColor;\n\t\t\t\tcontext.fillRect(\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.game.canman.canvas.width,\n\t\t\t\t\tthis.game.canman.canvas.height,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.game.draw(context);\n\t}\n\n\tprivate looper(): void {\n\t\tif (this._isLooping) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isLooping = true;\n\t\tconst context = this.game.canman.canvasContext;\n\n\t\tconst stopLoop = rafLoop(dt => {\n\t\t\tif (this.stop) {\n\t\t\t\tthis._isLooping = false;\n\t\t\t\tEventSystem.dispatchEvent(\"gameloopStopped\");\n\t\t\t\tconsole.log(\"Simulation stopped.\");\n\t\t\t\tstopLoop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Snap on big gaps (tab backgrounded, debugger break) \u2014 running\n\t\t\t// many updates to catch up would fast-forward the player.\n\t\t\tif (dt > MAX_DT_SECONDS) {\n\t\t\t\tthis.accumulator = 0;\n\t\t\t} else {\n\t\t\t\tthis.accumulator += dt;\n\t\t\t}\n\n\t\t\tlet steps = MAX_STEPS_PER_FRAME;\n\t\t\twhile (steps-- > 0 && this.accumulator >= Settings.fps) {\n\t\t\t\tthis.game.update(Settings.fps);\n\t\t\t\tthis.accumulator -= Settings.fps;\n\t\t\t\tthis.levelTime += Settings.fps * 1000;\n\t\t\t}\n\n\t\t\tthis.draw(context);\n\t\t});\n\n\t\tconsole.log(\"Simulation started.\");\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport Settings from \"@/core/Settings\";\nimport type Game from \"@/core/Game\";\n\nexport const KEYBOARD_KEYS = {\n\tKEY_0: \"Digit0\",\n\tKEY_1: \"Digit1\",\n\tKEY_2: \"Digit2\",\n\tKEY_3: \"Digit3\",\n\tKEY_4: \"Digit4\",\n\tKEY_5: \"Digit5\",\n\tKEY_6: \"Digit6\",\n\tKEY_7: \"Digit7\",\n\tKEY_8: \"Digit8\",\n\tKEY_9: \"Digit9\",\n\tKEY_A: \"KeyA\",\n\tKEY_B: \"KeyB\",\n\tKEY_C: \"KeyC\",\n\tKEY_D: \"KeyD\",\n\tKEY_DOWN: \"ArrowDown\",\n\tKEY_E: \"KeyE\",\n\tKEY_ENTER: \"Enter\",\n\tKEY_ESCAPE: \"Escape\",\n\tKEY_F: \"KeyF\",\n\tKEY_G: \"KeyG\",\n\tKEY_H: \"KeyH\",\n\tKEY_I: \"KeyI\",\n\tKEY_J: \"KeyJ\",\n\tKEY_K: \"KeyK\",\n\tKEY_L: \"KeyL\",\n\tKEY_LEFT: \"ArrowLeft\",\n\tKEY_M: \"KeyM\",\n\tKEY_N: \"KeyN\",\n\tKEY_O: \"KeyO\",\n\tKEY_P: \"KeyP\",\n\tKEY_Q: \"KeyQ\",\n\tKEY_R: \"KeyR\",\n\tKEY_RIGHT: \"ArrowRight\",\n\tKEY_S: \"KeyS\",\n\tKEY_SPACE: \"Space\",\n\tKEY_T: \"KeyT\",\n\tKEY_TAB: \"Tab\",\n\tKEY_U: \"KeyU\",\n\tKEY_UP: \"ArrowUp\",\n\tKEY_V: \"KeyV\",\n\tKEY_W: \"KeyW\",\n\tKEY_X: \"KeyX\",\n\tKEY_Y: \"KeyY\",\n\tKEY_Z: \"KeyZ\",\n} as const;\n\nexport default class Keyboard {\n\tpublic keys: Record<string, boolean> = {};\n\n\tconstructor(game: Game) {\n\t\tconst keyEvent = (event: KeyboardEvent): void => {\n\t\t\tconst code = event.code;\n\n\t\t\tconst pressed = event.type === \"keydown\";\n\t\t\tthis.keys[code] = pressed;\n\n\t\t\tif (\n\t\t\t\tSettings.debug &&\n\t\t\t\tcode === KEYBOARD_KEYS.KEY_ESCAPE &&\n\t\t\t\tpressed\n\t\t\t) {\n\t\t\t\tgame.gameloop.stopLoop();\n\t\t\t}\n\n\t\t\tEventSystem.dispatchEvent(\n\t\t\t\t\"inputKeyboard\",\n\t\t\t\tthis.keys,\n\t\t\t\tcode,\n\t\t\t\tpressed,\n\t\t\t);\n\t\t};\n\n\t\twindow.addEventListener(\"keydown\", keyEvent, false);\n\t\twindow.addEventListener(\"keyup\", keyEvent, false);\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\n\t\tEventSystem.addEventListener(\"gameloopStopped\", () => this.reset());\n\t}\n\n\tpublic reset(): void {\n\t\tfor (const key in this.keys) {\n\t\t\tthis.keys[key] = false;\n\t\t}\n\t}\n\n\tpublic stopPress(code: string): void {\n\t\tthis.keys[code] = false;\n\t}\n\n\tpublic isPressed(code: string): boolean {\n\t\treturn !!this.keys[code];\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport Vec2 from \"@/math/Vec2\";\nimport type Game from \"@/core/Game\";\nimport { clamp } from \"@/utilities/Number\";\n\nexport const POINTER_KEYS = {\n\tLEFT: 0,\n\tMIDDLE: 1,\n\tRIGHT: 2,\n\tPREV: 3,\n\tFORWARD: 4,\n} as const;\n\nexport default class Pointer {\n\tpublic hasMoved = false;\n\tpublic lastEvent: PointerEvent | null = null;\n\tpublic posReal = new Vec2();\n\tpublic posRealLast = new Vec2();\n\tpublic posScaled = new Vec2();\n\tpublic posScaledLast = new Vec2();\n\tpublic pressed: boolean[] = [];\n\tprivate game: Game;\n\n\tconstructor(game: Game) {\n\t\tthis.game = game;\n\n\t\tconst pointerMoveEvent = (event: PointerEvent): void => {\n\t\t\tif (event.target === this.game.canman.canvas) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\tthis.lastEvent = event;\n\t\t\tthis.hasMoved = true;\n\n\t\t\tthis.update(event);\n\n\t\t\tEventSystem.dispatchEvent(\"inputPointer\", this);\n\t\t};\n\n\t\tconst pointerStateChangeEvent = (event: PointerEvent): void => {\n\t\t\tif (event.target === this.game.canman.canvas) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\tthis.lastEvent = event;\n\n\t\t\tthis.pressed[event.button] = event.type === \"pointerdown\";\n\n\t\t\tEventSystem.dispatchEvent(\"inputPointer\", this);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", pointerMoveEvent, false);\n\t\twindow.addEventListener(\"pointerdown\", pointerStateChangeEvent, false);\n\t\twindow.addEventListener(\"pointerup\", pointerStateChangeEvent, false);\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\n\t\t// Attach to `document` (not `canvas`) so HTML UI overlays and any\n\t\t// secondary canvases also get right-click suppressed.\n\t\tdocument.addEventListener(\n\t\t\t\"contextmenu\",\n\t\t\t(event: Event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\t}\n\n\tpublic reset(): void {\n\t\tthis.pressed.length = 0;\n\t}\n\n\tprivate update(event: PointerEvent): void {\n\t\tthis.posRealLast.set(this.posReal.x, this.posReal.y);\n\t\tthis.posReal.set(event.clientX, event.clientY);\n\n\t\tthis.posScaledLast.set(this.posScaled.x, this.posScaled.y);\n\t\tthis.posScaled.set(\n\t\t\tclamp(\n\t\t\t\t(((event.clientX -\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.left) /\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.width) *\n\t\t\t\t\tthis.game.canman.width) |\n\t\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.game.canman.width,\n\t\t\t),\n\t\t\tclamp(\n\t\t\t\t(((event.clientY -\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.top) /\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.height) *\n\t\t\t\t\tthis.game.canman.height) |\n\t\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.game.canman.height,\n\t\t\t),\n\t\t);\n\t}\n}\n", "import Settings from \"@/core/Settings\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport { throttleByKey } from \"@/utilities/Functions\";\n\ndeclare global {\n\tinterface Window {\n\t\t/** Translate `key` for the active language. Throws until `prepareLanguage` has run. */\n\t\tt(key: string): string;\n\t}\n}\n\n// non-enumerable own property on the instance.\ndefineMethod(window, \"t\", function (): string {\n\tthrow new Error(\"Call 'prepareLanguage' first!\");\n});\n\nconst logMissingKey = throttleByKey<[string]>((count, key) => {\n\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\tconsole.warn(`\"${key}\" has no translation${suffix}`);\n});\n\nconst logMissingLanguage = throttleByKey<[string, string]>(\n\t(count, current, fallback) => {\n\t\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\t\tconsole.warn(\n\t\t\t`Language \"${current}\" not found, falling back to \"${fallback}\"${suffix}`,\n\t\t);\n\t},\n);\n\nexport type Languages = Record<string, Record<string, string>>;\n\nexport function prepareLanguage(\n\tlanguages: Languages,\n\tdefaultLanguage: string = \"en\",\n): void {\n\tif (!languages[defaultLanguage]) {\n\t\tthrow new Error(\n\t\t\t`Default language is defined as \"${defaultLanguage}\" but isn't supplied!`,\n\t\t);\n\t}\n\n\tconst allKeys: Set<string> = new Set();\n\n\tfor (const lang in languages) {\n\t\tfor (const key in languages[lang]) {\n\t\t\tallKeys.add(key);\n\t\t}\n\t}\n\n\tconst sortedKeys = [...allKeys].sort();\n\n\tfor (const lang in languages) {\n\t\tsortedKeys.forEach(key => {\n\t\t\tif (languages[lang][key] === undefined) {\n\t\t\t\tconsole.error(`\"${lang}\" misses \"${key}\"`);\n\t\t\t}\n\t\t});\n\t}\n\n\tdefineMethod(window, \"t\", function (key): string {\n\t\tconst currentLang = Settings.localStorage.language;\n\n\t\tlet language = languages[currentLang];\n\t\tif (!language) {\n\t\t\tlogMissingLanguage(currentLang, currentLang, defaultLanguage);\n\t\t\tlanguage = languages[defaultLanguage];\n\t\t}\n\n\t\tif (language[key] === undefined) {\n\t\t\tlogMissingKey(key, key);\n\t\t\treturn key;\n\t\t}\n\n\t\treturn language[key];\n\t});\n}\n", "import { defineMethod } from \"@/utilities/Prototype\";\n\n// #region clone\ndeclare global {\n\tinterface HTMLAudioElement {\n\t\t/** Deep-clone this audio element, preserving the current `volume`. */\n\t\tclone(): HTMLAudioElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLAudioElement.prototype,\n\t\"clone\",\n\tfunction (): HTMLAudioElement {\n\t\tconst node = this.cloneNode(true) as HTMLAudioElement;\n\t\tnode.volume = this.volume;\n\t\treturn node;\n\t},\n);\n// #endregion\n\n// #region stop\ndeclare global {\n\tinterface HTMLAudioElement {\n\t\t/** Volume restored by `stop()` after pausing. If unset, `stop()` leaves `volume` as-is. */\n\t\tdefaultVolume?: number;\n\t\t/** Pause playback, reset `currentTime` to 0, and restore `volume` to `defaultVolume` if set. */\n\t\tstop(): void;\n\t}\n}\n\ndefineMethod(HTMLAudioElement.prototype, \"stop\", function (): void {\n\tthis.pause();\n\tthis.currentTime = 0;\n\n\tif (this.defaultVolume !== undefined) {\n\t\tthis.volume = this.defaultVolume;\n\t}\n});\n// #endregion\n", "import Rect from \"@/math/Rect\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport type { Vector2, Vector4 } from \"@/math/Vec2\";\n\ntype Mode = \"fill\" | \"stroke\";\n\n// #region fillBar\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Fill a two-color bar sized by `amount`. Writes `fillStyle`; persists on the context \u2014 wrap in `save()`/`restore()` to preserve prior state.\n\t\t * @param c1 background, default `\"white\"`\n\t\t * @param c2 foreground, default `\"black\"`\n\t\t */\n\t\tfillBar(rect: Vector4, amount: number, c1?: string, c2?: string): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"fillBar\",\n\tfunction (rect, amount, c1 = \"white\", c2 = \"black\"): void {\n\t\tthis.fillStyle = c1;\n\t\tthis.fillRect(rect.x, rect.y, rect.w, rect.h);\n\n\t\tthis.fillStyle = c2;\n\t\tthis.fillRect(rect.x, rect.y, rect.w * amount, rect.h);\n\t},\n);\n// #endregion\n\n// #region fillFramedBar\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Fill a three-layer framed bar (outer band, frame, fill scaled by `amount`). Writes `fillStyle`; persists on the context \u2014 wrap in `save()`/`restore()` to preserve prior state.\n\t\t * @param amount fill fraction in `[0, 1]`. Default `0.8`. `\u2264 0` skips the fill layer.\n\t\t * @param padding frame inset on all sides. Default `4`.\n\t\t * @param colors outer band, frame, fill. Default `[\"white\", \"black\", \"red\"]`.\n\t\t */\n\t\tfillFramedBar(\n\t\t\trect: Vector4,\n\t\t\tamount?: number,\n\t\t\tpadding?: number,\n\t\t\tcolors?: [string, string, string],\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"fillFramedBar\",\n\tfunction (\n\t\trect,\n\t\tamount = 0.8,\n\t\tpadding = 4,\n\t\tcolors = [\"white\", \"black\", \"red\"],\n\t): void {\n\t\tthis.fillStyle = colors[0];\n\t\tthis.fillRect(rect.x, rect.y, rect.w, rect.h);\n\n\t\tthis.fillStyle = colors[1];\n\t\tthis.fillRect(\n\t\t\trect.x + padding,\n\t\t\trect.y + padding,\n\t\t\trect.w - padding * 2,\n\t\t\trect.h - padding * 2,\n\t\t);\n\n\t\tif (amount > 0) {\n\t\t\tthis.fillStyle = colors[2];\n\t\t\tthis.fillRect(\n\t\t\t\trect.x + padding,\n\t\t\t\trect.y + padding,\n\t\t\t\tamount * (rect.w - padding * 2),\n\t\t\t\trect.h - padding * 2,\n\t\t\t);\n\t\t}\n\t},\n);\n// #endregion\n\n// #region drawCircle\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draws a circle centered at `vecPos`.\n\t\t * @param amount sweep fraction in `[0, 1]`. Default `1` (full circle).\n\t\t */\n\t\tdrawCircle(\n\t\t\tvecPos: Vector2,\n\t\t\trad: number,\n\t\t\tmode: Mode,\n\t\t\tamount?: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawCircle\",\n\tfunction (vecPos, rad, mode, amount = 1): void {\n\t\tthis.beginPath();\n\t\tthis.arc(vecPos.x, vecPos.y, rad, 0, amount * 2 * Math.PI);\n\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawRect\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draws a rectangle (from `Vector4` or `x, y, w, h`). */\n\t\tdrawRect(rect: Vector4, mode: Mode): void;\n\t\tdrawRect(x: number, y: number, w: number, h: number, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawRect\",\n\tfunction (\n\t\t...args: [Vector4, Mode] | [number, number, number, number, Mode]\n\t): void {\n\t\tlet x: number;\n\t\tlet y: number;\n\t\tlet w: number;\n\t\tlet h: number;\n\t\tlet mode: Mode;\n\n\t\tif (typeof args[0] === \"number\") {\n\t\t\t[x, y, w, h, mode] = args as [number, number, number, number, Mode];\n\t\t} else {\n\t\t\t[{ x, y, w, h }, mode] = args as [Vector4, Mode];\n\t\t}\n\n\t\tthis.beginPath();\n\t\tthis.rect(x, y, w, h);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawRoundRect\ninterface DrawRoundRectOptions {\n\t/** Inset from the rect edges. Default `0` (no inset). */\n\tpadding?: number;\n\t/** Corner radius. Default `16`. */\n\tradius?: number;\n}\n\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a rounded rectangle from a `Vector4` or `x, y, w, h` plus an options bag. Delegates the corner path to native `roundRect` (Safari 16+ / Chrome 99+ / Firefox 113+). */\n\t\tdrawRoundRect(\n\t\t\trect: Vector4,\n\t\t\tmode: Mode,\n\t\t\toptions?: DrawRoundRectOptions,\n\t\t): void;\n\t\tdrawRoundRect(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw: number,\n\t\t\th: number,\n\t\t\tmode: Mode,\n\t\t\toptions?: DrawRoundRectOptions,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawRoundRect\",\n\tfunction (\n\t\t...args:\n\t\t\t| [Vector4, mode: Mode, DrawRoundRectOptions?]\n\t\t\t| [\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tmode: Mode,\n\t\t\t\t\tDrawRoundRectOptions?,\n\t\t\t ]\n\t): void {\n\t\tlet x: number;\n\t\tlet y: number;\n\t\tlet w: number;\n\t\tlet h: number;\n\t\tlet mode: Mode;\n\t\tlet options: DrawRoundRectOptions | undefined;\n\n\t\tif (typeof args[0] === \"number\") {\n\t\t\t[x, y, w, h, mode, options] = args as [\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tMode,\n\t\t\t\tDrawRoundRectOptions?,\n\t\t\t];\n\t\t} else {\n\t\t\t[{ x, y, w, h }, mode, options] = args as [\n\t\t\t\tVector4,\n\t\t\t\tMode,\n\t\t\t\tDrawRoundRectOptions?,\n\t\t\t];\n\t\t}\n\n\t\tconst { padding = 0, radius = 16 } = options ?? {};\n\n\t\tx += padding;\n\t\ty += padding;\n\t\tw -= padding * 2;\n\t\th -= padding * 2;\n\n\t\tthis.beginPath();\n\t\tthis.roundRect(x, y, w, h, radius);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region strokeDottedRect\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Stroke a dotted rectangle. Writes `lineWidth` and `setLineDash` \u2014 wrap in `save()`/`restore()` to preserve prior state. */\n\t\tstrokeDottedRect(rect: Vector4): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"strokeDottedRect\",\n\tfunction (rect): void {\n\t\tthis.setLineDash([15, 15]);\n\t\tthis.lineWidth = 5;\n\t\tthis.beginPath();\n\t\tthis.moveTo(rect.x, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y + rect.h);\n\t\tthis.lineTo(rect.x, rect.y + rect.h);\n\t\tthis.lineTo(rect.x, rect.y);\n\t\tthis.stroke();\n\t},\n);\n// #endregion\n\n// #region strokeLine\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a line segment from `(x1, y1)` to `(x2, y2)`. */\n\t\tstrokeLine(x1: number, y1: number, x2: number, y2: number): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"strokeLine\",\n\tfunction (x1, y1, x2, y2): void {\n\t\tthis.beginPath();\n\t\tthis.moveTo(x1, y1);\n\t\tthis.lineTo(x2, y2);\n\t\tthis.stroke();\n\t\tthis.closePath();\n\t},\n);\n// #endregion\n\n// #region drawPolygon\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draw a regular polygon centered in `rect`, with vertices on a circle of radius `min(rect.w, rect.h) * 0.5`.\n\t\t */\n\t\tdrawPolygon(sides: number, rect: Vector4, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawPolygon\",\n\tfunction (sides, rect, mode): void {\n\t\tconst rad = Math.min(rect.w, rect.h) * 0.5;\n\t\tconst Xcenter = rect.x + rect.w * 0.5;\n\t\tconst Ycenter = rect.y + rect.h * 0.5;\n\n\t\tthis.beginPath();\n\t\tthis.moveTo(Xcenter + rad, Ycenter);\n\n\t\tfor (let i = 1; i <= sides; i++) {\n\t\t\tthis.lineTo(\n\t\t\t\tMath.round(Xcenter + rad * Math.cos((i * 2 * Math.PI) / sides)),\n\t\t\t\tMath.round(Ycenter + rad * Math.sin((i * 2 * Math.PI) / sides)),\n\t\t\t);\n\t\t}\n\n\t\tthis.closePath();\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawTriangle\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a triangle: top-left \u2192 top-right \u2192 bottom-center. */\n\t\tdrawTriangle(rect: Vector4, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawTriangle\",\n\tfunction (rect, mode): void {\n\t\tthis.beginPath();\n\t\tthis.moveTo(rect.x, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y);\n\t\tthis.lineTo(rect.x + rect.w * 0.5, rect.y + rect.h);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region writeText\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Write text horizontally offset around `x` by `measureTextOffset` of its measured width.\n\t\t * @param measureTextOffset in `[0, 1]`. Default `0.5` (centered around `x`).\n\t\t */\n\t\twriteText(\n\t\t\ttext: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tmeasureTextOffset?: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"writeText\",\n\tfunction (text, x, y, measureTextOffset = 0.5): void {\n\t\tthis.fillText(\n\t\t\ttext,\n\t\t\tx - this.measureText(text).width * measureTextOffset,\n\t\t\ty,\n\t\t);\n\t},\n);\n// #endregion\n\n// #region writeMultilineText\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Word-wrap `text` into lines of pixel width `width`, drawing each line via `writeText`. Returns `false` and logs to `console.error` if `maxAttempts` is reached.\n\t\t * @param lineOffset vertical spacing between lines in px. Default `50`.\n\t\t * @param maxAttempts safety cap on wrap iterations. Default `50`.\n\t\t */\n\t\twriteMultilineText(\n\t\t\ttext: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\twidth: number,\n\t\t\tlineOffset?: number,\n\t\t\tmaxAttempts?: number,\n\t\t): boolean;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"writeMultilineText\",\n\tfunction (text, x, y, width, lineOffset = 50, maxAttempts = 50): boolean {\n\t\tconst words = text.split(\" \");\n\t\tlet attempts = 0;\n\n\t\twhile (words.length > 0 && attempts < maxAttempts) {\n\t\t\tlet count = words.length;\n\t\t\tfor (let i = 1; i <= words.length; i++) {\n\t\t\t\tconst textWidth = this.measureText(\n\t\t\t\t\twords.slice(0, i).join(\" \"),\n\t\t\t\t).width;\n\n\t\t\t\tif (textWidth > width) {\n\t\t\t\t\tcount = Math.max(1, i - 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.writeText(words.slice(0, count).join(\" \"), x, y, 0);\n\t\t\twords.splice(0, count);\n\t\t\ty += lineOffset;\n\t\t\tattempts++;\n\t\t}\n\n\t\tif (attempts >= maxAttempts) {\n\t\t\tconsole.error(\"maxAttempts reached\", attempts);\n\t\t}\n\n\t\treturn attempts < maxAttempts;\n\t},\n);\n// #endregion\n\n// #region drawImageRotated\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draw `image` rotated by `radians` around the center of its placement at `(x, y)`. Saves and restores the transform.\n\t\t * @param radians clockwise positive, in radians.\n\t\t */\n\t\tdrawImageRotated(\n\t\t\timage: HTMLCanvasElement,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tradians: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawImageRotated\",\n\tfunction (image, x, y, radians): void {\n\t\tthis.save();\n\t\tthis.translate(x + image.width * 0.5, y + image.height * 0.5);\n\t\tthis.rotate(radians);\n\t\tthis.drawImage(image, -image.width * 0.5, -image.height * 0.5);\n\t\tthis.restore();\n\t},\n);\n// #endregion\n\n// #region generateColor\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Build a colored rounded-rect stencil with a `drawPartialRoundRect` helper. The returned helper writes `fillStyle = \"white\"` on the caller's context \u2014 wrap in `save()`/`restore()` to preserve prior state. */\n\t\tgenerateColor(\n\t\t\tsize: number,\n\t\t\tcolor: string,\n\t\t): {\n\t\t\tcolors: [number, number][];\n\t\t\timage: HTMLCanvasElement;\n\t\t\tdrawPartialRoundRect: (\n\t\t\t\trect: Rect,\n\t\t\t\tamount: number,\n\t\t\t\toffsetX?: number,\n\t\t\t\toffsetY?: number,\n\t\t\t) => void;\n\t\t};\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"generateColor\",\n\tfunction (size, color) {\n\t\tconst cc = createNewCanvas(size, size);\n\t\tcc.context.strokeStyle = color;\n\t\tcc.context.lineWidth = 6;\n\t\tcc.context.drawRoundRect(0, 0, size, size, \"stroke\", {\n\t\t\tpadding: cc.context.lineWidth,\n\t\t\tradius: 15,\n\t\t});\n\n\t\tconst data = cc.context.getImageData(0, 0, size, size).data;\n\t\tconst allColors: [number, number][] = [];\n\t\tfor (let i = 0; i < data.length; i += 4) {\n\t\t\tif (data[i + 3]) {\n\t\t\t\tallColors.push([(i / 4) % size, (i / 4 / size) | 0]);\n\t\t\t}\n\t\t}\n\n\t\tconst colors: [number, number][] = [];\n\n\t\tallColors.forEach(c => {\n\t\t\tif (c[0] > size * 0.5) {\n\t\t\t\tcolors.push(c);\n\t\t\t}\n\t\t});\n\n\t\tfor (let i = allColors.length - 1; i >= 0; i--) {\n\t\t\tif (allColors[i][0] <= size * 0.5) {\n\t\t\t\tcolors.push(allColors[i]);\n\t\t\t}\n\t\t}\n\n\t\tconst drawPartialRoundRect = (\n\t\t\trect: Rect,\n\t\t\tamount: number,\n\t\t\toffsetX = 0,\n\t\t\toffsetY = 0,\n\t\t): void => {\n\t\t\tthis.drawImage(cc.canvas, rect.x + offsetX, rect.y + offsetY);\n\n\t\t\tthis.fillStyle = \"white\";\n\n\t\t\tfor (\n\t\t\t\tlet i = 0;\n\t\t\t\ti < Math.min(amount * colors.length, colors.length);\n\t\t\t\ti++\n\t\t\t) {\n\t\t\t\tthis.fillRect(\n\t\t\t\t\trect.x + colors[i][0] + offsetX,\n\t\t\t\t\trect.y + colors[i][1] + offsetY,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\treturn { colors, image: cc.canvas, drawPartialRoundRect };\n\t},\n);\n// #endregion\n", "import { defineMethod } from \"@/utilities/Prototype\";\n\nimport \"./Audio\";\nimport \"./CanvasRenderingContext2D\";\nimport \"./HTMLCanvasElement\";\n\n// #region subImage\ndeclare global {\n\tinterface HTMLImageElement {\n\t\t/**\n\t\t * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.\n\t\t * @param w default `this.width`\n\t\t * @param h default `this.height`\n\t\t */\n\t\tsubImage(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw?: number,\n\t\t\th?: number,\n\t\t): HTMLCanvasElement;\n\t}\n}\n\n// Reuse the canvas implementations on images. It calls `drawImage(this, ...)`\n// and reads `this.width / this.height` \u2014 all valid on HTMLImageElement too.\ndefineMethod(\n\tHTMLImageElement.prototype,\n\t\"subImage\",\n\tHTMLCanvasElement.prototype.subImage as HTMLImageElement[\"subImage\"],\n);\n// #endregion\n", "import CanvasManager from \"@/core/CanvasManager\";\nimport EventSystem from \"@/core/EventSystem\";\nimport Gameloop from \"./Gameloop\";\nimport Keyboard from \"@/input/Keyboard\";\nimport Pointer from \"@/input/Pointer\";\nimport Settings, { type SettingsOverrides } from \"@/core/Settings\";\nimport { debounce } from \"@/utilities/Functions\";\n\nimport \"@/localization/Translator\";\nimport \"@/prototypes/index\";\n\nexport default abstract class Game {\n\tpublic canman = new CanvasManager();\n\tpublic gameloop: Gameloop;\n\tpublic keyboard: Keyboard;\n\tpublic pointer: Pointer;\n\tprivate initialized = false;\n\n\tconstructor(settingOverrides: SettingsOverrides = {}) {\n\t\tSettings.init(settingOverrides, this);\n\n\t\thistory.scrollRestoration = \"manual\";\n\n\t\tthis.gameloop = new Gameloop(this);\n\t\tthis.keyboard = new Keyboard(this);\n\t\tthis.pointer = new Pointer(this);\n\t}\n\n\tpublic draw(_context: CanvasRenderingContext2D): void {\n\t\tthrow new Error(\"Override draw function!\");\n\t}\n\n\tpublic update(_dt: number): void {\n\t\tthrow new Error(\"Override update function!\");\n\t}\n\n\tpublic async init(): Promise<void> {\n\t\tthrow new Error(\n\t\t\t\"Override init() and start the game via preInit() \u2014 do not call init() directly.\",\n\t\t);\n\t}\n\n\tprotected async preInit(doInit = true): Promise<void> {\n\t\tif (this.initialized) {\n\t\t\tthrow new Error(\n\t\t\t\t\"preInit() may only be called once per Game instance.\",\n\t\t\t);\n\t\t}\n\t\tthis.initialized = true;\n\n\t\tthis.canman.finishSetup();\n\n\t\twindow.addEventListener(\n\t\t\t\"resize\",\n\t\t\tdebounce(() => EventSystem.dispatchEvent(\"resized\"), 250),\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.gameloop.levelTime = 0;\n\n\t\tif (doInit) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tEventSystem.dispatchEvent(\"resized\");\n\n\t\tif (Settings.autoloop) {\n\t\t\tthis.gameloop.startLoop();\n\t\t}\n\t}\n}\n", "import { rafLoop } from \"@/utilities/Functions\";\nimport { randomBetweenFloat } from \"@/utilities/Math\";\n\ntype CssStyleKey = {\n\t[K in keyof CSSStyleDeclaration]: K extends string\n\t\t? CSSStyleDeclaration[K] extends string\n\t\t\t? K\n\t\t\t: never\n\t\t: never;\n}[keyof CSSStyleDeclaration];\n\ntype CssProxy = (key: CssStyleKey, value: string) => void;\n\ninterface ShakeType {\n\tstep: number;\n\tupdate: (updateCss: CssProxy, time: number) => void;\n}\n\nexport const SHAKE_TYPES = {\n\tNORMAL: {\n\t\tstep: 3,\n\t\tupdate(updateCss: CssProxy, time: number): void {\n\t\t\tconst tr = `rotate(${randomBetweenFloat(-2, 2) * time}deg)`;\n\t\t\tupdateCss(\"transform\", tr);\n\t\t\tupdateCss(\"webkitTransform\", tr);\n\n\t\t\tupdateCss(\"filter\", `blur(${time * 5}px)`);\n\t\t},\n\t},\n\tFAST: {\n\t\tstep: 15,\n\t\tupdate(updateCss: CssProxy, time: number): void {\n\t\t\tupdateCss(\"filter\", `blur(${time * 3}px)`);\n\t\t},\n\t},\n} satisfies Record<string, ShakeType>;\n\n/**\n * Only the built-in shake types (NORMAL, FAST) are supported today.\n * Letting callers define their own could be a possible feature \u2014 impact pulses, slow rumble, directional jolts.\n */\nexport default class Screenshake {\n\tprivate isShaking: boolean = false;\n\tprivate shakeType: ShakeType = SHAKE_TYPES.NORMAL;\n\tprivate style: CSSStyleDeclaration;\n\n\tconstructor(element: HTMLElement) {\n\t\tthis.style = element.style;\n\t}\n\n\t/** Best-effort style restore: each key the shake writes is snapshotted on first write and rewritten when the shake ends or is disposed. */\n\tpublic shake(\n\t\tshakeType: ShakeType = SHAKE_TYPES.NORMAL,\n\t): null | (() => void) {\n\t\tif (this.isShaking) {\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.isShaking = true;\n\t\tthis.shakeType = shakeType;\n\t\tlet timer = 1;\n\n\t\tconst originalValue = new Map<string, string>();\n\t\tconst updateCssProxy: CssProxy = (key, value) => {\n\t\t\tif (!originalValue.has(key)) {\n\t\t\t\toriginalValue.set(key, this.style[key]);\n\t\t\t}\n\n\t\t\tthis.style[key] = value;\n\t\t};\n\n\t\tconst stopLoop = rafLoop(dt => {\n\t\t\tthis.shakeType.update(updateCssProxy, timer);\n\t\t\ttimer -= this.shakeType.step * dt;\n\n\t\t\tif (timer <= 0) {\n\t\t\t\tdispose();\n\t\t\t}\n\t\t});\n\n\t\tlet alive = true;\n\t\tconst dispose = (): void => {\n\t\t\t// `alive` is per-shake, so a stale dispose handle from a previous shake can't restore its old snapshot over a later shake or flip the shared isShaking flag.\n\t\t\tif (!alive) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\talive = false;\n\n\t\t\tstopLoop();\n\t\t\toriginalValue.forEach((value, key) => {\n\t\t\t\tthis.style[key] = value;\n\t\t\t});\n\t\t\tthis.isShaking = false;\n\t\t};\n\n\t\treturn dispose;\n\t}\n}\n", "import type Controller from \"./Controller\";\nimport type Game from \"@/core/Game\";\nimport type Vec2 from \"@/math/Vec2\";\nimport { clamp } from \"@/utilities/Number\";\nimport { loadImage } from \"@/loader/UrlLoaders\";\n\nconst SPEED = 600;\n\nlet CROSSHAIR: HTMLImageElement;\n(async (): Promise<HTMLImageElement> =>\n\t(CROSSHAIR = await loadImage(\n\t\t\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAilBMVEUAAAAaGhoZGRkZGRkbGxsZGRkaGhoWFhYgICAZGRkZGRkZGRkZGRkZGRkZGRkYGBgZGRkZGRkbGxsaGhoZGRkZGRkZGRkZGRkZGRkaGhoZGRkZGRkaGhoZGRkZGRkZGRkYGBgZGRkZGRkbGxsZGRkYGBgZGRkYGBgaGhoYGBgYGBgYGBgZGRkaGhqj+rsBAAAALXRSTlMA9fvsBINBCwfhZTnS2sByMcUZE8oe1TUqubeppJOLhlDyeiPOrp57X19dSkdeSFeiAAAELElEQVR42sSY2XaqQBBFD20jozKJI3E2Tun//72bKgmXZBmjLbT7KQ9J2HSdrqoFtMiCw2I2SUKvI0THC5PJbHEIMhjBOc/7HXWVTn9+dtAmbtdOhLqJSOyui3YYvXXUXXTeRmicfN9TNaxtYUf+shtbVtxd+pFdbC1Vo7fPm335Xe3Z0/VyI1FiWSiRm+V6WrPYNXcMwbSq8KCqcCXwMyWDKiXTAE3Q7auSMEpB/C7ApFGoSvpdPEs6q5IVA/hbgImrvM5SPIOMVorxfBe4U4BxfU8xq0hCmyAsM+1L4BEBlvd7ZeV0oyBtoQjvJIEHBRh58hQhbKlV/Uv4xNwBNAQYZy4uYdRIwsclRkkMaAowcXKJ8AceQy4UYfmApkCFbyli8VAZ3EIRwzGeF8B4qIjCxd04E0W8O2hCAM67IiYO7iQb8PEfgQYEmCOXYZDhLvIexyZAcwIIONK9/K735+d7YzQpgLHHBtkdBRtw/HI0K4B8yFVw/sz/pKxWswJVsiYubiILfv8MzQsg4zMoJG6x4PrnaEMAOedgcbP/cv7HaEcAY74LN7pySr9gBWhLAIFFL5j+GgCef0e0J4Ajz8bfYmBz/0WbAuCubOMqgaAL4LQr4NBVEMHVAoQUgDHaFcCYYhBeK0KkPvHRtgB8ek505QbQ/pugfQEktCun+MmMahObEIgpazP8oKs+mcOEAOb0rC6+Qy3Ac8wIOB41A3wjIKkTzAjgRE8LUGdK24I0JSBp55mixuhyBY0IVFdxhP/sKAHSnICkFOxQkeseAAtoH0GOL/Y0JF2TAi4N/j2+oEy8waQA3ij13yIYmxWIOYY1mxBmBRDSqdfqEZkWiDh31RgQqWmBVNBAqDaxAUwLYFDtZgn9ZF7A/to/HD4L8wJceQfAmVZB17yAS8vhuVwPpjAvwBN4Xq4i61cIrMu1hLrA8hUCS+oEQKY+2bxCYENPzhBQBuUrBKTFi9lBKbXFKwSwVUod+JNE8RqBgj9XzKgPGheoeuEMEx6FuoyEGAFPDMQJTwIfeuR9/t6QQw+fp0Go3wbcoWKGrn4jCOHpj6K1WtmWZa/UWn8ceejo74OhiCmEsQj198IOBDUiPZSwLPpjof0PlBL/mrd3GwiBIAiiAgRYCOcMfOzNP70TpNBCr4kAaX8zPVX+B6IluJ4luKIlSDbhOpZzms5lrMEmTI7hfoz3O/bgGEYX0f17s/07uYjCq3ib5y27iv1jxJ9jXpDwkowXpbws940Jb814c8rbcx5Q+IiGh1Q8puNBpY9qeVjt43o+sOAjGz+04mM7P7jko1s/vObjew8wcITDQywc4/Egk0e5OMzmcT4PNHqkk0OtHuv1YLNHuz3c7vF+Lzh4xcNLLgWajxedvOpVILt53a9AeCxQPguk1wLtt0B8blC/C+T3L/T/P3gDDpik2UVvAAAAAElFTkSuQmCC\",\n\t)))();\n\nexport default class ControllerCursor {\n\tprivate axisId: number;\n\tprivate controller: Controller;\n\tprivate game: Game;\n\tprivate pos: Vec2;\n\n\tpublic get centerPos(): Vec2 {\n\t\treturn this.pos\n\t\t\t.clone()\n\t\t\t.add(CROSSHAIR.width * 0.5, CROSSHAIR.height * 0.5);\n\t}\n\n\tconstructor(controller: Controller, game: Game, axisId: number) {\n\t\tthis.controller = controller;\n\t\tthis.game = game;\n\t\tthis.axisId = axisId;\n\n\t\tthis.pos = game.canman.size.mult(0.5);\n\t}\n\n\tpublic draw(context: CanvasRenderingContext2D): void {\n\t\tcontext.drawImage(CROSSHAIR, this.pos.x, this.pos.y);\n\t}\n\n\tpublic update(dt: number): void {\n\t\tconst step = this.controller.stick(this.axisId).mult(SPEED * dt);\n\n\t\tif (step.length() === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.pos.x = clamp(\n\t\t\tthis.pos.x + step.x,\n\t\t\t0,\n\t\t\tthis.game.canman.width - CROSSHAIR.width,\n\t\t);\n\n\t\tthis.pos.y = clamp(\n\t\t\tthis.pos.y + step.y,\n\t\t\t0,\n\t\t\tthis.game.canman.height - CROSSHAIR.height,\n\t\t);\n\t}\n}\n", "import ControllerCursor from \"./ControllerCursor\";\nimport EventSystem from \"@/core/EventSystem\";\nimport Vec2 from \"@/math/Vec2\";\nimport type Game from \"@/core/Game\";\nimport { map, threshold } from \"@/utilities/Number\";\n\nexport const CONTROLLER_KEYS = {\n\tA: 0,\n\tB: 1,\n\tX: 2,\n\tY: 3,\n\tLB: 4,\n\tRB: 5,\n\tLT: 6,\n\tRT: 7,\n\tSELECT: 8,\n\tSTART: 9,\n\tLEFT_STICK: 10,\n\tRIGHT_STICK: 11,\n\tUP: 12,\n\tDOWN: 13,\n\tLEFT: 14,\n\tRIGHT: 15,\n\tGUIDE: 16,\n} as const;\n\nconst AXIS_THRESHOLD = 0.3;\n\nexport default class Controller {\n\tpublic buttons: boolean[] = [];\n\tpublic cursors: ControllerCursor[] = [];\n\tprivate axes: Vec2[] = [];\n\tprivate index = -1;\n\tprivate lastTime = 0;\n\n\tconstructor(game: Game) {\n\t\tif (!(\"getGamepads\" in navigator)) {\n\t\t\tconsole.error(\"Controller not supported!\");\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = 0; i < 2; i++) {\n\t\t\tthis.cursors.push(new ControllerCursor(this, game, i));\n\t\t}\n\n\t\twindow.addEventListener(\"gamepadconnected\", (event: GamepadEvent) => {\n\t\t\tthis.index = event.gamepad.index;\n\t\t\tconsole.log(\"Gamepad connected:\", event.gamepad.id);\n\t\t\tEventSystem.dispatchEvent(\n\t\t\t\t\"inputControllerConnected\",\n\t\t\t\tevent.gamepad,\n\t\t\t);\n\t\t\tthis.vibrate();\n\t\t});\n\n\t\twindow.addEventListener(\n\t\t\t\"gamepaddisconnected\",\n\t\t\t(event: GamepadEvent) => {\n\t\t\t\tif (this.index === event.gamepad.index) {\n\t\t\t\t\tthis.index = -1;\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"Our Gamepad was disconnected:\",\n\t\t\t\t\t\tevent.gamepad.index,\n\t\t\t\t\t);\n\t\t\t\t\tEventSystem.dispatchEvent(\"inputControllerDisconnected\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"Different Gamepad was disconnected:\",\n\t\t\t\t\t\tevent.gamepad.index,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\t}\n\n\tpublic draw(context: CanvasRenderingContext2D): void {\n\t\tif (this.index < 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.cursors.forEach(cursor => cursor.draw(context));\n\t}\n\n\tpublic update(dt: number): void {\n\t\tthis.cursors.forEach(cursor => cursor.update(dt));\n\n\t\tconst gp = this.getGamepad();\n\n\t\tif (!gp || this.lastTime === gp.timestamp) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.lastTime = gp.timestamp;\n\n\t\tthis.buttons = gp.buttons.map(\n\t\t\t(button: GamepadButton) => button.pressed,\n\t\t);\n\n\t\tthis.axes.length = 0;\n\t\tconst axes = gp.axes;\n\n\t\tfor (let i = 0; i + 1 < axes.length; i += 2) {\n\t\t\tthis.axes.push(new Vec2(axes[i], axes[i + 1]));\n\t\t}\n\t}\n\n\tpublic reset(): void {\n\t\tthis.buttons.length = 0;\n\t\tthis.axes.length = 0;\n\t}\n\n\tpublic vibrate(): boolean {\n\t\tconst gp = this.getGamepad();\n\n\t\tif (!gp) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst vibrator = gp.vibrationActuator;\n\n\t\tif (vibrator) {\n\t\t\tvibrator.playEffect(\"dual-rumble\", {\n\t\t\t\tduration: 400,\n\t\t\t\tweakMagnitude: 1.0,\n\t\t\t\tstartDelay: 0,\n\t\t\t\tstrongMagnitude: 1.0,\n\t\t\t});\n\t\t}\n\n\t\treturn !!vibrator;\n\t}\n\n\tpublic stick(index: number): Vec2 {\n\t\tif (this.index < 0 || index >= this.axes.length) {\n\t\t\treturn new Vec2();\n\t\t}\n\n\t\treturn this.axes[index]\n\t\t\t.clone()\n\t\t\t.map((value: number) => threshold(value, AXIS_THRESHOLD))\n\t\t\t.map(\n\t\t\t\t(value: number) =>\n\t\t\t\t\tMath.sign(value) *\n\t\t\t\t\tmap(Math.abs(value), AXIS_THRESHOLD, 1, 0, 1),\n\t\t\t);\n\t}\n\n\tprivate getGamepad(): Gamepad | null {\n\t\treturn this.index < 0\n\t\t\t? null\n\t\t\t: (navigator.getGamepads()[this.index] ?? null);\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\nimport { throttle } from \"@/utilities/Functions\";\nimport { wrapRadians } from \"@/utilities/Math\";\n\nexport interface PolygonCollisionResult {\n\tintersect: boolean;\n\tminimumTranslationVector: Vec2;\n\twillIntersect: boolean;\n}\n\nconst warnZeroEdge = throttle(count => {\n\tconsole.warn(\n\t\t`Polygon.collide: found a zero-edge polygon \u2014 no collision possible. (called x${count} since last trace)`,\n\t);\n});\n\nfunction pointDirection(\n\txfrom: number,\n\tyfrom: number,\n\txto: number,\n\tyto: number,\n): number {\n\treturn Math.atan2(yto - yfrom, xto - xfrom);\n}\n\nfunction intervalDistance(\n\tminA: number,\n\tmaxA: number,\n\tminB: number,\n\tmaxB: number,\n): number {\n\treturn minA < minB ? minB - maxA : minA - maxB;\n}\n\nfunction projectPolygon(axis: Vec2, polygon: Polygon, bounds: Vec2): void {\n\tlet dotProduct = axis.dotProduct(polygon.points[0]);\n\tbounds.x = dotProduct;\n\tbounds.y = dotProduct;\n\n\tfor (let i = 1; i < polygon.points.length; i++) {\n\t\tdotProduct = polygon.points[i].dotProduct(axis);\n\n\t\tif (dotProduct < bounds.x) {\n\t\t\tbounds.x = dotProduct;\n\t\t} else if (dotProduct > bounds.y) {\n\t\t\tbounds.y = dotProduct;\n\t\t}\n\t}\n}\n\nexport default class Polygon {\n\t/**\n\t * `angle` is the simplification threshold in radians: vertices whose turn\n\t * angle wraps to within \u00B1`angle` of straight are dropped.\n\t */\n\tpublic static fromCanvas(\n\t\tcanvas: HTMLCanvasElement,\n\t\tdetail: number,\n\t\tangle: number,\n\t): Polygon {\n\t\tdetail = Math.max(2, detail);\n\n\t\tconst w = canvas.width;\n\t\tconst h = canvas.height;\n\t\tconst data = canvas.getContext(\"2d\")!.getImageData(0, 0, w, h).data;\n\n\t\tconst vertexX = [0];\n\t\tconst vertexY = [0];\n\t\tconst vertexK = [1];\n\n\t\tlet numPoints = 0;\n\t\tlet fy = -1;\n\t\tlet lx = 0;\n\t\tlet ly = 0;\n\n\t\tfor (let tx = 0; tx < w; tx += detail) {\n\t\t\tfor (let ty = 0; ty < h; ty += 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tif (fy < 0) {\n\t\t\t\t\t\tfy = ty;\n\t\t\t\t\t}\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let ty = 0; ty < h; ty += detail) {\n\t\t\tfor (let tx = w - 1; tx >= 0; tx -= 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && ty > ly) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let tx = w - 1; tx >= 0; tx -= detail) {\n\t\t\tfor (let ty = h - 1; ty >= 0; ty -= 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && tx < lx) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let ty = h - 1; ty >= 0; ty -= detail) {\n\t\t\tfor (let tx = 0; tx < w; tx += 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && ty < ly && ty > fy) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (numPoints < 3) {\n\t\t\tthrow new Error(\n\t\t\t\t`Polygon.fromCanvas: scan produced \"${numPoints}\" vertices (need >=3). Canvas may be empty or detail (${detail}) too large.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (let i = 0; i < numPoints; i++) {\n\t\t\tconst a = i;\n\t\t\tconst b = (i + 1) % numPoints;\n\t\t\tconst c = (i + 2) % numPoints;\n\n\t\t\tconst ang1 = pointDirection(\n\t\t\t\tvertexX[a],\n\t\t\t\tvertexY[a],\n\t\t\t\tvertexX[b],\n\t\t\t\tvertexY[b],\n\t\t\t);\n\t\t\tconst ang2 = pointDirection(\n\t\t\t\tvertexX[b],\n\t\t\t\tvertexY[b],\n\t\t\t\tvertexX[c],\n\t\t\t\tvertexY[c],\n\t\t\t);\n\n\t\t\tif (Math.abs(wrapRadians(ang1 - ang2)) <= angle) {\n\t\t\t\tvertexK[b] = 0;\n\t\t\t}\n\t\t}\n\n\t\tconst points: Vec2[] = [];\n\t\tfor (let i = 0; i < numPoints; i++) {\n\t\t\tif (vertexK[i] === 1) {\n\t\t\t\tpoints.push(new Vec2(vertexX[i], vertexY[i]));\n\t\t\t}\n\t\t}\n\n\t\treturn new Polygon(...points);\n\t}\n\n\tpublic static fromEdges(edges: number, size: Vec2 | number): Polygon {\n\t\tconst s = size instanceof Vec2 ? size : new Vec2(size, size);\n\n\t\tconst rad = Math.min(s.x, s.y) * 0.5;\n\t\tconst Xcenter = s.x * 0.5;\n\t\tconst Ycenter = s.y * 0.5;\n\n\t\tconst points: Vec2[] = [];\n\t\tfor (let i = 1; i <= edges; i++) {\n\t\t\tpoints.push(\n\t\t\t\tnew Vec2(\n\t\t\t\t\tMath.round(\n\t\t\t\t\t\tXcenter + rad * Math.cos((i * 2 * Math.PI) / edges),\n\t\t\t\t\t),\n\t\t\t\t\tMath.round(\n\t\t\t\t\t\tYcenter + rad * Math.sin((i * 2 * Math.PI) / edges),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn new Polygon(...points);\n\t}\n\n\tpublic static fromRect(rect: Rect): Polygon {\n\t\treturn new Polygon(\n\t\t\tnew Vec2(rect.x, rect.y),\n\t\t\tnew Vec2(rect.x + rect.w, rect.y),\n\t\t\tnew Vec2(rect.x + rect.w, rect.y + rect.h),\n\t\t\tnew Vec2(rect.x, rect.y + rect.h),\n\t\t);\n\t}\n\n\tprivate _center: Vec2 = new Vec2();\n\tprivate _points: Vec2[] = [];\n\tprivate edges: Vec2[] = [];\n\n\tpublic get center(): Readonly<Vec2> {\n\t\treturn this._center;\n\t}\n\n\tpublic get points(): Readonly<Vec2[]> {\n\t\treturn this._points;\n\t}\n\n\tconstructor(...points: Vec2[]) {\n\t\tthis.addPoints(...points);\n\t}\n\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tif (this._points.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontext.beginPath();\n\n\t\tcontext.moveTo(\n\t\t\t(offset.x + this._points[0].x) | 0,\n\t\t\t(offset.y + this._points[0].y) | 0,\n\t\t);\n\n\t\tfor (let i = 1; i < this._points.length; i++) {\n\t\t\tcontext.lineTo(\n\t\t\t\t(offset.x + this._points[i].x) | 0,\n\t\t\t\t(offset.y + this._points[i].y) | 0,\n\t\t\t);\n\t\t}\n\n\t\tcontext.closePath();\n\t\tcontext.stroke();\n\t}\n\n\tpublic addPoint(x: number, y: number): Polygon {\n\t\tthis._points.push(new Vec2(x, y));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\tpublic addPoints(...points: Vec2[]): Polygon {\n\t\tpoints.forEach(point => this._points.push(point.clone()));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\tpublic offset(x = 0, y = 0): Polygon {\n\t\tthis._points.forEach(point => point.add(x, y));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\tpublic rotate(angle: number, pos: Readonly<Vec2> = this.center) {\n\t\tif (!angle) {\n\t\t\treturn this;\n\t\t}\n\n\t\tconst cos = Math.cos(angle);\n\t\tconst sin = Math.sin(angle);\n\n\t\tthis._points.forEach(point => {\n\t\t\tconst dx = point.x - pos.x;\n\t\t\tconst dy = point.y - pos.y;\n\t\t\tpoint.set(dx * cos - dy * sin + pos.x, dx * sin + dy * cos + pos.y);\n\t\t});\n\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\tpublic collide(\n\t\totherPolygon: Polygon,\n\t\tvelocity: Vec2 = new Vec2(),\n\t): PolygonCollisionResult {\n\t\tconst result: PolygonCollisionResult = {\n\t\t\tintersect: true,\n\t\t\tminimumTranslationVector: new Vec2(),\n\t\t\twillIntersect: true,\n\t\t};\n\n\t\tconst edgeCountA = this.edges.length;\n\t\tconst edgeCountB = otherPolygon.edges.length;\n\n\t\tif (edgeCountA === 0 || edgeCountB === 0) {\n\t\t\twarnZeroEdge();\n\n\t\t\treturn {\n\t\t\t\tintersect: false,\n\t\t\t\tminimumTranslationVector: new Vec2(),\n\t\t\t\twillIntersect: false,\n\t\t\t};\n\t\t}\n\n\t\tlet minDistance = Infinity;\n\t\tlet translationAxis = new Vec2();\n\t\tlet edge: Vec2;\n\n\t\tfor (\n\t\t\tlet edgeIndex = 0;\n\t\t\tedgeIndex < edgeCountA + edgeCountB;\n\t\t\tedgeIndex++\n\t\t) {\n\t\t\tif (edgeIndex < edgeCountA) {\n\t\t\t\tedge = this.edges[edgeIndex];\n\t\t\t} else {\n\t\t\t\tedge = otherPolygon.edges[edgeIndex - edgeCountA];\n\t\t\t}\n\n\t\t\tconst axis = new Vec2(-edge.y, edge.x);\n\t\t\taxis.normalize();\n\n\t\t\tconst boundsA = new Vec2();\n\t\t\tconst boundsB = new Vec2();\n\t\t\tprojectPolygon(axis, this, boundsA);\n\t\t\tprojectPolygon(axis, otherPolygon, boundsB);\n\n\t\t\tif (\n\t\t\t\tintervalDistance(boundsA.x, boundsA.y, boundsB.x, boundsB.y) > 0\n\t\t\t) {\n\t\t\t\tresult.intersect = false;\n\t\t\t}\n\n\t\t\tconst velocityProjection = axis.dotProduct(velocity);\n\n\t\t\tif (velocityProjection < 0) {\n\t\t\t\tboundsA.x += velocityProjection;\n\t\t\t} else {\n\t\t\t\tboundsA.y += velocityProjection;\n\t\t\t}\n\n\t\t\tlet distance = intervalDistance(\n\t\t\t\tboundsA.x,\n\t\t\t\tboundsA.y,\n\t\t\t\tboundsB.x,\n\t\t\t\tboundsB.y,\n\t\t\t);\n\t\t\tif (distance > 0) {\n\t\t\t\tresult.willIntersect = false;\n\t\t\t}\n\n\t\t\tif (!result.intersect && !result.willIntersect) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdistance = Math.abs(distance);\n\t\t\tif (distance < minDistance) {\n\t\t\t\tminDistance = distance;\n\t\t\t\ttranslationAxis = axis.clone();\n\n\t\t\t\tconst d = this.center.clone().sub(otherPolygon.center);\n\t\t\t\tif (d.dotProduct(translationAxis) < 0) {\n\t\t\t\t\ttranslationAxis.negate();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (result.willIntersect) {\n\t\t\tresult.minimumTranslationVector = translationAxis.mult(minDistance);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tpublic clone(): Polygon {\n\t\treturn new Polygon(...this._points);\n\t}\n\n\tprivate update(): void {\n\t\tif (this._points.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// edges\n\t\tlet p1: Vec2;\n\t\tlet p2: Vec2;\n\n\t\t// Allocates one Vec2 per edge per call; called every offset/rotate.\n\t\t// Reuse via edges[i].set(...) if profiling shows GC pressure here.\n\t\tthis.edges.length = 0;\n\t\tfor (let i = 0; i < this._points.length; i++) {\n\t\t\tp1 = this._points[i];\n\n\t\t\tif (i + 1 >= this._points.length) {\n\t\t\t\tp2 = this._points[0];\n\t\t\t} else {\n\t\t\t\tp2 = this._points[i + 1];\n\t\t\t}\n\n\t\t\tthis.edges.push(p2.clone().sub(p1));\n\t\t}\n\n\t\t// center\n\t\tlet totalX = 0;\n\t\tlet totalY = 0;\n\n\t\tthis.points.forEach(point => {\n\t\t\ttotalX += point.x;\n\t\t\ttotalY += point.y;\n\t\t});\n\n\t\tthis.center.set(\n\t\t\ttotalX / this._points.length,\n\t\t\ttotalY / this._points.length,\n\t\t);\n\t}\n}\n", "/**\n * Recursively clone a value. Returns primitives and functions as-is (no copy).\n * Cyclic references resolve via an internal `WeakMap`. Explicit branches preserve\n * `Date`, `RegExp`, `Map`, `Set`, `Array`, `ArrayBuffer`, typed arrays, and `DataView`.\n * For plain objects / class instances the prototype is preserved via\n * `Object.create(...)` \u2014 the original constructor is *not* called, so no side\n * effects fire. Symbol keys and non-enumerable data properties are carried via descriptors.\n * Own accessor properties (`get`/`set`) are snapshotted to a data property by invoking\n * the getter on the source; this severs any closure binding to the original instance\n * but also drops live computation on the clone.\n */\nexport function deepClone<T>(obj: T): T {\n\treturn cloneInternal(obj, new WeakMap<object, unknown>());\n}\n\nfunction cloneInternal<T>(obj: T, hash: WeakMap<object, unknown>): T {\n\tif (Object(obj) !== obj || obj instanceof Function) {\n\t\t// primitive or function -> return as-is\n\t\treturn obj;\n\t}\n\n\tconst o = obj as object;\n\n\tif (hash.has(o)) {\n\t\t// cycle / already cloned -> return cached\n\t\treturn hash.get(o) as T;\n\t}\n\n\tif (obj instanceof Date) {\n\t\t// date -> clone via getTime\n\t\tconst cloned = new Date(obj.getTime());\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof RegExp) {\n\t\t// regex -> clone source + flags + lastIndex\n\t\tconst cloned = new RegExp(obj.source, obj.flags);\n\t\tcloned.lastIndex = obj.lastIndex;\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof Map) {\n\t\t// map -> recurse into entries\n\t\tconst cloned = new Map<unknown, unknown>();\n\t\thash.set(o, cloned);\n\t\tobj.forEach((v, k) => {\n\t\t\tcloned.set(cloneInternal(k, hash), cloneInternal(v, hash));\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof Set) {\n\t\t// set -> recurse into items\n\t\tconst cloned = new Set<unknown>();\n\t\thash.set(o, cloned);\n\t\tobj.forEach(v => {\n\t\t\tcloned.add(cloneInternal(v, hash));\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (Array.isArray(obj)) {\n\t\t// array -> recurse into items\n\t\tconst cloned: unknown[] = [];\n\t\thash.set(o, cloned);\n\t\tobj.forEach((item, i) => {\n\t\t\tcloned[i] = cloneInternal(item, hash);\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof ArrayBuffer) {\n\t\t// arraybuffer -> slice\n\t\tconst cloned = obj.slice(0);\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof DataView) {\n\t\t// dataview -> reslice underlying buffer\n\t\tconst buf = obj.buffer.slice(\n\t\t\tobj.byteOffset,\n\t\t\tobj.byteOffset + obj.byteLength,\n\t\t);\n\t\tconst cloned = new DataView(buf);\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (ArrayBuffer.isView(obj)) {\n\t\t// typed array -> slice (preserves subtype)\n\t\tconst cloned = (obj as unknown as Uint8Array).slice();\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tconst result = Object.create(Object.getPrototypeOf(o));\n\thash.set(o, result);\n\n\tReflect.ownKeys(o).forEach(key => {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(o, key)!;\n\t\tif (\"value\" in descriptor) {\n\t\t\tdescriptor.value = cloneInternal(descriptor.value, hash);\n\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\treturn;\n\t\t}\n\t\t// Accessor (get/set) \u2014 snapshot by invoking the getter on the source to\n\t\t// avoid closure-bound captures of the original instance. The clone gets\n\t\t// a plain data property; live computation is lost.\n\t\tconst snapshot = cloneInternal(\n\t\t\t(o as Record<PropertyKey, unknown>)[key as PropertyKey],\n\t\t\thash,\n\t\t);\n\t\tObject.defineProperty(result, key, {\n\t\t\tvalue: snapshot,\n\t\t\twritable: true,\n\t\t\tenumerable: descriptor.enumerable,\n\t\t\tconfigurable: descriptor.configurable,\n\t\t});\n\t});\n\n\treturn result as T;\n}\n", "/**\n * Trim `str` and collapse internal whitespace runs to a single space.\n */\nexport function compact(str: string): string {\n\treturn str.trim().replace(/\\s+/g, \" \");\n}\n\n/**\n * Replace the single character at `index` in `str`. Indexes by code point, so emoji and other supplementary-plane characters count as one. Throws on out-of-range index or multi-character `char`.\n */\nexport function replaceCharAt(\n\tstr: string,\n\tindex: number,\n\tchar: string,\n): string {\n\tconst codePoints = Array.from(str);\n\n\tif (index < 0 || index >= codePoints.length) {\n\t\tthrow new Error(\n\t\t\t`replaceCharAt index out of range: ${index} (length ${codePoints.length})`,\n\t\t);\n\t}\n\n\tconst charPoints = Array.from(char);\n\tif (charPoints.length !== 1) {\n\t\tthrow new Error(\n\t\t\t`replaceCharAt requires a single character, got length ${charPoints.length}`,\n\t\t);\n\t}\n\n\tcodePoints[index] = char;\n\treturn codePoints.join(\"\");\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/index.ts", "../src/utilities/Functions.ts", "../src/core/EventSystem.ts", "../src/audio/AudioBase.ts", "../src/utilities/Number.ts", "../src/utilities/Easing.ts", "../src/utilities/Array.ts", "../src/audio/Music.ts", "../src/audio/Sound.ts", "../src/utilities/Math.ts", "../src/utilities/Color.ts", "../src/color/Color.ts", "../src/color/ColorShifter.ts", "../src/math/Rect.ts", "../src/math/Vec2.ts", "../src/core/Settings.ts", "../src/utilities/DOM.ts", "../src/utilities/Grid.ts", "../src/utilities/Prototype.ts", "../src/loader/UrlLoaders.ts", "../src/prototypes/HTMLCanvasElement.ts", "../src/utilities/Canvas.ts", "../src/content/Animator.ts", "../src/content/ControllerCursor.ts", "../src/content/Particle.ts", "../src/content/Projectile.ts", "../src/core/CanvasManager.ts", "../src/core/Gameloop.ts", "../src/input/Keyboard.ts", "../src/input/Pointer.ts", "../src/localization/Translator.ts", "../src/prototypes/Audio.ts", "../src/prototypes/CanvasRenderingContext2D.ts", "../src/prototypes/index.ts", "../src/core/Game.ts", "../src/effects/Screenshake.ts", "../src/input/Controller.ts", "../src/math/Polygon.ts", "../src/utilities/Json.ts", "../src/utilities/String.ts"],
|
|
4
|
+
"sourcesContent": ["// generated by scripts/generate-barrel.mjs \u2014 do not edit\n\n// audio\nexport { default as AudioBase } from \"./audio/AudioBase\";\nexport * from \"./audio/AudioBase\";\nexport { default as Music } from \"./audio/Music\";\nexport { default as Sound } from \"./audio/Sound\";\n\n// color\nexport * from \"./color/Color\";\nexport * from \"./color/ColorShifter\";\n\n// content\nexport { default as Animator } from \"./content/Animator\";\nexport * from \"./content/Animator\";\nexport { default as ControllerCursor } from \"./content/ControllerCursor\";\nexport { default as Particle } from \"./content/Particle\";\nexport { default as Projectile } from \"./content/Projectile\";\n\n// core\nexport { default as CanvasManager } from \"./core/CanvasManager\";\nexport * from \"./core/CanvasManager\";\nexport { default as EventSystem } from \"./core/EventSystem\";\nexport * from \"./core/EventSystem\";\nexport { default as Game } from \"./core/Game\";\nexport { default as Gameloop } from \"./core/Gameloop\";\nexport * from \"./core/Gameloop\";\nexport { default as Settings } from \"./core/Settings\";\nexport * from \"./core/Settings\";\n\n// effects\nexport { default as Screenshake } from \"./effects/Screenshake\";\nexport * from \"./effects/Screenshake\";\n\n// input\nexport { default as Controller } from \"./input/Controller\";\nexport * from \"./input/Controller\";\nexport { default as Keyboard } from \"./input/Keyboard\";\nexport * from \"./input/Keyboard\";\nexport { default as Pointer } from \"./input/Pointer\";\nexport * from \"./input/Pointer\";\n\n// loader\nexport * from \"./loader/UrlLoaders\";\n\n// localization\nexport * from \"./localization/Translator\";\n\n// math\nexport { default as Polygon } from \"./math/Polygon\";\nexport * from \"./math/Polygon\";\nexport { default as Rect } from \"./math/Rect\";\nexport * from \"./math/Rect\";\nexport { default as Vec2 } from \"./math/Vec2\";\nexport * from \"./math/Vec2\";\n\n// prototypes\n\n// utilities\nexport * from \"./utilities/Array\";\nexport * from \"./utilities/Canvas\";\nexport * from \"./utilities/Color\";\nexport * from \"./utilities/DOM\";\nexport * from \"./utilities/Easing\";\nexport * from \"./utilities/Functions\";\nexport * from \"./utilities/Grid\";\nexport * from \"./utilities/Json\";\nexport * from \"./utilities/Math\";\nexport * from \"./utilities/Number\";\nexport * from \"./utilities/Prototype\";\nexport * from \"./utilities/String\";\n", "/**\n * Returns a debounced wrapper that runs `callback` only after `delay` ms of silence (trailing edge).\n */\nexport function debounce<T extends unknown[]>(\n\tcallback: (...args: T) => void,\n\tdelay: number,\n): (...args: T) => void {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\treturn (...args: T) => {\n\t\tclearTimeout(timer);\n\t\ttimer = setTimeout(() => callback(...args), delay);\n\t};\n}\n\n/**\n * Promise that resolves after `time` milliseconds.\n */\nexport function delay(time: number): Promise<void> {\n\treturn new Promise(res => setTimeout(res, time));\n}\n\n/**\n * Returns `true` when touch is the primary input right now (game-UI question: show touch controls?).\n * Mode-aware: a convertible in laptop mode returns `false`, in tablet mode returns `true`.\n * Snapshot at call time \u2014 won't auto-update if the user switches modes mid-game.\n */\nexport function isTouchPrimary(): boolean {\n\treturn matchMedia(\"(pointer: coarse)\").matches;\n}\n\n/**\n * Run `tick(dt)` on every animation frame; `dt` is seconds since the previous\n * frame (0 on the first call). Returns a cancel function that stops the loop \u2014\n * no further ticks fire after it's called, even if one was already queued.\n */\nexport function rafLoop(tick: (dt: number) => void): () => void {\n\tlet lastTime = 0;\n\tlet running = true;\n\tlet handle = 0;\n\n\tconst wrapped = (now: number): void => {\n\t\tconst dt = lastTime === 0 ? 0 : (now - lastTime) / 1000;\n\t\tlastTime = now;\n\n\t\ttick(dt);\n\n\t\t// `running` covers stop-from-inside-tick: after tick returns, skip the requeue.\n\t\tif (running) {\n\t\t\thandle = requestAnimationFrame(wrapped);\n\t\t}\n\t};\n\n\thandle = requestAnimationFrame(wrapped);\n\n\treturn () => {\n\t\trunning = false;\n\t\tcancelAnimationFrame(handle);\n\t};\n}\n\n/**\n * Returns a throttled wrapper that runs `callback` at most once per `delay` ms (leading edge).\n * The callback receives the number of wrapper calls since the previous firing (inclusive of this one).\n */\nexport function throttle(\n\tcallback: (callCount: number) => void,\n\tdelay: number = 1000,\n): () => void {\n\tlet lastCalled = -Infinity;\n\tlet callCount = 0;\n\n\treturn () => {\n\t\tcallCount++;\n\n\t\tconst now = performance.now();\n\n\t\tif (now - lastCalled > delay) {\n\t\t\tlastCalled = now;\n\t\t\tconst count = callCount;\n\t\t\tcallCount = 0;\n\t\t\tcallback(count);\n\t\t}\n\t};\n}\n\n/**\n * Like `throttle`, but tracks the last firing independently per `key` \u2014\n * different keys never throttle each other. Use for de-duplicating repeated\n * error/warning logs by message identity. When the throttle fires, args from\n * the most recent call for that key are passed through alongside `callCount`.\n */\nexport function throttleByKey<T extends unknown[]>(\n\tcallback: (callCount: number, ...args: T) => void,\n\tdelay: number = 1000,\n): (key: string, ...args: T) => void {\n\tconst wrappers = new Map<string, (...args: T) => void>();\n\n\treturn (key, ...args) => {\n\t\tlet wrapper = wrappers.get(key);\n\n\t\tif (!wrapper) {\n\t\t\tlet latest: T;\n\t\t\tconst throttled = throttle(\n\t\t\t\tcount => callback(count, ...latest),\n\t\t\t\tdelay,\n\t\t\t);\n\t\t\twrapper = (...a: T) => {\n\t\t\t\tlatest = a;\n\t\t\t\tthrottled();\n\t\t\t};\n\t\t\twrappers.set(key, wrapper);\n\t\t}\n\n\t\twrapper(...args);\n\t};\n}\n\n/**\n * Filename component of a URL/path, without directory, extension, or query string.\n * Returns `null` when no usable name can be derived: a path ending in `/`, or a stem containing a malformed percent-escape that `decodeURIComponent` rejects.\n */\nexport function urlBasename(path: string): string | null {\n\tconst url = new URL(path, \"http://_/\");\n\tconst base = url.pathname.split(\"/\").pop()!;\n\tconst dot = base.lastIndexOf(\".\");\n\tconst stem = dot > 0 ? base.slice(0, dot) : base;\n\n\tif (!stem) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn decodeURIComponent(stem);\n\t} catch {\n\t\treturn null;\n\t}\n}\n", "import type Pointer from \"@/input/Pointer\";\nimport { throttleByKey } from \"@/utilities/Functions\";\n\n/**\n * Type-safe registry of engine events and their payload tuples. Both {@link EventSystem.addEventListener} and {@link EventSystem.dispatchEvent} are generic over this map, so the listener callback and dispatched args are checked against the declared shape.\n */\nexport interface GameEventMap {\n\t/** Fired by {@link Gameloop} once teardown completes, after `stopLoop()` is called. */\n\tgameloopStopped: [];\n\t/** Fired by {@link Controller} when a gamepad is connected. Payload is the native `Gamepad`. */\n\tinputControllerConnected: [event: Gamepad];\n\t/** Fired by {@link Controller} when *our* tracked gamepad disconnects. Other gamepads disconnecting are logged but don't dispatch. */\n\tinputControllerDisconnected: [];\n\t/** Fired by {@link Keyboard} on every key down/up with the live `keys` map, the `code` that changed, and its new pressed state. */\n\tinputKeyboard: [\n\t\tkeys: Record<string, boolean>,\n\t\tcode: string,\n\t\tpressed: boolean,\n\t];\n\t/** Fired by {@link Pointer} on every move and button transition. Payload is the `Pointer` instance \u2014 read `posScaled`/`pressed` from it. */\n\tinputPointer: [pointer: Pointer];\n\t/** Fired by {@link Game.preInit} once at startup and on every debounced `window.resize` thereafter. The canonical \"viewport changed\" signal. */\n\tresized: [];\n}\n\n/** Options for {@link EventSystem.addEventListener}. */\nexport interface EventSystemOptions {\n\t/** Auto-dispose the listener after the first dispatch. */\n\tonce?: boolean;\n\t/** Dispose the listener when the signal aborts. Already-aborted signals make `addEventListener` a no-op. */\n\tsignal?: AbortSignal;\n}\n\ntype GameEventListener<K extends keyof GameEventMap> = {\n\tcallback: (...args: GameEventMap[K]) => void;\n\tdispose: () => void;\n\toptions: { once: boolean; signal?: AbortSignal };\n};\n\n/**\n * Synchronous, type-safe pub/sub for engine-wide events. Static-only \u2014 call as `EventSystem.addEventListener(...)` / `EventSystem.dispatchEvent(...)`. Event names and payloads are constrained by {@link GameEventMap}.\n *\n * Guarantees:\n *\n * - Listeners registered during a dispatch are deferred to the next dispatch (won't fire in the round that registered them).\n * - `once` listeners are removed *before* their callback runs, so nested dispatches and throwing callbacks can't double-fire them.\n * - A throwing callback is caught and logged (throttled per `eventName:message`); siblings still receive the event.\n */\nexport default class EventSystem {\n\tprivate static eventListener: {\n\t\t[K in keyof GameEventMap]?: Map<number, GameEventListener<K>>;\n\t} = {};\n\n\tprivate static logListenerError = throttleByKey<[string, unknown]>(\n\t\t(count, eventName, err) => {\n\t\t\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\t\t\tconsole.error(\n\t\t\t\t`EventSystem listener for \"${eventName}\" threw${suffix}:`,\n\t\t\t\terr,\n\t\t\t);\n\t\t},\n\t);\n\n\t// Monotonic counter \u2014 each listener gets an id assigned at registration.\n\t// `dispatchEvent` captures the value at start as a boundary so listeners\n\t// registered mid-dispatch (id > maxId) are deferred to the next dispatch.\n\tprivate static nextId = 0;\n\n\t/**\n\t * Register a listener for `eventName`. Returns a dispose function \u2014 the primary teardown path. Multiple disposers (returned, `once`, `signal.abort`) are idempotent. Use {@link EventSystemOptions} for `once` and `signal` behavior.\n\t */\n\tpublic static addEventListener<K extends keyof GameEventMap>(\n\t\teventName: K,\n\t\tcallback: (...args: GameEventMap[K]) => void,\n\t\toptions: EventSystemOptions = {},\n\t): () => void {\n\t\tif (options.signal?.aborted) {\n\t\t\treturn function dispose(): void {};\n\t\t}\n\n\t\tconst id = ++this.nextId;\n\n\t\t// `function` declaration (not arrow) so it's hoisted and can reference\n\t\t// the `listener` constant defined below \u2014 both close over the same id.\n\t\t// Used by: user-returned disposer, the once-path in dispatchEvent, and\n\t\t// the signal's abort handler. Idempotent via Map.delete's false return.\n\t\tfunction dispose(): void {\n\t\t\tconst bucket = EventSystem.eventListener[eventName];\n\n\t\t\tif (!bucket?.delete(id)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Drop the bucket entry when empty so `eventListener` doesn't grow\n\t\t\t// monotonically and `dispatchEvent` can short-circuit on `!bucket`\n\t\t\t// without a per-dispatch size check.\n\t\t\tif (bucket.size === 0) {\n\t\t\t\tdelete EventSystem.eventListener[eventName];\n\t\t\t}\n\n\t\t\tif (listener.options.signal) {\n\t\t\t\tlistener.options.signal.removeEventListener(\"abort\", dispose);\n\t\t\t}\n\t\t}\n\n\t\tconst listener: GameEventListener<K> = {\n\t\t\tcallback,\n\t\t\tdispose,\n\t\t\toptions: { once: options.once ?? false, signal: options.signal },\n\t\t};\n\n\t\tlet bucket = this.eventListener[eventName];\n\n\t\tif (!bucket) {\n\t\t\tbucket = new Map();\n\t\t\tthis.eventListener[eventName] = bucket;\n\t\t}\n\n\t\tbucket.set(id, listener);\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener(\"abort\", dispose, { once: true });\n\t\t}\n\n\t\treturn dispose;\n\t}\n\n\t/** Synchronously fire `eventName` with the typed payload. Listeners are invoked in registration order; nested dispatches and self-disposing listeners are handled safely. */\n\tpublic static dispatchEvent<K extends keyof GameEventMap>(\n\t\teventName: K,\n\t\t...params: GameEventMap[K]\n\t): void {\n\t\tconst bucket = this.eventListener[eventName];\n\n\t\tif (!bucket) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Snapshot the id boundary \u2014 listeners registered during this dispatch\n\t\t// (which would have ids > maxId) are skipped this round.\n\t\tconst maxId = this.nextId;\n\n\t\t// Map.forEach is safe under mid-iteration mutation:\n\t\t// - entries deleted during the walk are skipped natively, so a callback\n\t\t// calling dispose() on itself, a sibling, or via nested dispatch needs\n\t\t// no extra bookkeeping;\n\t\t// - entries added during the walk would otherwise be visited, but the\n\t\t// `id > maxId` filter excludes them;\n\t\t// - nested forEach on the same Map keeps its own position, so recursive\n\t\t// dispatch works without depth tracking.\n\t\tbucket.forEach((entry, id) => {\n\t\t\tif (id > maxId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Remove the once-listener *before* invoking the callback so a nested\n\t\t\t// dispatch of the same event can't fire it a second time, and so a\n\t\t\t// throwing callback still leaves the bucket clean.\n\t\t\tif (entry.options.once) {\n\t\t\t\tentry.dispose();\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tentry.callback(...params);\n\t\t\t} catch (err) {\n\t\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\t\tthis.logListenerError(`${eventName}:${msg}`, eventName, err);\n\t\t\t}\n\t\t});\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport { urlBasename } from \"@/utilities/Functions\";\n\n/** Entry shape passed to {@link AudioBase.register}. */\nexport interface RegisterData {\n\t/** URL or relative path to the audio file. */\n\tpath: string;\n\t/** Identifier used by `play(name)` / `fade(name)`. */\n\tname: string;\n\t/** Per-song volume override in `[0, 1]`. Falls back to `register`'s `defaultVolume`. */\n\tvolume?: number;\n}\n\nconst MEDIA_ERROR_CODES: Record<number, string> = {\n\t1: \"ABORTED\",\n\t2: \"NETWORK\",\n\t3: \"DECODE\",\n\t4: \"SRC_NOT_SUPPORTED\",\n};\n\n/**\n * Shared registration, enable/disable, and teardown machinery for {@link Sound} and {@link Music}. Auto-subscribes to the `\"gameloopStopped\"` event so playback halts on loop teardown.\n */\nexport default abstract class AudioBase {\n\t/** Registered audio elements keyed by name. Subclasses read this; mutate via {@link register}. */\n\tprotected songs: Map<string, HTMLAudioElement> = new Map();\n\tprivate _enabled: boolean;\n\tprivate registered: boolean = false;\n\n\t/** Whether playback is permitted. Setting to `false` invokes {@link stop} immediately. */\n\tpublic get enabled(): boolean {\n\t\treturn this._enabled;\n\t}\n\n\t/** Setting to `false` invokes {@link stop} immediately; subclasses (notably {@link Music}) may re-start playback when flipped back to `true`. */\n\tpublic set enabled(value: boolean) {\n\t\tthis._enabled = value;\n\n\t\tif (!value) {\n\t\t\tthis.stop();\n\t\t}\n\t}\n\n\tconstructor(enabled: boolean = true) {\n\t\tthis._enabled = enabled;\n\n\t\tEventSystem.addEventListener(\"gameloopStopped\", () => this.stop());\n\t}\n\n\t/** Load and register one or more audio files. Each entry may be a bare URL string (the file's basename becomes the name) or a {@link RegisterData} object. Per-song volume falls back to `defaultVolume`. **Call once per instance** \u2014 throws on a second invocation, on non-finite volume, or on volume outside `[0, 1]`. Load failures are logged to `console.error` but don't throw. */\n\tpublic register(\n\t\tdefaultVolume: number = 1,\n\t\t...songs: (RegisterData | string)[]\n\t): void {\n\t\tthis.throwOnBadVolume(defaultVolume, \"defaultVolume\");\n\n\t\tif (this.registered) {\n\t\t\tthrow new Error(\"register() can only be called once per instance\");\n\t\t}\n\t\tthis.registered = true;\n\n\t\tsongs.forEach(song => {\n\t\t\tif (typeof song === \"string\") {\n\t\t\t\tsong = { name: urlBasename(song) ?? song, path: song };\n\t\t\t} else if (song.volume !== undefined) {\n\t\t\t\tthis.throwOnBadVolume(song.volume, `Volume of \"${song.name}\"`);\n\t\t\t}\n\n\t\t\tconst audio = new window.Audio();\n\n\t\t\taudio.addEventListener(\"error\", () => {\n\t\t\t\tconst err = audio.error;\n\t\t\t\tconst reason = err\n\t\t\t\t\t? `${MEDIA_ERROR_CODES[err.code] ?? err.code}${err.message ? `: ${err.message}` : \"\"}`\n\t\t\t\t\t: \"unknown\";\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Failed to load audio \"${song.name}\" from \"${audio.src}\": ${reason}`,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\taudio.preload = \"auto\";\n\t\t\taudio.src = song.path;\n\t\t\taudio.id = song.name;\n\t\t\taudio.volume = song.volume ?? defaultVolume;\n\t\t\taudio.defaultVolume = audio.volume;\n\n\t\t\tthis.songs.set(song.name, audio);\n\t\t});\n\t}\n\n\t/** Base hook called when {@link enabled} flips to `false` and on `\"gameloopStopped\"`. The default is a no-op; {@link Sound} and {@link Music} override it to cut playback. Subclass overrides should call `super.stop()`. */\n\tpublic stop(): void {\n\t\tvoid 0;\n\t}\n\n\tprivate throwOnBadVolume(volume: number, name: string): void {\n\t\tif (!Number.isFinite(volume)) {\n\t\t\tthrow new Error(\n\t\t\t\tname + \" is invalid, it has to be in range of 0 to 1\",\n\t\t\t);\n\t\t}\n\n\t\tif (volume < 0) {\n\t\t\tthrow new Error(\n\t\t\t\tname + \" has to be above 0. What's a negative volume anyway?\",\n\t\t\t);\n\t\t}\n\n\t\tif (volume > 1) {\n\t\t\tthrow new Error(\n\t\t\t\tname +\n\t\t\t\t\t\" has to be lower or equal to 1! If you need a louder volume, you need to update the audio file itself.\",\n\t\t\t);\n\t\t}\n\t}\n}\n", "/**\n * Compare two numbers with float tolerance. Default epsilon absorbs typical accumulated rounding error from normalize/rotate/divide chains.\n */\nexport function approxEqual(a: number, b: number, epsilon = 1e-9): boolean {\n\treturn Math.abs(a - b) <= epsilon;\n}\n\n/**\n * Clamp values between two values\n */\nexport function clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Map value from one range to another. Returns `low2` when the source range is degenerate (`low1 === high1`).\n */\nexport function mapUnclamped(\n\tvalue: number,\n\tlow1: number,\n\thigh1: number,\n\tlow2: number,\n\thigh2: number,\n): number {\n\tif (low1 === high1) {\n\t\treturn low2;\n\t}\n\n\treturn low2 + ((high2 - low2) * (value - low1)) / (high1 - low1);\n}\n\n/**\n * Map value from one range to another (with clamping). Output range allows to be inverted (`high2 < low2`).\n */\nexport function map(\n\tvalue: number,\n\tlow1: number,\n\thigh1: number,\n\tlow2: number,\n\thigh2: number,\n): number {\n\treturn clamp(\n\t\tmapUnclamped(value, low1, high1, low2, high2),\n\t\tMath.min(low2, high2),\n\t\tMath.max(low2, high2),\n\t);\n}\n\n/**\n * Zero out values with `|value| < cutoff`; pass the rest through unchanged.\n */\nexport function threshold(value: number, cutoff: number): number {\n\tif (Math.abs(value) < cutoff) {\n\t\treturn 0;\n\t}\n\n\treturn value;\n}\n\n/**\n * Format number with dot separators (e.g., 1.000.000). Rounds to the nearest integer via `Math.round`; non-finite values pass through as their `toString()` form.\n */\nexport function toDotted(value: number): string {\n\treturn Math.round(value)\n\t\t.toString()\n\t\t.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \".\");\n}\n\n/**\n * Wrap `value` into `[min, max)` modulo the range size. Useful for cyclic ranges like angles.\n * Caller steps via `value + n`; this function handles the wrap-around.\n * Bounds are swapped if passed in reverse order. Throws when `min \u2248 max` (degenerate range, via `approxEqual`).\n */\nexport function wrapValue(value: number, min: number, max: number): number {\n\tif (approxEqual(min, max)) {\n\t\tthrow new RangeError(`wrapValue: min and max must differ (got ${min})`);\n\t}\n\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\tconst range = max - min;\n\treturn ((((value - min) % range) + range) % range) + min;\n}\n", "/**\n * Quadratic ease-in (slow start, accelerates).\n */\nexport function easeIn(t: number): number {\n\treturn t * t;\n}\n\n/**\n * Quadratic ease-in-out (accelerates, then decelerates).\n */\nexport function easeInOut(t: number): number {\n\treturn t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t);\n}\n\n/**\n * Quadratic ease-out (fast start, decelerates).\n */\nexport function easeOut(t: number): number {\n\treturn t * (2 - t);\n}\n\n/**\n * Identity (constant rate of change).\n */\nexport function linear(t: number): number {\n\treturn t;\n}\n\n/** Names of the built-in easing curves. Use as a key into {@link EASINGS}. */\nexport type EasingName = \"ease-in\" | \"ease-in-out\" | \"ease-out\" | \"linear\";\n\n/** Lookup table from {@link EasingName} to its easing function (`t \u2208 [0, 1] \u2192 eased t`). */\nexport const EASINGS: Record<EasingName, (t: number) => number> = {\n\t\"ease-in\": easeIn,\n\t\"ease-in-out\": easeInOut,\n\t\"ease-out\": easeOut,\n\tlinear: linear,\n};\n", "/**\n * Split an array into chunks of at most `maxLength` elements each. Throws when `maxLength < 1`.\n */\nexport function chunk<T>(array: ReadonlyArray<T>, maxLength: number): T[][] {\n\tif (!Number.isFinite(maxLength) || maxLength < 1) {\n\t\tthrow new RangeError(\n\t\t\t`chunk: maxLength must be a finite number >= 1 (got ${maxLength})`,\n\t\t);\n\t}\n\n\tconst result: T[][] = [];\n\tlet part: T[] = [];\n\n\tarray.forEach((item, i) => {\n\t\tpart.push(item);\n\n\t\tif (part.length === maxLength || i === array.length - 1) {\n\t\t\tresult.push(part);\n\t\t\tpart = [];\n\t\t}\n\t});\n\n\treturn result;\n}\n\n/**\n * Pick a uniformly random element from `array`. Throws if `array` is empty \u2014 guard at the call site if that's possible.\n */\nexport function randomItem<T>(array: ReadonlyArray<T>): T {\n\tif (array.length === 0) {\n\t\tthrow new Error(\"randomItem called on empty array\");\n\t}\n\n\treturn array[(Math.random() * array.length) | 0];\n}\n\n/**\n * Remove an entry of an Array\n */\nexport function remove<T>(arr: T[], item: T): void {\n\tconst index = arr.indexOf(item);\n\tif (index >= 0) {\n\t\tarr.splice(index, 1);\n\t}\n}\n\n/**\n * Shuffle array using Fisher-Yates algorithm with custom random signer\n */\nexport function shuffle<T>(arr: ReadonlyArray<T>): T[] {\n\tconst result = arr.slice();\n\n\tfor (let i = result.length - 1; i > 0; i--) {\n\t\tconst j = Math.floor(Math.random() * (i + 1));\n\t\t[result[i], result[j]] = [result[j], result[i]];\n\t}\n\n\treturn result;\n}\n", "import AudioBase from \"./AudioBase\";\nimport { clamp } from \"@/utilities/Number\";\nimport { type EasingName, EASINGS } from \"@/utilities/Easing\";\nimport { rafLoop } from \"@/utilities/Functions\";\nimport { randomItem, remove } from \"@/utilities/Array\";\n\n/**\n * Background music with eased cross-fades. Tracks auto-cycle: when the current track ends, the next one fades in. Inherits registration, enable/disable, and volume from {@link AudioBase}.\n *\n * Random track picking excludes the previous two songs to avoid back-to-back repeats. If only one track is registered, it's looped instead of faded.\n */\nexport default class Music extends AudioBase {\n\tprivate last: HTMLAudioElement | null = null;\n\tprivate current: HTMLAudioElement | null = null;\n\tprivate next: HTMLAudioElement | null = null;\n\tprivate fadeCancel: (() => void) | null = null;\n\n\t/** `true` while a fade is in progress OR the current track is actively playing. */\n\tpublic get isPlaying(): boolean {\n\t\treturn (\n\t\t\t!!this.fadeCancel ||\n\t\t\t(this.current instanceof window.Audio && !this.current.paused)\n\t\t);\n\t}\n\n\t/** Whether music playback is permitted (inherited from {@link AudioBase}). */\n\tpublic get enabled(): boolean {\n\t\treturn super.enabled;\n\t}\n\n\t/** Flipping from `false` to `true` while no music is playing auto-starts a fade-in to a random track. */\n\tpublic set enabled(value: boolean) {\n\t\tsuper.enabled = value;\n\n\t\tif (value && !this.isPlaying) {\n\t\t\tthis.fade();\n\t\t}\n\t}\n\n\t/**\n\t * Cross-fade to `name` (or a random unplayed track when `null`) over `fadeTime` ms. `easing.cur` controls the outgoing track's volume curve, `easing.next` the incoming one. Cancels any in-progress fade. No-op when disabled. Throws on `fadeTime <= 0`, an empty registry, or an unknown `name`. When the new track ends, the next fade fires automatically \u2014 call {@link stop} to break the cycle.\n\t */\n\tpublic fade(\n\t\tname: string | null = null,\n\t\tfadeTime: number = 1000,\n\t\teasing: {\n\t\t\tcur: EasingName;\n\t\t\tnext: EasingName;\n\t\t} = {\n\t\t\tcur: \"ease-in\",\n\t\t\tnext: \"ease-out\",\n\t\t},\n\t): void {\n\t\tif (fadeTime <= 0) {\n\t\t\tthrow new Error(`fadeTime must be > 0, got ${fadeTime}`);\n\t\t}\n\n\t\tif (this.songs.size === 0) {\n\t\t\tthrow new Error(\"No music registered!\");\n\t\t}\n\n\t\tif (name && !this.songs.has(name)) {\n\t\t\tthrow new Error(`Music \"${name}\" not registered!`);\n\t\t}\n\n\t\tif (!this.enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.fadeCancel) {\n\t\t\tconsole.warn(\"Stopping current music fading.\");\n\t\t\tthis.fadeCancel();\n\t\t\tthis.fadeCancel = null;\n\t\t\tthis.current?.stop();\n\t\t\tthis.current = this.next;\n\t\t\tthis.next = null;\n\t\t}\n\n\t\tif (this.songs.size === 1) {\n\t\t\tconsole.info(\"Only one music registered, playing that looped.\");\n\t\t\tthis.current = this.songs.values().next().value!;\n\t\t\tthis.current.loop = true;\n\t\t\tthis.current.play();\n\t\t\treturn;\n\t\t}\n\n\t\tif (name) {\n\t\t\tthis.next = this.songs.get(name)!;\n\t\t} else {\n\t\t\tthis.next = this.getRandom();\n\n\t\t\tif (!this.next) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"Not enough songs to pick a fresh one, replaying the previous one.\",\n\t\t\t\t);\n\t\t\t\tthis.next = this.last!;\n\t\t\t}\n\t\t}\n\n\t\tthis.next.onended = (): void => {\n\t\t\tthis.fade();\n\t\t};\n\t\tthis.next.volume = 0;\n\t\tthis.next.play();\n\n\t\tconsole.log(`Start fading to music: \"${this.next.id}\"`);\n\n\t\tif (this.current) {\n\t\t\tthis.current.onended = (): void => void 0;\n\t\t}\n\n\t\tconst curEase = EASINGS[easing.cur];\n\t\tconst nextEase = EASINGS[easing.next];\n\t\tconst fadeTimeSeconds = fadeTime / 1000;\n\n\t\tlet time = 0;\n\t\tconst curStartVolume = this.current?.volume ?? 0;\n\t\tthis.fadeCancel = rafLoop(dt => {\n\t\t\ttime += dt / fadeTimeSeconds;\n\n\t\t\tif (this.current) {\n\t\t\t\tthis.current.volume =\n\t\t\t\t\tcurStartVolume * (1 - clamp(curEase(time), 0, 1));\n\t\t\t}\n\n\t\t\tthis.next!.volume =\n\t\t\t\tthis.next!.defaultVolume! * clamp(nextEase(time), 0, 1);\n\n\t\t\tif (time >= 1) {\n\t\t\t\tthis.fadeCancel?.();\n\t\t\t\tthis.fadeCancel = null;\n\n\t\t\t\tif (this.current) {\n\t\t\t\t\tthis.current.stop();\n\t\t\t\t\tthis.current.volume = this.current.defaultVolume!;\n\t\t\t\t}\n\n\t\t\t\tthis.next!.volume = this.next!.defaultVolume!;\n\n\t\t\t\tthis.last = this.current;\n\t\t\t\tthis.current = this.next;\n\t\t\t\tthis.next = null;\n\t\t\t}\n\t\t});\n\t}\n\n\t/** Stop everything immediately: cancels any in-flight fade, halts current and next tracks, and breaks the auto-cycle chain. Restart via {@link fade} or by flipping {@link enabled}. */\n\tpublic stop(): void {\n\t\tsuper.stop();\n\n\t\tthis.fadeCancel?.();\n\t\tthis.fadeCancel = null;\n\n\t\tthis.current?.stop();\n\t\tthis.next?.stop();\n\n\t\tthis.last = this.current;\n\t\tthis.current = this.next;\n\t\tthis.next = null;\n\t}\n\n\tprivate getRandom(): HTMLAudioElement | null {\n\t\tconst allSongs = Array.from(this.songs.values());\n\n\t\tif (this.last) {\n\t\t\tremove(allSongs, this.last);\n\t\t}\n\n\t\tif (this.current) {\n\t\t\tremove(allSongs, this.current);\n\t\t}\n\n\t\tif (allSongs.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn randomItem(allSongs);\n\t}\n}\n", "import AudioBase from \"./AudioBase\";\nimport { remove } from \"@/utilities/Array\";\n\n/** One-shot SFX. Each {@link play} call clones the registered `HTMLAudioElement` so the same sound can overlap itself; {@link stop} cuts every in-flight clone. Inherits registration, enable/disable, and volume from {@link AudioBase}. */\nexport default class Sound extends AudioBase {\n\tprivate currentSounds: HTMLAudioElement[] = [];\n\n\t/** Play the registered sound `name` once. Returns a promise that resolves when playback starts (or immediately if `enabled` is `false`) and rejects on autoplay/permission errors. Throws synchronously if no sounds are registered or `name` is unknown. Each call allocates a clone, so concurrent plays of the same name overlap. */\n\tpublic play(name: string): Promise<void> {\n\t\tif (this.songs.size === 0) {\n\t\t\tthrow new Error(\"No sounds registered!\");\n\t\t}\n\n\t\tif (!this.songs.has(name)) {\n\t\t\tthrow new Error(`Sound \"${name}\" not registered!`);\n\t\t}\n\n\t\tif (!this.enabled) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tconst newSound = this.songs.get(name)!.clone();\n\t\tthis.currentSounds.push(newSound);\n\n\t\tconst cleanup = (): void => remove(this.currentSounds, newSound);\n\t\tnewSound.onended = cleanup;\n\t\tnewSound.onerror = (): void => {\n\t\t\tcleanup();\n\t\t\tconsole.error(\n\t\t\t\t`Playback failed for Sound \"${name}\", reason: ${newSound.error?.message ?? \"unknown\"}`,\n\t\t\t);\n\t\t};\n\n\t\treturn newSound.play().catch((err): void => {\n\t\t\tcleanup();\n\t\t\tthrow err;\n\t\t});\n\t}\n\n\t/** Stop and forget every currently-playing clone. Also calls the base-class teardown. */\n\tpublic stop(): void {\n\t\tsuper.stop();\n\n\t\tthis.currentSounds.forEach(audio => audio.stop());\n\t\tthis.currentSounds.length = 0;\n\t}\n}\n", "import { throttle } from \"./Functions\";\nimport { wrapValue } from \"./Number\";\n\nconst NUMERIC_PATTERN = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\n\n/**\n * Check if a value is a finite number or a string holding one. Accepts optional leading sign, decimal forms (`.5`, `5.`, `3.14`), and scientific notation (`1e5`, `-3.14e-2`).\n */\nexport function isNumeric(value: unknown): boolean {\n\tif (typeof value === \"number\") {\n\t\treturn Number.isFinite(value);\n\t}\n\n\tif (typeof value === \"string\") {\n\t\treturn NUMERIC_PATTERN.test(value.trim());\n\t}\n\n\treturn false;\n}\n\n/**\n * Generate a random angle between 0 and 2-PI in radians\n */\nexport function random2Pi(): number {\n\treturn Math.random() * Math.PI * 2;\n}\n\n/**\n * Generate a random float between two values. Bounds may be passed in either order.\n */\nexport function randomBetweenFloat(min: number, max: number): number {\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Generate a random integer in `[min, max]` (both bounds inclusive). Bounds may be passed in either order.\n */\nexport function randomBetweenInt(min: number, max: number): number {\n\tif (min > max) {\n\t\t[min, max] = [max, min];\n\t}\n\n\treturn Math.floor(min + Math.random() * (max - min + 1));\n}\n\n/**\n * Generate a random boolean value\n */\nexport function randomBoolean(): boolean {\n\treturn Math.random() >= 0.5;\n}\n\n/**\n * Generate a random sign (1 or -1)\n */\nexport function randomSign(): number {\n\treturn randomBoolean() ? 1 : -1;\n}\n\nconst warnInvalidTime = throttle(count => {\n\tconsole.warn(\n\t\t`toHHMMSS() received invalid input (NaN, Infinity, or negative) x${count} since last warning; returning \"00:00\".`,\n\t);\n});\n\n/**\n * Format time in seconds as HH:MM:SS string\n */\nexport function toHHMMSS(time: number): string {\n\tif (!Number.isFinite(time) || time < 0) {\n\t\twarnInvalidTime();\n\t\treturn \"00:00\";\n\t}\n\n\ttime = Math.floor(time);\n\n\tconst h = Math.floor(time / 3600);\n\tconst m = Math.floor((time - h * 3600) / 60);\n\tconst s = time - h * 3600 - m * 60;\n\n\tconst hours = h < 10 ? \"0\" + h : \"\" + h;\n\tconst minutes = m < 10 ? \"0\" + m : \"\" + m;\n\tconst seconds = s < 10 ? \"0\" + s : \"\" + s;\n\n\tif (h === 0) {\n\t\treturn `${minutes}:${seconds}`;\n\t}\n\n\treturn `${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * Convert radians to degrees\n */\nexport function toDegrees(radians: number): number {\n\treturn (radians * 180) / Math.PI;\n}\n\n/**\n * Convert degrees to radians\n */\nexport function toRadians(degrees: number): number {\n\treturn (degrees * Math.PI) / 180;\n}\n\n/**\n * Wrap an angle in radians into `[-PI, PI)`.\n */\nexport function wrapRadians(angle: number): number {\n\treturn wrapValue(angle, -Math.PI, Math.PI);\n}\n\n/**\n * Wrap an angle in degrees into `[-180, 180)`.\n */\nexport function wrapDegrees(angle: number): number {\n\treturn wrapValue(angle, -180, 180);\n}\n\n/**\n * Round a number to a specified number of decimal places\n */\nexport function roundTo(number: number, digitsAfterPoint: number): number {\n\tconst power = Math.pow(10, digitsAfterPoint);\n\n\treturn Math.round(number * power) / power;\n}\n\nconst factorialsCache: Record<number, number> = { 0: 1 };\nlet largestCachedFactorial = 0;\nlet factorialOverflowAt = Infinity;\n\n/**\n * Calculate factorial of a non-negative integer. Memoized \u2014 repeat calls reuse cached intermediates.\n * Returns `Infinity` once `n!` overflows the IEEE 754 double range (around `n = 171`).\n */\nexport function getFactorial(n: number): number {\n\tconst intN = Math.floor(n);\n\n\tif (intN < 0 || !Number.isFinite(intN)) {\n\t\tthrow new Error(\"getFactorial requires non-negative integer\");\n\t}\n\n\tif (intN >= factorialOverflowAt) {\n\t\treturn Infinity;\n\t}\n\n\tif (factorialsCache[intN] !== undefined) {\n\t\treturn factorialsCache[intN];\n\t}\n\n\tlet result = factorialsCache[largestCachedFactorial];\n\tfor (let i = largestCachedFactorial + 1; i <= intN; i++) {\n\t\tresult *= i;\n\n\t\tif (!Number.isFinite(result)) {\n\t\t\tfactorialOverflowAt = i;\n\t\t\treturn Infinity;\n\t\t}\n\n\t\tfactorialsCache[i] = result;\n\t\tlargestCachedFactorial = i;\n\t}\n\n\treturn result;\n}\n", "import { randomBetweenInt } from \"./Math\";\n\n/** `[r, g, b]` tuple of integer channel values, each in `[0, 255]`. */\nexport type RGB = [number, number, number];\n\n/**\n * Convert an `(r, g, b)` triple (0-255) to a `#rrggbb` hex string.\n * Low-level; prefer `Color.toHex()` outside hot per-pixel loops.\n */\nexport function rgb2hex(red: number, green: number, blue: number): string {\n\treturn \"#\" + (0x1000000 + rgb2Int(red, green, blue)).toString(16).slice(1);\n}\n\n/**\n * Pack `(r, g, b[, a])` channels into a single integer key.\n * RGB are 0-255. Alpha is 0-1 (CSS convention); divide canvas byte-alpha by 255 before passing.\n * Without alpha: 24-bit `RGB`. With alpha: 32-bit `RGBA` (forced unsigned).\n * Useful for fast per-pixel lookups: cheaper than building a hex string.\n */\nexport function rgb2Int(\n\tred: number,\n\tgreen: number,\n\tblue: number,\n\talpha?: number,\n): number {\n\tif (alpha === undefined) {\n\t\treturn (red << 16) | (green << 8) | blue;\n\t}\n\n\tconst a = Math.round(alpha * 255);\n\treturn ((red << 24) | (green << 16) | (blue << 8) | a) >>> 0;\n}\n\n/**\n * Convert a `#rgb` or `#rrggbb` hex string to an `[r, g, b]` integer tuple.\n * Low-level; prefer `Color.fromHex()` outside hot per-pixel loops. Caller must pass a valid hex string.\n */\nexport function hex2rgb(hex: string): RGB {\n\treturn hex\n\t\t.replace(\n\t\t\t/^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n\t\t\t(_: string, r: string, g: string, b: string) =>\n\t\t\t\t\"#\" + r + r + g + g + b + b,\n\t\t)\n\t\t.substring(1)\n\t\t.match(/.{2}/g)!\n\t\t.map((x: string) => parseInt(x, 16)) as RGB;\n}\n\n/**\n * HSL \u2192 RGB channel helper used by `Color.fromHSL`. Inputs are normalized to `[0, 1]`.\n */\nexport function hue2rgb(p: number, q: number, t: number): number {\n\tif (t < 0) {\n\t\tt += 1;\n\t}\n\n\tif (t > 1) {\n\t\tt -= 1;\n\t}\n\n\tif (t < 1 / 6) {\n\t\treturn p + (q - p) * 6 * t;\n\t}\n\n\tif (t < 1 / 2) {\n\t\treturn q;\n\t}\n\n\tif (t < 2 / 3) {\n\t\treturn p + (q - p) * (2 / 3 - t) * 6;\n\t}\n\n\treturn p;\n}\n\n/**\n * Random `#rgb` short hex color.\n */\nexport function randomHex(): string {\n\t// Can in theory return <4 hex digits if Math.random() lands on a value with trailing zeros (probability \u2248 2^-40).\n\treturn \"#\" + Math.random().toString(16).slice(2, 6);\n}\n\n/**\n * Random `[r, g, b]` integer tuple; each channel uniform in `[min, max]`.\n */\nexport function randomRgb(min = 0, max = 255): RGB {\n\treturn [\n\t\trandomBetweenInt(min, max),\n\t\trandomBetweenInt(min, max),\n\t\trandomBetweenInt(min, max),\n\t];\n}\n", "import { approxEqual, clamp, wrapValue } from \"@/utilities/Number\";\nimport { hue2rgb } from \"@/utilities/Color\";\n\n/** Components returned by {@link Color.toHSLObject}. */\nexport interface HSLObject {\n\t/** Hue in degrees, `[0, 360]`. */\n\th: number;\n\t/** Saturation in percent, `[0, 100]`. */\n\ts: number;\n\t/** Lightness in percent, `[0, 100]`. */\n\tl: number;\n\t/** Alpha in `[0, 1]`. */\n\ta: number;\n}\n\n/**\n * RGBA color with chainable mutators. Channels are stored clamped (`r/g/b` \u2208 `[0, 255]`, `alpha` \u2208 `[0, 1]`) \u2014 every mutator routes through {@link set}, so direct field writes aren't possible and clamping/rounding is uniform.\n *\n * **Hue unit gotcha**: {@link fromHSL} takes hue in **degrees** (CSS convention), but {@link hueRotate} takes **radians** (codebase convention). Use `Math.PI` etc. for hueRotate.\n *\n * All `to*` methods return CSS-compatible strings; `toHSLObject` returns the components as numbers if you need to mutate them.\n */\nexport class Color {\n\t/** Parse `#rgb`, `#rgba`, `#rrggbb`, or `#rrggbbaa` (case-insensitive, `#` optional). Throws on any other shape or on non-hex characters. */\n\tpublic static fromHex(hex: string): Color {\n\t\tlet cleanHex = hex.replace(\"#\", \"\").toUpperCase();\n\n\t\tif (!/^[0-9A-F]+$/.test(cleanHex)) {\n\t\t\tthrow new Error(`Invalid hex color: ${hex}`);\n\t\t}\n\n\t\tif (cleanHex.length === 3 || cleanHex.length === 4) {\n\t\t\tcleanHex = cleanHex\n\t\t\t\t.split(\"\")\n\t\t\t\t.map(c => c + c)\n\t\t\t\t.join(\"\");\n\t\t}\n\n\t\tif (cleanHex.length !== 6 && cleanHex.length !== 8) {\n\t\t\tthrow new Error(`Invalid hex color: ${hex}`);\n\t\t}\n\n\t\tconst r = parseInt(cleanHex.slice(0, 2), 16);\n\t\tconst g = parseInt(cleanHex.slice(2, 4), 16);\n\t\tconst b = parseInt(cleanHex.slice(4, 6), 16);\n\n\t\tif (cleanHex.length === 8) {\n\t\t\tconst a = parseInt(cleanHex.slice(6, 8), 16);\n\n\t\t\treturn new Color(r, g, b, a / 255);\n\t\t}\n\n\t\treturn new Color(r, g, b);\n\t}\n\n\t/** Build from HSL(A). `h` in **degrees** (wraps mod 360), `s`/`l` in percent `[0, 100]`, `a` in `[0, 1]`. The degree convention matches CSS \u2014 note that {@link hueRotate} uses radians instead. */\n\tpublic static fromHSL(\n\t\th: number,\n\t\ts: number,\n\t\tl: number,\n\t\ta: number = 1,\n\t): Color {\n\t\tconst hNorm = wrapValue(h, 0, 360) / 360;\n\t\tconst sNorm = s / 100;\n\t\tconst lNorm = l / 100;\n\n\t\tlet r, g, b;\n\n\t\tif (sNorm === 0) {\n\t\t\tr = g = b = lNorm;\n\t\t} else {\n\t\t\tconst q =\n\t\t\t\tlNorm < 0.5\n\t\t\t\t\t? lNorm * (1 + sNorm)\n\t\t\t\t\t: lNorm + sNorm - lNorm * sNorm;\n\t\t\tconst p = 2 * lNorm - q;\n\t\t\tr = hue2rgb(p, q, hNorm + 1 / 3);\n\t\t\tg = hue2rgb(p, q, hNorm);\n\t\t\tb = hue2rgb(p, q, hNorm - 1 / 3);\n\t\t}\n\n\t\treturn new Color(r * 255, g * 255, b * 255, a);\n\t}\n\n\tprivate _r!: number;\n\tprivate _g!: number;\n\tprivate _b!: number;\n\tprivate _alpha: number = 1;\n\n\t/** Red channel, `[0, 255]`. Read-only; mutate via {@link set} or any chainable transform. */\n\tpublic get r(): number {\n\t\treturn this._r;\n\t}\n\n\t/** Green channel, `[0, 255]`. Read-only; mutate via {@link set} or any chainable transform. */\n\tpublic get g(): number {\n\t\treturn this._g;\n\t}\n\n\t/** Blue channel, `[0, 255]`. Read-only; mutate via {@link set} or any chainable transform. */\n\tpublic get b(): number {\n\t\treturn this._b;\n\t}\n\n\t/** Alpha channel, `[0, 1]`. Read-only; mutate via {@link set} (pass the fourth arg). */\n\tpublic get alpha(): number {\n\t\treturn this._alpha;\n\t}\n\n\tconstructor(r: number, g: number, b: number, a?: number) {\n\t\tthis.set(r, g, b, a);\n\t}\n\n\t/** Primary mutator \u2014 every other transform on this class routes through it. Clamps `r`/`g`/`b` to `[0, 255]` and `a` to `[0, 1]`; alpha is snapped to exact `0` or `1` when within `approxEqual` tolerance so equality checks stay clean. Returns `this` for chaining. */\n\tpublic set(r: number, g: number, b: number, a?: number): this {\n\t\tthis._r = clamp(r, 0, 255);\n\t\tthis._g = clamp(g, 0, 255);\n\t\tthis._b = clamp(b, 0, 255);\n\n\t\tif (a !== undefined) {\n\t\t\tconst clamped = clamp(a, 0, 1);\n\t\t\tthis._alpha = approxEqual(clamped, 0)\n\t\t\t\t? 0\n\t\t\t\t: approxEqual(clamped, 1)\n\t\t\t\t\t? 1\n\t\t\t\t\t: clamped;\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/** Apply a 3\u00D73 RGB color matrix in row-major order (`m1..m9`). Alpha is unchanged. Used by {@link grayscale}, {@link hueRotate}, {@link saturate}, {@link sepia}. Mutates and returns `this`. */\n\tpublic applyMatrix(\n\t\tm1: number,\n\t\tm2: number,\n\t\tm3: number,\n\t\tm4: number,\n\t\tm5: number,\n\t\tm6: number,\n\t\tm7: number,\n\t\tm8: number,\n\t\tm9: number,\n\t): this {\n\t\treturn this.set(\n\t\t\tthis.r * m1 + this.g * m2 + this.b * m3,\n\t\t\tthis.r * m4 + this.g * m5 + this.b * m6,\n\t\t\tthis.r * m7 + this.g * m8 + this.b * m9,\n\t\t);\n\t}\n\n\t/** Multiply each channel by `factor`. `factor < 1` darkens, `factor > 1` brightens (clamped at 255). Mutates and returns `this`. */\n\tpublic brightness(factor: number): this {\n\t\treturn this.set(this.r * factor, this.g * factor, this.b * factor);\n\t}\n\n\t/** Push each channel away from `127.5` (the midtone) by `factor`. `factor < 1` flattens contrast, `> 1` increases it, `0` collapses every channel to gray. Mutates and returns `this`. */\n\tpublic contrast(factor: number): this {\n\t\tconst midtone = 127.5;\n\t\treturn this.set(\n\t\t\tmidtone + (this.r - midtone) * factor,\n\t\t\tmidtone + (this.g - midtone) * factor,\n\t\t\tmidtone + (this.b - midtone) * factor,\n\t\t);\n\t}\n\n\t/** Desaturate via the standard luminance-preserving matrix. `value` in `[0, 1]`: `0` is a no-op, `1` is full grayscale. Mutates and returns `this`. */\n\tpublic grayscale(value: number = 1): this {\n\t\tconst m1 = 0.2126 + 0.7874 * (1 - value);\n\t\tconst m2 = 0.7152 - 0.7152 * (1 - value);\n\t\tconst m3 = 0.0722 - 0.0722 * (1 - value);\n\t\tconst m4 = 0.2126 - 0.2126 * (1 - value);\n\t\tconst m5 = 0.7152 + 0.2848 * (1 - value);\n\t\tconst m6 = 0.0722 - 0.0722 * (1 - value);\n\t\tconst m7 = 0.2126 - 0.2126 * (1 - value);\n\t\tconst m8 = 0.7152 - 0.7152 * (1 - value);\n\t\tconst m9 = 0.0722 + 0.9278 * (1 - value);\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\t/** Rotate hue by `radians` (use `Math.PI / 2` etc.). Unlike {@link fromHSL}, this takes radians, not degrees. Mutates and returns `this`. */\n\tpublic hueRotate(radians: number): this {\n\t\tconst cos = Math.cos(radians);\n\t\tconst sin = Math.sin(radians);\n\n\t\tconst m1 = 0.213 + cos * 0.787 - sin * 0.213;\n\t\tconst m2 = 0.715 - cos * 0.715 - sin * 0.715;\n\t\tconst m3 = 0.072 - cos * 0.072 + sin * 0.928;\n\t\tconst m4 = 0.213 - cos * 0.213 + sin * 0.143;\n\t\tconst m5 = 0.715 + cos * 0.285 + sin * 0.14;\n\t\tconst m6 = 0.072 - cos * 0.072 - sin * 0.283;\n\t\tconst m7 = 0.213 - cos * 0.213 - sin * 0.787;\n\t\tconst m8 = 0.715 - cos * 0.715 + sin * 0.715;\n\t\tconst m9 = 0.072 + cos * 0.928 + sin * 0.072;\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\t/** Interpolate each channel toward its inverse (`255 - c`). `factor` in `[0, 1]`: `0` is unchanged, `1` is fully inverted. Mutates and returns `this`. */\n\tpublic invert(factor: number = 1): this {\n\t\treturn this.set(\n\t\t\tthis.r * (1 - factor) + (255 - this.r) * factor,\n\t\t\tthis.g * (1 - factor) + (255 - this.g) * factor,\n\t\t\tthis.b * (1 - factor) + (255 - this.b) * factor,\n\t\t);\n\t}\n\n\t/** Linear blend toward `other`. `amount` in `[0, 1]`: `0` keeps `this`, `1` becomes `other`. Mixes alpha too. Mutates and returns `this`. */\n\tpublic mix(other: Color, amount: number): this {\n\t\tconst inv = 1 - amount;\n\n\t\treturn this.set(\n\t\t\tthis.r * inv + other.r * amount,\n\t\t\tthis.g * inv + other.g * amount,\n\t\t\tthis.b * inv + other.b * amount,\n\t\t\tthis.alpha * inv + other.alpha * amount,\n\t\t);\n\t}\n\n\t/** Round each RGB channel to the nearest integer. Alpha is untouched. Mutates and returns `this`. */\n\tpublic round(): this {\n\t\treturn this.set(\n\t\t\tMath.round(this.r),\n\t\t\tMath.round(this.g),\n\t\t\tMath.round(this.b),\n\t\t);\n\t}\n\n\t/** Saturation matrix. `value` typically in `[0, 2]`: `0` desaturates to grayscale (same as `grayscale(1)`), `1` is a no-op, `> 1` oversaturates. Mutates and returns `this`. */\n\tpublic saturate(value: number = 1): this {\n\t\tconst m1 = 0.213 + 0.787 * value;\n\t\tconst m2 = 0.715 - 0.715 * value;\n\t\tconst m3 = 0.072 - 0.072 * value;\n\t\tconst m4 = 0.213 - 0.213 * value;\n\t\tconst m5 = 0.715 + 0.285 * value;\n\t\tconst m6 = 0.072 - 0.072 * value;\n\t\tconst m7 = 0.213 - 0.213 * value;\n\t\tconst m8 = 0.715 - 0.715 * value;\n\t\tconst m9 = 0.072 + 0.928 * value;\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\t/** Sepia matrix. `value` in `[0, 1]`: `0` is unchanged, `1` is full sepia. Mutates and returns `this`. */\n\tpublic sepia(value: number = 1): this {\n\t\tconst m1 = 0.393 + 0.607 * (1 - value);\n\t\tconst m2 = 0.769 - 0.769 * (1 - value);\n\t\tconst m3 = 0.189 - 0.189 * (1 - value);\n\t\tconst m4 = 0.349 - 0.349 * (1 - value);\n\t\tconst m5 = 0.686 + 0.314 * (1 - value);\n\t\tconst m6 = 0.168 - 0.168 * (1 - value);\n\t\tconst m7 = 0.272 - 0.272 * (1 - value);\n\t\tconst m8 = 0.534 - 0.534 * (1 - value);\n\t\tconst m9 = 0.131 + 0.869 * (1 - value);\n\n\t\treturn this.applyMatrix(m1, m2, m3, m4, m5, m6, m7, m8, m9);\n\t}\n\n\t/** Tint or shade. `percent` in `[-1, 1]`: negative shades toward black, positive tints toward white, magnitude is the amount. Mutates and returns `this`. */\n\tpublic shade(percent: number): this {\n\t\tconst target = percent < 0 ? 0 : 255;\n\t\tconst p = Math.abs(percent);\n\n\t\treturn this.set(\n\t\t\tthis.r + (target - this.r) * p,\n\t\t\tthis.g + (target - this.g) * p,\n\t\t\tthis.b + (target - this.b) * p,\n\t\t);\n\t}\n\n\t/** CSS hex string. `#rrggbb` when alpha is exactly `1`, `#rrggbbaa` otherwise. Channels are rounded. */\n\tpublic toHex(): string {\n\t\tconst r = Math.round(this.r).toString(16).padStart(2, \"0\");\n\t\tconst g = Math.round(this.g).toString(16).padStart(2, \"0\");\n\t\tconst b = Math.round(this.b).toString(16).padStart(2, \"0\");\n\t\tconst rgb = `#${r}${g}${b}`;\n\n\t\tif (this.alpha === 1) {\n\t\t\treturn rgb;\n\t\t}\n\n\t\tconst a = Math.round(this.alpha * 255);\n\t\treturn `${rgb}${a.toString(16).padStart(2, \"0\")}`;\n\t}\n\n\t/** CSS HSL string. `hsl(h, s%, l%)` when alpha is exactly `1`, `hsla(...)` otherwise. Hue is in degrees. */\n\tpublic toHSL(): string {\n\t\tconst { h, s, l } = this.toHSLObject();\n\t\tconst cssH = Math.round(h);\n\t\tconst cssS = Math.round(s);\n\t\tconst cssL = Math.round(l);\n\n\t\treturn this.alpha === 1\n\t\t\t? `hsl(${cssH}, ${cssS}%, ${cssL}%)`\n\t\t\t: `hsla(${cssH}, ${cssS}%, ${cssL}%, ${this.alpha.toFixed(2)})`;\n\t}\n\n\t/** HSL(A) components as numbers \u2014 see {@link HSLObject}. Use when you need to compute against the values rather than render them as a string. */\n\tpublic toHSLObject(): HSLObject {\n\t\tconst r = this.r / 255;\n\t\tconst g = this.g / 255;\n\t\tconst b = this.b / 255;\n\n\t\tconst max = Math.max(r, g, b);\n\t\tconst min = Math.min(r, g, b);\n\t\tconst l = (max + min) / 2;\n\t\tlet h = 0;\n\t\tlet s = 0;\n\n\t\tif (max !== min) {\n\t\t\tconst d = max - min;\n\t\t\ts = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n\t\t\tswitch (max) {\n\t\t\t\tcase r:\n\t\t\t\t\th = (g - b) / d + (g < b ? 6 : 0);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase g:\n\t\t\t\t\th = (b - r) / d + 2;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase b:\n\t\t\t\t\th = (r - g) / d + 4;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\th /= 6;\n\t\t}\n\n\t\treturn { h: h * 360, s: s * 100, l: l * 100, a: this.alpha };\n\t}\n\n\t/** CSS RGB string. `rgb(r, g, b)` when alpha is exactly `1`, `rgba(r, g, b, a)` otherwise. Channels are rounded. */\n\tpublic toRGB(): string {\n\t\tconst r = Math.round(this.r);\n\t\tconst g = Math.round(this.g);\n\t\tconst b = Math.round(this.b);\n\n\t\treturn this.alpha === 1\n\t\t\t? `rgb(${r}, ${g}, ${b})`\n\t\t\t: `rgba(${r}, ${g}, ${b}, ${this.alpha.toFixed(2)})`;\n\t}\n\n\t/** New `Color` with the same channels. */\n\tpublic clone(): Color {\n\t\treturn new Color(this.r, this.g, this.b, this.alpha);\n\t}\n\n\t/** Approximate equality (within `approxEqual` tolerance). Pass `compareAlpha: false` to ignore the alpha channel. */\n\tpublic equals(other: Color, compareAlpha: boolean = true): boolean {\n\t\treturn (\n\t\t\tapproxEqual(this.r, other.r) &&\n\t\t\tapproxEqual(this.g, other.g) &&\n\t\t\tapproxEqual(this.b, other.b) &&\n\t\t\t(!compareAlpha || approxEqual(this.alpha, other.alpha))\n\t\t);\n\t}\n}\n", "import { Color } from \"./Color\";\nimport { wrapDegrees } from \"@/utilities/Math\";\nimport { wrapValue } from \"@/utilities/Number\";\nimport type { RGB } from \"@/utilities/Color\";\n\ntype FilterValues = [\n\tinvert: number,\n\tsepia: number,\n\tsaturate: number,\n\thueRotate: number,\n\tbrightness: number,\n\tcontrast: number,\n];\n\ninterface SpsaResult {\n\tvalues: FilterValues;\n\tloss: number;\n}\n\nconst SATURATE = 2;\nconst HUE_ROTATE = 3;\nconst BRIGHTNESS = 4;\nconst CONTRAST = 5;\n\n/**\n * Used when hue-rotate does not work e.g. on dark images\n * Based on https://codepen.io/sosuke/pen/Pjoqqp\n * https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters/43960991#43960991\n *\n * As the result does vary because of a Math.random(),\n * I would suggest console.log some filters, pick nice ones and hardcode them instead:\n * console.log(colorShifter(randomRgb(1, 10)));\n */\nexport function colorShifter(rgb: RGB) {\n\tconst color = new Color(rgb[0], rgb[1], rgb[2]);\n\tconst solver = new Solver(color);\n\tconst result = solver.solve();\n\n\treturn result.filter.replace(\"filter: \", \"\").replace(\";\", \"\");\n}\n\nclass Solver {\n\tprivate reusedColor: Color;\n\tprivate target: Color;\n\tprivate targetHSL: {\n\t\th: number;\n\t\ts: number;\n\t\tl: number;\n\t};\n\n\tconstructor(target: Color) {\n\t\tthis.target = target;\n\t\tthis.targetHSL = target.toHSLObject();\n\t\tthis.reusedColor = new Color(0, 0, 0);\n\t}\n\n\tpublic css(filters: FilterValues): string {\n\t\tconst [invert, sepia, saturate, hueRotate, brightness, contrast] =\n\t\t\tfilters;\n\n\t\treturn `filter: invert(${Math.round(invert)}%) sepia(${Math.round(sepia)}%) saturate(${Math.round(saturate)}%) hue-rotate(${Math.round(hueRotate * 3.6)}deg) brightness(${Math.round(brightness)}%) contrast(${Math.round(contrast)}%);`;\n\t}\n\n\tpublic loss(filters: FilterValues): number {\n\t\tconst [invert, sepia, saturate, hueRotate, brightness, contrast] =\n\t\t\tfilters;\n\t\tconst color = this.reusedColor;\n\t\tcolor.set(0, 0, 0);\n\n\t\tcolor.invert(invert / 100);\n\t\tcolor.sepia(sepia / 100);\n\t\tcolor.saturate(saturate / 100);\n\t\tcolor.hueRotate((hueRotate / 100) * Math.PI * 2);\n\t\tcolor.brightness(brightness / 100);\n\t\tcolor.contrast(contrast / 100);\n\n\t\tconst colorHSL = color.toHSLObject();\n\n\t\treturn (\n\t\t\tMath.abs(color.r - this.target.r) +\n\t\t\tMath.abs(color.g - this.target.g) +\n\t\t\tMath.abs(color.b - this.target.b) +\n\t\t\t// h is cyclic 0-360; wrap diff into \u00B1180 then scale to 0-100 to keep loss balance with the other terms\n\t\t\tMath.abs(wrapDegrees(colorHSL.h - this.targetHSL.h)) / 1.8 +\n\t\t\tMath.abs(colorHSL.s - this.targetHSL.s) +\n\t\t\tMath.abs(colorHSL.l - this.targetHSL.l)\n\t\t);\n\t}\n\n\tpublic solve(): SpsaResult & { filter: string } {\n\t\tconst result = this.solveNarrow(this.solveWide());\n\n\t\treturn {\n\t\t\tvalues: result.values,\n\t\t\tloss: result.loss,\n\t\t\tfilter: this.css(result.values),\n\t\t};\n\t}\n\n\tpublic solveNarrow(wide: SpsaResult): SpsaResult {\n\t\tconst A = wide.loss;\n\t\tconst c = 2;\n\t\tconst A1 = A + 1;\n\t\tconst a: FilterValues = [\n\t\t\t0.25 * A1,\n\t\t\t0.25 * A1,\n\t\t\tA1,\n\t\t\t0.25 * A1,\n\t\t\t0.2 * A1,\n\t\t\t0.2 * A1,\n\t\t];\n\n\t\treturn this.spsa(A, a, c, wide.values, 500);\n\t}\n\n\tpublic solveWide(): SpsaResult {\n\t\tconst A = 5;\n\t\tconst c = 15;\n\t\tconst a: FilterValues = [60, 180, 18000, 600, 1.2, 1.2];\n\n\t\tlet best: SpsaResult = {\n\t\t\tloss: Infinity,\n\t\t\tvalues: [50, 20, 3750, 50, 100, 100],\n\t\t};\n\t\tfor (let i = 0; best.loss > 25 && i < 3; i++) {\n\t\t\tconst initial: FilterValues = [50, 20, 3750, 50, 100, 100];\n\t\t\tconst result = this.spsa(A, a, c, initial, 1000);\n\t\t\tif (result.loss < best.loss) {\n\t\t\t\tbest = result;\n\t\t\t}\n\t\t}\n\n\t\treturn best;\n\t}\n\n\tpublic spsa(\n\t\tA: number,\n\t\ta: FilterValues,\n\t\tc: number,\n\t\tvalues: FilterValues,\n\t\titers: number,\n\t): SpsaResult {\n\t\tvalues = values.slice() as FilterValues;\n\t\tconst alpha = 1;\n\t\tconst gamma = 0.16666666666666666;\n\n\t\tlet best: FilterValues = values.slice() as FilterValues;\n\t\tlet bestLoss = Infinity;\n\t\tconst deltas: FilterValues = [0, 0, 0, 0, 0, 0];\n\t\tconst highArgs: FilterValues = [0, 0, 0, 0, 0, 0];\n\t\tconst lowArgs: FilterValues = [0, 0, 0, 0, 0, 0];\n\n\t\tfor (let k = 0; k < iters; k++) {\n\t\t\tconst ck = c / Math.pow(k + 1, gamma);\n\t\t\tfor (let i = 0; i < 6; i++) {\n\t\t\t\tdeltas[i] = Math.random() > 0.5 ? 1 : -1;\n\t\t\t\thighArgs[i] = values[i] + ck * deltas[i];\n\t\t\t\tlowArgs[i] = values[i] - ck * deltas[i];\n\t\t\t}\n\n\t\t\tconst lossDiff = this.loss(highArgs) - this.loss(lowArgs);\n\t\t\tfor (let i = 0; i < 6; i++) {\n\t\t\t\tconst g = (lossDiff / (2 * ck)) * deltas[i];\n\t\t\t\tconst ak = a[i] / Math.pow(A + k + 1, alpha);\n\t\t\t\tvalues[i] = fix(values[i] - ak * g, i);\n\t\t\t}\n\n\t\t\tconst loss = this.loss(values);\n\t\t\tif (loss < bestLoss) {\n\t\t\t\tbest = values.slice() as FilterValues;\n\t\t\t\tbestLoss = loss;\n\t\t\t}\n\t\t}\n\n\t\treturn { values: best, loss: bestLoss };\n\n\t\tfunction fix(value: number, idx: number): number {\n\t\t\tlet max = 100;\n\t\t\tif (idx === SATURATE) {\n\t\t\t\tmax = 7500;\n\t\t\t} else if (idx === BRIGHTNESS || idx === CONTRAST) {\n\t\t\t\tmax = 200;\n\t\t\t}\n\n\t\t\tif (idx === HUE_ROTATE) {\n\t\t\t\tvalue = wrapValue(value, 0, max);\n\t\t\t} else if (value < 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else if (value > max) {\n\t\t\t\tvalue = max;\n\t\t\t}\n\n\t\t\treturn value;\n\t\t}\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Polygon from \"@/math/Polygon\";\nimport { approxEqual } from \"@/utilities/Number\";\nimport type { Vector2, Vector4 } from \"@/math/Vec2\";\n\n/** Derived geometry returned by {@link Rect.sides}. */\nexport interface Sides {\n\t/** Lower edge (`y + h`). */\n\tbottom: number;\n\t/** Center point. */\n\tcenterPos: Vec2;\n\t/** Half the width and height. */\n\thalfSize: Vec2;\n\t/** Right edge (`x + w`). */\n\tright: number;\n}\n\n/** Axis-aligned 2D rectangle (`x`, `y`, `w`, `h`). */\nexport default class Rect {\n\t/** Build from an `HTMLElement` (via `getBoundingClientRect`) or a `DOMRect`. */\n\tpublic static fromBoundingClientRect(rect: DOMRect | HTMLElement): Rect {\n\t\tif (rect instanceof HTMLElement) {\n\t\t\trect = rect.getBoundingClientRect();\n\t\t}\n\n\t\treturn new Rect(rect.left, rect.top, rect.width, rect.height);\n\t}\n\n\t/** Axis-aligned bounding box of a polygon's points. Throws if the polygon has no points. */\n\tpublic static fromPolygon(polygon: Polygon): Rect {\n\t\tif (polygon.points.length === 0) {\n\t\t\tthrow new Error(\"Supplied polygon has no points!\");\n\t\t}\n\n\t\tlet minX = Infinity;\n\t\tlet minY = Infinity;\n\t\tlet maxX = -Infinity;\n\t\tlet maxY = -Infinity;\n\n\t\tpolygon.points.forEach(point => {\n\t\t\tif (point.x < minX) {\n\t\t\t\tminX = point.x;\n\t\t\t}\n\n\t\t\tif (point.x > maxX) {\n\t\t\t\tmaxX = point.x;\n\t\t\t}\n\n\t\t\tif (point.y < minY) {\n\t\t\t\tminY = point.y;\n\t\t\t}\n\n\t\t\tif (point.y > maxY) {\n\t\t\t\tmaxY = point.y;\n\t\t\t}\n\t\t});\n\n\t\treturn new Rect(minX, minY, maxX - minX, maxY - minY);\n\t}\n\n\tprivate _h = 0;\n\tprivate _w = 0;\n\tprivate _x = 0;\n\tprivate _y = 0;\n\tprivate _sides!: Sides;\n\tprivate sideIsDirty: boolean = true;\n\n\t/** Height. */\n\tpublic get h(): number {\n\t\treturn this._h;\n\t}\n\n\t/** Height. */\n\tpublic set h(value: number) {\n\t\tthis._h = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\t/** Width. */\n\tpublic get w(): number {\n\t\treturn this._w;\n\t}\n\n\t/** Width. */\n\tpublic set w(value: number) {\n\t\tthis._w = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\t/** Top-left x. */\n\tpublic get x(): number {\n\t\treturn this._x;\n\t}\n\n\t/** Top-left x. */\n\tpublic set x(value: number) {\n\t\tthis._x = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\t/** Top-left y. */\n\tpublic get y(): number {\n\t\treturn this._y;\n\t}\n\n\t/** Top-left y. */\n\tpublic set y(value: number) {\n\t\tthis._y = value;\n\t\tthis.sideIsDirty = true;\n\t}\n\n\t/** Derived sides/center/halfSize. Lazily recomputed after any `x`/`y`/`w`/`h` change. */\n\tpublic get sides(): Readonly<Sides> {\n\t\tif (this.sideIsDirty) {\n\t\t\tthis._sides = {\n\t\t\t\tbottom: this.y + this.h,\n\t\t\t\tcenterPos: new Vec2(\n\t\t\t\t\tthis.x + this.w * 0.5,\n\t\t\t\t\tthis.y + this.h * 0.5,\n\t\t\t\t),\n\t\t\t\thalfSize: new Vec2(this.w * 0.5, this.h * 0.5),\n\t\t\t\tright: this.x + this.w,\n\t\t\t};\n\n\t\t\tthis.sideIsDirty = false;\n\t\t}\n\n\t\treturn this._sides;\n\t}\n\n\tconstructor(x = 0, y = 0, w = 0, h = 0) {\n\t\tthis.set(x, y, w, h);\n\t}\n\n\t/** Grow on every side by `delta` (`x`/`y` shift in, `w`/`h` grow by `2*delta`). Pass a negative value to shrink. Mutates and returns `this`. */\n\tpublic inflate(delta: number): Rect {\n\t\tthis.x -= delta;\n\t\tthis.y -= delta;\n\n\t\tthis.w += 2 * delta;\n\t\tthis.h += 2 * delta;\n\n\t\tthis.sideIsDirty = true;\n\n\t\treturn this;\n\t}\n\n\t/** Round `x` and `y` to the nearest integer. `w`/`h` are unchanged. Mutates and returns `this`. */\n\tpublic round(): Rect {\n\t\tthis.x = Math.round(this.x);\n\t\tthis.y = Math.round(this.y);\n\n\t\tthis.sideIsDirty = true;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Replace fields. The first arg may be a `Vector4` (sets all four), a `Vector2` (sets `x`/`y` only, unless explicit `w`/`h` follow), or `x` as a number with separate `y`/`w`/`h`. Mutates and returns `this`.\n\t */\n\tpublic set(\n\t\tx: Vector4 | Vector2 | number = 0,\n\t\ty: number = 0,\n\t\tw?: number,\n\t\th?: number,\n\t): Rect {\n\t\tif (typeof x === \"number\") {\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t} else {\n\t\t\tif (\"w\" in x) {\n\t\t\t\tthis.w = x.w;\n\t\t\t\tthis.h = x.h;\n\t\t\t}\n\n\t\t\tthis.x = x.x;\n\t\t\tthis.y = x.y;\n\t\t}\n\n\t\tif (w !== undefined) {\n\t\t\tthis.w = w;\n\t\t}\n\n\t\tif (h !== undefined) {\n\t\t\tthis.h = h;\n\t\t}\n\n\t\tthis.sideIsDirty = true;\n\t\treturn this;\n\t}\n\n\t/** AABB-vs-AABB overlap test (inclusive of touching edges). */\n\tpublic collide(rect: Rect): boolean {\n\t\treturn (\n\t\t\tthis.x <= rect.x + rect.w &&\n\t\t\tthis.x + this.w >= rect.x &&\n\t\t\tthis.y <= rect.y + rect.h &&\n\t\t\tthis.y + this.h >= rect.y\n\t\t);\n\t}\n\n\t/** `true` when `rect` is fully inside `this`. */\n\tpublic collideFull(rect: Rect): boolean {\n\t\treturn (\n\t\t\trect.x + rect.w <= this.x + this.w &&\n\t\t\trect.x >= this.x &&\n\t\t\trect.y >= this.y &&\n\t\t\trect.y + rect.h <= this.y + this.h\n\t\t);\n\t}\n\n\t/** `true` when `vec` lies inside `this` (inclusive of edges). */\n\tpublic collidePoint(vec: Vector2): boolean {\n\t\treturn (\n\t\t\tthis.x <= vec.x &&\n\t\t\tvec.x <= this.x + this.w &&\n\t\t\tthis.y <= vec.y &&\n\t\t\tvec.y <= this.y + this.h\n\t\t);\n\t}\n\n\t/** Side of `this` that `rect` overlaps from, or `\"none\"` if disjoint. Useful for picking a bounce axis. */\n\tpublic collideSide(\n\t\trect: Rect,\n\t): \"none\" | \"top\" | \"bottom\" | \"left\" | \"right\" {\n\t\tconst dx = this.x + this.w * 0.5 - (rect.x + rect.w * 0.5);\n\t\tconst dy = this.y + this.h * 0.5 - (rect.y + rect.h * 0.5);\n\t\tconst width = (this.w + rect.w) * 0.5;\n\t\tconst height = (this.h + rect.h) * 0.5;\n\t\tconst crossWidth = width * dy;\n\t\tconst crossHeight = height * dx;\n\t\tlet collision: \"none\" | \"top\" | \"bottom\" | \"left\" | \"right\" = \"none\";\n\n\t\tif (Math.abs(dx) <= width && Math.abs(dy) <= height) {\n\t\t\tif (crossWidth > crossHeight) {\n\t\t\t\tcollision = crossWidth > -crossHeight ? \"bottom\" : \"left\";\n\t\t\t} else {\n\t\t\t\tcollision = crossWidth > -crossHeight ? \"right\" : \"top\";\n\t\t\t}\n\t\t}\n\n\t\treturn collision;\n\t}\n\n\t/** Top-left corner as a new `Vec2`. */\n\tpublic pos(): Vec2 {\n\t\treturn new Vec2(this.x, this.y);\n\t}\n\n\t/** Width and height as a new `Vec2`. */\n\tpublic size(): Vec2 {\n\t\treturn new Vec2(this.w, this.h);\n\t}\n\n\t/** Debug string like `\"Rect [x: 0, y: 0, w: 10, h: 20]\"`. */\n\tpublic toString(): string {\n\t\treturn `Rect [x: ${this.x}, y: ${this.y}, w: ${this.w}, h: ${this.h}]`;\n\t}\n\n\t/** New `Rect` with the same values. */\n\tpublic clone(): Rect {\n\t\treturn new Rect(this.x, this.y, this.w, this.h);\n\t}\n\n\t/** Approximate equality. Pass `withSize: false` to compare position only. */\n\tpublic equals(other: Rect, withSize: boolean = true): boolean {\n\t\tlet output =\n\t\t\tapproxEqual(this.x, other.x) && approxEqual(this.y, other.y);\n\n\t\tif (output && withSize) {\n\t\t\toutput =\n\t\t\t\tapproxEqual(this.w, other.w) && approxEqual(this.h, other.h);\n\t\t}\n\n\t\treturn output;\n\t}\n}\n", "import Rect from \"./Rect\";\nimport { approxEqual, clamp } from \"@/utilities/Number\";\nimport { throttle } from \"@/utilities/Functions\";\n\n/** Object literal compatible with `Vec2` (e.g. `{ x, y }`). */\nexport interface Vector2 {\n\t/** Horizontal component. */\n\tx: number;\n\t/** Vertical component. */\n\ty: number;\n}\n\n/** {@link Vector2} plus `w`/`h` for AABB-style values. */\nexport interface Vector4 extends Vector2 {\n\t/** Width. */\n\tw: number;\n\t/** Height. */\n\th: number;\n}\n\n/**\n * Operation types for vector calculations\n */\nconst Operation = {\n\tAdd: 1,\n\tSub: 2,\n\tMult: 3,\n\tDiv: 4,\n\tRem: 5,\n\tEqual: 6,\n\tMod: 7,\n} as const;\n\nconst warnZeroNormalize = throttle(count =>\n\tconsole.warn(\n\t\t`Vec2.normalize() called on zero vector x${count} since last warning; returning zero.`,\n\t),\n);\n\nconst warnNonFinite = throttle(count =>\n\tconsole.warn(\n\t\t`Vec2 operation produced non-finite value x${count} since last warning; check for zero divisor.`,\n\t),\n);\n\n/**\n * 2D vector. Scalar args to `set`/`add`/`sub`/`mult`/`div`/`rem`/`mod`/`equals`\n * broadcast to both axes: `vec.add(5)` adds 5 to x and y, `vec.mult(-1)` negates\n * both. Pass `(x, y)` or a `Vector2` for per-axis values.\n */\nexport default class Vec2 {\n\t/** Unit vector at angle `rad` (radians), scaled per-axis. `scaleY` defaults to `scaleX`. */\n\tpublic static fromAngle(\n\t\trad: number,\n\t\tscaleX = 1,\n\t\tscaleY: number = scaleX,\n\t): Vec2 {\n\t\treturn new Vec2(Math.cos(rad) * scaleX, Math.sin(rad) * scaleY);\n\t}\n\n\t/** Horizontal component. */\n\tpublic x = 0;\n\t/** Vertical component. */\n\tpublic y = 0;\n\n\tconstructor(x: Vector2 | number = 0, y?: number) {\n\t\tthis.calculate(Operation.Equal, x, y);\n\t}\n\n\t/** Replace components. Mutates and returns `this`. */\n\tpublic set(v: Vector2): Vec2;\n\tpublic set(x: number, y?: number): Vec2;\n\tpublic set(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Equal, x, y);\n\t}\n\n\t/** Set each component to its absolute value. Mutates and returns `this`. */\n\tpublic abs(): Vec2 {\n\t\treturn this.map(Math.abs);\n\t}\n\n\t/** Per-axis add. Mutates and returns `this`. */\n\tpublic add(v: Vector2): Vec2;\n\tpublic add(x: number, y?: number): Vec2;\n\tpublic add(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Add, x, y);\n\t}\n\n\t/** Round each component up. Mutates and returns `this`. */\n\tpublic ceil(): Vec2 {\n\t\treturn this.map(Math.ceil);\n\t}\n\n\t/** Clamp each axis to its `[min, max]` range. `y` defaults to `x`. Mutates and returns `this`. */\n\tpublic clamp(x: [number, number], y: [number, number] = x): Vec2 {\n\t\tthis.x = clamp(this.x, x[0], x[1]);\n\t\tthis.y = clamp(this.y, y[0], y[1]);\n\n\t\treturn this;\n\t}\n\n\t/** Per-axis divide. Mutates and returns `this`. */\n\tpublic div(v: Vector2): Vec2;\n\tpublic div(x: number, y?: number): Vec2;\n\tpublic div(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Div, x, y);\n\t}\n\n\t/** Round each component down. Mutates and returns `this`. */\n\tpublic floor(): Vec2 {\n\t\treturn this.map(Math.floor);\n\t}\n\n\t/**\n\t * Apply `callback` to each component (`index` is `0` for x, `1` for y). Mutates and returns `this`.\n\t *\n\t * @example\n\t * ```ts\n\t * new Vec2(3.6, -2.1).map(Math.trunc); // Vec2 { x: 3, y: -2 }\n\t * new Vec2(2, 5).map((v, i) => v * (i + 1)); // Vec2 { x: 2, y: 10 }\n\t * ```\n\t */\n\tpublic map(callback: (value: number, index: number) => number): Vec2 {\n\t\tthis.x = callback(this.x, 0);\n\t\tthis.y = callback(this.y, 1);\n\t\treturn this;\n\t}\n\n\t/** Per-axis Euclidean modulo (result sign matches the divisor). Mutates and returns `this`. */\n\tpublic mod(v: Vector2): Vec2;\n\tpublic mod(x: number, y?: number): Vec2;\n\tpublic mod(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Mod, x, y);\n\t}\n\n\t/** Per-axis multiply. Mutates and returns `this`. */\n\tpublic mult(v: Vector2): Vec2;\n\tpublic mult(x: number, y?: number): Vec2;\n\tpublic mult(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Mult, x, y);\n\t}\n\n\t/** Flip the sign of both components (same as `mult(-1)`). Mutates and returns `this`. */\n\tpublic negate(): Vec2 {\n\t\treturn this.mult(-1);\n\t}\n\n\t/** Scale to unit length. Zero-length vectors are left untouched and warn (throttled). Mutates and returns `this`. */\n\tpublic normalize(): Vec2 {\n\t\tconst length = this.length();\n\n\t\tif (approxEqual(length, 0)) {\n\t\t\twarnZeroNormalize();\n\t\t\treturn this;\n\t\t}\n\n\t\treturn this.map(value => value / length);\n\t}\n\n\t/** Scale so `|x| + |y| === 1`. Zero-length vectors are left untouched. Mutates and returns `this`. */\n\tpublic normalizeManhattan(): Vec2 {\n\t\tconst length = this.lengthManhattan();\n\n\t\tif (approxEqual(length, 0)) {\n\t\t\treturn this;\n\t\t}\n\n\t\treturn this.map(value => value / length);\n\t}\n\n\t/** Per-axis remainder (JavaScript `%`, sign follows the dividend). Mutates and returns `this`. */\n\tpublic rem(v: Vector2): Vec2;\n\tpublic rem(x: number, y?: number): Vec2;\n\tpublic rem(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Rem, x, y);\n\t}\n\n\t/** Round each component to the nearest integer. Mutates and returns `this`. */\n\tpublic round(): Vec2 {\n\t\tthis.x = Math.round(this.x);\n\t\tthis.y = Math.round(this.y);\n\t\treturn this;\n\t}\n\n\t/** Per-axis subtract. Mutates and returns `this`. */\n\tpublic sub(v: Vector2): Vec2;\n\tpublic sub(x: number, y?: number): Vec2;\n\tpublic sub(x: Vector2 | number, y?: number): Vec2 {\n\t\treturn this.calculate(Operation.Sub, x, y);\n\t}\n\n\t/** Angle in radians. No arg: angle of `this` from origin. With `other`: angle from `this` toward `other`. */\n\tpublic angle(other?: Vector2): number {\n\t\tif (!other) {\n\t\t\treturn Math.atan2(this.y, this.x);\n\t\t}\n\n\t\treturn Math.atan2(other.y - this.y, other.x - this.x);\n\t}\n\n\t/** Euclidean distance to `other`. */\n\tpublic distance(other: Vector2): number {\n\t\treturn Math.sqrt(\n\t\t\tMath.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2),\n\t\t);\n\t}\n\n\t/** Manhattan distance (`|dx| + |dy|`) to `other`. */\n\tpublic distanceManhattan(other: Vector2): number {\n\t\treturn Math.abs(other.x - this.x) + Math.abs(other.y - this.y);\n\t}\n\n\t/** Dot product with `other`. */\n\tpublic dotProduct(other: Vector2): number {\n\t\treturn this.x * other.x + this.y * other.y;\n\t}\n\n\t/** `true` when both components are finite (rules out `NaN` and `\u00B1Infinity`). */\n\tpublic isValid(): boolean {\n\t\treturn Number.isFinite(this.x) && Number.isFinite(this.y);\n\t}\n\n\t/** Euclidean magnitude (`sqrt(x\u00B2 + y\u00B2)`). */\n\tpublic length(): number {\n\t\treturn Math.sqrt(this.x * this.x + this.y * this.y);\n\t}\n\n\t/** Manhattan magnitude (`|x| + |y|`). */\n\tpublic lengthManhattan(): number {\n\t\treturn Math.abs(this.x) + Math.abs(this.y);\n\t}\n\n\t/** Larger of the two components. */\n\tpublic max(): number {\n\t\treturn Math.max(this.x, this.y);\n\t}\n\n\t/** Smaller of the two components. */\n\tpublic min(): number {\n\t\treturn Math.min(this.x, this.y);\n\t}\n\n\t/** Tuple `[x, y]`. */\n\tpublic toArray(): [number, number] {\n\t\treturn [this.x, this.y];\n\t}\n\n\t/** Build a `Rect` with the argument as position and `this` as size. */\n\tpublic toRectAddPos(v: Vector2): Rect;\n\tpublic toRectAddPos(x: number, y?: number): Rect;\n\tpublic toRectAddPos(x: Vector2 | number, y?: number): Rect {\n\t\treturn this.concat(true, x, y);\n\t}\n\n\t/** Build a `Rect` with `this` as position and the argument as size. */\n\tpublic toRectAddSize(v: Vector2): Rect;\n\tpublic toRectAddSize(x: number, y?: number): Rect;\n\tpublic toRectAddSize(width: Vector2 | number, height?: number): Rect {\n\t\treturn this.concat(false, width, height);\n\t}\n\n\t/** Debug string like `\"Vec2 [x: 1, y: 2]\"`. */\n\tpublic toString(): string {\n\t\treturn `Vec2 [x: ${this.x}, y: ${this.y}]`;\n\t}\n\n\t/** New `Vec2` with the same components. */\n\tpublic clone(): Vec2 {\n\t\treturn new Vec2(this.x, this.y);\n\t}\n\n\t/** Approximate equality (within `approxEqual` tolerance). Scalar broadcasts. */\n\tpublic equals(v: Vector2): boolean;\n\tpublic equals(x: number, y?: number): boolean;\n\tpublic equals(x: Vector2 | number, y?: number): boolean {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\treturn approxEqual(this.x, x2) && approxEqual(this.y, y2);\n\t}\n\n\tprivate calculate(\n\t\toperation: (typeof Operation)[keyof typeof Operation],\n\t\tx: Vector2 | number,\n\t\ty?: number,\n\t): Vec2 {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\tswitch (operation) {\n\t\t\tcase Operation.Add:\n\t\t\t\tthis.x += x2;\n\t\t\t\tthis.y += y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Sub:\n\t\t\t\tthis.x -= x2;\n\t\t\t\tthis.y -= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Mult:\n\t\t\t\tthis.x *= x2;\n\t\t\t\tthis.y *= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Div:\n\t\t\t\tthis.x /= x2;\n\t\t\t\tthis.y /= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Rem:\n\t\t\t\tthis.x %= x2;\n\t\t\t\tthis.y %= y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Equal:\n\t\t\t\tthis.x = x2;\n\t\t\t\tthis.y = y2;\n\t\t\t\tbreak;\n\n\t\t\tcase Operation.Mod:\n\t\t\t\tthis.x = ((this.x % x2) + x2) % x2;\n\t\t\t\tthis.y = ((this.y % y2) + y2) % y2;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\toperation satisfies never;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (!this.isValid()) {\n\t\t\twarnNonFinite();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tprivate concat(first: boolean, x: Vector2 | number, y?: number): Rect {\n\t\tconst [x2, y2]: number[] = this.getValues(x, y);\n\n\t\tif (first) {\n\t\t\treturn new Rect(x2, y2, this.x, this.y);\n\t\t}\n\n\t\treturn new Rect(this.x, this.y, x2, y2);\n\t}\n\n\tprivate getValues(x: Vector2 | number, y?: number): number[] {\n\t\tlet inputX = 0;\n\t\tlet inputY = 0;\n\n\t\tif (typeof x === \"number\") {\n\t\t\tinputX = x;\n\t\t\tif (y === undefined) {\n\t\t\t\tinputY = x;\n\t\t\t} else {\n\t\t\t\tinputY = y;\n\t\t\t}\n\t\t} else {\n\t\t\tif (y === undefined) {\n\t\t\t\tinputX = x.x;\n\t\t\t\tinputY = x.y;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"When x is a Vector2, y must be omitted!\");\n\t\t\t}\n\t\t}\n\n\t\treturn [inputX, inputY];\n\t}\n}\n", "import type Game from \"./Game\";\n\n/** Subset of writable Settings fields that {@link Settings.init} accepts (everything except the methods and persisted-storage view). Pass to `super()` when subclassing {@link Game}. */\nexport type SettingsOverrides = Partial<\n\tOmit<\n\t\ttypeof Settings,\n\t\t\"prototype\" | \"init\" | \"setLocalStorage\" | \"localStorage\"\n\t>\n>;\n\nconst LOCAL_STORAGE_KEY = \"gleam\";\n\n/** Engine-wide configuration. A static-class singleton \u2014 read/write top-level fields directly (`Settings.fps = 1 / 30`). Initialised once via {@link init} from `Game`'s constructor; calling `init` twice throws. */\nexport default class Settings {\n\t/** Enable smoothing on the main canvas context. Default `false` for crisp pixel art. */\n\tpublic static antialias = false;\n\t/** Start the gameloop automatically after `init()` resolves. Disable to drive `gameloop.startLoop()` manually. Default `true`. */\n\tpublic static autoloop = true;\n\t/** CSS color used when {@link useClearRect} is `false`. Default `\"#444\"`. */\n\tpublic static backgroundColor = \"#444\";\n\t/** Debug mode: assigns the `Game` instance to `window.game` and lets {@link Keyboard} Escape stop the loop. Default `false`. */\n\tpublic static debug = false;\n\t/** Skip the per-frame canvas clear. Use for trail/decay effects where you manage clearing yourself. Default `false`. */\n\tpublic static doNotClear = false;\n\t/** Stretch the main canvas to fill the window on resize while preserving its aspect ratio. Default `true`. */\n\tpublic static enableResize = true;\n\t/** Default font family for `canman.setFontSize`. Default `\"Arial\"`. */\n\tpublic static font = \"Arial\";\n\t/** **Seconds per fixed step**, not frames per second \u2014 `1 / 60` = 60 Hz, `1 / 30` = 30 Hz. Must be finite and `> 0` or {@link init} throws. */\n\tpublic static fps = 1 / 60;\n\t/** Callback invoked from the `beforeunload` handler when {@link warnBeforeClose} is `true`. Useful for \"are you sure?\" autosave logic. */\n\tpublic static triedToClose?: () => void;\n\t/** Clear the canvas with `clearRect` (transparent) when `true`, or `fillRect` with {@link backgroundColor} when `false`. Default `true`. */\n\tpublic static useClearRect = true;\n\t/** Show a browser \"are you sure?\" dialog on tab close. Required for {@link triedToClose} to fire. Default `false`. */\n\tpublic static warnBeforeClose = false;\n\tprivate static initialized = false;\n\t// Only mutated via `setLocalStorage` (typed) and via the localStorage\n\t// round-trip in `init()` \u2014 since `setLocalStorage` is the sole writer of\n\t// the persisted blob, the parsed payload is trusted to match the schema.\n\tprivate static readonly _localStorage = {\n\t\tlanguage: \"\",\n\t};\n\n\t/** Read-only view of the persisted localStorage blob. Writes go through {@link setLocalStorage}. */\n\tpublic static get localStorage(): Readonly<typeof Settings._localStorage> {\n\t\treturn this._localStorage;\n\t}\n\n\t/** One-time setup \u2014 called by `Game`'s constructor with the overrides passed to `super()`. Validates {@link fps}, loads the persisted localStorage blob, derives `language` from `navigator.language`, and wires the close-warning handler if {@link warnBeforeClose}. Throws if called twice or if `fps` isn't a finite positive number. */\n\tpublic static init(overrides: SettingsOverrides, game: Game): void {\n\t\tif (this.initialized) {\n\t\t\tthrow new Error(\"Settings.init called twice\");\n\t\t}\n\n\t\tObject.assign(this, overrides);\n\n\t\t// fps from `overrides` can be NaN or Infinity; both pass `<= 0`.\n\t\tif (!(Number.isFinite(this.fps) && this.fps > 0)) {\n\t\t\tthrow new Error(`Settings.fps must be > 0, got ${this.fps}`);\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\t// debug-only devtools hook; kept as `any` so the temporary\n\t\t\t// debug surface doesn't leak into any .d.ts file.\n\t\t\t(window as any).game = game;\n\t\t}\n\n\t\tif (this.warnBeforeClose) {\n\t\t\twindow.addEventListener(\n\t\t\t\t\"beforeunload\",\n\t\t\t\t(event: BeforeUnloadEvent) => {\n\t\t\t\t\tthis.triedToClose?.();\n\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.returnValue = true;\n\t\t\t\t\treturn \"Are you sure?\";\n\t\t\t\t},\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\n\t\tthis._localStorage.language = navigator.language.split(\"-\")[0] || \"en\";\n\n\t\tconst storage = localStorage.getItem(LOCAL_STORAGE_KEY);\n\t\tif (storage) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(storage);\n\t\t\t\tObject.assign(this._localStorage, parsed);\n\t\t\t} catch (_e) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"Couldn't parse local storage! Will be cleaned now.\",\n\t\t\t\t\tstorage,\n\t\t\t\t);\n\t\t\t\tlocalStorage.removeItem(LOCAL_STORAGE_KEY);\n\t\t\t}\n\t\t}\n\n\t\tthis.initialized = true;\n\t}\n\n\t/** Typed setter for the persisted localStorage blob. Writes both in-memory and to actual `localStorage` (under a single JSON key \u2014 `\"gleam\"`). The only supported way to mutate persisted state. */\n\tpublic static setLocalStorage<K extends keyof typeof this._localStorage>(\n\t\tkey: K,\n\t\tvalue: (typeof this._localStorage)[K],\n\t): void {\n\t\tthis._localStorage[key] = value;\n\n\t\tlocalStorage.setItem(\n\t\t\tLOCAL_STORAGE_KEY,\n\t\t\tJSON.stringify(this._localStorage),\n\t\t);\n\t}\n}\n", "/** `get`/`set` helpers for CSS custom properties (`--name`) on `:root`. Build via {@link initCSSVariables}. */\nexport interface CSSVariables {\n\t/** The `:root` element these helpers read from / write to. */\n\troot: HTMLElement;\n\t/** Read the computed value of `--${name}`. */\n\tget(name: string): string;\n\t/** Write `value` to `--${name}` on the root element's inline style. */\n\tset(name: string, value: string): void;\n}\n\n/**\n * `querySelector` variant that throws when no element matches.\n * Optionally narrow the return type per tag, e.g. `getElement<HTMLCanvasElement>(\"canvas\")`.\n */\nexport function getElement<T extends Element = HTMLElement>(\n\tquery: string,\n\tparent: ParentNode = document,\n): T {\n\tconst el = parent.querySelector<T>(query);\n\tif (!el) {\n\t\tthrow new Error(`Element not found: ${query}`);\n\t}\n\treturn el;\n}\n\n/**\n * Apply a partial `CSSStyleDeclaration` to an element.\n */\nexport function styleElement(\n\telement: HTMLElement,\n\tstyles: Partial<CSSStyleDeclaration>,\n): void {\n\tObject.assign(element.style, styles);\n}\n\n/**\n * Toggle `element.style.display` between `\"\"` (active) and `\"none\"` (inactive).\n */\nexport function setDisplay(element: HTMLElement, active: boolean): void {\n\telement.style.display = active ? \"\" : \"none\";\n}\n\n/**\n * Toggle `element.style.visibility` between `\"\"` (active) and `\"hidden\"` (inactive).\n */\nexport function setVisibility(element: HTMLElement, active: boolean): void {\n\telement.style.visibility = active ? \"\" : \"hidden\";\n}\n\n/**\n * Returns `get` / `set` helpers for CSS custom properties (`--name`) on the `:root` element.\n */\nexport function initCSSVariables(): CSSVariables {\n\tconst root = getElement(\":root\");\n\n\treturn {\n\t\troot,\n\t\tget(name: string): string {\n\t\t\treturn getComputedStyle(root).getPropertyValue(\"--\" + name);\n\t\t},\n\t\tset(name: string, value: string): void {\n\t\t\troot.style.setProperty(\"--\" + name, value);\n\t\t},\n\t};\n}\n\n/**\n * Calls `callback` on pointerdown of the matched element, then keeps calling it every `delay` ms\n * until pointerup or pointercancel. Uses pointer capture so the action persists while the cursor\n * drags off the element (and over descendants). Unifies mouse, touch, and pen. Throws if no element\n * matches. Returns a dispose function that removes the listeners and stops any in-flight interval.\n */\nexport function doWhilePressed(\n\tquerySelector: string,\n\tcallback: () => void,\n\tdelay = 200,\n): () => void {\n\tconst element = getElement(querySelector);\n\n\tlet intervalId: ReturnType<typeof setInterval> | undefined;\n\tlet activePointerId: number | null = null;\n\n\tfunction start(event: PointerEvent): void {\n\t\tif (activePointerId !== null) {\n\t\t\treturn;\n\t\t}\n\n\t\tactivePointerId = event.pointerId;\n\t\telement.setPointerCapture(activePointerId);\n\n\t\tclearInterval(intervalId);\n\t\tcallback();\n\t\tintervalId = setInterval(() => callback(), delay);\n\t}\n\n\tfunction stop(event: PointerEvent): void {\n\t\tif (event.pointerId !== activePointerId) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearInterval(intervalId);\n\t\telement.releasePointerCapture(event.pointerId);\n\t\tactivePointerId = null;\n\t}\n\n\telement.addEventListener(\"pointerdown\", start);\n\telement.addEventListener(\"pointerup\", stop);\n\telement.addEventListener(\"pointercancel\", stop);\n\n\tfunction dispose(): void {\n\t\telement.removeEventListener(\"pointerdown\", start);\n\t\telement.removeEventListener(\"pointerup\", stop);\n\t\telement.removeEventListener(\"pointercancel\", stop);\n\n\t\tclearInterval(intervalId);\n\t\tif (activePointerId !== null) {\n\t\t\telement.releasePointerCapture(activePointerId);\n\t\t\tactivePointerId = null;\n\t\t}\n\t}\n\n\treturn dispose;\n}\n\n/**\n * Resolves the next time `type` fires on `element` (one-shot listener). Pass an `AbortSignal`\n * to cancel \u2014 rejects with `signal.reason` and removes the listener.\n */\nexport async function waitForEvent<K extends keyof HTMLElementEventMap>(\n\telement: HTMLElement,\n\ttype: K,\n\tsignal?: AbortSignal,\n): Promise<void> {\n\tif (signal?.aborted) {\n\t\tthrow signal.reason;\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\telement.addEventListener(type, () => resolve(), {\n\t\t\tonce: true,\n\t\t\tsignal,\n\t\t});\n\t\tsignal?.addEventListener(\"abort\", () => reject(signal.reason), {\n\t\t\tonce: true,\n\t\t});\n\t});\n}\n", "import type { Vector2 } from \"@/math/Vec2\";\n\n/**\n * Clone a 2D grid; the outer array and each row become independent copies.\n * Row cells are kept as-is (suitable for primitive cells; for nested structures use `deepClone`).\n */\nexport function cloneGrid<T>(grid: ReadonlyArray<ReadonlyArray<T>>): T[][] {\n\treturn grid.map(row => row.slice());\n}\n\n/**\n * Convert a 1D index to `{x, y}` for a 2D grid of the given row width.\n */\nexport function convert1DTo2D(index: number, width: number): Vector2 {\n\treturn {\n\t\tx: index % width,\n\t\ty: (index / width) | 0,\n\t};\n}\n\n/**\n * Convert 2D `(x, y)` coordinates to a 1D index for a grid of the given row width.\n */\nexport function convert2DTo1D(\n\tindexX: number,\n\tindexY: number,\n\twidth: number,\n): number {\n\treturn indexX + width * indexY;\n}\n\n/** Primitive cell types accepted by {@link generateGrid}'s overload that takes a default value (used so every cell can safely share the same primitive without aliasing). */\nexport type GridPrimitive =\n\t| string\n\t| number\n\t| boolean\n\t| bigint\n\t| symbol\n\t| null\n\t| undefined;\n\n/**\n * Generate a `height \u00D7 width` 2D grid; every cell holds `defaultValue`. Restricted to primitives at the type level \u2014 for object/array cells use the factory overload to avoid every cell sharing the same reference.\n */\nexport function generateGrid<T extends GridPrimitive>(\n\theight: number,\n\twidth: number,\n\tdefaultValue: T,\n): T[][];\n/**\n * Generate a `height \u00D7 width` 2D grid by invoking `factory(x, y)` for each cell. Use this overload for object/array cells (and for any per-cell computation).\n */\nexport function generateGrid<T>(\n\theight: number,\n\twidth: number,\n\tfactory: (x: number, y: number) => T,\n): T[][];\nexport function generateGrid<T>(\n\theight: number,\n\twidth: number,\n\tvalueOrFactory: T | ((x: number, y: number) => T),\n): T[][] {\n\tconst isFactory = typeof valueOrFactory === \"function\";\n\n\treturn Array.from({ length: height }, (_, y) =>\n\t\tArray.from({ length: width }, (_, x) =>\n\t\t\tisFactory\n\t\t\t\t? (valueOrFactory as (x: number, y: number) => T)(x, y)\n\t\t\t\t: valueOrFactory,\n\t\t),\n\t);\n}\n", "/** Conditional helper used by {@link defineMethod}: given `T[K]` is a function, produces a corresponding function type with `this: T` bound to the prototype owner. Non-function members resolve to `never` so prototype patches can't target accessors or fields by mistake. */\nexport type Method<T, K extends keyof T> = T[K] extends (\n\t...args: infer A\n) => infer R\n\t? (this: T, ...args: A) => R\n\t: never;\n\n/**\n * Define `name` as a non-enumerable method on `proto`. Carries the declared signature so impl `this` and parameters are inferred from the merged declaration.\n */\nexport function defineMethod<T, K extends keyof T>(\n\tproto: T,\n\tname: K,\n\tvalue: Method<T, K>,\n): void {\n\tObject.defineProperty(proto, name, {\n\t\tvalue,\n\t\tconfigurable: true,\n\t\twritable: true,\n\t});\n}\n", "import { createNewCanvas } from \"@/utilities/Canvas\";\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/**\n * Validates URL format and protocol before any side effects.\n * Throws on invalid URLs or disallowed protocols.\n */\nexport function validateUrl(url: string): void {\n\tconst schemeMatch = url.trim().match(/^([a-z][a-z0-9+.-]*):/i);\n\n\tif (!schemeMatch) {\n\t\t// has no scheme -> relative url -> allow\n\t\treturn;\n\t}\n\n\tconst scheme = schemeMatch[1].toLowerCase();\n\n\tif ([\"blob\", \"data\", \"http\", \"https\"].includes(scheme)) {\n\t\t// has known scheme -> allow\n\t\treturn;\n\t}\n\n\t// well, has unknown scheme -> oh oh\n\tthrow new Error(`Invalid URL protocol: ${url}`);\n}\n\n/**\n * Safe loading wrapper with global timeout and error handling.\n * Use this for any async loading operation that needs timeout protection.\n * Timeout rejects the returned promise but does not cancel the underlying\n * fetch/Image \u2014 the request continues until natural completion. Adding\n * AbortSignal support would require a full rewrite (factory-based API).\n * Maybe a future feature, though.\n */\nexport function safeLoad<T>(\n\tpromise: Promise<T>,\n\turl: string,\n\toperationName: string,\n): Promise<T> {\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\n\tconst timeoutPromise = new Promise<T>((_, reject) => {\n\t\ttimeoutId = setTimeout(() => {\n\t\t\treject(\n\t\t\t\tnew Error(\n\t\t\t\t\t`Timeout (${DEFAULT_TIMEOUT_MS}ms) when loading ${operationName}: ${url}`,\n\t\t\t\t),\n\t\t\t);\n\t\t}, DEFAULT_TIMEOUT_MS);\n\t});\n\n\treturn Promise.race([promise, timeoutPromise])\n\t\t.catch((error: Error) => {\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tconst errorMessage = error?.message || String(error);\n\n\t\t\t// Log detailed error with file path for debugging\n\t\t\tconsole.error(\n\t\t\t\t`${operationName} failed on ${url}\\n ${errorMessage}`,\n\t\t\t);\n\n\t\t\t// Re-throw wrapped error to be caught by caller\n\t\t\tthrow error;\n\t\t})\n\t\t.finally(() => clearTimeout(timeoutId));\n}\n\n/**\n * Loads an image with timeout and error handling\n */\nexport async function loadImage(url: string): Promise<HTMLImageElement> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tnew Promise<HTMLImageElement>((resolve, reject): void => {\n\t\t\tconst image = new Image();\n\n\t\t\timage.onload = () => resolve(image);\n\t\t\timage.onerror = () =>\n\t\t\t\treject(new Error(`Image failed to load: ${url}`));\n\n\t\t\timage.crossOrigin = \"anonymous\";\n\t\t\timage.src = url;\n\t\t}),\n\t\turl,\n\t\t\"image\",\n\t);\n}\n\n/**\n * Loads a canvas from image URL with error handling\n */\nexport async function loadCanvas(url: string): Promise<HTMLCanvasElement> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\t(async () => {\n\t\t\tconst image = await loadImage(url);\n\t\t\tconst cc = createNewCanvas(image.width, image.height);\n\t\t\tcc.canvas.id = url;\n\t\t\tcc.context.drawImage(image, 0, 0);\n\t\t\treturn cc.canvas;\n\t\t})(),\n\t\turl,\n\t\t\"canvas\",\n\t);\n}\n\n/**\n * Loads text content from URL with error handling\n */\nexport async function loadText(url: string): Promise<string> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\t(async () => {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`HTTP ${response.status}: Failed to load text from ${url}\\n Status: ${response.status} ${response.statusText}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn response.text();\n\t\t})(),\n\t\turl,\n\t\t\"text\",\n\t);\n}\n\n/**\n * Loads JSON data from URL with error handling\n */\nexport async function loadJson<T = unknown>(url: string): Promise<T> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tloadText(url).then(text => JSON.parse(text) as T),\n\t\turl,\n\t\t\"JSON\",\n\t);\n}\n\n/**\n * Loads JSON with inline comments\n */\nexport async function loadJsonCommented<T = unknown>(url: string): Promise<T> {\n\tvalidateUrl(url);\n\n\treturn safeLoad(\n\t\tloadText(url).then(text => {\n\t\t\t// strips lines starting with //\n\t\t\tconst lines = text\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter(line => {\n\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\tif (!trimmed || trimmed.startsWith(\"//\")) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\n\t\t\treturn JSON.parse(lines) as T;\n\t\t}),\n\t\turl,\n\t\t\"JSON (commented)\",\n\t);\n}\n\ninterface SpriteJson {\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n\tname: string;\n\t[key: string]: string | number;\n}\n\ninterface SpriteJsonFile {\n\toptions: { file: string };\n\tsprites: SpriteJson[];\n}\n\n/**\n * Loads image sprites from JSON configuration with error handling\n */\nexport async function loadImageFromJson(\n\tbaseUrl: string,\n\tfilenameOrJson: string,\n\tjsonInput = false,\n): Promise<Record<string, HTMLCanvasElement>> {\n\tif (!baseUrl.endsWith(\"/\")) {\n\t\tbaseUrl += \"/\";\n\t}\n\n\tlet json: SpriteJsonFile;\n\n\t// Handle both inline JSON and file loading cases\n\tif (jsonInput) {\n\t\ttry {\n\t\t\tjson = JSON.parse(filenameOrJson) as SpriteJsonFile;\n\t\t} catch (parseError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to parse inline JSON: ${(parseError as SyntaxError).message}`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tconst url = baseUrl + filenameOrJson + \".json\";\n\n\t\tjson = await loadJson<SpriteJsonFile>(url);\n\t}\n\n\t// Handle JSON parsing errors gracefully\n\tif (!json || !json.options?.file) {\n\t\tconst source = jsonInput\n\t\t\t? \"inline JSON\"\n\t\t\t: `${baseUrl}${filenameOrJson}.json`;\n\n\t\tthrow new Error(\n\t\t\t`JSON missing 'options.file' property\\n Source: ${source}`,\n\t\t);\n\t}\n\n\tconst canvas = await loadCanvas(baseUrl + json.options.file);\n\tconst sprites: Record<string, HTMLCanvasElement> = {};\n\n\tif (!json.sprites || !Array.isArray(json.sprites)) {\n\t\tthrow new Error(\n\t\t\t`JSON missing 'sprites' array\\n Source: ${baseUrl}${filenameOrJson}.json`,\n\t\t);\n\t}\n\n\tjson.sprites.forEach((sprite, i) => {\n\t\tif (\n\t\t\tsprite.x === undefined ||\n\t\t\tsprite.y === undefined ||\n\t\t\t!sprite.w ||\n\t\t\t!sprite.h ||\n\t\t\t!sprite.name\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid sprite data at index ${i}: ${JSON.stringify(sprite, null, 2)}`,\n\t\t\t);\n\t\t}\n\n\t\tconst newSprite = canvas.subImage(\n\t\t\tsprite.x,\n\t\t\tsprite.y,\n\t\t\tsprite.w,\n\t\t\tsprite.h,\n\t\t);\n\n\t\tfor (const key in sprite) {\n\t\t\tnewSprite.dataset[key] = String(sprite[key]);\n\t\t}\n\n\t\tsprites[sprite.name] = newSprite;\n\t});\n\n\treturn sprites;\n}\n\n/**\n * Loads multiple resources concurrently with error handling\n */\nexport async function loadBunch<T extends Record<string, Promise<unknown>>>(\n\tbunch: T,\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> {\n\tconst output = {} as { [K in keyof T]: Awaited<T[K]> };\n\tconst keys = Object.keys(bunch) as (keyof T)[];\n\n\treturn Promise.all(keys.map(k => bunch[k])).then(datas => {\n\t\tkeys.forEach((key, i) => {\n\t\t\toutput[key] = datas[i];\n\t\t});\n\n\t\treturn output;\n\t});\n}\n", "import { convert2DTo1D } from \"@/utilities/Grid\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport { hex2rgb, type RGB, rgb2Int } from \"@/utilities/Color\";\nimport { loadImage } from \"@/loader/UrlLoaders\";\n\nexport {};\n\n// #region hasAnyColor\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** `true` if any pixel has a non-zero RGBA byte. */\n\t\thasAnyColor(): boolean;\n\t}\n}\n\ndefineMethod(HTMLCanvasElement.prototype, \"hasAnyColor\", function (): boolean {\n\tconst pixels = this.getContext(\"2d\")!.getImageData(\n\t\t0,\n\t\t0,\n\t\tthis.width,\n\t\tthis.height,\n\t).data;\n\n\treturn pixels.some(pixel => pixel !== 0);\n});\n// #endregion\n\n// #region getPixelAt\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Read the pixel at `(x, y)`. Out-of-bounds reads return zero/transparent.\n\t\t * Not for hot paths \u2014 each call issues a fresh `getImageData`. For bulk reads, call `getImageData` once and index into the buffer.\n\t\t * @param output return format. Default `\"integer\"`.\n\t\t */\n\t\tgetPixelAt(x: number, y: number, output?: \"integer\"): number;\n\t\tgetPixelAt(x: number, y: number, output: \"array\"): [...RGB, number];\n\t\tgetPixelAt(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\toutput: \"json\",\n\t\t): { r: number; g: number; b: number; a: number };\n\t\tgetPixelAt(x: number, y: number, output: \"string\"): string;\n\t}\n}\n\ndefineMethod(HTMLCanvasElement.prototype, \"getPixelAt\", function (\n\tthis: HTMLCanvasElement,\n\tx: number,\n\ty: number,\n\toutput: \"integer\" | \"array\" | \"json\" | \"string\" = \"integer\",\n) {\n\tlet r = 0;\n\tlet g = 0;\n\tlet b = 0;\n\tlet a = 0;\n\n\tif (x >= 0 && x < this.width && y >= 0 && y < this.height) {\n\t\tconst data = this.getContext(\"2d\")!.getImageData(x, y, 1, 1).data;\n\t\tr = data[0];\n\t\tg = data[1];\n\t\tb = data[2];\n\t\ta = data[3];\n\t}\n\n\tswitch (output) {\n\t\tcase \"array\":\n\t\t\treturn [r, g, b, a];\n\n\t\tcase \"json\":\n\t\t\treturn { r, g, b, a };\n\n\t\tcase \"string\":\n\t\t\treturn `rgba(${r}, ${g}, ${b}, ${a})`;\n\n\t\tcase \"integer\":\n\t\tdefault:\n\t\t\treturn rgb2Int(r, g, b, a / 255);\n\t}\n} as HTMLCanvasElement[\"getPixelAt\"]);\n// #endregion\n\n// #region replaceColors\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Replace pixel colors by RGB hex key. Alpha is ignored \u2014 fully-transparent pixels are skipped, semi-transparent pixels keep their alpha.\n\t\t */\n\t\treplaceColors(replacements: Record<string, string>): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"replaceColors\",\n\tfunction (replacements): HTMLCanvasElement {\n\t\tconst lookup = new Map<number, RGB>();\n\t\tfor (const from in replacements) {\n\t\t\tconst [fr, fg, fb] = hex2rgb(from);\n\t\t\tconst [tr, tg, tb] = hex2rgb(replacements[from]);\n\t\t\tlookup.set(rgb2Int(fr, fg, fb), [tr, tg, tb]);\n\t\t}\n\n\t\tconst context = this.getContext(\"2d\")!;\n\t\tconst image = context.getImageData(0, 0, this.width, this.height);\n\t\tconst { data } = image;\n\n\t\tfor (let i = 0; i < data.length; i += 4) {\n\t\t\tif (data[i + 3] === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst replacement = lookup.get(\n\t\t\t\trgb2Int(data[i], data[i + 1], data[i + 2]),\n\t\t\t);\n\n\t\t\tif (replacement !== undefined) {\n\t\t\t\tdata[i] = replacement[0];\n\t\t\t\tdata[i + 1] = replacement[1];\n\t\t\t\tdata[i + 2] = replacement[2];\n\t\t\t}\n\t\t}\n\n\t\tcontext.putImageData(image, 0, 0);\n\t\treturn this;\n\t},\n);\n// #endregion\n\n// #region rotateBy\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Rotate around the center into a new square canvas sized to fit any rotation (`diam = ceil(sqrt(w\u00B2 + h\u00B2))`). */\n\t\trotateBy(radians: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"rotateBy\",\n\tfunction (radians): HTMLCanvasElement {\n\t\tconst diam = Math.ceil(\n\t\t\tMath.sqrt(this.width * this.width + this.height * this.height),\n\t\t);\n\t\tconst cc = createNewCanvas(diam, diam);\n\n\t\tcc.context.translate(diam * 0.5, diam * 0.5);\n\t\tcc.context.rotate(radians);\n\t\tcc.context.drawImage(this, -this.width * 0.5, -this.height * 0.5);\n\t\tcc.context.translate(-diam * 0.5, -diam * 0.5);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region rotateByAligned\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Rotate around the center within the original `width \u00D7 height`; corners that fall outside are clipped. */\n\t\trotateByAligned(radians: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"rotateByAligned\",\n\tfunction (radians): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(this.width * 0.5, this.height * 0.5);\n\t\tcc.context.rotate(radians);\n\t\tcc.context.translate(-this.width * 0.5, -this.height * 0.5);\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region autoCrop\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Trim fully-transparent borders. Returns a new canvas cropped to the bounding box of opaque pixels. */\n\t\tautoCrop(): HTMLCanvasElement;\n\t}\n}\n\n// https://stackoverflow.com/a/58882518\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"autoCrop\",\n\tfunction (): HTMLCanvasElement {\n\t\tconst topLeft = {\n\t\t\tx: this.width,\n\t\t\ty: this.height,\n\t\t\tupdate(x: number, y: number): void {\n\t\t\t\tthis.x = Math.min(this.x, x);\n\t\t\t\tthis.y = Math.min(this.y, y);\n\t\t\t},\n\t\t};\n\n\t\tconst bottomRight = {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tupdate(x: number, y: number): void {\n\t\t\t\tthis.x = Math.max(this.x, x);\n\t\t\t\tthis.y = Math.max(this.y, y);\n\t\t\t},\n\t\t};\n\n\t\tconst context = this.getContext(\"2d\")!;\n\n\t\tconst imageData = context.getImageData(0, 0, this.width, this.height);\n\n\t\tfor (let y = 0; y < this.height; y++) {\n\t\t\tfor (let x = 0; x < this.width; x++) {\n\t\t\t\tconst alpha =\n\t\t\t\t\timageData.data[convert2DTo1D(x * 4, y * 4, this.width) + 3];\n\n\t\t\t\tif (alpha !== 0) {\n\t\t\t\t\ttopLeft.update(x, y);\n\t\t\t\t\tbottomRight.update(x, y);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// fully-transparent canvas -> nothing to crop to\n\t\tif (topLeft.x > bottomRight.x) {\n\t\t\treturn this.clone();\n\t\t}\n\n\t\tconst width = bottomRight.x - topLeft.x + 1;\n\t\tconst height = bottomRight.y - topLeft.y + 1;\n\n\t\treturn this.subImage(topLeft.x, topLeft.y, width, height);\n\t},\n);\n// #endregion\n\n// #region scaleBy\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Scale into a new canvas. Throws if any factor is `\u2264 0`.\n\t\t * @param scaleX horizontal scale factor. Default `1`.\n\t\t * @param scaleY vertical scale factor. Default = `scaleX`.\n\t\t */\n\t\tscaleBy(scaleX?: number, scaleY?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"scaleBy\",\n\tfunction (scaleX = 1, scaleY = scaleX): HTMLCanvasElement {\n\t\tif (scaleX <= 0 || scaleY <= 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`scaleBy requires positive scale factors, got: ${scaleX} x ${scaleY}`,\n\t\t\t);\n\t\t}\n\n\t\tconst cc = createNewCanvas(this.width * scaleX, this.height * scaleY);\n\n\t\tcc.context.scale(scaleX, scaleY);\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region resize\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Scale into a new canvas so the chosen axis equals `size`, preserving aspect ratio.\n\t\t * @param isWidth match `size` against width when `true`, height when `false`. Default `true`.\n\t\t */\n\t\tresize(size: number, isWidth?: boolean): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"resize\",\n\tfunction (size, isWidth = true): HTMLCanvasElement {\n\t\tif (isWidth) {\n\t\t\treturn this.scaleBy(size / this.width);\n\t\t}\n\n\t\treturn this.scaleBy(size / this.height);\n\t},\n);\n// #endregion\n\n// #region flipX\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Mirror horizontally into a new canvas.\n\t\t * @param offsetX horizontal shift applied after flipping. Default `0`.\n\t\t */\n\t\tflipX(offsetX?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"flipX\",\n\tfunction (offsetX = 0): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(this.width + offsetX, 0);\n\t\tcc.context.scale(-1, 1);\n\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region flipY\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Mirror vertically into a new canvas.\n\t\t * @param offsetY vertical shift applied after flipping. Default `0`.\n\t\t */\n\t\tflipY(offsetY?: number): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"flipY\",\n\tfunction (offsetY = 0): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\n\t\tcc.context.translate(0, this.height + offsetY);\n\t\tcc.context.scale(1, -1);\n\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region subImage\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/**\n\t\t * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.\n\t\t * @param w default `this.width`\n\t\t * @param h default `this.height`\n\t\t */\n\t\tsubImage(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw?: number,\n\t\t\th?: number,\n\t\t): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"subImage\",\n\tfunction (x, y, w, h): HTMLCanvasElement {\n\t\tif (w === undefined) {\n\t\t\tw = this.width;\n\t\t}\n\n\t\tif (h === undefined) {\n\t\t\th = this.height;\n\t\t}\n\n\t\tconst cc = createNewCanvas(w, h);\n\t\tcc.context.drawImage(this, x, y, w, h, 0, 0, w, h);\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region clone\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Copy this canvas (same dimensions, content, `id`, and `dataset`) into a new canvas. */\n\t\tclone(): HTMLCanvasElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"clone\",\n\tfunction (): HTMLCanvasElement {\n\t\tconst cc = createNewCanvas(this.width, this.height);\n\t\tcc.canvas.id = this.id;\n\t\tcc.context.drawImage(this, 0, 0);\n\n\t\tfor (const key in this.dataset) {\n\t\t\tcc.canvas.dataset[key] = this.dataset[key];\n\t\t}\n\n\t\treturn cc.canvas;\n\t},\n);\n// #endregion\n\n// #region toImage\ndeclare global {\n\tinterface HTMLCanvasElement {\n\t\t/** Convert image canvas to `Promise<HTMLImageElement>` via `toDataURL`. */\n\t\ttoImage(): Promise<HTMLImageElement>;\n\t}\n}\n\ndefineMethod(\n\tHTMLCanvasElement.prototype,\n\t\"toImage\",\n\tfunction (): Promise<HTMLImageElement> {\n\t\treturn loadImage(this.toDataURL());\n\t},\n);\n// #endregion\n", "import Settings from \"@/core/Settings\";\nimport { getElement } from \"./DOM\";\nimport { rgb2Int } from \"./Color\";\n\nimport \"@/prototypes/HTMLCanvasElement\"; // splitSpriteSheet relies on the subImage patch\n\n/** A `<canvas>` element paired with its 2D rendering context. Returned by {@link createNewCanvas} / {@link getCanvasConstruct} and inherited by {@link CanvasHolder}. */\nexport interface CanvasConstruct {\n\t/** The `<canvas>` element. */\n\tcanvas: HTMLCanvasElement;\n\t/** Its 2D rendering context. */\n\tcontext: CanvasRenderingContext2D;\n}\n\n/**\n * Create a new `<canvas>` of the given size with its 2D context. Antialiasing defaults to `Settings.antialias`.\n */\nexport function createNewCanvas(\n\twidth: number,\n\theight: number,\n\tantialias: boolean = Settings.antialias,\n): CanvasConstruct {\n\tconst canvas = document.createElement(\"canvas\");\n\tcanvas.width = width;\n\tcanvas.height = height;\n\n\tconst context = canvas.getContext(\"2d\")!;\n\tcontext.imageSmoothingEnabled = antialias;\n\n\treturn {\n\t\tcanvas,\n\t\tcontext,\n\t};\n}\n\n/**\n * Look up an existing canvas by CSS selector and return it with its 2D context.\n */\nexport function getCanvasConstruct(selector: string): CanvasConstruct {\n\tconst canvas = getElement<HTMLCanvasElement>(selector);\n\tconst context = canvas.getContext(\"2d\")!;\n\n\treturn {\n\t\tcanvas,\n\t\tcontext,\n\t};\n}\n\n/**\n * Apply a CSS `filter` string to an image and return the result as a new canvas.\n */\nexport function applyFilterOnCanvas(\n\timage: HTMLCanvasElement | HTMLImageElement,\n\tfilter: string,\n\twidth: number = image.width,\n\theight: number = image.height,\n): HTMLCanvasElement {\n\tconst cc = createNewCanvas(width, height);\n\n\tcc.context.filter = filter;\n\tcc.context.drawImage(image, 0, 0);\n\tcc.context.filter = \"none\";\n\n\treturn cc.canvas;\n}\n\n/**\n * Rotate the hue of an image by `hue` degrees via CSS `hue-rotate(...)` filter.\n */\nexport function rotateHue(\n\timage: HTMLCanvasElement | HTMLImageElement,\n\thue: number,\n\twidth?: number,\n\theight?: number,\n): HTMLCanvasElement {\n\treturn applyFilterOnCanvas(\n\t\timage,\n\t\t\"hue-rotate(\" + hue + \"deg)\",\n\t\twidth,\n\t\theight,\n\t);\n}\n\n/**\n * Recolor an opaque canvas in place using composite operations,\n * preserving the alpha mask of the source image. Wraps the body in `save`/`restore`\n * so `fillStyle` / `globalCompositeOperation` writes don't leak to the caller's context.\n * https://stackoverflow.com/a/45201094\n */\nexport function changeColor(\n\tcontext: CanvasRenderingContext2D,\n\toriImg: HTMLCanvasElement,\n\tnewColor: string,\n): void {\n\tcontext.save();\n\n\tcontext.clearRect(0, 0, oriImg.width, oriImg.height);\n\tcontext.globalCompositeOperation = \"source-over\";\n\tcontext.drawImage(oriImg, 0, 0, oriImg.width, oriImg.height);\n\n\tcontext.globalCompositeOperation = \"color\";\n\tcontext.fillStyle = newColor;\n\tcontext.fillRect(0, 0, oriImg.width, oriImg.height);\n\n\tcontext.globalCompositeOperation = \"destination-in\";\n\tcontext.drawImage(oriImg, 0, 0, oriImg.width, oriImg.height);\n\n\tcontext.restore();\n}\n\n/**\n * Split a sprite-sheet image into individual sprite canvases laid out as `elementsX \u00D7 elementsY`.\n * Throws if the image dimensions don't divide evenly \u2014 sheets are expected to be authored that way.\n */\nexport function splitSpriteSheet(\n\timg: HTMLCanvasElement,\n\telementsX: number,\n\telementsY: number,\n): HTMLCanvasElement[] {\n\tif (img.width % elementsX !== 0 || img.height % elementsY !== 0) {\n\t\tthrow new Error(\n\t\t\t`SpriteSheet doesn't divide evenly: ${img.width}x${img.height} / ${elementsX}x${elementsY}`,\n\t\t);\n\t}\n\n\tconst sizeX = img.width / elementsX;\n\tconst sizeY = img.height / elementsY;\n\tconst sprites: HTMLCanvasElement[] = [];\n\n\tArray.from({ length: elementsY }).forEach((_, row) => {\n\t\tArray.from({ length: elementsX }).forEach((_, col) => {\n\t\t\tsprites.push(img.subImage(col * sizeX, row * sizeY, sizeX, sizeY));\n\t\t});\n\t});\n\n\treturn sprites;\n}\n\n/**\n * Count occurrences of each color in an image, keyed by `#rrggbb`.\n * `pixelAmount` multiplies each count and floors to int; values < 1 will drop low-count colors entirely (count rounds to 0).\n * `removeLowerThan` / `removeHigherThan` drop entries outside the range; `0` disables either bound.\n */\nexport function getUsedColors(\n\timage: HTMLCanvasElement,\n\tpixelAmount = 1,\n\tremoveLowerThan = 0,\n\tremoveHigherThan = 0,\n): Map<string, number> {\n\tconst data = image\n\t\t.getContext(\"2d\")!\n\t\t.getImageData(0, 0, image.width, image.height).data;\n\tconst counts = new Map<number, number>();\n\n\tfor (let i = 0; i < data.length; i += 4) {\n\t\tconst key = rgb2Int(data[i], data[i + 1], data[i + 2]);\n\t\tcounts.set(key, (counts.get(key) ?? 0) + 1);\n\t}\n\n\tif (pixelAmount < 1 || removeLowerThan > 0 || removeHigherThan > 0) {\n\t\tcounts.forEach((value, key) => {\n\t\t\tconst newAmount = (value * pixelAmount) | 0;\n\n\t\t\tif (\n\t\t\t\tnewAmount === 0 ||\n\t\t\t\t(removeLowerThan > 0 && newAmount < removeLowerThan) ||\n\t\t\t\t(removeHigherThan > 0 && newAmount > removeHigherThan)\n\t\t\t) {\n\t\t\t\tcounts.delete(key);\n\t\t\t} else {\n\t\t\t\tcounts.set(key, newAmount);\n\t\t\t}\n\t\t});\n\t}\n\n\tconst result = new Map<string, number>();\n\tcounts.forEach((count, rgbInt) => {\n\t\tresult.set(\"#\" + (0x1000000 + rgbInt).toString(16).slice(1), count);\n\t});\n\n\treturn result;\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { randomBetweenFloat } from \"@/utilities/Math\";\n\n/** A named animation: a list of frame sprites and the per-frame `timing` (seconds). */\nexport interface SpriteAnimation {\n\t/** Mark this animation as the default \u2014 played by {@link Animator.reset} and right after {@link Animator.add} when registered. At most one per Animator. */\n\tdefault?: boolean;\n\t/** Unique identifier. Pass to {@link Animator.play}. */\n\tname: string;\n\t/** Frame images in playback order. Uniform size is assumed within a single animation. */\n\tsprites: HTMLCanvasElement[] | HTMLImageElement[];\n\t/** Seconds each frame stays visible before advancing. */\n\ttiming: number;\n}\n\n/** Fires once after the last frame of an animation plays. Cleared after firing. */\nexport type onEndType = () => void;\n/** Map of `frameIndex \u2192 callback`. The callback for a given frame fires once when that frame becomes active, then is removed from the map. */\nexport type onFrameType = Record<number, () => void>;\n\n/** Minimum shape an entity must satisfy to be animated by {@link Animator}. */\nexport interface BaseEntity {\n\t/** Top-left position used as the draw anchor. */\n\tpos: Vec2;\n\t/** Optional horizontal anchor offset for flipped frames. Defaults to the current sprite width on first render. */\n\tflipX?: number;\n}\n\n/**\n * Sprite-sheet animator. Hosts a list of named animations (registered via {@link add} / {@link addAnimation}) and drives them per-frame from `update(dt)`. Pre-renders each frame to a 2\u00D7-wide cached canvas keyed by `${namespace}.${animationName}` \u2014 so multiple entities sharing a `namespace` reuse the same rendered images.\n *\n * Use {@link play} to switch animations, {@link playOnce} for one-shot animations that fall back to the previous one, and {@link Animator.onEnd}/`onFrame` callbacks for frame- or animation-end hooks.\n */\nexport default class Animator {\n\tprivate static spriteCache = new Map<\n\t\tstring,\n\t\t{ unflipped: HTMLCanvasElement[]; flipped: HTMLCanvasElement[] }\n\t>();\n\n\t/**\n\t * Drop cached rendered sprites. Pass a namespace to evict only that prefix; omit to clear all.\n\t */\n\tpublic static clearSpriteCache(namespace?: string): void {\n\t\tif (namespace === undefined) {\n\t\t\tAnimator.spriteCache.clear();\n\t\t\treturn;\n\t\t}\n\n\t\tconst prefix = `${namespace}.`;\n\t\tAnimator.spriteCache.forEach((_, key) => {\n\t\t\tif (key.startsWith(prefix)) {\n\t\t\t\tAnimator.spriteCache.delete(key);\n\t\t\t}\n\t\t});\n\t}\n\n\t/** When `false`, {@link update} is a no-op. Set automatically to `false` after a single-frame animation finishes and via {@link reset} when no default animation exists. */\n\tpublic active = true;\n\t/** Current rendered frame (after flip processing). Pulled from the cache by {@link setImage} every time the frame advances. */\n\tpublic image!: HTMLCanvasElement;\n\t/** Index of the current frame within the current animation's `sprites` array. */\n\tpublic imageId = 0;\n\t/** Flip the rendered sprite horizontally. Caches a separate \"flipped\" bucket so toggling is cheap. */\n\tpublic lookLeft = false;\n\t/** One-shot callback that fires when the current animation's last frame finishes. Cleared after firing. */\n\tpublic onEnd: onEndType | undefined;\n\t/** Current sprite's `(width, height)`. Updated by {@link setImage}. */\n\tpublic size: Vec2 = new Vec2();\n\tprivate animations: SpriteAnimation[] = [];\n\tprivate currentAnimation = 0;\n\tprivate entity: BaseEntity;\n\tprivate lastPlayed: string | undefined;\n\tprivate namespace: string;\n\tprivate onFrame?: onFrameType;\n\tprivate playVersion = 0;\n\tprivate timer = 0;\n\n\t/** The currently-playing animation. `undefined` if no animations have been added yet. */\n\tpublic get current(): SpriteAnimation {\n\t\treturn this.animations[this.currentAnimation];\n\t}\n\n\t/**\n\t * Bind to `entity` and stamp `namespace` as the prefix for cache keys (`${namespace}.${animationName}`). **Use distinct namespaces for animators whose sprite sets differ** \u2014 sharing a namespace across mismatched sprite sets serves the wrong cached frames.\n\t */\n\tconstructor(entity: BaseEntity, namespace: string) {\n\t\tthis.entity = entity;\n\t\tthis.namespace = namespace;\n\t}\n\n\t/** Blit the current cached frame at `entity.pos + offset`, shifted left by `size.x` to compensate for the 2\u00D7-wide cache canvas. */\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.drawImage(\n\t\t\tthis.image,\n\t\t\tthis.entity.pos.x + offset.x - this.size.x,\n\t\t\tthis.entity.pos.y + offset.y,\n\t\t);\n\t}\n\n\t/** Advance the timer; when it crosses `current.timing`, step to the next frame, fire any `onFrame[index]` callback, and on rollover fire `onEnd` and queue `lastPlayed` (set by {@link playOnce}). No-op when {@link active} is `false`. */\n\tpublic update(dt: number): void {\n\t\tif (!this.active) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer += dt;\n\n\t\tif (this.timer <= this.current.timing) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer -= this.current.timing;\n\t\tthis.imageId++;\n\n\t\t// on animation end / no more sprites\n\t\tif (this.imageId >= this.current.sprites.length) {\n\t\t\tconst onEnd = this.onEnd;\n\t\t\tthis.onEnd = undefined;\n\t\t\tthis.onFrame = undefined;\n\t\t\tthis.imageId = 0;\n\n\t\t\tconst versionBefore = this.playVersion;\n\t\t\tonEnd?.();\n\t\t\tif (this.playVersion !== versionBefore) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.lastPlayed) {\n\t\t\t\tthis.play(this.lastPlayed);\n\t\t\t\tthis.lastPlayed = undefined;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.current.sprites.length === 1) {\n\t\t\t\tthis.active = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.onFrame?.[this.imageId]) {\n\t\t\tconst cb = this.onFrame[this.imageId];\n\t\t\tdelete this.onFrame[this.imageId];\n\n\t\t\tconst versionBefore = this.playVersion;\n\t\t\tcb();\n\t\t\tif (this.playVersion !== versionBefore) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.active) {\n\t\t\tthis.setImage();\n\t\t}\n\t}\n\n\t/** Register a new animation. Logs an error (but still registers) if `defaultAnim` is true while another default already exists, or if `name` collides with an existing animation. Auto-plays the new animation when `defaultAnim` is `true`. */\n\tpublic add(\n\t\tname: string,\n\t\tsprites: HTMLCanvasElement[] | HTMLImageElement[],\n\t\ttiming: number,\n\t\tdefaultAnim = false,\n\t): void {\n\t\tif (\n\t\t\tdefaultAnim &&\n\t\t\tthis.animations.some((anim: SpriteAnimation) => anim.default)\n\t\t) {\n\t\t\tconsole.error(\"Only one default animation allowed!\");\n\t\t}\n\n\t\tif (\n\t\t\tthis.animations.some((anim: SpriteAnimation) => anim.name === name)\n\t\t) {\n\t\t\tconsole.error(\"Duplicate animation name!\");\n\t\t}\n\n\t\tthis.animations.push({\n\t\t\tdefault: defaultAnim,\n\t\t\tname,\n\t\t\tsprites,\n\t\t\ttiming,\n\t\t});\n\n\t\tif (defaultAnim) {\n\t\t\tthis.play(name);\n\t\t}\n\t}\n\n\t/** Convenience wrapper around {@link add} that takes a packed {@link SpriteAnimation}. `defaultAnim` is OR'd with `anim.default`. */\n\tpublic addAnimation(anim: SpriteAnimation, defaultAnim = false): void {\n\t\tthis.add(\n\t\t\tanim.name,\n\t\t\tanim.sprites,\n\t\t\tanim.timing,\n\t\t\tanim.default || defaultAnim,\n\t\t);\n\t}\n\n\t/** Draw the current frame rotated by `angle` radians around a sprite-relative pivot (75% width, 50% height). Uses `setTransform` and resets the transform on exit. */\n\tpublic drawRotated(\n\t\tcontext: CanvasRenderingContext2D,\n\t\tangle: number,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tconst x = this.entity.pos.x + offset.x;\n\t\tconst y = this.entity.pos.y + offset.y;\n\t\tconst w = this.image.width * 0.75;\n\t\tconst h = this.image.height * 0.5;\n\t\tcontext.setTransform(1, 0, 0, 1, x + w - this.size.x, y + h);\n\t\tcontext.rotate(angle);\n\t\tcontext.drawImage(this.image, -w, -h);\n\t\tcontext.setTransform(1, 0, 0, 1, 0, 0);\n\t}\n\n\t/** Switch to the named animation, rewinding timer and frame index. Optionally register `onEnd` (fires after the last frame) and `onFrame` (frame-indexed callbacks). Any previous {@link Animator.onEnd} fires before the new one is set. Throws if `name` isn't registered. */\n\tpublic play(name: string, onEnd?: onEndType, onFrame?: onFrameType): void {\n\t\tconst index = this.animations.findIndex(\n\t\t\t(anim: SpriteAnimation) => anim.name === name,\n\t\t);\n\n\t\tif (index < 0) {\n\t\t\tthrow new Error(`Animator.play: animation \"${name}\" not found`);\n\t\t}\n\n\t\tthis.playVersion++;\n\t\tconst myVersion = this.playVersion;\n\n\t\tthis.imageId = 0;\n\t\tthis.timer = 0;\n\t\tthis.currentAnimation = index;\n\t\tthis.setImage();\n\n\t\tconst prevOnEnd = this.onEnd;\n\t\tthis.onEnd = onEnd;\n\t\tthis.onFrame = onFrame;\n\t\tprevOnEnd?.();\n\n\t\tif (this.playVersion !== myVersion) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active = true;\n\t}\n\n\t/** {@link play} only if `name` isn't already the current animation. Returns `true` if it started a new playback, `false` if it was already playing. */\n\tpublic playIfNot(\n\t\tname: string,\n\t\tonEnd?: onEndType,\n\t\tonFrame?: onFrameType,\n\t): boolean {\n\t\tif (!this.isPlaying(name)) {\n\t\t\tthis.play(name, onEnd, onFrame);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/** Queue an animation to play once the current one finishes. Pass `undefined` to cancel the queue. Used internally by {@link playOnce}. */\n\tpublic playNextOnce(name: string | undefined): void {\n\t\tthis.lastPlayed = name;\n\t}\n\n\t/**\n\t * Play `name` once, then return to the previously-playing animation. Calling with the currently-playing name re-loops it indefinitely (lastPlayed restores to itself).\n\t */\n\tpublic playOnce(\n\t\tname: string,\n\t\tonEnd?: onEndType,\n\t\tonFrame?: onFrameType,\n\t): void {\n\t\tthis.lastPlayed = this.current?.name;\n\t\tthis.play(name, onEnd, onFrame);\n\t}\n\n\t/** Randomize the frame timer to a value in `[0, current.timing)`. Useful when spawning many instances of the same animation to break phase lockstep. */\n\tpublic randomTimer(): void {\n\t\tthis.timer = randomBetweenFloat(0, this.current.timing);\n\t}\n\n\t/** Drop every registered animation and clear this instance's cached frames. {@link active} resets to `true`; pending callbacks are cleared. */\n\tpublic removeAllAnimations(): void {\n\t\tthis.animations.length = 0;\n\t\tthis.active = true;\n\t\tthis.onEnd = undefined;\n\t\tthis.onFrame = undefined;\n\t\tAnimator.clearSpriteCache(this.namespace);\n\t}\n\n\t/** Switch back to the default animation if one was registered (marked via `defaultAnim`); otherwise just stop animating ({@link active} = `false`). */\n\tpublic reset(): void {\n\t\tconst defaultAnim = this.animations.find(\n\t\t\t(anim: SpriteAnimation) => anim.default,\n\t\t);\n\n\t\tif (defaultAnim) {\n\t\t\tthis.play(defaultAnim.name);\n\t\t\tthis.active = true;\n\t\t} else {\n\t\t\tthis.active = false;\n\t\t}\n\t}\n\n\t/** `true` when `name` matches the currently-playing animation. */\n\tpublic isPlaying(name: string): boolean {\n\t\treturn this.current && this.current.name === name;\n\t}\n\n\t/**\n\t * Update `image` and `size` from the current sprite. Assumes uniform sprite size within an animation. Caches rendered canvases per (animation, frame, lookLeft) \u2014 if you mutate `entity.flipX` after first render, call `removeAllAnimations()` or recreate the Animator to invalidate.\n\t */\n\tprotected setImage(): void {\n\t\tconst animation = this.current;\n\t\tconst sprite = animation.sprites[this.imageId];\n\t\tthis.size.set(sprite.width, sprite.height);\n\n\t\tif (this.entity.flipX === undefined) {\n\t\t\tthis.entity.flipX = this.size.x;\n\t\t}\n\n\t\tconst key = `${this.namespace}.${animation.name}`;\n\t\tlet cache = Animator.spriteCache.get(key);\n\t\tif (!cache) {\n\t\t\tcache = { unflipped: [], flipped: [] };\n\t\t\tAnimator.spriteCache.set(key, cache);\n\t\t}\n\n\t\tconst bucket = this.lookLeft ? cache.flipped : cache.unflipped;\n\n\t\tif (!bucket[this.imageId]) {\n\t\t\tconst cc = createNewCanvas(this.size.x * 2, this.size.y);\n\t\t\tcc.context.translate(\n\t\t\t\tthis.size.x + (this.lookLeft ? this.entity.flipX : 0),\n\t\t\t\t0,\n\t\t\t);\n\t\t\tif (this.lookLeft) {\n\t\t\t\tcc.context.scale(-1, 1);\n\t\t\t}\n\t\t\tcc.context.drawImage(sprite, 0, 0);\n\t\t\tbucket[this.imageId] = cc.canvas;\n\t\t}\n\n\t\tthis.image = bucket[this.imageId];\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Controller from \"@/input/Controller\";\n\n/**\n * On-screen crosshairs driven by a {@link Controller}'s analog sticks. Each anchor in `sticks` gets its own crosshair that follows the corresponding stick's deflection with frame-rate-independent exponential smoothing (50 ms half-life). The caller owns the anchor positions and the crosshair image \u2014 any `CanvasImageSource` works (a loaded `HTMLImageElement`, a procedurally-drawn `HTMLCanvasElement`, an `ImageBitmap`, \u2026).\n *\n * {@link update} polls the controller for you; don't call {@link Controller.poll} again from the same `update` step.\n */\nexport default class ControllerCursor {\n\tprivate controller: Controller;\n\tprivate crosshair: CanvasImageSource;\n\tprivate range: number;\n\tprivate sticks: { pos: Vec2; offset: Vec2 }[] = [];\n\n\t/**\n\t * @param controller Gamepad input source.\n\t * @param crosshair Drawn at each cursor position via `CanvasRenderingContext2D.drawImage`. The image's top-left is the draw origin \u2014 center the visible reticle inside the image, or offset the anchors to compensate.\n\t * @param sticks Anchor positions, one per stick to track. Cloned at construction so caller mutation is harmless.\n\t * @param range Max pixel deflection from anchor at full stick. Default `80`.\n\t */\n\tconstructor(\n\t\tcontroller: Controller,\n\t\tcrosshair: CanvasImageSource,\n\t\tsticks: Vec2[],\n\t\trange = 80,\n\t) {\n\t\tthis.controller = controller;\n\t\tthis.crosshair = crosshair;\n\t\tthis.range = range;\n\n\t\tsticks.forEach(stick =>\n\t\t\tthis.sticks.push({ pos: stick.clone(), offset: new Vec2() }),\n\t\t);\n\t}\n\n\t/** Draw a crosshair at `anchor + offset` for each tracked stick. */\n\tpublic draw(context: CanvasRenderingContext2D): void {\n\t\tthis.sticks.forEach(stick => {\n\t\t\tcontext.drawImage(\n\t\t\t\tthis.crosshair,\n\t\t\t\tstick.pos.x + stick.offset.x,\n\t\t\t\tstick.pos.y + stick.offset.y,\n\t\t\t);\n\t\t});\n\t}\n\n\t/** Pull fresh stick state via {@link Controller.poll} and smooth each crosshair's offset toward `stickAxis * range`. Frame-rate independent \u2014 50 ms to cover half the remaining distance. */\n\tpublic update(dt: number): void {\n\t\tconst alpha = 1 - Math.pow(0.5, dt / 0.05);\n\t\tthis.controller.poll().forEach((axi, index) => {\n\t\t\tconst offset = this.sticks[index].offset;\n\t\t\toffset.x += (axi.x * this.range - offset.x) * alpha;\n\t\t\toffset.y += (axi.y * this.range - offset.y) * alpha;\n\t\t});\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\nimport { random2Pi, randomBetweenInt } from \"@/utilities/Math\";\n\n/**\n * Single particle drawn as a filled circle. The constructor seeds a random velocity (random angle, per-axis speed in `[50, 150]` px/s) and a random `maxLifeTime` in `[0.5, 1.5]` s \u2014 spawn many at once for spark/dust effects. Each tick `update(dt)` advances `lifetime` and `pos`; the particle is \"dead\" when {@link alive} flips to `false`.\n */\nexport default class Particle {\n\t/** CSS color string passed to `context.fillStyle` in {@link draw}. */\n\tprotected color: string;\n\t/** Accumulated time (seconds) since spawn or last {@link resetLifetime}. */\n\tprotected lifetime: number = 0;\n\t/** Lifetime cap in seconds, randomized to `[0.5, 1.5]` at construction. */\n\tprotected maxLifeTime: number;\n\t/** Top-left position. Cloned from the constructor arg so the caller's `Vec2` isn't aliased. */\n\tprotected pos: Vec2;\n\t/** Circle radius (pixels). */\n\tprotected size: number;\n\t/** Velocity in px/s. Seeded randomly by the constructor (random angle, random magnitude per axis). */\n\tprotected vel: Vec2;\n\t/** Backing storage for the {@link rect} getter. Subclasses can read it; the public-facing accessor is {@link rect}. */\n\tprotected _rect: Rect;\n\n\t/** `false` once {@link lifetime} reaches {@link maxLifeTime}. Owners typically filter dead particles out of their list each frame, or call {@link resetLifetime} to recycle. */\n\tpublic get alive(): boolean {\n\t\treturn this.lifetime < this.maxLifeTime;\n\t}\n\n\t/** Read-only AABB tracking `pos` and the particle's `size`. Recomputed each {@link update}. */\n\tpublic get rect(): Readonly<Rect> {\n\t\treturn this._rect;\n\t}\n\n\tconstructor(pos: Vec2, color: string, size: number = 2) {\n\t\tthis.pos = pos.clone();\n\t\tthis.color = color;\n\t\tthis.size = size;\n\n\t\tthis._rect = pos.toRectAddSize(size);\n\n\t\tthis.vel = Vec2.fromAngle(\n\t\t\trandom2Pi(),\n\t\t\trandomBetweenInt(50, 150),\n\t\t\trandomBetweenInt(50, 150),\n\t\t);\n\n\t\tthis.maxLifeTime = 0.5 + Math.random();\n\t}\n\n\t/** Fill a circle at `pos + offset` using {@link color}. `offset` is useful for shifting by a camera/world transform without mutating `pos`. */\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.fillStyle = this.color;\n\t\tcontext.drawCircle(\n\t\t\t{\n\t\t\t\tx: this.pos.x + offset.x,\n\t\t\t\ty: this.pos.y + offset.y,\n\t\t\t},\n\t\t\tthis.size,\n\t\t\t\"fill\",\n\t\t);\n\t}\n\n\t/** Integrate lifetime, position, and bounding rect. */\n\tpublic update(dt: number): void {\n\t\tthis.lifetime += dt;\n\t\tthis.pos.x += this.vel.x * dt;\n\t\tthis.pos.y += this.vel.y * dt;\n\t\tthis._rect.set(this.pos.x, this.pos.y);\n\t}\n\n\t/** Recycle a dead particle by subtracting `maxLifeTime` from `lifetime` \u2014 preserves any overshoot so a pool of pre-allocated particles can stay phase-stable across loops. Note this doesn't re-randomize `vel` or `pos`; mutate those externally if you want a fresh trajectory. */\n\tpublic resetLifetime(): void {\n\t\tthis.lifetime -= this.maxLifeTime;\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\n\n/**\n * A self-propelled sprite \u2014 `update(dt)` advances `pos` along `vel * speed`, accumulates `lifetime`, and flips {@link alive} to `false` once `lifetime >= maxLifetime`. The image is pre-baked to a rotated canvas matching the velocity direction; call {@link rebuildRotation} after re-aiming.\n *\n * The `T` generic types the optional {@link payload} so callers can attach typed metadata (damage, owner, etc.) without losing inference.\n */\nexport default class Projectile<T = unknown> {\n\t/** Seconds after which {@link alive} flips to `false`. Defaults to `Infinity` \u2014 no natural expiry. */\n\tpublic maxLifetime = Infinity;\n\t/** Caller-supplied data. Typed via the class generic so consumers can read `projectile.payload` without casting. */\n\tpublic payload?: T;\n\t/** Magnitude multiplier applied to `vel` each update: `pos += vel * speed * dt`. Pass a unit-length `vel` to make this read as \"pixels per second\". */\n\tpublic speed = 1200;\n\t/** Current pre-rotated sprite. Re-baked by {@link rebuildRotation} from the un-rotated `originalImage`. */\n\tprotected image!: HTMLCanvasElement;\n\t/** Accumulated time (seconds). Drives the {@link alive} check against {@link maxLifetime}. */\n\tprotected lifetime = 0;\n\t/** Top-left position. Cloned from the constructor arg so the caller's `Vec2` isn't aliased. */\n\tprotected pos: Vec2;\n\t/** Current sprite rotation in radians, kept in sync with `vel` by {@link rebuildRotation}. */\n\tprotected rotation = 0;\n\t/** Velocity direction vector. Multiplied by {@link speed} each update \u2014 pass a unit vector for `speed`-as-px-per-second semantics. Cloned from the constructor arg. */\n\tprotected vel: Vec2;\n\t/** Backing storage for the {@link rect} getter. Subclasses can read it; mutate via `pos`/{@link rebuildRotation} instead of touching it directly. */\n\tprotected _rect: Rect;\n\tprivate originalImage: HTMLCanvasElement;\n\n\t/** `false` once {@link lifetime} reaches {@link maxLifetime}. Owners typically filter dead projectiles out of their list each frame. */\n\tpublic get alive(): boolean {\n\t\treturn this.lifetime < this.maxLifetime;\n\t}\n\n\t/** Read-only AABB tracking `pos` and the (rotated) image size. Recomputed in {@link update} and {@link rebuildRotation}. */\n\tpublic get rect(): Readonly<Rect> {\n\t\treturn this._rect;\n\t}\n\n\tconstructor(pos: Vec2, image: HTMLCanvasElement, vel: Vec2 = new Vec2()) {\n\t\tthis.pos = pos.clone();\n\t\tthis.originalImage = image;\n\t\tthis.vel = vel.clone();\n\n\t\tthis._rect = pos.toRectAddSize(image.width, image.height);\n\n\t\tthis.rebuildRotation();\n\t}\n\n\t/** Blit the pre-rotated image at `pos + offset`. `offset` is useful for shifting by a camera/world transform without mutating `pos`. */\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tcontext.drawImage(\n\t\t\tthis.image,\n\t\t\tthis.pos.x + offset.x,\n\t\t\tthis.pos.y + offset.y,\n\t\t);\n\t}\n\n\t/** Integrate motion and advance lifetime. Doesn't re-bake the rotation \u2014 call {@link rebuildRotation} after mutating `vel`. */\n\tpublic update(dt: number): void {\n\t\tthis.lifetime += dt;\n\n\t\tthis.pos.x += this.vel.x * this.speed * dt;\n\t\tthis.pos.y += this.vel.y * this.speed * dt;\n\n\t\tthis._rect.set(this.pos.x, this.pos.y);\n\t}\n\n\t/**\n\t * Re-bake the sprite to match the current `vel` direction (rotation = `atan2(vel.y, vel.x)`) and update `rect` to the new bounds. Allocates a fresh rotated canvas every call \u2014 no internal cache, so heavy re-aiming (homing/seeking) is a candidate for adding quantized caching.\n\t */\n\tpublic rebuildRotation(): void {\n\t\tthis.rotation = Math.atan2(this.vel.y, this.vel.x);\n\t\tthis.image = this.originalImage.rotateBy(this.rotation);\n\t\tthis._rect.w = this.image.width;\n\t\tthis._rect.h = this.image.height;\n\t}\n\n\t/** Force {@link alive} to `false` immediately (sets `lifetime` past `maxLifetime`). Use when the projectile should die on collision/impact, not from natural expiry. */\n\tpublic remove(): void {\n\t\tthis.lifetime = this.maxLifetime * 2;\n\t}\n}\n", "import EventSystem from \"./EventSystem\";\nimport Settings from \"@/core/Settings\";\nimport Vec2 from \"@/math/Vec2\";\nimport { type CanvasConstruct, getCanvasConstruct } from \"@/utilities/Canvas\";\n\n/** Role tags for canvases passed to {@link CanvasManager.setupCanvas}. Only `MAIN` is enforced (exactly one); the others are free-form labels you can use to group background/overlay canvases. */\nexport const CANVAS_TYPES = {\n\t/** Catch-all tag for canvases without a specific role. */\n\tANY: Symbol(\"any\"),\n\t/** Generic placeholder tag \u2014 distinct from `ANY` so consumers can differentiate. */\n\tDEFAULT: Symbol(\"default\"),\n\t/** Background canvas (drawn behind the main one). */\n\tBACKGROUND: Symbol(\"background\"),\n\t/** Primary render target. Exactly one canvas must be registered with this type before {@link CanvasManager.finishSetup}. */\n\tMAIN: Symbol(\"main\"),\n} as const;\n\n/** Entry stored in {@link CanvasManager.canvasHolder} for each registered canvas. */\nexport interface CanvasHolder extends CanvasConstruct {\n\t/** Selector the canvas was registered under (also the map key). */\n\tid: string;\n\t/** Whether this canvas participates in {@link CanvasManager.resize} (rescaled to fit the window while preserving its buffer aspect ratio). */\n\tresize: boolean;\n\t/** Role tag \u2014 one of {@link CANVAS_TYPES}. */\n\ttype: symbol;\n}\n\n/**\n * Tracks registered canvases and exposes the main 2D context. The width/height accessors and `size` getter all refer to the **buffer** dimensions (the canvas's `width`/`height` attributes \u2014 drawing-space pixels), while {@link resizedSize} and {@link ratio} describe the **display** size after CSS scaling.\n *\n * Owned by `Game` (`game.canman`). Lifecycle: subclass registers canvases via {@link setupCanvas} in its constructor, then `preInit()` calls {@link finishSetup}.\n */\nexport default class CanvasManager {\n\t/** Cached `getBoundingClientRect()` of the main canvas. Refreshed in {@link resize}. Used to map pointer client coords into canvas space. */\n\tpublic canvasBoundingClientRect!: DOMRect;\n\t/** Registry of every {@link setupCanvas}-registered canvas, keyed by selector. */\n\tpublic canvasHolder: Record<string, CanvasHolder> = {};\n\t/** Display-to-buffer scale factor after the last {@link resize} (`displayWidth / bufferWidth`). `1` until the first resize. */\n\tpublic ratio = 1;\n\t/** Display (CSS-pixel) size of the main canvas after the last {@link resize}. Independent of the buffer dimensions in {@link width}/{@link height}. */\n\tpublic resizedSize: Vec2 = new Vec2();\n\tprivate mainHolder!: CanvasHolder;\n\n\t/** Main canvas element (the one registered with `CANVAS_TYPES.MAIN`). */\n\tpublic get canvas(): HTMLCanvasElement {\n\t\treturn this.mainHolder.canvas;\n\t}\n\n\t/** Main canvas 2D rendering context. */\n\tpublic get canvasContext(): CanvasRenderingContext2D {\n\t\treturn this.mainHolder.context;\n\t}\n\n\t/** Main canvas **buffer** height (the drawing surface, not the CSS display size). */\n\tpublic get height(): number {\n\t\treturn this.canvas.height;\n\t}\n\n\t/** Main canvas **buffer** height (the drawing surface, not the CSS display size). */\n\tpublic set height(height: number) {\n\t\tthis.canvas.height = height;\n\t}\n\n\t/** Main canvas buffer dimensions as a new `Vec2`. */\n\tpublic get size(): Vec2 {\n\t\treturn new Vec2(this.width, this.height);\n\t}\n\n\t/** Main canvas **buffer** width (the drawing surface, not the CSS display size). */\n\tpublic get width(): number {\n\t\treturn this.canvas.width;\n\t}\n\n\t/** Main canvas **buffer** width (the drawing surface, not the CSS display size). */\n\tpublic set width(width: number) {\n\t\tthis.canvas.width = width;\n\t}\n\n\t/** Finalize the canvas registry. Called once by `Game.preInit()`. Validates that exactly one `CANVAS_TYPES.MAIN` canvas is registered and that its buffer is non-zero, caches its bounding rect, and wires the `\"resized\"` listener if `Settings.enableResize`. Throws on duplicate calls or invalid registry state. */\n\tpublic finishSetup(): void {\n\t\tif (this.mainHolder) {\n\t\t\tthrow new Error(\"Already set up.\");\n\t\t}\n\n\t\tconst mainCanvas = Object.values(this.canvasHolder).filter(\n\t\t\tholder => holder.type === CANVAS_TYPES.MAIN,\n\t\t);\n\n\t\tif (mainCanvas.length === 0) {\n\t\t\tthrow new Error(\"No main canvas defined!\");\n\t\t}\n\n\t\tif (mainCanvas.length > 1) {\n\t\t\tthrow new Error(\"Multiple main canvas defined!\");\n\t\t}\n\n\t\tthis.mainHolder = mainCanvas[0];\n\n\t\tif (this.width === 0 || this.height === 0) {\n\t\t\tthrow new Error(\"Main canvas has zero width or height.\");\n\t\t}\n\n\t\tthis.canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\n\t\tif (Settings.enableResize) {\n\t\t\tEventSystem.addEventListener(\"resized\", (): void => this.resize());\n\t\t}\n\t}\n\n\t/** Rescale every opt-in canvas (`holder.resize === true`) to fit the window while preserving its buffer aspect ratio. Updates `style.width`/`style.height` only \u2014 buffer dimensions don't change. Refreshes {@link canvasBoundingClientRect}, {@link resizedSize}, and {@link ratio} from the main canvas. */\n\tpublic resize(): void {\n\t\tconst windowRatio = window.innerHeight / window.innerWidth;\n\n\t\tObject.values(this.canvasHolder).forEach(ch => {\n\t\t\tif (!ch.resize) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst canvasRatio = ch.canvas.height / ch.canvas.width;\n\t\t\tlet width: number;\n\t\t\tlet height: number;\n\n\t\t\tif (windowRatio < canvasRatio) {\n\t\t\t\theight = window.innerHeight;\n\t\t\t\twidth = height / canvasRatio;\n\t\t\t} else {\n\t\t\t\twidth = window.innerWidth;\n\t\t\t\theight = width * canvasRatio;\n\t\t\t}\n\n\t\t\tif (ch.canvas === this.canvas) {\n\t\t\t\tthis.resizedSize = new Vec2(width, height);\n\t\t\t\tthis.ratio = width / this.width;\n\t\t\t}\n\n\t\t\tch.canvas.style.width = width + \"px\";\n\t\t\tch.canvas.style.height = height + \"px\";\n\t\t});\n\n\t\tthis.canvasBoundingClientRect = this.canvas.getBoundingClientRect();\n\t}\n\n\t/** Set the main context's `font` to `${size}px \"${font}\"`. Defaults the family to `Settings.font`. */\n\tpublic setFontSize(size: number, font: string = Settings.font): void {\n\t\tthis.canvasContext.font = `${size}px \"${font}\"`;\n\t}\n\n\t/** Register a canvas at `selector` with the given role tag. Initializes its context (`fillStyle`/`strokeStyle` = white, font = `12px Arial`) and returns the {@link CanvasHolder}. `resize` defaults to `Settings.enableResize`. Throws if the selector doesn't match an element or has already been registered. */\n\tpublic setupCanvas(\n\t\tcanvasType: symbol,\n\t\tselector: string,\n\t\tresize: boolean = Settings.enableResize,\n\t): CanvasHolder {\n\t\tif (!document.querySelector(selector)) {\n\t\t\tthrow new Error(\"Canvas '\" + selector + \"' does not exist!\");\n\t\t}\n\n\t\tif (this.canvasHolder[selector]) {\n\t\t\tthrow new Error(`Canvas \"${selector}\" was already registered!`);\n\t\t}\n\n\t\tconst newCanvas: CanvasHolder = Object.assign(\n\t\t\t{},\n\t\t\tgetCanvasConstruct(selector),\n\t\t\t{\n\t\t\t\tid: selector,\n\t\t\t\tresize,\n\t\t\t\ttype: canvasType,\n\t\t\t},\n\t\t);\n\t\tnewCanvas.context.fillStyle = \"white\";\n\t\tnewCanvas.context.strokeStyle = \"white\";\n\t\tnewCanvas.context.font = \"12px Arial\";\n\n\t\tthis.canvasHolder[selector] = newCanvas;\n\n\t\treturn newCanvas;\n\t}\n}\n", "import EventSystem from \"./EventSystem\";\nimport Settings from \"./Settings\";\nimport type Game from \"./Game\";\nimport { rafLoop } from \"@/utilities/Functions\";\n\n/** rAF gaps larger than this (s) reset the accumulator instead of running catch-up steps \u2014 keeps a backgrounded tab or paused debugger from fast-forwarding the simulation on resume. */\nexport const MAX_DT_SECONDS = 0.25;\n/** Hard cap on update steps per rendered frame. If simulation can't keep up, it falls behind in `levelTime` rather than blocking the main thread. */\nexport const MAX_STEPS_PER_FRAME = 5;\n\n/**\n * Fixed-step game loop. Owned by `Game` (`game.gameloop`) \u2014 usually started automatically by `preInit()` when `Settings.autoloop` is `true`. Each rendered frame:\n *\n * 1. Accumulates real time\n * 2. Runs `game.update(Settings.fps)` zero-or-more times until the accumulator is drained (bounded by {@link MAX_STEPS_PER_FRAME} to avoid runaway catch-up)\n * 3. Clears the canvas (per `Settings.doNotClear` / `Settings.useClearRect`) and calls `game.draw(context)`\n *\n * Fires the {@link EventSystem} `\"gameloopStopped\"` event when teardown completes (not when {@link stopLoop} is called).\n */\nexport default class Gameloop {\n\t/** Simulation time in milliseconds. Advances by `Settings.fps * 1000` per update step, so it reflects simulated time, not wall-clock \u2014 paused/dropped frames don't add. Use this for time-driven spawning, animations, etc. */\n\tpublic levelTime = 0;\n\tprivate _isLooping = false;\n\tprivate accumulator = 0;\n\tprivate game: Game;\n\tprivate stop = false;\n\n\t/** `true` while the rAF callback is registered. Goes `false` only after the final frame fires the `\"gameloopStopped\"` event. */\n\tpublic get isLooping(): boolean {\n\t\treturn this._isLooping;\n\t}\n\n\tconstructor(game: Game) {\n\t\tthis.game = game;\n\t}\n\n\t/** Begin the rAF loop. Throws if {@link stopLoop} was called but teardown hasn't completed yet \u2014 wait for the `\"gameloopStopped\"` event before restarting. */\n\tpublic startLoop(): void {\n\t\tif (this._isLooping && this.stop) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Gameloop teardown is pending; wait for the \\\"gameloopStopped\\\" event before restarting.\",\n\t\t\t);\n\t\t}\n\n\t\tthis.stop = false;\n\t\tthis.looper();\n\t}\n\n\t/** Request that the loop stop on its next tick. Asynchronous \u2014 the loop tears down on the following frame and dispatches `\"gameloopStopped\"` when done. */\n\tpublic stopLoop(): void {\n\t\tthis.stop = true;\n\t}\n\n\tprivate draw(context: CanvasRenderingContext2D): void {\n\t\tif (!Settings.doNotClear) {\n\t\t\tif (Settings.useClearRect) {\n\t\t\t\tcontext.clearRect(\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.game.canman.canvas.width,\n\t\t\t\t\tthis.game.canman.canvas.height,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tcontext.fillStyle = Settings.backgroundColor;\n\t\t\t\tcontext.fillRect(\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tthis.game.canman.canvas.width,\n\t\t\t\t\tthis.game.canman.canvas.height,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.game.draw(context);\n\t}\n\n\tprivate looper(): void {\n\t\tif (this._isLooping) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isLooping = true;\n\t\tconst context = this.game.canman.canvasContext;\n\n\t\tconst stopLoop = rafLoop(dt => {\n\t\t\tif (this.stop) {\n\t\t\t\tthis._isLooping = false;\n\t\t\t\tEventSystem.dispatchEvent(\"gameloopStopped\");\n\t\t\t\tconsole.log(\"Simulation stopped.\");\n\t\t\t\tstopLoop();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Snap on big gaps (tab backgrounded, debugger break) \u2014 running\n\t\t\t// many updates to catch up would fast-forward the player.\n\t\t\tif (dt > MAX_DT_SECONDS) {\n\t\t\t\tthis.accumulator = 0;\n\t\t\t} else {\n\t\t\t\tthis.accumulator += dt;\n\t\t\t}\n\n\t\t\tlet steps = MAX_STEPS_PER_FRAME;\n\t\t\twhile (steps-- > 0 && this.accumulator >= Settings.fps) {\n\t\t\t\tthis.game.update(Settings.fps);\n\t\t\t\tthis.accumulator -= Settings.fps;\n\t\t\t\tthis.levelTime += Settings.fps * 1000;\n\t\t\t}\n\n\t\t\tthis.draw(context);\n\t\t});\n\n\t\tconsole.log(\"Simulation started.\");\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport Settings from \"@/core/Settings\";\nimport type Game from \"@/core/Game\";\n\n/** `KeyboardEvent.code` constants for the keys Gleam tracks by name. Use as the argument to {@link Keyboard.isPressed} / {@link Keyboard.stopPress} or as a string key into {@link Keyboard.keys}. */\nexport const KEYBOARD_KEYS = {\n\t/** Digit row `0`. */\n\tKEY_0: \"Digit0\",\n\t/** Digit row `1`. */\n\tKEY_1: \"Digit1\",\n\t/** Digit row `2`. */\n\tKEY_2: \"Digit2\",\n\t/** Digit row `3`. */\n\tKEY_3: \"Digit3\",\n\t/** Digit row `4`. */\n\tKEY_4: \"Digit4\",\n\t/** Digit row `5`. */\n\tKEY_5: \"Digit5\",\n\t/** Digit row `6`. */\n\tKEY_6: \"Digit6\",\n\t/** Digit row `7`. */\n\tKEY_7: \"Digit7\",\n\t/** Digit row `8`. */\n\tKEY_8: \"Digit8\",\n\t/** Digit row `9`. */\n\tKEY_9: \"Digit9\",\n\t/** Letter `A`. */\n\tKEY_A: \"KeyA\",\n\t/** Letter `B`. */\n\tKEY_B: \"KeyB\",\n\t/** Letter `C`. */\n\tKEY_C: \"KeyC\",\n\t/** Letter `D`. */\n\tKEY_D: \"KeyD\",\n\t/** Down arrow. */\n\tKEY_DOWN: \"ArrowDown\",\n\t/** Letter `E`. */\n\tKEY_E: \"KeyE\",\n\t/** Enter / Return. */\n\tKEY_ENTER: \"Enter\",\n\t/** Escape. Note: in `Settings.debug` mode this stops the gameloop. */\n\tKEY_ESCAPE: \"Escape\",\n\t/** Letter `F`. */\n\tKEY_F: \"KeyF\",\n\t/** Letter `G`. */\n\tKEY_G: \"KeyG\",\n\t/** Letter `H`. */\n\tKEY_H: \"KeyH\",\n\t/** Letter `I`. */\n\tKEY_I: \"KeyI\",\n\t/** Letter `J`. */\n\tKEY_J: \"KeyJ\",\n\t/** Letter `K`. */\n\tKEY_K: \"KeyK\",\n\t/** Letter `L`. */\n\tKEY_L: \"KeyL\",\n\t/** Left arrow. */\n\tKEY_LEFT: \"ArrowLeft\",\n\t/** Letter `M`. */\n\tKEY_M: \"KeyM\",\n\t/** Letter `N`. */\n\tKEY_N: \"KeyN\",\n\t/** Letter `O`. */\n\tKEY_O: \"KeyO\",\n\t/** Letter `P`. */\n\tKEY_P: \"KeyP\",\n\t/** Letter `Q`. */\n\tKEY_Q: \"KeyQ\",\n\t/** Letter `R`. */\n\tKEY_R: \"KeyR\",\n\t/** Right arrow. */\n\tKEY_RIGHT: \"ArrowRight\",\n\t/** Letter `S`. */\n\tKEY_S: \"KeyS\",\n\t/** Space bar. */\n\tKEY_SPACE: \"Space\",\n\t/** Letter `T`. */\n\tKEY_T: \"KeyT\",\n\t/** Tab. */\n\tKEY_TAB: \"Tab\",\n\t/** Letter `U`. */\n\tKEY_U: \"KeyU\",\n\t/** Up arrow. */\n\tKEY_UP: \"ArrowUp\",\n\t/** Letter `V`. */\n\tKEY_V: \"KeyV\",\n\t/** Letter `W`. */\n\tKEY_W: \"KeyW\",\n\t/** Letter `X`. */\n\tKEY_X: \"KeyX\",\n\t/** Letter `Y`. */\n\tKEY_Y: \"KeyY\",\n\t/** Letter `Z`. */\n\tKEY_Z: \"KeyZ\",\n} as const;\n\n/**\n * Keyboard state. Wired into `Game` automatically. The preferred way to consume input is to poll {@link isPressed} from `update` \u2014 game input is held-state-based (\"is W held this frame?\"), and combining with {@link stopPress} handles one-shot actions cleanly. The {@link EventSystem} `\"inputKeyboard\"` event (payload: `(keys, code, pressed)`) is available for cases that genuinely need edge-triggered handling.\n *\n * State is cleared on `window` blur and on `gameloopStopped` so held keys don't stay \"pressed\" when focus or the loop is lost. In `Settings.debug` mode, pressing Escape stops the gameloop.\n */\nexport default class Keyboard {\n\t/** Live map of `KeyboardEvent.code` \u2192 pressed state. Codes only appear after the key has been touched at least once; missing codes read as `undefined` (use {@link isPressed} for a safe `boolean`). */\n\tpublic keys: Record<string, boolean> = {};\n\n\tconstructor(game: Game) {\n\t\tconst keyEvent = (event: KeyboardEvent): void => {\n\t\t\tconst code = event.code;\n\n\t\t\tconst pressed = event.type === \"keydown\";\n\t\t\tthis.keys[code] = pressed;\n\n\t\t\tif (\n\t\t\t\tSettings.debug &&\n\t\t\t\tcode === KEYBOARD_KEYS.KEY_ESCAPE &&\n\t\t\t\tpressed\n\t\t\t) {\n\t\t\t\tgame.gameloop.stopLoop();\n\t\t\t}\n\n\t\t\tEventSystem.dispatchEvent(\n\t\t\t\t\"inputKeyboard\",\n\t\t\t\tthis.keys,\n\t\t\t\tcode,\n\t\t\t\tpressed,\n\t\t\t);\n\t\t};\n\n\t\twindow.addEventListener(\"keydown\", keyEvent, false);\n\t\twindow.addEventListener(\"keyup\", keyEvent, false);\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\n\t\tEventSystem.addEventListener(\"gameloopStopped\", () => this.reset());\n\t}\n\n\t/** Mark every tracked key as released. Called automatically on `window` blur and on `gameloopStopped`. */\n\tpublic reset(): void {\n\t\tfor (const key in this.keys) {\n\t\t\tthis.keys[key] = false;\n\t\t}\n\t}\n\n\t/** Mark a single key as released \u2014 used to consume a press so subsequent ticks don't re-trigger one-shot actions while the key is still held. */\n\tpublic stopPress(code: string): void {\n\t\tthis.keys[code] = false;\n\t}\n\n\t/** `true` when `code` is currently held. Safe for untouched keys (returns `false` rather than `undefined`). */\n\tpublic isPressed(code: string): boolean {\n\t\treturn !!this.keys[code];\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport Vec2 from \"@/math/Vec2\";\nimport type Game from \"@/core/Game\";\nimport { clamp } from \"@/utilities/Number\";\n\n/** Button indices that match `PointerEvent.button` and index into {@link Pointer.pressed}. */\nexport const POINTER_KEYS = {\n\t/** Primary button (left for right-handers). */\n\tLEFT: 0,\n\t/** Middle button / wheel click. */\n\tMIDDLE: 1,\n\t/** Secondary button (right for right-handers). */\n\tRIGHT: 2,\n\t/** \"Back\" side button (browser back). */\n\tPREV: 3,\n\t/** \"Forward\" side button. */\n\tFORWARD: 4,\n} as const;\n\n/**\n * Pointer (mouse / pen / touch) state. Wired into `Game` automatically. The preferred way to consume input is to subscribe to the {@link EventSystem} `\"inputPointer\"` event \u2014 it fires on every move and button transition, with this `Pointer` instance as the payload. If you need the latest state on a frame boundary instead, poll `game.pointer.posScaled` and `game.pointer.pressed[POINTER_KEYS.LEFT]` from `update`.\n *\n * Suppresses the browser context menu on right-click globally.\n */\nexport default class Pointer {\n\t/** Dirty bit set to `true` on every move and never cleared by the engine \u2014 flip it back to `false` after reading to detect \"moved since last check\". */\n\tpublic hasMoved = false;\n\t/** Last raw `PointerEvent` received. `null` until any pointer event fires. Use for properties not surfaced as Vec2/booleans (pressure, pointerType, etc.). */\n\tpublic lastEvent: PointerEvent | null = null;\n\t/** Viewport-space coordinates (`event.clientX/Y` \u2014 CSS pixels relative to the page). */\n\tpublic posReal = new Vec2();\n\t/** Previous tick's {@link posReal}. Subtract for a per-frame delta. */\n\tpublic posRealLast = new Vec2();\n\t/** Canvas-space coordinates, mapped from the bounding rect into the main canvas's pixel buffer and clamped to its size. This is the position to use for in-game logic. */\n\tpublic posScaled = new Vec2();\n\t/** Previous tick's {@link posScaled}. */\n\tpublic posScaledLast = new Vec2();\n\t/** Per-button pressed state. Index with {@link POINTER_KEYS} (e.g. `pressed[POINTER_KEYS.LEFT]`). Sparse \u2014 unindexed entries are `undefined`, not `false`. */\n\tpublic pressed: boolean[] = [];\n\tprivate game: Game;\n\n\tconstructor(game: Game) {\n\t\tthis.game = game;\n\n\t\tconst pointerMoveEvent = (event: PointerEvent): void => {\n\t\t\tif (event.target === this.game.canman.canvas) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\tthis.lastEvent = event;\n\t\t\tthis.hasMoved = true;\n\n\t\t\tthis.update(event);\n\n\t\t\tEventSystem.dispatchEvent(\"inputPointer\", this);\n\t\t};\n\n\t\tconst pointerStateChangeEvent = (event: PointerEvent): void => {\n\t\t\tif (event.target === this.game.canman.canvas) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\tthis.lastEvent = event;\n\n\t\t\tthis.pressed[event.button] = event.type === \"pointerdown\";\n\n\t\t\tEventSystem.dispatchEvent(\"inputPointer\", this);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", pointerMoveEvent, false);\n\t\twindow.addEventListener(\"pointerdown\", pointerStateChangeEvent, false);\n\t\twindow.addEventListener(\"pointerup\", pointerStateChangeEvent, false);\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\n\t\t// Attach to `document` (not `canvas`) so HTML UI overlays and any\n\t\t// secondary canvases also get right-click suppressed.\n\t\tdocument.addEventListener(\n\t\t\t\"contextmenu\",\n\t\t\t(event: Event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\t}\n\n\t/** Clear all pressed-button state. Called automatically on `window` blur so held buttons don't stay \"pressed\" forever when focus is lost. */\n\tpublic reset(): void {\n\t\tthis.pressed.length = 0;\n\t}\n\n\tprivate update(event: PointerEvent): void {\n\t\tthis.posRealLast.set(this.posReal.x, this.posReal.y);\n\t\tthis.posReal.set(event.clientX, event.clientY);\n\n\t\tthis.posScaledLast.set(this.posScaled.x, this.posScaled.y);\n\t\tthis.posScaled.set(\n\t\t\tclamp(\n\t\t\t\t(((event.clientX -\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.left) /\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.width) *\n\t\t\t\t\tthis.game.canman.width) |\n\t\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.game.canman.width,\n\t\t\t),\n\t\t\tclamp(\n\t\t\t\t(((event.clientY -\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.top) /\n\t\t\t\t\tthis.game.canman.canvasBoundingClientRect.height) *\n\t\t\t\t\tthis.game.canman.height) |\n\t\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.game.canman.height,\n\t\t\t),\n\t\t);\n\t}\n}\n", "import Settings from \"@/core/Settings\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport { throttleByKey } from \"@/utilities/Functions\";\n\ndeclare global {\n\tinterface Window {\n\t\t/** Translate `key` for the active language. Throws until `prepareLanguage` has run. */\n\t\tt(key: string): string;\n\t}\n}\n\n// non-enumerable own property on the instance.\ndefineMethod(window, \"t\", function (): string {\n\tthrow new Error(\"Call 'prepareLanguage' first!\");\n});\n\nconst logMissingKey = throttleByKey<[string]>((count, key) => {\n\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\tconsole.warn(`\"${key}\" has no translation${suffix}`);\n});\n\nconst logMissingLanguage = throttleByKey<[string, string]>(\n\t(count, current, fallback) => {\n\t\tconst suffix = count > 1 ? ` (x${count} since last log)` : \"\";\n\n\t\tconsole.warn(\n\t\t\t`Language \"${current}\" not found, falling back to \"${fallback}\"${suffix}`,\n\t\t);\n\t},\n);\n\n/** Translation tables keyed by `languageCode \u2192 translationKey \u2192 text` (e.g. `{ en: { hello: \"Hi\" }, de: { hello: \"Hallo\" } }`). */\nexport type Languages = Record<string, Record<string, string>>;\n\n/**\n * Install the global `window.t(key)` translator. Picks the active language from `Settings.localStorage.language` (seeded from `navigator.language` and overridable via `Settings.setLocalStorage(\"language\", ...)`). Falls back to `defaultLanguage` when the active language isn't registered; returns the key itself when a translation is missing. Both fallback cases log a throttled `console.warn`. Logs `console.error` per missing key during preparation if some languages don't cover every key. Throws if `defaultLanguage` isn't in `languages`.\n */\nexport function prepareLanguage(\n\tlanguages: Languages,\n\tdefaultLanguage: string = \"en\",\n): void {\n\tif (!languages[defaultLanguage]) {\n\t\tthrow new Error(\n\t\t\t`Default language is defined as \"${defaultLanguage}\" but isn't supplied!`,\n\t\t);\n\t}\n\n\tconst allKeys: Set<string> = new Set();\n\n\tfor (const lang in languages) {\n\t\tfor (const key in languages[lang]) {\n\t\t\tallKeys.add(key);\n\t\t}\n\t}\n\n\tconst sortedKeys = [...allKeys].sort();\n\n\tfor (const lang in languages) {\n\t\tsortedKeys.forEach(key => {\n\t\t\tif (languages[lang][key] === undefined) {\n\t\t\t\tconsole.error(`\"${lang}\" misses \"${key}\"`);\n\t\t\t}\n\t\t});\n\t}\n\n\tdefineMethod(window, \"t\", function (key): string {\n\t\tconst currentLang = Settings.localStorage.language;\n\n\t\tlet language = languages[currentLang];\n\t\tif (!language) {\n\t\t\tlogMissingLanguage(currentLang, currentLang, defaultLanguage);\n\t\t\tlanguage = languages[defaultLanguage];\n\t\t}\n\n\t\tif (language[key] === undefined) {\n\t\t\tlogMissingKey(key, key);\n\t\t\treturn key;\n\t\t}\n\n\t\treturn language[key];\n\t});\n}\n", "import { defineMethod } from \"@/utilities/Prototype\";\n\n// #region clone\ndeclare global {\n\tinterface HTMLAudioElement {\n\t\t/** Deep-clone this audio element, preserving the current `volume`. */\n\t\tclone(): HTMLAudioElement;\n\t}\n}\n\ndefineMethod(\n\tHTMLAudioElement.prototype,\n\t\"clone\",\n\tfunction (): HTMLAudioElement {\n\t\tconst node = this.cloneNode(true) as HTMLAudioElement;\n\t\tnode.volume = this.volume;\n\t\treturn node;\n\t},\n);\n// #endregion\n\n// #region stop\ndeclare global {\n\tinterface HTMLAudioElement {\n\t\t/** Volume restored by `stop()` after pausing. If unset, `stop()` leaves `volume` as-is. */\n\t\tdefaultVolume?: number;\n\t\t/** Pause playback, reset `currentTime` to 0, and restore `volume` to `defaultVolume` if set. */\n\t\tstop(): void;\n\t}\n}\n\ndefineMethod(HTMLAudioElement.prototype, \"stop\", function (): void {\n\tthis.pause();\n\tthis.currentTime = 0;\n\n\tif (this.defaultVolume !== undefined) {\n\t\tthis.volume = this.defaultVolume;\n\t}\n});\n// #endregion\n", "import Rect from \"@/math/Rect\";\nimport { createNewCanvas } from \"@/utilities/Canvas\";\nimport { defineMethod } from \"@/utilities/Prototype\";\nimport type { Vector2, Vector4 } from \"@/math/Vec2\";\n\ntype Mode = \"fill\" | \"stroke\";\n\n// #region fillBar\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Fill a two-color bar sized by `amount`. Writes `fillStyle`; persists on the context \u2014 wrap in `save()`/`restore()` to preserve prior state.\n\t\t * @param c1 background, default `\"white\"`\n\t\t * @param c2 foreground, default `\"black\"`\n\t\t */\n\t\tfillBar(rect: Vector4, amount: number, c1?: string, c2?: string): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"fillBar\",\n\tfunction (rect, amount, c1 = \"white\", c2 = \"black\"): void {\n\t\tthis.fillStyle = c1;\n\t\tthis.fillRect(rect.x, rect.y, rect.w, rect.h);\n\n\t\tthis.fillStyle = c2;\n\t\tthis.fillRect(rect.x, rect.y, rect.w * amount, rect.h);\n\t},\n);\n// #endregion\n\n// #region fillFramedBar\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Fill a three-layer framed bar (outer band, frame, fill scaled by `amount`). Writes `fillStyle`; persists on the context \u2014 wrap in `save()`/`restore()` to preserve prior state.\n\t\t * @param amount fill fraction in `[0, 1]`. Default `0.8`. `\u2264 0` skips the fill layer.\n\t\t * @param padding frame inset on all sides. Default `4`.\n\t\t * @param colors outer band, frame, fill. Default `[\"white\", \"black\", \"red\"]`.\n\t\t */\n\t\tfillFramedBar(\n\t\t\trect: Vector4,\n\t\t\tamount?: number,\n\t\t\tpadding?: number,\n\t\t\tcolors?: [string, string, string],\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"fillFramedBar\",\n\tfunction (\n\t\trect,\n\t\tamount = 0.8,\n\t\tpadding = 4,\n\t\tcolors = [\"white\", \"black\", \"red\"],\n\t): void {\n\t\tthis.fillStyle = colors[0];\n\t\tthis.fillRect(rect.x, rect.y, rect.w, rect.h);\n\n\t\tthis.fillStyle = colors[1];\n\t\tthis.fillRect(\n\t\t\trect.x + padding,\n\t\t\trect.y + padding,\n\t\t\trect.w - padding * 2,\n\t\t\trect.h - padding * 2,\n\t\t);\n\n\t\tif (amount > 0) {\n\t\t\tthis.fillStyle = colors[2];\n\t\t\tthis.fillRect(\n\t\t\t\trect.x + padding,\n\t\t\t\trect.y + padding,\n\t\t\t\tamount * (rect.w - padding * 2),\n\t\t\t\trect.h - padding * 2,\n\t\t\t);\n\t\t}\n\t},\n);\n// #endregion\n\n// #region drawCircle\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draws a circle centered at `vecPos`.\n\t\t * @param amount sweep fraction in `[0, 1]`. Default `1` (full circle).\n\t\t */\n\t\tdrawCircle(\n\t\t\tvecPos: Vector2,\n\t\t\trad: number,\n\t\t\tmode: Mode,\n\t\t\tamount?: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawCircle\",\n\tfunction (vecPos, rad, mode, amount = 1): void {\n\t\tthis.beginPath();\n\t\tthis.arc(vecPos.x, vecPos.y, rad, 0, amount * 2 * Math.PI);\n\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawRect\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draws a rectangle (from `Vector4` or `x, y, w, h`). */\n\t\tdrawRect(rect: Vector4, mode: Mode): void;\n\t\tdrawRect(x: number, y: number, w: number, h: number, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawRect\",\n\tfunction (\n\t\t...args: [Vector4, Mode] | [number, number, number, number, Mode]\n\t): void {\n\t\tlet x: number;\n\t\tlet y: number;\n\t\tlet w: number;\n\t\tlet h: number;\n\t\tlet mode: Mode;\n\n\t\tif (typeof args[0] === \"number\") {\n\t\t\t[x, y, w, h, mode] = args as [number, number, number, number, Mode];\n\t\t} else {\n\t\t\t[{ x, y, w, h }, mode] = args as [Vector4, Mode];\n\t\t}\n\n\t\tthis.beginPath();\n\t\tthis.rect(x, y, w, h);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawRoundRect\ninterface DrawRoundRectOptions {\n\t/** Inset from the rect edges. Default `0` (no inset). */\n\tpadding?: number;\n\t/** Corner radius. Default `16`. */\n\tradius?: number;\n}\n\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a rounded rectangle from a `Vector4` or `x, y, w, h` plus an options bag. Delegates the corner path to native `roundRect` (Safari 16+ / Chrome 99+ / Firefox 113+). */\n\t\tdrawRoundRect(\n\t\t\trect: Vector4,\n\t\t\tmode: Mode,\n\t\t\toptions?: DrawRoundRectOptions,\n\t\t): void;\n\t\tdrawRoundRect(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw: number,\n\t\t\th: number,\n\t\t\tmode: Mode,\n\t\t\toptions?: DrawRoundRectOptions,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawRoundRect\",\n\tfunction (\n\t\t...args:\n\t\t\t| [Vector4, mode: Mode, DrawRoundRectOptions?]\n\t\t\t| [\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tnumber,\n\t\t\t\t\tmode: Mode,\n\t\t\t\t\tDrawRoundRectOptions?,\n\t\t\t ]\n\t): void {\n\t\tlet x: number;\n\t\tlet y: number;\n\t\tlet w: number;\n\t\tlet h: number;\n\t\tlet mode: Mode;\n\t\tlet options: DrawRoundRectOptions | undefined;\n\n\t\tif (typeof args[0] === \"number\") {\n\t\t\t[x, y, w, h, mode, options] = args as [\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tMode,\n\t\t\t\tDrawRoundRectOptions?,\n\t\t\t];\n\t\t} else {\n\t\t\t[{ x, y, w, h }, mode, options] = args as [\n\t\t\t\tVector4,\n\t\t\t\tMode,\n\t\t\t\tDrawRoundRectOptions?,\n\t\t\t];\n\t\t}\n\n\t\tconst { padding = 0, radius = 16 } = options ?? {};\n\n\t\tx += padding;\n\t\ty += padding;\n\t\tw -= padding * 2;\n\t\th -= padding * 2;\n\n\t\tthis.beginPath();\n\t\tthis.roundRect(x, y, w, h, radius);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region strokeDottedRect\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Stroke a dotted rectangle. Writes `lineWidth` and `setLineDash` \u2014 wrap in `save()`/`restore()` to preserve prior state. */\n\t\tstrokeDottedRect(rect: Vector4): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"strokeDottedRect\",\n\tfunction (rect): void {\n\t\tthis.setLineDash([15, 15]);\n\t\tthis.lineWidth = 5;\n\t\tthis.beginPath();\n\t\tthis.moveTo(rect.x, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y + rect.h);\n\t\tthis.lineTo(rect.x, rect.y + rect.h);\n\t\tthis.lineTo(rect.x, rect.y);\n\t\tthis.stroke();\n\t},\n);\n// #endregion\n\n// #region strokeLine\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a line segment from `(x1, y1)` to `(x2, y2)`. */\n\t\tstrokeLine(x1: number, y1: number, x2: number, y2: number): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"strokeLine\",\n\tfunction (x1, y1, x2, y2): void {\n\t\tthis.beginPath();\n\t\tthis.moveTo(x1, y1);\n\t\tthis.lineTo(x2, y2);\n\t\tthis.stroke();\n\t\tthis.closePath();\n\t},\n);\n// #endregion\n\n// #region drawPolygon\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draw a regular polygon centered in `rect`, with vertices on a circle of radius `min(rect.w, rect.h) * 0.5`.\n\t\t */\n\t\tdrawPolygon(sides: number, rect: Vector4, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawPolygon\",\n\tfunction (sides, rect, mode): void {\n\t\tconst rad = Math.min(rect.w, rect.h) * 0.5;\n\t\tconst Xcenter = rect.x + rect.w * 0.5;\n\t\tconst Ycenter = rect.y + rect.h * 0.5;\n\n\t\tthis.beginPath();\n\t\tthis.moveTo(Xcenter + rad, Ycenter);\n\n\t\tfor (let i = 1; i <= sides; i++) {\n\t\t\tthis.lineTo(\n\t\t\t\tMath.round(Xcenter + rad * Math.cos((i * 2 * Math.PI) / sides)),\n\t\t\t\tMath.round(Ycenter + rad * Math.sin((i * 2 * Math.PI) / sides)),\n\t\t\t);\n\t\t}\n\n\t\tthis.closePath();\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region drawTriangle\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Draw a triangle: top-left \u2192 top-right \u2192 bottom-center. */\n\t\tdrawTriangle(rect: Vector4, mode: Mode): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawTriangle\",\n\tfunction (rect, mode): void {\n\t\tthis.beginPath();\n\t\tthis.moveTo(rect.x, rect.y);\n\t\tthis.lineTo(rect.x + rect.w, rect.y);\n\t\tthis.lineTo(rect.x + rect.w * 0.5, rect.y + rect.h);\n\t\tthis[mode]();\n\t},\n);\n// #endregion\n\n// #region writeText\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Write text horizontally offset around `x` by `measureTextOffset` of its measured width.\n\t\t * @param measureTextOffset in `[0, 1]`. Default `0.5` (centered around `x`).\n\t\t */\n\t\twriteText(\n\t\t\ttext: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tmeasureTextOffset?: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"writeText\",\n\tfunction (text, x, y, measureTextOffset = 0.5): void {\n\t\tthis.fillText(\n\t\t\ttext,\n\t\t\tx - this.measureText(text).width * measureTextOffset,\n\t\t\ty,\n\t\t);\n\t},\n);\n// #endregion\n\n// #region writeMultilineText\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Word-wrap `text` into lines of pixel width `width`, drawing each line via `writeText`. Returns `false` and logs to `console.error` if `maxAttempts` is reached.\n\t\t * @param lineOffset vertical spacing between lines in px. Default `50`.\n\t\t * @param maxAttempts safety cap on wrap iterations. Default `50`.\n\t\t */\n\t\twriteMultilineText(\n\t\t\ttext: string,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\twidth: number,\n\t\t\tlineOffset?: number,\n\t\t\tmaxAttempts?: number,\n\t\t): boolean;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"writeMultilineText\",\n\tfunction (text, x, y, width, lineOffset = 50, maxAttempts = 50): boolean {\n\t\tconst words = text.split(\" \");\n\t\tlet attempts = 0;\n\n\t\twhile (words.length > 0 && attempts < maxAttempts) {\n\t\t\tlet count = words.length;\n\t\t\tfor (let i = 1; i <= words.length; i++) {\n\t\t\t\tconst textWidth = this.measureText(\n\t\t\t\t\twords.slice(0, i).join(\" \"),\n\t\t\t\t).width;\n\n\t\t\t\tif (textWidth > width) {\n\t\t\t\t\tcount = Math.max(1, i - 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.writeText(words.slice(0, count).join(\" \"), x, y, 0);\n\t\t\twords.splice(0, count);\n\t\t\ty += lineOffset;\n\t\t\tattempts++;\n\t\t}\n\n\t\tif (attempts >= maxAttempts) {\n\t\t\tconsole.error(\"maxAttempts reached\", attempts);\n\t\t}\n\n\t\treturn attempts < maxAttempts;\n\t},\n);\n// #endregion\n\n// #region drawImageRotated\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/**\n\t\t * Draw `image` rotated by `radians` around the center of its placement at `(x, y)`. Saves and restores the transform.\n\t\t * @param radians clockwise positive, in radians.\n\t\t */\n\t\tdrawImageRotated(\n\t\t\timage: HTMLCanvasElement,\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tradians: number,\n\t\t): void;\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"drawImageRotated\",\n\tfunction (image, x, y, radians): void {\n\t\tthis.save();\n\t\tthis.translate(x + image.width * 0.5, y + image.height * 0.5);\n\t\tthis.rotate(radians);\n\t\tthis.drawImage(image, -image.width * 0.5, -image.height * 0.5);\n\t\tthis.restore();\n\t},\n);\n// #endregion\n\n// #region generateColor\ndeclare global {\n\tinterface CanvasRenderingContext2D {\n\t\t/** Build a colored rounded-rect stencil with a `drawPartialRoundRect` helper. The returned helper writes `fillStyle = \"white\"` on the caller's context \u2014 wrap in `save()`/`restore()` to preserve prior state. */\n\t\tgenerateColor(\n\t\t\tsize: number,\n\t\t\tcolor: string,\n\t\t): {\n\t\t\tcolors: [number, number][];\n\t\t\timage: HTMLCanvasElement;\n\t\t\tdrawPartialRoundRect: (\n\t\t\t\trect: Rect,\n\t\t\t\tamount: number,\n\t\t\t\toffsetX?: number,\n\t\t\t\toffsetY?: number,\n\t\t\t) => void;\n\t\t};\n\t}\n}\n\ndefineMethod(\n\tCanvasRenderingContext2D.prototype,\n\t\"generateColor\",\n\tfunction (size, color) {\n\t\tconst cc = createNewCanvas(size, size);\n\t\tcc.context.strokeStyle = color;\n\t\tcc.context.lineWidth = 6;\n\t\tcc.context.drawRoundRect(0, 0, size, size, \"stroke\", {\n\t\t\tpadding: cc.context.lineWidth,\n\t\t\tradius: 15,\n\t\t});\n\n\t\tconst data = cc.context.getImageData(0, 0, size, size).data;\n\t\tconst allColors: [number, number][] = [];\n\t\tfor (let i = 0; i < data.length; i += 4) {\n\t\t\tif (data[i + 3]) {\n\t\t\t\tallColors.push([(i / 4) % size, (i / 4 / size) | 0]);\n\t\t\t}\n\t\t}\n\n\t\tconst colors: [number, number][] = [];\n\n\t\tallColors.forEach(c => {\n\t\t\tif (c[0] > size * 0.5) {\n\t\t\t\tcolors.push(c);\n\t\t\t}\n\t\t});\n\n\t\tfor (let i = allColors.length - 1; i >= 0; i--) {\n\t\t\tif (allColors[i][0] <= size * 0.5) {\n\t\t\t\tcolors.push(allColors[i]);\n\t\t\t}\n\t\t}\n\n\t\tconst drawPartialRoundRect = (\n\t\t\trect: Rect,\n\t\t\tamount: number,\n\t\t\toffsetX = 0,\n\t\t\toffsetY = 0,\n\t\t): void => {\n\t\t\tthis.drawImage(cc.canvas, rect.x + offsetX, rect.y + offsetY);\n\n\t\t\tthis.fillStyle = \"white\";\n\n\t\t\tfor (\n\t\t\t\tlet i = 0;\n\t\t\t\ti < Math.min(amount * colors.length, colors.length);\n\t\t\t\ti++\n\t\t\t) {\n\t\t\t\tthis.fillRect(\n\t\t\t\t\trect.x + colors[i][0] + offsetX,\n\t\t\t\t\trect.y + colors[i][1] + offsetY,\n\t\t\t\t\t1,\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\treturn { colors, image: cc.canvas, drawPartialRoundRect };\n\t},\n);\n// #endregion\n", "import { defineMethod } from \"@/utilities/Prototype\";\n\nimport \"./Audio\";\nimport \"./CanvasRenderingContext2D\";\nimport \"./HTMLCanvasElement\";\n\n// #region subImage\ndeclare global {\n\tinterface HTMLImageElement {\n\t\t/**\n\t\t * Crop a `(w, h)` sub-region starting at `(x, y)` into a new canvas.\n\t\t * @param w default `this.width`\n\t\t * @param h default `this.height`\n\t\t */\n\t\tsubImage(\n\t\t\tx: number,\n\t\t\ty: number,\n\t\t\tw?: number,\n\t\t\th?: number,\n\t\t): HTMLCanvasElement;\n\t}\n}\n\n// Reuse the canvas implementations on images. It calls `drawImage(this, ...)`\n// and reads `this.width / this.height` \u2014 all valid on HTMLImageElement too.\ndefineMethod(\n\tHTMLImageElement.prototype,\n\t\"subImage\",\n\tHTMLCanvasElement.prototype.subImage as HTMLImageElement[\"subImage\"],\n);\n// #endregion\n", "import CanvasManager from \"@/core/CanvasManager\";\nimport EventSystem from \"@/core/EventSystem\";\nimport Gameloop from \"./Gameloop\";\nimport Keyboard from \"@/input/Keyboard\";\nimport Pointer from \"@/input/Pointer\";\nimport Settings, { type SettingsOverrides } from \"@/core/Settings\";\nimport { debounce } from \"@/utilities/Functions\";\n\nimport \"@/localization/Translator\";\nimport \"@/prototypes/index\";\n\n/**\n * Abstract base for a Gleam game. Subclass it and implement {@link init}, {@link update}, and {@link draw}. The constructor wires up {@link CanvasManager}, {@link Gameloop}, {@link Keyboard}, and {@link Pointer}; the subclass must register at least one canvas with `canman.setupCanvas(...)` and then call {@link preInit} to start everything.\n *\n * **Singleton-per-page.** The framework registers global listeners on `window`/`document` and writes `history.scrollRestoration`; multiple instances on the same page will fight each other.\n */\nexport default abstract class Game {\n\t/** Canvas registry + 2D context exposure. Register canvases here from the constructor (`canman.setupCanvas(CANVAS_TYPES.MAIN, \"#game\")`) before calling {@link preInit}. */\n\tpublic canman = new CanvasManager();\n\t/** The fixed-step driver. Started automatically by `preInit` when `Settings.autoloop` is `true`. */\n\tpublic gameloop: Gameloop;\n\t/** Live keyboard state. See {@link Keyboard}. */\n\tpublic keyboard: Keyboard;\n\t/** Live pointer (mouse / pen / touch) state. See {@link Pointer}. */\n\tpublic pointer: Pointer;\n\tprivate initialized = false;\n\n\tconstructor(settingOverrides: SettingsOverrides = {}) {\n\t\tSettings.init(settingOverrides, this);\n\n\t\thistory.scrollRestoration = \"manual\";\n\n\t\tthis.gameloop = new Gameloop(this);\n\t\tthis.keyboard = new Keyboard(this);\n\t\tthis.pointer = new Pointer(this);\n\t}\n\n\t/** Render the current frame. Called by {@link Gameloop} after the canvas is cleared. Subclasses must override \u2014 the default throws. */\n\tpublic draw(_context: CanvasRenderingContext2D): void {\n\t\tthrow new Error(\"Override draw function!\");\n\t}\n\n\t/** Advance the simulation by `dt` seconds (= `Settings.fps`). Called by {@link Gameloop} zero-or-more times per frame depending on real-time accumulation. Subclasses must override \u2014 the default throws. */\n\tpublic update(_dt: number): void {\n\t\tthrow new Error(\"Override update function!\");\n\t}\n\n\t/** One-time setup hook (assets, world build) invoked by {@link preInit}. Can be `async`; the loop waits for it to resolve before starting. **Do not call directly** \u2014 kick off via {@link preInit} from the constructor. Subclasses must override \u2014 the default throws. */\n\tpublic async init(): Promise<void> {\n\t\tthrow new Error(\n\t\t\t\"Override init() and start the game via preInit() \u2014 do not call init() directly.\",\n\t\t);\n\t}\n\n\t/** Finalise engine wiring and start the loop. Call once from the subclass constructor *after* registering canvases. Steps: `canman.finishSetup()` \u2192 install debounced `window.resize` \u2192 reset `gameloop.levelTime` \u2192 `await this.init()` (if `doInit`) \u2192 dispatch `\"resized\"` \u2192 start the loop if `Settings.autoloop`. Throws if called twice. Pass `doInit: false` to skip the `init()` await (useful for tests). */\n\tprotected async preInit(doInit = true): Promise<void> {\n\t\tif (this.initialized) {\n\t\t\tthrow new Error(\n\t\t\t\t\"preInit() may only be called once per Game instance.\",\n\t\t\t);\n\t\t}\n\t\tthis.initialized = true;\n\n\t\tthis.canman.finishSetup();\n\n\t\twindow.addEventListener(\n\t\t\t\"resize\",\n\t\t\tdebounce(() => EventSystem.dispatchEvent(\"resized\"), 250),\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.gameloop.levelTime = 0;\n\n\t\tif (doInit) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tEventSystem.dispatchEvent(\"resized\");\n\n\t\tif (Settings.autoloop) {\n\t\t\tthis.gameloop.startLoop();\n\t\t}\n\t}\n}\n", "import { rafLoop } from \"@/utilities/Functions\";\nimport { randomBetweenFloat } from \"@/utilities/Math\";\n\n/** String-valued keys of `CSSStyleDeclaration` \u2014 the ones safe to assign a `string` value to via {@link CssProxy}. */\nexport type CssStyleKey = {\n\t[K in keyof CSSStyleDeclaration]: K extends string\n\t\t? CSSStyleDeclaration[K] extends string\n\t\t\t? K\n\t\t\t: never\n\t\t: never;\n}[keyof CSSStyleDeclaration];\n\n/** Setter handed to {@link ShakeType.update} that writes a CSS value. Snapshots the prior value on first write per key so it can be restored on dispose. */\nexport type CssProxy = (key: CssStyleKey, value: string) => void;\n\n/** Shape for a custom shake recipe. */\nexport interface ShakeType {\n\t/** Decay rate applied each frame: `timer -= step * dt`. Higher = shorter shake (3 \u2248 \u2153s, 15 \u2248 1/15s). */\n\tstep: number;\n\t/** Per-frame mutator. `time` decays from `1` to `0` over the shake \u2014 multiply your intensity by it for a natural fall-off. */\n\tupdate: (updateCss: CssProxy, time: number) => void;\n}\n\n/** Built-in shake recipes. Pass one to {@link Screenshake.shake}. */\nexport const SHAKE_TYPES = {\n\t/** ~0.33 s wobble combining a small random rotation with a blur fall-off. */\n\tNORMAL: {\n\t\t/** Decay rate \u2014 see {@link ShakeType.step}. */\n\t\tstep: 3,\n\t\t/** Per-frame mutator \u2014 see {@link ShakeType.update}. */\n\t\tupdate(updateCss: CssProxy, time: number): void {\n\t\t\tconst tr = `rotate(${randomBetweenFloat(-2, 2) * time}deg)`;\n\t\t\tupdateCss(\"transform\", tr);\n\t\t\tupdateCss(\"webkitTransform\", tr);\n\n\t\t\tupdateCss(\"filter\", `blur(${time * 5}px)`);\n\t\t},\n\t},\n\t/** ~0.07 s impact: blur-only fall-off, no rotation. */\n\tFAST: {\n\t\t/** Decay rate \u2014 see {@link ShakeType.step}. */\n\t\tstep: 15,\n\t\t/** Per-frame mutator \u2014 see {@link ShakeType.update}. */\n\t\tupdate(updateCss: CssProxy, time: number): void {\n\t\t\tupdateCss(\"filter\", `blur(${time * 3}px)`);\n\t\t},\n\t},\n} satisfies Record<string, ShakeType>;\n\n/**\n * Shake an element by mutating its inline CSS each rAF tick. One shake per instance \u2014 re-calling {@link shake} while one is active returns `null`. The returned dispose function (and natural timer expiry) restores every CSS key the shake touched.\n *\n * Only the built-in {@link SHAKE_TYPES} (`NORMAL`, `FAST`) are supported today. Letting callers define their own would be a natural extension \u2014 impact pulses, slow rumble, directional jolts \u2014 since {@link ShakeType} is already public.\n */\nexport default class Screenshake {\n\tprivate isShaking: boolean = false;\n\tprivate shakeType: ShakeType = SHAKE_TYPES.NORMAL;\n\tprivate style: CSSStyleDeclaration;\n\n\tconstructor(element: HTMLElement) {\n\t\tthis.style = element.style;\n\t}\n\n\t/** Start a shake of the given `shakeType`. Returns a dispose function that stops the shake early and restores every CSS key it touched, or `null` if a shake is already active on this instance. Auto-stops and restores when the timer reaches zero. */\n\tpublic shake(\n\t\tshakeType: ShakeType = SHAKE_TYPES.NORMAL,\n\t): null | (() => void) {\n\t\tif (this.isShaking) {\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.isShaking = true;\n\t\tthis.shakeType = shakeType;\n\t\tlet timer = 1;\n\n\t\tconst originalValue = new Map<string, string>();\n\t\tconst updateCssProxy: CssProxy = (key, value) => {\n\t\t\tif (!originalValue.has(key)) {\n\t\t\t\toriginalValue.set(key, this.style[key]);\n\t\t\t}\n\n\t\t\tthis.style[key] = value;\n\t\t};\n\n\t\tconst stopLoop = rafLoop(dt => {\n\t\t\tthis.shakeType.update(updateCssProxy, timer);\n\t\t\ttimer -= this.shakeType.step * dt;\n\n\t\t\tif (timer <= 0) {\n\t\t\t\tdispose();\n\t\t\t}\n\t\t});\n\n\t\tlet alive = true;\n\t\tconst dispose = (): void => {\n\t\t\t// `alive` is per-shake, so a stale dispose handle from a previous shake can't restore its old snapshot over a later shake or flip the shared isShaking flag.\n\t\t\tif (!alive) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\talive = false;\n\n\t\t\tstopLoop();\n\t\t\toriginalValue.forEach((value, key) => {\n\t\t\t\tthis.style[key] = value;\n\t\t\t});\n\t\t\tthis.isShaking = false;\n\t\t};\n\n\t\treturn dispose;\n\t}\n}\n", "import EventSystem from \"@/core/EventSystem\";\nimport Vec2 from \"@/math/Vec2\";\n\n/** Button indices for the standard gamepad mapping (W3C Gamepad spec). Use as the index into {@link Controller.buttons}. */\nexport const CONTROLLER_KEYS = {\n\t/** Bottom face button \u2014 `A` on Xbox, `\u00D7` on PlayStation. */\n\tA: 0,\n\t/** Right face button \u2014 `B` on Xbox, `\u25CB` on PlayStation. */\n\tB: 1,\n\t/** Left face button \u2014 `X` on Xbox, `\u25A1` on PlayStation. */\n\tX: 2,\n\t/** Top face button \u2014 `Y` on Xbox, `\u25B3` on PlayStation. */\n\tY: 3,\n\t/** Left bumper / shoulder. */\n\tLB: 4,\n\t/** Right bumper / shoulder. */\n\tRB: 5,\n\t/** Left trigger. The digital pressed-state lives here; the analog value is on the underlying `Gamepad.buttons[6].value`. */\n\tLT: 6,\n\t/** Right trigger. The digital pressed-state lives here; the analog value is on the underlying `Gamepad.buttons[7].value`. */\n\tRT: 7,\n\t/** Back / Select / Share. */\n\tSELECT: 8,\n\t/** Start / Options / Menu. */\n\tSTART: 9,\n\t/** Left stick click (L3). */\n\tLEFT_STICK: 10,\n\t/** Right stick click (R3). */\n\tRIGHT_STICK: 11,\n\t/** D-pad up. */\n\tUP: 12,\n\t/** D-pad down. */\n\tDOWN: 13,\n\t/** D-pad left. */\n\tLEFT: 14,\n\t/** D-pad right. */\n\tRIGHT: 15,\n\t/** Guide / Home / PS button. Not exposed by all browsers. */\n\tGUIDE: 16,\n} as const;\n\nconst DEADZONE = 0.25;\n\n/**\n * Gamepad input. The first connected gamepad becomes \"our\" gamepad; later ones are ignored until ours disconnects. Connection / disconnection fires {@link EventSystem} `\"inputControllerConnected\"` / `\"inputControllerDisconnected\"`.\n *\n * Poll {@link buttons} (indexed via {@link CONTROLLER_KEYS}) and {@link poll} from your `update`. State is cleared on `window` blur and on disconnect so held buttons / non-neutral sticks don't stay live across focus loss. Visualizing is not the controller's responsibility \u2014 see {@link ControllerCursor} for the built-in on-screen visualization, or read {@link poll} directly to drive your own.\n *\n * Logs to `console.error` if the browser doesn't expose the Gamepad API.\n */\nexport default class Controller {\n\t/** Pressed-state per button, indexed in the same order as the underlying `Gamepad.buttons`. Index with {@link CONTROLLER_KEYS}. Updated by {@link poll}; empty until the first non-cached poll. */\n\tpublic buttons: boolean[] = [];\n\tprivate axes: Vec2[] = [];\n\tprivate index = -1;\n\tprivate lastTime = 0;\n\n\tconstructor() {\n\t\tif (!(\"getGamepads\" in navigator)) {\n\t\t\tconsole.error(\"Controller not supported!\");\n\t\t\treturn;\n\t\t}\n\n\t\twindow.addEventListener(\"gamepadconnected\", (event: GamepadEvent) => {\n\t\t\tthis.index = event.gamepad.index;\n\t\t\tfor (let i = 0; i < event.gamepad.axes.length / 2; i++) {\n\t\t\t\tthis.axes.push(new Vec2());\n\t\t\t}\n\t\t\tconsole.log(\"Gamepad connected:\", event.gamepad.id);\n\t\t\tEventSystem.dispatchEvent(\n\t\t\t\t\"inputControllerConnected\",\n\t\t\t\tevent.gamepad,\n\t\t\t);\n\t\t\tthis.vibrate();\n\t\t});\n\n\t\twindow.addEventListener(\n\t\t\t\"gamepaddisconnected\",\n\t\t\t(event: GamepadEvent) => {\n\t\t\t\tif (this.index === event.gamepad.index) {\n\t\t\t\t\tthis.index = -1;\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"Our Gamepad was disconnected:\",\n\t\t\t\t\t\tevent.gamepad.index,\n\t\t\t\t\t);\n\t\t\t\t\tthis.reset();\n\t\t\t\t\tEventSystem.dispatchEvent(\"inputControllerDisconnected\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"Different Gamepad was disconnected:\",\n\t\t\t\t\t\tevent.gamepad.index,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\twindow.addEventListener(\"blur\", () => this.reset(), false);\n\t}\n\n\t/** Read the current gamepad state and return one {@link Vec2} per stick pair with a circular deadzone applied (`0.25` inner radius, output magnitude clamped to `[0, 1]`). The returned array (and each `Vec2` in it) is reused across calls \u2014 clone if you need to retain. Also refreshes {@link buttons}. Returns the cached array unchanged when the gamepad timestamp hasn't advanced. */\n\tpublic poll(): Vec2[] {\n\t\tconst gp = this.getGamepad();\n\n\t\tif (!gp || this.lastTime === gp.timestamp) {\n\t\t\treturn this.axes;\n\t\t}\n\n\t\tthis.lastTime = gp.timestamp;\n\n\t\tthis.buttons = gp.buttons.map(\n\t\t\t(button: GamepadButton) => button.pressed,\n\t\t);\n\n\t\tfor (let i = 0; i < this.axes.length; i++) {\n\t\t\tthis.axes[i].set(gp.axes[i * 2], gp.axes[i * 2 + 1]);\n\n\t\t\tconst mag = this.axes[i].length();\n\t\t\tif (mag < DEADZONE) {\n\t\t\t\tthis.axes[i].set(0, 0);\n\t\t\t} else {\n\t\t\t\tthis.axes[i].mult(\n\t\t\t\t\t(Math.min(1, mag) - DEADZONE) / (1 - DEADZONE) / mag,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn this.axes;\n\t}\n\n\t/** Clear {@link buttons} and the cached stick axes. Called automatically on `window` blur and on gamepad disconnect. */\n\tpublic reset(): void {\n\t\tthis.buttons.length = 0;\n\t\tthis.axes.length = 0;\n\t}\n\n\t/** Trigger a 400 ms full-strength dual-rumble pulse. Returns `false` when no gamepad is connected or the pad has no `vibrationActuator`; `true` when the effect was dispatched. */\n\tpublic vibrate(): boolean {\n\t\tconst gp = this.getGamepad();\n\n\t\tif (!gp) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst vibrator = gp.vibrationActuator;\n\n\t\tif (vibrator) {\n\t\t\tvibrator.playEffect(\"dual-rumble\", {\n\t\t\t\tduration: 400,\n\t\t\t\tweakMagnitude: 1.0,\n\t\t\t\tstartDelay: 0,\n\t\t\t\tstrongMagnitude: 1.0,\n\t\t\t});\n\t\t}\n\n\t\treturn !!vibrator;\n\t}\n\n\tprivate getGamepad(): Gamepad | null {\n\t\treturn this.index < 0\n\t\t\t? null\n\t\t\t: (navigator.getGamepads()[this.index] ?? null);\n\t}\n}\n", "import Vec2 from \"@/math/Vec2\";\nimport type Rect from \"@/math/Rect\";\nimport { throttle } from \"@/utilities/Functions\";\nimport { wrapRadians } from \"@/utilities/Math\";\n\n/** Result of a {@link Polygon.collide} call. */\nexport interface PolygonCollisionResult {\n\t/** `true` if the polygons currently overlap. */\n\tintersect: boolean;\n\t/** Smallest displacement that would separate the polygons (zero `Vec2` when they're disjoint). */\n\tminimumTranslationVector: Vec2;\n\t/** `true` if applying the `velocity` passed to `collide` would put the polygons into contact. */\n\twillIntersect: boolean;\n}\n\nconst warnZeroEdge = throttle(count => {\n\tconsole.warn(\n\t\t`Polygon.collide: found a zero-edge polygon \u2014 no collision possible. (called x${count} since last trace)`,\n\t);\n});\n\nfunction pointDirection(\n\txfrom: number,\n\tyfrom: number,\n\txto: number,\n\tyto: number,\n): number {\n\treturn Math.atan2(yto - yfrom, xto - xfrom);\n}\n\nfunction intervalDistance(\n\tminA: number,\n\tmaxA: number,\n\tminB: number,\n\tmaxB: number,\n): number {\n\treturn minA < minB ? minB - maxA : minA - maxB;\n}\n\nfunction projectPolygon(axis: Vec2, polygon: Polygon, bounds: Vec2): void {\n\tlet dotProduct = axis.dotProduct(polygon.points[0]);\n\tbounds.x = dotProduct;\n\tbounds.y = dotProduct;\n\n\tfor (let i = 1; i < polygon.points.length; i++) {\n\t\tdotProduct = polygon.points[i].dotProduct(axis);\n\n\t\tif (dotProduct < bounds.x) {\n\t\t\tbounds.x = dotProduct;\n\t\t} else if (dotProduct > bounds.y) {\n\t\t\tbounds.y = dotProduct;\n\t\t}\n\t}\n}\n\n/**\n * Convex 2D polygon. **The collision API ({@link Polygon.collide}) uses SAT, which is mathematically defined only for convex polygons** \u2014 feeding it a concave polygon silently produces wrong results.\n */\nexport default class Polygon {\n\t/**\n\t * Trace an outline around the opaque pixels of `canvas` via four directional sweeps (top, right, bottom, left). `detail` is the pixel stride (\u2265 2) between scanline samples \u2014 higher = faster but coarser. `angle` is the simplification threshold in radians: vertices whose turn angle wraps to within \u00B1`angle` of straight are dropped. Throws if fewer than 3 vertices survive.\n\t *\n\t * **Convex shapes only.** The sweep ignores anything an outer-perimeter ray can't reach: holes (donuts), inward bays (a \"C\" opening sideways), or any row/column with multiple disjoint opaque spans. For those inputs the result is either a broken polygon or simply the outer hull, and {@link Polygon.collide} relies on convexity anyway.\n\t */\n\tpublic static fromCanvas(\n\t\tcanvas: HTMLCanvasElement,\n\t\tdetail: number,\n\t\tangle: number,\n\t): Polygon {\n\t\tdetail = Math.max(2, detail);\n\n\t\tconst w = canvas.width;\n\t\tconst h = canvas.height;\n\t\tconst data = canvas.getContext(\"2d\")!.getImageData(0, 0, w, h).data;\n\n\t\tconst vertexX = [0];\n\t\tconst vertexY = [0];\n\t\tconst vertexK = [1];\n\n\t\tlet numPoints = 0;\n\t\tlet fy = -1;\n\t\tlet lx = 0;\n\t\tlet ly = 0;\n\n\t\tfor (let tx = 0; tx < w; tx += detail) {\n\t\t\tfor (let ty = 0; ty < h; ty += 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tif (fy < 0) {\n\t\t\t\t\t\tfy = ty;\n\t\t\t\t\t}\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let ty = 0; ty < h; ty += detail) {\n\t\t\tfor (let tx = w - 1; tx >= 0; tx -= 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && ty > ly) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let tx = w - 1; tx >= 0; tx -= detail) {\n\t\t\tfor (let ty = h - 1; ty >= 0; ty -= 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && tx < lx) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let ty = h - 1; ty >= 0; ty -= detail) {\n\t\t\tfor (let tx = 0; tx < w; tx += 1) {\n\t\t\t\tif (data[(ty * w + tx) * 4 + 3] !== 0 && ty < ly && ty > fy) {\n\t\t\t\t\tvertexX[numPoints] = tx;\n\t\t\t\t\tvertexY[numPoints] = ty;\n\t\t\t\t\tvertexK[numPoints] = 1;\n\t\t\t\t\tnumPoints++;\n\t\t\t\t\tlx = tx;\n\t\t\t\t\tly = ty;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (numPoints < 3) {\n\t\t\tthrow new Error(\n\t\t\t\t`Polygon.fromCanvas: scan produced \"${numPoints}\" vertices (need >=3). Canvas may be empty or detail (${detail}) too large.`,\n\t\t\t);\n\t\t}\n\n\t\tfor (let i = 0; i < numPoints; i++) {\n\t\t\tconst a = i;\n\t\t\tconst b = (i + 1) % numPoints;\n\t\t\tconst c = (i + 2) % numPoints;\n\n\t\t\tconst ang1 = pointDirection(\n\t\t\t\tvertexX[a],\n\t\t\t\tvertexY[a],\n\t\t\t\tvertexX[b],\n\t\t\t\tvertexY[b],\n\t\t\t);\n\t\t\tconst ang2 = pointDirection(\n\t\t\t\tvertexX[b],\n\t\t\t\tvertexY[b],\n\t\t\t\tvertexX[c],\n\t\t\t\tvertexY[c],\n\t\t\t);\n\n\t\t\tif (Math.abs(wrapRadians(ang1 - ang2)) <= angle) {\n\t\t\t\tvertexK[b] = 0;\n\t\t\t}\n\t\t}\n\n\t\tconst points: Vec2[] = [];\n\t\tfor (let i = 0; i < numPoints; i++) {\n\t\t\tif (vertexK[i] === 1) {\n\t\t\t\tpoints.push(new Vec2(vertexX[i], vertexY[i]));\n\t\t\t}\n\t\t}\n\n\t\treturn new Polygon(...points);\n\t}\n\n\t/** Regular convex polygon with `edges` vertices, inscribed in a bounding box of `size` (number = square). */\n\tpublic static fromEdges(edges: number, size: Vec2 | number): Polygon {\n\t\tconst s = size instanceof Vec2 ? size : new Vec2(size, size);\n\n\t\tconst rad = Math.min(s.x, s.y) * 0.5;\n\t\tconst Xcenter = s.x * 0.5;\n\t\tconst Ycenter = s.y * 0.5;\n\n\t\tconst points: Vec2[] = [];\n\t\tfor (let i = 1; i <= edges; i++) {\n\t\t\tpoints.push(\n\t\t\t\tnew Vec2(\n\t\t\t\t\tMath.round(\n\t\t\t\t\t\tXcenter + rad * Math.cos((i * 2 * Math.PI) / edges),\n\t\t\t\t\t),\n\t\t\t\t\tMath.round(\n\t\t\t\t\t\tYcenter + rad * Math.sin((i * 2 * Math.PI) / edges),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\treturn new Polygon(...points);\n\t}\n\n\t/** Polygon from the four corners of `rect`. */\n\tpublic static fromRect(rect: Rect): Polygon {\n\t\treturn new Polygon(\n\t\t\tnew Vec2(rect.x, rect.y),\n\t\t\tnew Vec2(rect.x + rect.w, rect.y),\n\t\t\tnew Vec2(rect.x + rect.w, rect.y + rect.h),\n\t\t\tnew Vec2(rect.x, rect.y + rect.h),\n\t\t);\n\t}\n\n\tprivate _center: Vec2 = new Vec2();\n\tprivate _points: Vec2[] = [];\n\tprivate edges: Vec2[] = [];\n\n\t/** Centroid (mean of vertex positions). Recomputed whenever the vertex set changes. */\n\tpublic get center(): Readonly<Vec2> {\n\t\treturn this._center;\n\t}\n\n\t/** Read-only view of the current vertex list. Use `addPoint`/`offset`/`rotate` to mutate. */\n\tpublic get points(): Readonly<Vec2[]> {\n\t\treturn this._points;\n\t}\n\n\tconstructor(...points: Vec2[]) {\n\t\tthis.addPoints(...points);\n\t}\n\n\t/** Stroke the polygon to `context`, shifted by `offset`. Coordinates are truncated to integers (via `| 0`) for crisp lines. */\n\tpublic draw(\n\t\tcontext: CanvasRenderingContext2D,\n\t\toffset: Vec2 = new Vec2(),\n\t): void {\n\t\tif (this._points.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontext.beginPath();\n\n\t\tcontext.moveTo(\n\t\t\t(offset.x + this._points[0].x) | 0,\n\t\t\t(offset.y + this._points[0].y) | 0,\n\t\t);\n\n\t\tfor (let i = 1; i < this._points.length; i++) {\n\t\t\tcontext.lineTo(\n\t\t\t\t(offset.x + this._points[i].x) | 0,\n\t\t\t\t(offset.y + this._points[i].y) | 0,\n\t\t\t);\n\t\t}\n\n\t\tcontext.closePath();\n\t\tcontext.stroke();\n\t}\n\n\t/** Append a single vertex at `(x, y)`. Mutates and returns `this`. */\n\tpublic addPoint(x: number, y: number): Polygon {\n\t\tthis._points.push(new Vec2(x, y));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\t/** Append cloned copies of every passed vertex. Mutates and returns `this`. */\n\tpublic addPoints(...points: Vec2[]): Polygon {\n\t\tpoints.forEach(point => this._points.push(point.clone()));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\t/** Translate every vertex by `(x, y)`. Mutates and returns `this`. */\n\tpublic offset(x = 0, y = 0): Polygon {\n\t\tthis._points.forEach(point => point.add(x, y));\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\t/** Rotate by `angle` radians around `pos` (defaults to the centroid). Mutates and returns `this`. */\n\tpublic rotate(angle: number, pos: Readonly<Vec2> = this.center) {\n\t\tif (!angle) {\n\t\t\treturn this;\n\t\t}\n\n\t\tconst cos = Math.cos(angle);\n\t\tconst sin = Math.sin(angle);\n\n\t\tthis._points.forEach(point => {\n\t\t\tconst dx = point.x - pos.x;\n\t\t\tconst dy = point.y - pos.y;\n\t\t\tpoint.set(dx * cos - dy * sin + pos.x, dx * sin + dy * cos + pos.y);\n\t\t});\n\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n\n\t/** SAT collision against `otherPolygon`. **Both polygons must be convex** \u2014 SAT silently misses collisions for concave shapes. Pass a non-zero `velocity` to also compute whether the polygons would intersect after that displacement. Warns and returns a no-collision result if either polygon has zero edges. */\n\tpublic collide(\n\t\totherPolygon: Polygon,\n\t\tvelocity: Vec2 = new Vec2(),\n\t): PolygonCollisionResult {\n\t\tconst result: PolygonCollisionResult = {\n\t\t\tintersect: true,\n\t\t\tminimumTranslationVector: new Vec2(),\n\t\t\twillIntersect: true,\n\t\t};\n\n\t\tconst edgeCountA = this.edges.length;\n\t\tconst edgeCountB = otherPolygon.edges.length;\n\n\t\tif (edgeCountA === 0 || edgeCountB === 0) {\n\t\t\twarnZeroEdge();\n\n\t\t\treturn {\n\t\t\t\tintersect: false,\n\t\t\t\tminimumTranslationVector: new Vec2(),\n\t\t\t\twillIntersect: false,\n\t\t\t};\n\t\t}\n\n\t\tlet minDistance = Infinity;\n\t\tlet translationAxis = new Vec2();\n\t\tlet edge: Vec2;\n\n\t\tfor (\n\t\t\tlet edgeIndex = 0;\n\t\t\tedgeIndex < edgeCountA + edgeCountB;\n\t\t\tedgeIndex++\n\t\t) {\n\t\t\tif (edgeIndex < edgeCountA) {\n\t\t\t\tedge = this.edges[edgeIndex];\n\t\t\t} else {\n\t\t\t\tedge = otherPolygon.edges[edgeIndex - edgeCountA];\n\t\t\t}\n\n\t\t\tconst axis = new Vec2(-edge.y, edge.x);\n\t\t\taxis.normalize();\n\n\t\t\tconst boundsA = new Vec2();\n\t\t\tconst boundsB = new Vec2();\n\t\t\tprojectPolygon(axis, this, boundsA);\n\t\t\tprojectPolygon(axis, otherPolygon, boundsB);\n\n\t\t\tif (\n\t\t\t\tintervalDistance(boundsA.x, boundsA.y, boundsB.x, boundsB.y) > 0\n\t\t\t) {\n\t\t\t\tresult.intersect = false;\n\t\t\t}\n\n\t\t\tconst velocityProjection = axis.dotProduct(velocity);\n\n\t\t\tif (velocityProjection < 0) {\n\t\t\t\tboundsA.x += velocityProjection;\n\t\t\t} else {\n\t\t\t\tboundsA.y += velocityProjection;\n\t\t\t}\n\n\t\t\tlet distance = intervalDistance(\n\t\t\t\tboundsA.x,\n\t\t\t\tboundsA.y,\n\t\t\t\tboundsB.x,\n\t\t\t\tboundsB.y,\n\t\t\t);\n\t\t\tif (distance > 0) {\n\t\t\t\tresult.willIntersect = false;\n\t\t\t}\n\n\t\t\tif (!result.intersect && !result.willIntersect) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdistance = Math.abs(distance);\n\t\t\tif (distance < minDistance) {\n\t\t\t\tminDistance = distance;\n\t\t\t\ttranslationAxis = axis.clone();\n\n\t\t\t\tconst d = this.center.clone().sub(otherPolygon.center);\n\t\t\t\tif (d.dotProduct(translationAxis) < 0) {\n\t\t\t\t\ttranslationAxis.negate();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (result.willIntersect) {\n\t\t\tresult.minimumTranslationVector = translationAxis.mult(minDistance);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/** New `Polygon` with the same vertices. */\n\tpublic clone(): Polygon {\n\t\treturn new Polygon(...this._points);\n\t}\n\n\tprivate update(): void {\n\t\tif (this._points.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// edges\n\t\tlet p1: Vec2;\n\t\tlet p2: Vec2;\n\n\t\t// Allocates one Vec2 per edge per call; called every offset/rotate.\n\t\t// Reuse via edges[i].set(...) if profiling shows GC pressure here.\n\t\tthis.edges.length = 0;\n\t\tfor (let i = 0; i < this._points.length; i++) {\n\t\t\tp1 = this._points[i];\n\n\t\t\tif (i + 1 >= this._points.length) {\n\t\t\t\tp2 = this._points[0];\n\t\t\t} else {\n\t\t\t\tp2 = this._points[i + 1];\n\t\t\t}\n\n\t\t\tthis.edges.push(p2.clone().sub(p1));\n\t\t}\n\n\t\t// center\n\t\tlet totalX = 0;\n\t\tlet totalY = 0;\n\n\t\tthis.points.forEach(point => {\n\t\t\ttotalX += point.x;\n\t\t\ttotalY += point.y;\n\t\t});\n\n\t\tthis.center.set(\n\t\t\ttotalX / this._points.length,\n\t\t\ttotalY / this._points.length,\n\t\t);\n\t}\n}\n", "/**\n * Recursively clone a value. Returns primitives and functions as-is (no copy).\n * Cyclic references resolve via an internal `WeakMap`. Explicit branches preserve\n * `Date`, `RegExp`, `Map`, `Set`, `Array`, `ArrayBuffer`, typed arrays, and `DataView`.\n * For plain objects / class instances the prototype is preserved via\n * `Object.create(...)` \u2014 the original constructor is *not* called, so no side\n * effects fire. Symbol keys and non-enumerable data properties are carried via descriptors.\n * Own accessor properties (`get`/`set`) are snapshotted to a data property by invoking\n * the getter on the source; this severs any closure binding to the original instance\n * but also drops live computation on the clone.\n */\nexport function deepClone<T>(obj: T): T {\n\treturn cloneInternal(obj, new WeakMap<object, unknown>());\n}\n\nfunction cloneInternal<T>(obj: T, hash: WeakMap<object, unknown>): T {\n\tif (Object(obj) !== obj || obj instanceof Function) {\n\t\t// primitive or function -> return as-is\n\t\treturn obj;\n\t}\n\n\tconst o = obj as object;\n\n\tif (hash.has(o)) {\n\t\t// cycle / already cloned -> return cached\n\t\treturn hash.get(o) as T;\n\t}\n\n\tif (obj instanceof Date) {\n\t\t// date -> clone via getTime\n\t\tconst cloned = new Date(obj.getTime());\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof RegExp) {\n\t\t// regex -> clone source + flags + lastIndex\n\t\tconst cloned = new RegExp(obj.source, obj.flags);\n\t\tcloned.lastIndex = obj.lastIndex;\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof Map) {\n\t\t// map -> recurse into entries\n\t\tconst cloned = new Map<unknown, unknown>();\n\t\thash.set(o, cloned);\n\t\tobj.forEach((v, k) => {\n\t\t\tcloned.set(cloneInternal(k, hash), cloneInternal(v, hash));\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof Set) {\n\t\t// set -> recurse into items\n\t\tconst cloned = new Set<unknown>();\n\t\thash.set(o, cloned);\n\t\tobj.forEach(v => {\n\t\t\tcloned.add(cloneInternal(v, hash));\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (Array.isArray(obj)) {\n\t\t// array -> recurse into items\n\t\tconst cloned: unknown[] = [];\n\t\thash.set(o, cloned);\n\t\tobj.forEach((item, i) => {\n\t\t\tcloned[i] = cloneInternal(item, hash);\n\t\t});\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof ArrayBuffer) {\n\t\t// arraybuffer -> slice\n\t\tconst cloned = obj.slice(0);\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (obj instanceof DataView) {\n\t\t// dataview -> reslice underlying buffer\n\t\tconst buf = obj.buffer.slice(\n\t\t\tobj.byteOffset,\n\t\t\tobj.byteOffset + obj.byteLength,\n\t\t);\n\t\tconst cloned = new DataView(buf);\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tif (ArrayBuffer.isView(obj)) {\n\t\t// typed array -> slice (preserves subtype)\n\t\tconst cloned = (obj as unknown as Uint8Array).slice();\n\t\thash.set(o, cloned);\n\t\treturn cloned as T;\n\t}\n\n\tconst result = Object.create(Object.getPrototypeOf(o));\n\thash.set(o, result);\n\n\tReflect.ownKeys(o).forEach(key => {\n\t\tconst descriptor = Object.getOwnPropertyDescriptor(o, key)!;\n\t\tif (\"value\" in descriptor) {\n\t\t\tdescriptor.value = cloneInternal(descriptor.value, hash);\n\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\treturn;\n\t\t}\n\t\t// Accessor (get/set) \u2014 snapshot by invoking the getter on the source to\n\t\t// avoid closure-bound captures of the original instance. The clone gets\n\t\t// a plain data property; live computation is lost.\n\t\tconst snapshot = cloneInternal(\n\t\t\t(o as Record<PropertyKey, unknown>)[key as PropertyKey],\n\t\t\thash,\n\t\t);\n\t\tObject.defineProperty(result, key, {\n\t\t\tvalue: snapshot,\n\t\t\twritable: true,\n\t\t\tenumerable: descriptor.enumerable,\n\t\t\tconfigurable: descriptor.configurable,\n\t\t});\n\t});\n\n\treturn result as T;\n}\n", "/**\n * Trim `str` and collapse internal whitespace runs to a single space.\n */\nexport function compact(str: string): string {\n\treturn str.trim().replace(/\\s+/g, \" \");\n}\n\n/**\n * Replace the single character at `index` in `str`. Indexes by code point, so emoji and other supplementary-plane characters count as one. Throws on out-of-range index or multi-character `char`.\n */\nexport function replaceCharAt(\n\tstr: string,\n\tindex: number,\n\tchar: string,\n): string {\n\tconst codePoints = Array.from(str);\n\n\tif (index < 0 || index >= codePoints.length) {\n\t\tthrow new Error(\n\t\t\t`replaceCharAt index out of range: ${index} (length ${codePoints.length})`,\n\t\t);\n\t}\n\n\tconst charPoints = Array.from(char);\n\tif (charPoints.length !== 1) {\n\t\tthrow new Error(\n\t\t\t`replaceCharAt requires a single character, got length ${charPoints.length}`,\n\t\t);\n\t}\n\n\tcodePoints[index] = char;\n\treturn codePoints.join(\"\");\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["delay", "dispose", "bucket", "delay", "_", "_"]
|
|
7
7
|
}
|