q5 2.23.13 → 2.24.1
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/deno.json +1 -1
- package/package.json +1 -1
- package/q5.d.ts +29 -42
- package/q5.js +15 -17
- package/q5.min.js +2 -2
package/deno.json
CHANGED
package/package.json
CHANGED
package/q5.d.ts
CHANGED
|
@@ -1716,7 +1716,7 @@ createCanvas(200);
|
|
|
1716
1716
|
let c = color('lime');
|
|
1717
1717
|
|
|
1718
1718
|
function draw() {
|
|
1719
|
-
set(
|
|
1719
|
+
set(random(200), random(200), c);
|
|
1720
1720
|
updatePixels();
|
|
1721
1721
|
}
|
|
1722
1722
|
*/
|
|
@@ -2376,11 +2376,13 @@ function mouseWheel(e) {
|
|
|
2376
2376
|
|
|
2377
2377
|
// 🧮 math
|
|
2378
2378
|
|
|
2379
|
-
|
|
2380
|
-
* Generates
|
|
2381
|
-
*
|
|
2382
|
-
* If
|
|
2383
|
-
* If
|
|
2379
|
+
/** 🧮
|
|
2380
|
+
* Generates a random value.
|
|
2381
|
+
*
|
|
2382
|
+
* - If no inputs are provided, returns a number between 0 and 1.
|
|
2383
|
+
* - If one numerical input is provided, returns a number between 0 and the provided value.
|
|
2384
|
+
* - If two numerical inputs are provided, returns a number between the two values.
|
|
2385
|
+
* - If an array is provided, returns a random element from the array.
|
|
2384
2386
|
* @param {number | any[]} [low] lower bound (inclusive) or an array
|
|
2385
2387
|
* @param {number} [high] upper bound (exclusive)
|
|
2386
2388
|
* @returns {number | any} a random number or element
|
|
@@ -2390,52 +2392,37 @@ background(200);
|
|
|
2390
2392
|
frameRate(5);
|
|
2391
2393
|
|
|
2392
2394
|
function draw() {
|
|
2393
|
-
circle(100, 100, random(200));
|
|
2394
|
-
}
|
|
2395
|
-
*/
|
|
2396
|
-
function random(low?: number | any[], high?: number): number | any;
|
|
2397
|
-
|
|
2398
|
-
/** 🧮
|
|
2399
|
-
* Generates a random number within the range of the canvas width.
|
|
2400
|
-
* @param {number} [margin] distance to extend (positive) or contract (negative) the range from canvas edges
|
|
2401
|
-
* @returns {number} random x value
|
|
2402
|
-
* @example
|
|
2403
|
-
createCanvas(200, 100);
|
|
2404
|
-
background(200);
|
|
2405
|
-
|
|
2406
|
-
function draw() {
|
|
2407
|
-
circle(randomX(), 50, random(50));
|
|
2395
|
+
circle(100, 100, random(20, 200));
|
|
2408
2396
|
}
|
|
2409
2397
|
* @example
|
|
2410
|
-
createCanvas(200, 100);
|
|
2411
|
-
background(200);
|
|
2412
|
-
|
|
2413
2398
|
function draw() {
|
|
2414
|
-
circle(
|
|
2399
|
+
circle(random(200), random(200), 10);
|
|
2415
2400
|
}
|
|
2416
2401
|
*/
|
|
2417
|
-
function
|
|
2402
|
+
function random(low?: number | any[], high?: number): number | any;
|
|
2418
2403
|
|
|
2419
|
-
/**
|
|
2420
|
-
*
|
|
2421
|
-
*
|
|
2422
|
-
*
|
|
2404
|
+
/**
|
|
2405
|
+
* ___Experimental! May be renamed or removed in the future.___
|
|
2406
|
+
*
|
|
2407
|
+
* Generates a random number within a symmetric range around zero.
|
|
2408
|
+
*
|
|
2409
|
+
* Equivalent to `random(-val, val)`.
|
|
2410
|
+
* @param {number} val absolute maximum value, default is 1
|
|
2411
|
+
* @returns {number} random number between -val and val
|
|
2423
2412
|
* @example
|
|
2424
|
-
createCanvas(200);
|
|
2425
|
-
background(200);
|
|
2426
|
-
|
|
2427
2413
|
function draw() {
|
|
2428
|
-
|
|
2414
|
+
translate(mouseX, mouseY);
|
|
2415
|
+
circle(randSym(5), randSym(5), 5);
|
|
2429
2416
|
}
|
|
2430
2417
|
* @example
|
|
2431
|
-
|
|
2432
|
-
|
|
2418
|
+
let q = await Q5.WebGPU();
|
|
2419
|
+
createCanvas(200, 100);
|
|
2433
2420
|
|
|
2434
|
-
|
|
2435
|
-
circle(
|
|
2436
|
-
}
|
|
2421
|
+
q.draw = () => {
|
|
2422
|
+
circle(randSym(50), 0, random(50));
|
|
2423
|
+
};
|
|
2437
2424
|
*/
|
|
2438
|
-
function
|
|
2425
|
+
function randSym(val: number): number;
|
|
2439
2426
|
|
|
2440
2427
|
/** 🧮
|
|
2441
2428
|
* Calculates the distance between two points.
|
|
@@ -3131,7 +3118,7 @@ let rec = createRecorder();
|
|
|
3131
3118
|
rec.bitrate = 10;
|
|
3132
3119
|
|
|
3133
3120
|
function draw() {
|
|
3134
|
-
circle(mouseX,
|
|
3121
|
+
circle(mouseX, random(height), 10);
|
|
3135
3122
|
}
|
|
3136
3123
|
*/
|
|
3137
3124
|
function createRecorder(): HTMLElement;
|
|
@@ -3158,7 +3145,7 @@ function draw() {
|
|
|
3158
3145
|
* @param {string} fileName
|
|
3159
3146
|
* @example
|
|
3160
3147
|
function draw() {
|
|
3161
|
-
square(mouseX,
|
|
3148
|
+
square(mouseX, random(200), 10);
|
|
3162
3149
|
}
|
|
3163
3150
|
|
|
3164
3151
|
function mousePressed() {
|
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.24
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -16,7 +16,6 @@ function Q5(scope, parent, renderer) {
|
|
|
16
16
|
$._renderer = renderer || Q5.render;
|
|
17
17
|
$['_' + $._renderer] = true;
|
|
18
18
|
}
|
|
19
|
-
$._preloadCount = 0;
|
|
20
19
|
|
|
21
20
|
let autoLoaded = scope == 'auto';
|
|
22
21
|
scope ??= 'global';
|
|
@@ -72,11 +71,13 @@ function Q5(scope, parent, renderer) {
|
|
|
72
71
|
$.deviceOrientation = window.screen?.orientation?.type;
|
|
73
72
|
}
|
|
74
73
|
|
|
74
|
+
$._preloadCount = 0;
|
|
75
75
|
$._incrementPreload = () => q._preloadCount++;
|
|
76
76
|
$._decrementPreload = () => q._preloadCount--;
|
|
77
77
|
|
|
78
78
|
$._usePreload = true;
|
|
79
79
|
$.usePreloadSystem = (v) => ($._usePreload = v);
|
|
80
|
+
$.isPreloadSupported = () => $._usePreload;
|
|
80
81
|
|
|
81
82
|
$._draw = (timestamp) => {
|
|
82
83
|
let ts = timestamp || performance.now();
|
|
@@ -339,7 +340,7 @@ function createCanvas(w, h, opt) {
|
|
|
339
340
|
}
|
|
340
341
|
}
|
|
341
342
|
|
|
342
|
-
Q5.version = Q5.VERSION = '2.
|
|
343
|
+
Q5.version = Q5.VERSION = '2.24';
|
|
343
344
|
|
|
344
345
|
if (typeof document == 'object') {
|
|
345
346
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -2743,6 +2744,8 @@ Q5.modules.dom = ($, q) => {
|
|
|
2743
2744
|
if ($.canvas) $.canvas.parentElement.append(el);
|
|
2744
2745
|
else document.body.append(el);
|
|
2745
2746
|
|
|
2747
|
+
el.elt = el; // p5 compat
|
|
2748
|
+
|
|
2746
2749
|
return el;
|
|
2747
2750
|
};
|
|
2748
2751
|
$.createEl = $.createElement;
|
|
@@ -3391,13 +3394,7 @@ Q5.modules.math = ($, q) => {
|
|
|
3391
3394
|
}
|
|
3392
3395
|
};
|
|
3393
3396
|
|
|
3394
|
-
|
|
3395
|
-
$.randomX = (v = 0) => $.random(-v, $.canvas.w + v);
|
|
3396
|
-
$.randomY = (v = 0) => $.random(-v, $.canvas.h + v);
|
|
3397
|
-
} else {
|
|
3398
|
-
$.randomX = (v = 0) => $.random(-$.canvas.hw - v, $.canvas.hw + v);
|
|
3399
|
-
$.randomY = (v = 0) => $.random(-$.canvas.hh - v, $.canvas.hh + v);
|
|
3400
|
-
}
|
|
3397
|
+
$.randSym = (v = 1) => $.random(-v, v);
|
|
3401
3398
|
|
|
3402
3399
|
$.randomGenerator = (method) => {
|
|
3403
3400
|
if (method == $.LCG) rng1 = lcg();
|
|
@@ -4725,10 +4722,11 @@ Q5.Vector.mult = (v, u) => v.copy().mult(u);
|
|
|
4725
4722
|
Q5.Vector.normalize = (v) => v.copy().normalize();
|
|
4726
4723
|
Q5.Vector.rem = (v, u) => v.copy().rem(u);
|
|
4727
4724
|
Q5.Vector.sub = (v, u) => v.copy().sub(u);
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4725
|
+
Q5.Vector.reflect = (v, n) => v.copy().reflect(n);
|
|
4726
|
+
Q5.Vector.random2D = () => new Q5.Vector().random2D();
|
|
4727
|
+
Q5.Vector.random3D = () => new Q5.Vector().random3D();
|
|
4728
|
+
Q5.Vector.fromAngle = (th, l) => new Q5.Vector().fromAngle(th, l);
|
|
4729
|
+
Q5.Vector.fromAngles = (th, ph, l) => new Q5.Vector().fromAngles(th, ph, l);
|
|
4732
4730
|
Q5.renderers.webgpu = {};
|
|
4733
4731
|
|
|
4734
4732
|
Q5.renderers.webgpu.canvas = ($, q) => {
|
|
@@ -6095,9 +6093,9 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6095
6093
|
}
|
|
6096
6094
|
}
|
|
6097
6095
|
|
|
6098
|
-
if (shapeVertCount
|
|
6099
|
-
|
|
6100
|
-
|
|
6096
|
+
if (!shapeVertCount) return;
|
|
6097
|
+
if (shapeVertCount == 1) return $.point(sv[0], -sv[1]);
|
|
6098
|
+
if (shapeVertCount == 2) return $.line(sv[0], -sv[1], sv[4], -sv[5]);
|
|
6101
6099
|
|
|
6102
6100
|
// close the shape if requested
|
|
6103
6101
|
if (close) {
|
package/q5.min.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.24
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
7
7
|
*/
|
|
8
|
-
function Q5(e,t,r){let a=this;a._q5=!0,a._parent=t,"webgpu-fallback"==r?(a._renderer="c2d",a._webgpu=a._webgpuFallback=!0):(a._renderer=r||Q5.render,a["_"+a._renderer]=!0),a._preloadCount=0;let o,n="auto"==e;if(e??="global","auto"==e){if(!(window.setup||window.update||window.draw))return;e="global"}a._scope=e,"global"==e&&(Q5._hasGlobal=a._isGlobal=!0,o=Q5._esm?globalThis:Q5._server?global:window),"graphics"==e&&(a._graphics=!0);let i=new Proxy(a,{set:(e,t,r)=>(a[t]=r,a._isGlobal&&(o[t]=r),!0)});a.canvas=a.ctx=a.drawingContext=null,a.pixels=[];let s=null,l=!0;a.frameCount=0,a.deltaTime=16,a._targetFrameRate=0,a._targetFrameDuration=16.666666666666668,a._frameRate=a._fps=60,a._loop=!0,a._hooks={postCanvas:[],preRender:[],postRender:[]};let d=0;a.millis=()=>performance.now()-d,a.noCanvas=()=>{a.canvas?.remove&&a.canvas.remove(),a.canvas=0,i.ctx=i.drawingContext=0},window&&(a.windowWidth=window.innerWidth,a.windowHeight=window.innerHeight,a.deviceOrientation=window.screen?.orientation?.type),a._incrementPreload=()=>i._preloadCount++,a._decrementPreload=()=>i._preloadCount--,a._usePreload=!0,a.usePreloadSystem=e=>a._usePreload=e,a._draw=e=>{let t=e||performance.now();if(a._lastFrameTime??=t-a._targetFrameDuration,a._didResize&&(a.windowResized(),a._didResize=!1),a._loop)if(l)s=h(a._draw);else{let e=t+a._targetFrameDuration,r=e-performance.now();for(;r<0;)r+=a._targetFrameDuration;log(r),s=setTimeout((()=>a._draw(e)),r)}else if(a.frameCount&&!a._redraw)return;if(a.frameCount&&l&&!a._redraw){if(t-a._lastFrameTime<a._targetFrameDuration-4)return}i.deltaTime=t-a._lastFrameTime,a._frameRate=1e3/a.deltaTime,i.frameCount++;let r=performance.now();a.resetMatrix(),a._beginRender&&a._beginRender();for(let e of Q5.methods.pre)e.call(a);try{a.draw()}catch(e){throw Q5.errorTolerant||a.noLoop(),a._fes&&a._fes(e),e}for(let e of Q5.methods.post)e.call(a);a.postProcess(),a._render&&a._render(),a._finishRender&&a._finishRender(),i.pmouseX=a.mouseX,i.pmouseY=a.mouseY,i.moveX=i.moveY=0,a._lastFrameTime=t;let o=performance.now();a._fps=Math.round(1e3/(o-r))},a.noLoop=()=>{a._loop=!1,s&&(l?cancelAnimationFrame(s):clearTimeout(s)),s=null},a.loop=()=>{a._loop=!0,a._setupDone&&null==s&&a._draw()},a.isLooping=()=>a._loop,a.redraw=(e=1)=>{a._redraw=!0;for(let t=0;t<e;t++)a._draw();a._redraw=!1},a.remove=()=>{a.noLoop(),a.canvas.remove()},a.frameRate=e=>(e&&(a._targetFrameRate=e,a._targetFrameDuration=1e3/e,a._loop&&a._setupDone&&null!=s&&(l?cancelAnimationFrame(s):clearTimeout(s),s=null),l=e<=60,setTimeout((()=>a._draw()),a._targetFrameDuration)),a._frameRate),a.getTargetFrameRate=()=>a._targetFrameRate||60,a.getFPS=()=>a._fps,a.Element=function(e){this.elt=e},a._elements=[],a.describe=()=>{},a.log=a.print=console.log;for(let e in Q5.modules)Q5.modules[e](a,i);let c=Q5.renderers[a._renderer];for(let e in c)c[e](a,i);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(a[e]=Q5[e]);if(a._graphics)return;if("global"==e){let e=Object.assign({},a);delete e.Color,Object.assign(Q5,e),delete Q5.Q5}for(let e of Q5.methods.init)e.call(a);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof a[e]&&(a[e]=t.bind(a));if("global"==e){let e=Object.getOwnPropertyNames(a);for(let t of e)"_"!=t[0]&&(o[t]=a[t])}"function"==typeof e&&e(a),Q5._instanceCount++;let h=window.requestAnimationFrame||function(e){const t=a._lastFrameTime+a._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},u=o||a;a._isTouchAware=u.touchStarted||u.touchMoved||u.touchEnded,a._isGlobal&&(a.preload=u.preload,a.setup=u.setup,a.draw=u.draw,a.postProcess=u.postProcess),a.preload??=()=>{},a.setup??=()=>{},a.draw??=()=>{},a.postProcess??=()=>{};let p=["setup","postProcess","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","mouseWheel","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of p)u[e]?a._isGlobal&&(a[e]=t=>{try{return u[e](t)}catch(e){throw a._fes&&a._fes(e),e}}):a[e]=()=>{};async function f(){if(a._startDone=!0,a._preloadCount>0||a._g?._preloadCount>0)return h(f);d=performance.now(),await a.setup(),a._setupDone=!0,a.frameCount||(null===a.ctx&&a.createCanvas(200,200),h(a._draw))}function _(){try{a.preload(),a._startDone||f()}catch(e){throw a._fes&&a._fes(e),e}}n?_():setTimeout(_,32)}function createCanvas(e,t,r){if(!Q5._hasGlobal){(new Q5).createCanvas(e,t,r)}}Q5.render="c2d",Q5.renderers={},Q5.modules={},Q5._server="object"==typeof process,Q5._esm=void 0===this,Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{Q5.disableFriendlyErrors||console.error(t+": "+e)},Q5._validateParameters=()=>!0,Q5.methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],Q5._server&&(global.p5??=global.Q5=Q5),"object"==typeof window?window.p5??=window.Q5=Q5:global.window=0,Q5.version=Q5.VERSION="2.23","object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})),Q5.modules.canvas=(e,t)=>{e._Canvas=window.OffscreenCanvas||function(){return document.createElement("canvas")},Q5._server?Q5._createServerCanvas&&(t.canvas=Q5._createServerCanvas(100,100)):"image"!=e._scope&&"graphics"!=e._scope||(t.canvas=new e._Canvas(100,100)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas());let r=e.canvas;if(e.width=200,e.height=200,e._pixelDensity=1,e.displayDensity=()=>window.devicePixelRatio||1,r&&(r.width=200,r.height=200,"image"!=e._scope&&(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity()))),e._adjustDisplay=()=>{r.style&&(r.style.width=r.w+"px",r.style.height=r.h+"px")},e.createCanvas=function(t,a,o){"object"==typeof t&&(o=t,t=null),o??=arguments[3],"string"==typeof o&&(o={renderer:o});let n=Object.assign({},Q5.canvasOptions);if("object"==typeof o&&Object.assign(n,o),"image"!=e._scope)if("graphics"==e._scope)e._pixelDensity=this._pixelDensity;else if(window.IntersectionObserver){let t=!1;new IntersectionObserver((a=>{r.visible=a[0].isIntersecting,t||(e._wasLooping=e._loop,t=!0),r.visible?e._wasLooping&&!e._loop&&e.loop():(e._wasLooping=e._loop,e.noLoop())})).observe(r)}e._setCanvasSize(t,a),Object.assign(r,n);let i=e._createCanvas(r.w,r.h,n);if(e._hooks)for(let t of e._hooks.postCanvas)t();return e._addEventMethods&&e._addEventMethods(r),i},e.createGraphics=function(t,r,a={}){"string"==typeof a&&(a={renderer:a});let o=new Q5("graphics",void 0,a.renderer||(e._webgpuFallback?"webgpu-fallback":e._renderer));a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace,o.createCanvas.call(e,t,r,a);let n=o._pixelDensity*e._defaultImageScale;return o.defaultWidth=t*n,o.defaultHeight=r*n,o},e._setCanvasSize=(a,o)=>{o??=a??window.innerHeight,a??=window.innerWidth,r.w=a=Math.ceil(a),r.h=o=Math.ceil(o),t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=o/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(o*e._pixelDensity),e._da?e.flexibleCanvas(e._dau):(t.width=a,t.height=o),e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay()},e._setImageSize=(a,o)=>{t.width=r.w=a,t.height=r.h=o,t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=o/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(o*e._pixelDensity)},e.defaultImageScale=t=>t?e._defaultImageScale=t:e._defaultImageScale,e.defaultImageScale(.5),"image"!=e._scope){if(r&&"graphics"!=e._scope){function a(){let t=e._parent;t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),r.parent(t)}r.parent=t=>{function a(){e.frameCount>1&&(e._didResize=!0,e._adjustDisplay())}r.parentElement&&r.parentElement.removeChild(r),"string"==typeof t&&(t=document.getElementById(t)),t.append(r),"function"==typeof ResizeObserver?(e._ro&&e._ro.disconnect(),e._ro=new ResizeObserver(a),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",a)},document.body?a():document.addEventListener("DOMContentLoaded",a)}e.resizeCanvas=(t,a)=>{if(!e.ctx)return e.createCanvas(t,a);t==r.w&&a==r.h||e._resizeCanvas(t,a)},r&&!Q5._createServerCanvas&&(r.resize=e.resizeCanvas),e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._resizeCanvas(r.w,r.h),t):e._pixelDensity,e.flexibleCanvas=(a=400)=>{a?(e._da=r.width/(a*e._pixelDensity),t.width=e._dau=a,t.height=r.h/r.w*a):e._da=0},e._styleNames=["_fill","_stroke","_strokeWeight","_doStroke","_doFill","_strokeSet","_fillSet","_shadow","_doShadow","_shadowOffsetX","_shadowOffsetY","_shadowBlur","_tint","_colorMode","_colorFormat","Color","_imageMode","_rectMode","_ellipseMode","_textSize","_textAlign","_textBaseline"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t)},e.popStyles=()=>{let r=e._styles.pop();for(let t of e._styleNames)e[t]=r[t];t.Color=r.Color},window&&"graphics"!=e._scope&&window.addEventListener("resize",(()=>{e._didResize=!0,t.windowWidth=window.innerWidth,t.windowHeight=window.innerHeight,t.deviceOrientation=window.screen?.orientation?.type}))}},Q5.CENTER="center",Q5.LEFT="left",Q5.RIGHT="right",Q5.TOP="top",Q5.BOTTOM="bottom",Q5.BASELINE="alphabetic",Q5.MIDDLE="middle",Q5.NORMAL="normal",Q5.ITALIC="italic",Q5.BOLD="bold",Q5.BOLDITALIC="italic bold",Q5.ROUND="round",Q5.SQUARE="butt",Q5.PROJECT="square",Q5.MITER="miter",Q5.BEVEL="bevel",Q5.NONE="none",Q5.SIMPLE="simple",Q5.CHORD_OPEN=0,Q5.PIE_OPEN=1,Q5.PIE=2,Q5.CHORD=3,Q5.RADIUS="radius",Q5.CORNER="corner",Q5.CORNERS="corners",Q5.OPEN=0,Q5.CLOSE=1,Q5.VIDEO="video",Q5.AUDIO="audio",Q5.LANDSCAPE="landscape",Q5.PORTRAIT="portrait",Q5.BLEND="source-over",Q5.REMOVE="destination-out",Q5.ADD="lighter",Q5.DARKEST="darken",Q5.LIGHTEST="lighten",Q5.DIFFERENCE="difference",Q5.SUBTRACT="subtract",Q5.EXCLUSION="exclusion",Q5.MULTIPLY="multiply",Q5.SCREEN="screen",Q5.REPLACE="copy",Q5.OVERLAY="overlay",Q5.HARD_LIGHT="hard-light",Q5.SOFT_LIGHT="soft-light",Q5.DODGE="color-dodge",Q5.BURN="color-burn",Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.SEPIA=9,Q5.BRIGHTNESS=10,Q5.SATURATION=11,Q5.CONTRAST=12,Q5.HUE_ROTATE=13,Q5.C2D=Q5.P2D=Q5.P2DHDR="c2d",Q5.WEBGL="webgl",Q5.WEBGPU="webgpu",Q5.canvasOptions={alpha:!1,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",Q5.renderers.c2d={},Q5.renderers.c2d.canvas=(e,t)=>{let r=e.canvas;if(e.colorMode&&e.colorMode("rgb",255),e._createCanvas=function(a,o,n){if(r)return t.ctx=t.drawingContext=r.getContext("2d",n),"image"!=e._scope&&(e.ctx.fillStyle=e._fill="white",e.ctx.strokeStyle=e._stroke="black",e.ctx.lineCap="round",e.ctx.lineJoin="miter",e.ctx.textAlign="left",e._strokeWeight=1),e.ctx.scale(e._pixelDensity,e._pixelDensity),e.ctx.save(),r;console.error("q5 canvas could not be created. skia-canvas and jsdom packages not found.")},e.clear=()=>{e.ctx.save(),e.ctx.resetTransform(),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.restore()},"image"==e._scope)return;e.background=function(t){e.ctx.save(),e.ctx.resetTransform(),e.ctx.globalAlpha=1,t.canvas?e.image(t,0,0,e.canvas.width,e.canvas.height):(Q5.Color&&!t._q5Color&&(t=e.color(...arguments)),e.ctx.fillStyle=t.toString(),e.ctx.fillRect(0,0,e.canvas.width,e.canvas.height)),e.ctx.restore()},e._resizeCanvas=(t,a)=>{let o,n={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(n[t]=e.ctx[t]);if(delete n.canvas,e.frameCount>1){o=new e._Canvas(r.width,r.height),o.w=r.w,o.h=r.h,o.getContext("2d").drawImage(r,0,0)}e._setCanvasSize(t,a);for(let t in n)e.ctx[t]=n[t];e.scale(e._pixelDensity),o&&e.ctx.drawImage(o,0,0,o.w,o.h)},e.fill=function(t){if(e._doFill=e._fillSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doFill=!1;e.ctx.fillStyle=e._fill=t.toString()},e.stroke=function(t){if(e._doStroke=e._strokeSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doStroke=!1;e.ctx.strokeStyle=e._stroke=t.toString()},e.strokeWeight=t=>{t||(e._doStroke=!1),e._da&&(t*=e._da),e.ctx.lineWidth=e._strokeWeight=t||1e-4},e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.opacity=t=>e.ctx.globalAlpha=t,e._doShadow=!1,e._shadowOffsetX=e._shadowOffsetY=e._shadowBlur=10,e.shadow=function(t){if(Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doShadow=!1;e.ctx.shadowColor=e._shadow=t.toString(),e._doShadow=!0,e.ctx.shadowOffsetX||=e._shadowOffsetX,e.ctx.shadowOffsetY||=e._shadowOffsetY,e.ctx.shadowBlur||=e._shadowBlur},e.shadowBox=(t,r,a)=>{e.ctx.shadowOffsetX=e._shadowOffsetX=t,e.ctx.shadowOffsetY=e._shadowOffsetY=r||t,e.ctx.shadowBlur=e._shadowBlur=a||0},e.noShadow=()=>{e._doShadow=!1,e.ctx.shadowOffsetX=e.ctx.shadowOffsetY=e.ctx.shadowBlur=0},e.translate=(t,r)=>{e._da&&(t*=e._da,r*=e._da),e.ctx.translate(t,r)},e.rotate=t=>{e._angleMode&&(t=e.radians(t)),e.ctx.rotate(t)},e.scale=(t,r)=>{t.x&&(r=t.y,t=t.x),r??=t,e.ctx.scale(t,r)},e.applyMatrix=(t,r,a,o,n,i)=>e.ctx.transform(t,r,a,o,n,i),e.shearX=t=>e.ctx.transform(1,0,e.tan(t),1,0,0),e.shearY=t=>e.ctx.transform(1,e.tan(t),0,1,0,0),e.resetMatrix=()=>{e.ctx&&(e.ctx.resetTransform(),e.scale(e._pixelDensity),e._webgpu&&e.translate(e.halfWidth,e.halfHeight))},e.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore();let a=e.popStyles;e.popStyles=()=>{a(),e.ctx.fillStyle=e._fill,e.ctx.strokeStyle=e._stroke,e.ctx.lineWidth=e._strokeWeight,e.ctx.shadowColor=e._shadow,e.ctx.shadowOffsetX=e._doShadow?e._shadowOffsetX:0,e.ctx.shadowOffsetY=e._doShadow?e._shadowOffsetY:0,e.ctx.shadowBlur=e._doShadow?e._shadowBlur:0},e.push=()=>{e.ctx.save(),e.pushStyles()},e.pop=()=>{e.ctx.restore(),a()}},Q5.renderers.c2d.shapes=e=>{e._doStroke=!0,e._doFill=!0,e._strokeSet=!1,e._fillSet=!1,e._ellipseMode=Q5.CENTER,e._rectMode=Q5.CORNER;let t=!0,r=[];function a(){e._doFill&&e.ctx.fill(),e._doStroke&&e.ctx.stroke()}e.blendMode=t=>e.ctx.globalCompositeOperation=t,e.strokeCap=t=>e.ctx.lineCap=t,e.strokeJoin=t=>e.ctx.lineJoin=t,e.ellipseMode=t=>e._ellipseMode=t,e.rectMode=t=>e._rectMode=t,e.curveDetail=()=>{},e.line=(t,r,a,o)=>{e._doStroke&&(e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(a,o),e.ctx.stroke())};const o=2*Math.PI;function n(t,r,a,n,i,s,l){if(e._angleMode&&(i=e.radians(i),s=e.radians(s)),(i%=o)<0&&(i+=o),(s%=o)<0&&(s+=o),i>s&&(s+=o),i==s)return e.ellipse(t,r,a,n);if(a/=2,n/=2,e._doFill||l!=e.PIE_OPEN||(l=e.CHORD_OPEN),e.ctx.beginPath(),e.ctx.ellipse(t,r,a,n,0,i,s),l!=e.PIE&&l!=e.PIE_OPEN||e.ctx.lineTo(t,r),e._doFill&&e.ctx.fill(),e._doStroke){if(l!=e.PIE&&l!=e.CHORD||e.ctx.closePath(),l!=e.PIE_OPEN)return e.ctx.stroke();e.ctx.beginPath(),e.ctx.ellipse(t,r,a,n,0,i,s),e.ctx.stroke()}}function i(t,r,n,i){e.ctx.beginPath(),e.ctx.ellipse(t,r,n/2,i/2,0,0,o),a()}function s(t,r,o,n,i,l,d,c){return void 0===i?function(t,r,o,n){e._da&&(t*=e._da,r*=e._da,o*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.rect(t,r,o,n),a()}(t,r,o,n):void 0===l?s(t,r,o,n,i,i,i,i):(e._da&&(t*=e._da,r*=e._da,o*=e._da,n*=e._da,i*=e._da,l*=e._da,c*=e._da,d*=e._da),e.ctx.roundRect(t,r,o,n,[i,l,d,c]),void a())}e.arc=(t,r,a,o,i,s,l)=>{if(i==s)return e.ellipse(t,r,a,o);e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),l??=e.PIE_OPEN,e._ellipseMode==e.CENTER?n(t,r,a,o,i,s,l):e._ellipseMode==e.RADIUS?n(t,r,2*a,2*o,i,s,l):e._ellipseMode==e.CORNER?n(t+a/2,r+o/2,a,o,i,s,l):e._ellipseMode==e.CORNERS&&n((t+a)/2,(r+o)/2,a-t,o-r,i,s,l)},e.ellipse=(t,r,a,o)=>{o??=a,e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),e._ellipseMode==e.CENTER?i(t,r,a,o):e._ellipseMode==e.RADIUS?i(t,r,2*a,2*o):e._ellipseMode==e.CORNER?i(t+a/2,r+o/2,a,o):e._ellipseMode==e.CORNERS&&i((t+a)/2,(r+o)/2,a-t,o-r)},e.circle=(t,r,n)=>{e._ellipseMode==e.CENTER?(e._da&&(t*=e._da,r*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.arc(t,r,n/2,0,o),a()):e.ellipse(t,r,n,n)},e.point=(t,r)=>{e._doStroke&&(t.x&&(r=t.y,t=t.x),e._da&&(t*=e._da,r*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(t,r),e.ctx.stroke())},e.rect=(t,r,a,o=a,n,i,l,d)=>{e._rectMode==e.CENTER?s(t-a/2,r-o/2,a,o,n,i,l,d):e._rectMode==e.RADIUS?s(t-a,r-o,2*a,2*o,n,i,l,d):e._rectMode==e.CORNER?s(t,r,a,o,n,i,l,d):e._rectMode==e.CORNERS&&s(t,r,a-t,o-r,n,i,l,d)},e.square=(t,r,a,o,n,i,s)=>e.rect(t,r,a,a,o,n,i,s),e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(a,o)=>{e._da&&(a*=e._da,o*=e._da),r=[],t?e.ctx.moveTo(a,o):e.ctx.lineTo(a,o),t=!1},e.bezierVertex=(t,a,o,n,i,s)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da),r=[],e.ctx.bezierCurveTo(t,a,o,n,i,s)},e.quadraticVertex=(t,a,o,n)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da),r=[],e.ctx.quadraticCurveTo(t,a,o,n)},e.bezier=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,o,n,i,s,l),e.endShape()},e.triangle=(t,r,a,o,n,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(e.CLOSE)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),a()},e.curveVertex=(a,o)=>{if(e._da&&(a*=e._da,o*=e._da),r.push([a,o]),r.length<4)return;let n=r.at(-4),i=r.at(-3),s=r.at(-2),l=r.at(-1),d=i[0]+(s[0]-n[0])/6,c=i[1]+(s[1]-n[1])/6,h=s[0]-(l[0]-i[0])/6,u=s[1]-(l[1]-i[1])/6;t&&(e.ctx.moveTo(i[0],i[1]),t=!1),e.ctx.bezierCurveTo(d,c,h,u,s[0],s[1])},e.curve=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,o),e.curveVertex(n,i),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,a,o)=>{const n=o*o*o,i=o*o;return e*(-.5*n+i-.5*o)+t*(1.5*n-2.5*i+1)+r*(-1.5*n+2*i+.5*o)+a*(.5*n-.5*i)},e.bezierPoint=(e,t,r,a,o)=>{const n=1-o;return Math.pow(n,3)*e+3*Math.pow(n,2)*o*t+3*n*Math.pow(o,2)*r+Math.pow(o,3)*a},e.curveTangent=(e,t,r,a,o)=>{const n=o*o;return e*(-3*n/2+2*o-.5)+t*(9*n/2-5*o)+r*(-9*n/2+4*o+.5)+a*(3*n/2-o)},e.bezierTangent=(e,t,r,a,o)=>{const n=1-o;return 3*a*Math.pow(o,2)-3*r*Math.pow(o,2)+6*r*n*o-6*t*n*o+3*t*Math.pow(n,2)-3*e*Math.pow(n,2)},e.erase=function(t,r){255==e._colorFormat&&(t&&(t/=255),r&&(r/=255)),e.ctx.save(),e.ctx.globalCompositeOperation="destination-out",e.ctx.fillStyle=`rgb(0 0 0 / ${t||1})`,e.ctx.strokeStyle=`rgb(0 0 0 / ${r||1})`},e.noErase=function(){e.ctx.globalCompositeOperation="source-over",e.ctx.restore()},e.inFill=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInPath(t*a,r*a)},e.inStroke=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInStroke(t*a,r*a)}},Q5.renderers.c2d.image=(e,t)=>{Q5.Image??=class{constructor(e,r,a={}){let o=this;o._scope="image",o.canvas=o.ctx=o.drawingContext=null,o.pixels=[],Q5.modules.canvas(o,o);let n=Q5.renderers.c2d;for(let e of["canvas","image","soft_filters"])n[e]&&n[e](o,o);o._pixelDensity=a.pixelDensity||1,o.createCanvas(e,r,a);let i=o._pixelDensity*t._defaultImageScale;o.defaultWidth=e*i,o.defaultHeight=r*i,delete o.createCanvas,o._loop=!1}get w(){return this.width}get h(){return this.height}},e._tint=null;let r=null;e.createImage=(t,r,a)=>(a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace||Q5.canvasOptions.colorSpace,new Q5.Image(t,r,a)),e.loadImage=function(r,a,o){if(r.canvas)return r;if("gif"==r.slice(-3).toLowerCase())throw new Error("q5 doesn't support GIFs. Use a video or p5play animation instead. https://github.com/q5js/q5.js/issues/84");t._preloadCount++;let n=[...arguments].at(-1);"object"==typeof n?(o=n,a=null):o=null;let i=e.createImage(1,1,o),s=i._pixelDensity,l=new window.Image;return l.crossOrigin="Anonymous",i._loader=new Promise(((r,o)=>{l.onload=()=>{l._pixelDensity=s,i.defaultWidth=l.width*e._defaultImageScale,i.defaultHeight=l.height*e._defaultImageScale,i.naturalWidth=l.naturalWidth||l.width,i.naturalHeight=l.naturalHeight||l.height,i._setImageSize(Math.ceil(i.naturalWidth/s),Math.ceil(i.naturalHeight/s)),i.ctx.drawImage(l,0,0),t._preloadCount--,a&&a(i),delete i._loader,r(i)},l.onerror=e=>{t._preloadCount--,o(e)}})),i.src=l.src=r,e._usePreload?i:i._loader},e.imageMode=t=>e._imageMode=t,e.image=(t,r,a,o,n,i=0,s=0,l,d)=>{if(!t)return;let c=t.canvas||t;o??=t.defaultWidth||c.width||t.videoWidth,n??=t.defaultHeight||c.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*o,a-=.5*n),e._da&&(r*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da,l*=e._da,d*=e._da);let h=t._pixelDensity||1;if(l?l*=h:l=c.width||c.videoWidth,d?d*=h:d=c.height||c.videoHeight,e._tint){if(t._retint||t._tint!=e._tint){t._tintImg??=e.createImage(t.w,t.h,{pixelDensity:h}),t._tintImg.width==t.width&&t._tintImg.height==t.height||t._tintImg.resize(t.w,t.h);let r=t._tintImg.ctx;r.globalCompositeOperation="copy",r.fillStyle=e._tint,r.fillRect(0,0,t.width,t.height),t.canvas.alpha&&(r.globalCompositeOperation="destination-in",r.drawImage(c,0,0,t.width,t.height)),r.globalCompositeOperation="multiply",r.drawImage(c,0,0,t.width,t.height),t._tint=e._tint,t._retint=!1}c=t._tintImg.canvas}t.flipped&&(e.ctx.save(),e.ctx.translate(r+o,0),e.ctx.scale(-1,1),r=0),e.ctx.drawImage(c,i*h,s*h,l,d,r,a,o,n),t.flipped&&e.ctx.restore()},e.filter=(t,r)=>{e.ctx.save();let a="";if(e.ctx.filter){if("string"==typeof t)a=t;else if(t==Q5.GRAY)a="saturate(0%)";else if(t==Q5.INVERT)a="invert(100%)";else if(t==Q5.BLUR){a=`blur(${Math.ceil(r*e._pixelDensity)||1}px)`}else if(t==Q5.THRESHOLD){r??=.5,a=`saturate(0%) brightness(${Math.floor(.5/Math.max(r,1e-5)*100)}%) contrast(1000000%)`}else if(t==Q5.SEPIA)a=`sepia(${r??1})`;else if(t==Q5.BRIGHTNESS)a=`brightness(${r??1})`;else if(t==Q5.SATURATION)a=`saturate(${r??1})`;else if(t==Q5.CONTRAST)a=`contrast(${r??1})`;else if(t==Q5.HUE_ROTATE){a=`hue-rotate(${r}${0==e._angleMode?"rad":"deg"})`}if(a&&(e.ctx.filter=a,"none"==e.ctx.filter))throw new Error(`Invalid filter format: ${t}`)}a||e._softFilter(t,r),e.ctx.globalCompositeOperation="source-over",e.ctx.drawImage(e.canvas,0,0,e.canvas.w,e.canvas.h),e.ctx.restore(),e.modified=e._retint=!0},"image"==e._scope&&(e.resize=(t,r)=>{let a=e.canvas,o=new e._Canvas(a.width,a.height);o.getContext("2d",{colorSpace:a.colorSpace}).drawImage(a,0,0),e._setImageSize(t,r),e.defaultWidth=a.width*e._defaultImageScale,e.defaultHeight=a.height*e._defaultImageScale,e.ctx.clearRect(0,0,a.width,a.height),e.ctx.drawImage(o,0,0,a.width,a.height),e.modified=e._retint=!0}),e._getImageData=(t,r,a,o)=>e.ctx.getImageData(t,r,a,o,{colorSpace:e.canvas.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,r=e.canvas.width,a=e.canvas.height,o=e._getImageData(0,0,r,a).data,n=r,i=0,s=a,l=0,d=3;for(let e=0;e<a;e++)for(let t=0;t<r;t++)0!==o[d]&&(t<n&&(n=t),t>i&&(i=t),e<s&&(s=e),e>l&&(l=e)),d+=4;return s=Math.floor(s/t),l=Math.floor(l/t),n=Math.floor(n/t),i=Math.floor(i/t),e.get(n,s,i-n+1,l-s+1)},e.mask=t=>{e.ctx.save(),e.ctx.resetTransform();let r=e.ctx.globalCompositeOperation;e.ctx.globalCompositeOperation="destination-in",e.ctx.drawImage(t.canvas,0,0),e.ctx.globalCompositeOperation=r,e.ctx.restore(),e.modified=e._retint=!0},e.inset=(t,r,a,o,n,i,s,l)=>{let d=e._pixelDensity||1;e.ctx.drawImage(e.canvas,t*d,r*d,a*d,o*d,n,i,s,l),e.modified=e._retint=!0},e.copy=()=>{let t=e.get();for(let r in e)"function"==typeof e[r]||/(canvas|ctx|texture|textureIndex)/.test(r)||(t[r]=e[r]);return t},e.get=(t,r,a,o)=>{let n=e._pixelDensity||1;if(void 0!==t&&void 0===a){let a=e._getImageData(t*n,r*n,1,1).data;return[a[0],a[1],a[2],a[3]/255]}t=Math.floor(t||0)*n,r=Math.floor(r||0)*n,a??=e.width,o??=e.height;let i=e.createImage(a,o,{pixelDensity:n});return i.ctx.drawImage(e.canvas,t,r,a*n,o*n,0,0,a,o),i.width=a,i.height=o,i},e.set=(t,r,a)=>{if(t=Math.floor(t),r=Math.floor(r),e.modified=e._retint=!0,a.canvas){let o=e._tint;return e._tint=null,e.image(a,t,r),void(e._tint=o)}e.pixels.length||e.loadPixels();let o=e._pixelDensity||1;for(let n=0;n<o;n++)for(let i=0;i<o;i++){let s=4*((r*o+n)*e.canvas.width+t*o+i);e.pixels[s]=a.r,e.pixels[s+1]=a.g,e.pixels[s+2]=a.b,e.pixels[s+3]=a.a}},e.loadPixels=()=>{r=e._getImageData(0,0,e.canvas.width,e.canvas.height),t.pixels=r.data},e.updatePixels=()=>{null!=r&&(e.ctx.putImageData(r,0,0),e.modified=e._retint=!0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,"image"!=e._scope&&(e._saveCanvas=async(e,t)=>{if((e=e.canvas||e)instanceof OffscreenCanvas){const r=await e.convertToBlob({type:"image/"+t});return await new Promise((e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(r)}))}return e.toDataURL("image/"+t)},e.tint=function(t){e._tint=(t._q5Color?t:e.color(...arguments)).toString()},e.noTint=()=>e._tint=null)},Q5.renderers.c2d.soft_filters=e=>{let t=null;function r(){let r=e.canvas.width*e.canvas.height*4;t&&t.length==r||(t=new Uint8ClampedArray(r))}e._softFilter=(a,o)=>{e._filters||(e._filters=[],e._filters[Q5.THRESHOLD]=(e,t)=>{void 0===t?t=127.5:t*=255;for(let r=0;r<e.length;r+=4){const a=.2126*e[r]+.7152*e[r+1]+.0722*e[r+2];e[r]=e[r+1]=e[r+2]=a>=t?255:0}},e._filters[Q5.GRAY]=e=>{for(let t=0;t<e.length;t+=4){const r=.2126*e[t]+.7152*e[t+1]+.0722*e[t+2];e[t]=e[t+1]=e[t+2]=r}},e._filters[Q5.OPAQUE]=e=>{for(let t=0;t<e.length;t+=4)e[t+3]=255},e._filters[Q5.INVERT]=e=>{for(let t=0;t<e.length;t+=4)e[t]=255-e[t],e[t+1]=255-e[t+1],e[t+2]=255-e[t+2]},e._filters[Q5.POSTERIZE]=(e,t=4)=>{let r=t-1;for(let a=0;a<e.length;a+=4)e[a]=255*(e[a]*t>>8)/r,e[a+1]=255*(e[a+1]*t>>8)/r,e[a+2]=255*(e[a+2]*t>>8)/r},e._filters[Q5.DILATE]=(a,o)=>{o??=Math.max,r(),t.set(a);let[n,i]=[e.canvas.width,e.canvas.height];for(let e=0;e<i;e++)for(let r=0;r<n;r++){let s=4*Math.max(r-1,0),l=4*Math.min(r+1,n-1),d=4*Math.max(e-1,0)*n,c=4*Math.min(e+1,i-1)*n,h=4*e*n,u=4*r;for(let e=0;e<4;e++){let r=e+d,n=e+c,i=e+h;a[h+u+e]=o(t[r+u],t[i+s],t[i+u],t[i+l],t[n+u])}}},e._filters[Q5.ERODE]=t=>{e._filters[Q5.DILATE](t,Math.min)},e._filters[Q5.BLUR]=(a,o)=>{o=o||1,o=Math.floor(o*e._pixelDensity),r(),t.set(a);let n=2*o+1,i=function(e){let t=new Float32Array(e),r=.3*o+.8,a=r*r*2;for(let o=0;o<e;o++){let n=o-e/2,i=Math.exp(-n*n/a)/(2.5066282746*r);t[o]=i}return t}(n),[s,l]=[e.canvas.width,e.canvas.height];for(let e=0;e<l;e++)for(let r=0;r<s;r++){let l=0,d=0,c=0,h=0;for(let a=0;a<n;a++){let n=4*(e*s+Math.min(Math.max(r-o+a,0),s-1));l+=t[n]*i[a],d+=t[n+1]*i[a],c+=t[n+2]*i[a],h+=t[n+3]*i[a]}let u=4*(e*s+r);a[u]=l,a[u+1]=d,a[u+2]=c,a[u+3]=h}t.set(a);for(let e=0;e<l;e++)for(let r=0;r<s;r++){let d=0,c=0,h=0,u=0;for(let a=0;a<n;a++){let n=4*(Math.min(Math.max(e-o+a,0),l-1)*s+r);d+=t[n]*i[a],c+=t[n+1]*i[a],h+=t[n+2]*i[a],u+=t[n+3]*i[a]}let p=4*(e*s+r);a[p]=d,a[p+1]=c,a[p+2]=h,a[p+3]=u}});let n=e._getImageData(0,0,e.canvas.width,e.canvas.height);e._filters[a](n.data,o),e.ctx.putImageData(n,0,0)}},Q5.renderers.c2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",a=!1,o=15,n=3,i="normal",s="normal",l=!1,d=0,c=[],h=!1,u=!1,p=0,f=12e3,_=e._textCache={};e.loadFont=(r,a)=>{t._preloadCount++;let o=r.split("/").pop().split(".")[0].replace(" ",""),n=new FontFace(o,`url(${r})`);return document.fonts.add(n),n._loader=(async()=>{let e;try{await n.load()}catch(t){e=t}if(t._preloadCount--,delete n._loader,e)throw e;return a&&a(n),n})(),e.textFont(o),e._usePreload?n:n._loader},e.textFont=e=>{if(e&&"string"!=typeof e&&(e=e.family),!e||e==r)return r;r=e,l=!0,d=-1},e.textSize=t=>{if(null==t)return e._textSize;e._da&&(t*=e._da),e._textSize=t,l=!0,d=-1,a||(o=1.25*t,n=o-t)},e.textStyle=e=>{if(!e)return i;i=e,l=!0,d=-1},e.textWeight=e=>{if(!e)return s;s=e,l=!0,d=-1},e.textLeading=t=>null==t?o||1.25*e._textSize:(a=!0,t==o?o:(e._da&&(t*=e._da),o=t,n=t-e._textSize,void(d=-1))),e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)};const g=()=>{e.ctx.font=`${i} ${s} ${e._textSize}px ${r}`,l=!1};e.textWidth=t=>(l&&g(),e.ctx.measureText(t).width),e.textAscent=t=>(l&&g(),e.ctx.measureText(t).actualBoundingBoxAscent),e.textDescent=t=>(l&&g(),e.ctx.measureText(t).actualBoundingBoxDescent),e.textFill=e.fill,e.textStroke=e.stroke;e.textCache=(e,t)=>(t&&(f=t),void 0!==e&&(h=e),h),e.createTextImage=(t,r,a)=>{u=!0;let o=e.text(t,0,0,r,a);return u=!1,o};let m=[];e.text=(t,a,s,x,v)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString(),e._da&&(a*=e._da,s*=e._da);let y,b,w,S,C=e.ctx;if(l&&g(),(h||u)&&(-1==d&&(()=>{let t=r+e._textSize+i+o,a=5381;for(let e=0;e<t.length;e++)a=33*a^t.charCodeAt(e);d=a>>>0})(),y=_[t],y&&(y=y[d]),y)){if(y._fill==e._fill&&y._stroke==e._stroke&&y._strokeWeight==e._strokeWeight)return u?y:e.textImage(y,a,s);y.clear()}if(-1==t.indexOf("\n")?m[0]=t:m=t.split("\n"),t.length>x){let e=[];for(let t of m){let r=0;for(;r<t.length;){let a=r+x;if(a>=t.length){e.push(t.slice(r));break}let o=t.lastIndexOf(" ",a);(-1===o||o<r)&&(o=a),e.push(t.slice(r,o)),r=o+1}}m=e}if(h||u){if(b=0,w=o*m.length,y)y.modified=!0;else{let r=e.ctx.textBaseline;e.ctx.textBaseline="alphabetic";let a=C.measureText(" "),i=a.fontBoundingBoxAscent,s=a.fontBoundingBoxDescent;e.ctx.textBaseline=r,y=e.createImage.call(e,Math.ceil(C.measureText(t).width),Math.ceil(w+s),{pixelDensity:e._pixelDensity}),y._ascent=i,y._descent=s,y._top=s+n,y._middle=y._top+.5*i,y._bottom=y._top+i,y._leading=o}y._fill=e._fill,y._stroke=e._stroke,y._strokeWeight=e._strokeWeight,C=y.ctx,C.font=e.ctx.font,C.fillStyle=e._fill,C.strokeStyle=e._stroke,C.lineWidth=e.ctx.lineWidth}else b=a,w=s;e._fillSet||(S=C.fillStyle,C.fillStyle="black");let M=0;for(let t of m)if(e._doStroke&&e._strokeSet&&C.strokeText(t,b,w),e._doFill&&C.fillText(t,b,w),w+=o,M++,M>=v)break;if(m=[],e._fillSet||(C.fillStyle=S),h||u){if(c.push(d),(_[t]??={})[d]=y,p++,p>f){let e=Math.ceil(p/2),t=c.splice(0,e);for(let e in _){e=_[e];for(let r of t)delete e[r]}p-=e}if(u)return y;e.textImage(y,a,s)}},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let o=e._imageMode;e._imageMode="corner";let n=e._textAlign;"center"==n?r-=t.canvas.hw:"right"==n&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"middle"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=o}},Q5.fonts=[],Q5.modules.color=(e,t)=>{e.RGB=e.RGBA=e.RGBHDR=e._colorMode="rgb",e.HSL="hsl",e.HSB="hsb",e.OKLCH="oklch",e.SRGB="srgb",e.DISPLAY_P3="display-p3",e.colorMode=(r,a,o)=>{e._colorMode=r;let n="srgb"==e.canvas.colorSpace||"srgb"==o;a??="rgb"==r&&(e._c2d||n)?255:1,e._colorFormat="integer"==a||255==a?255:1,"oklch"==r?t.Color=Q5.ColorOKLCH:"hsl"==r?t.Color=n?Q5.ColorHSL:Q5.ColorHSL_P3:"hsb"==r?t.Color=n?Q5.ColorHSB:Q5.ColorHSB_P3:(255==e._colorFormat?t.Color=n?Q5.ColorRGB_8:Q5.ColorRGB_P3_8:t.Color=n?Q5.ColorRGB:Q5.ColorRGB_P3,e._colorMode="rgb")},e._namedColors={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],cyan:[0,255,255],darkviolet:[148,0,211],gold:[255,215,0],green:[0,128,0],gray:[128,128,128],grey:[128,128,128],hotpink:[255,105,180],indigo:[75,0,130],khaki:[240,230,140],lightgreen:[144,238,144],lime:[0,255,0],magenta:[255,0,255],navy:[0,0,128],orange:[255,165,0],olive:[128,128,0],peachpuff:[255,218,185],pink:[255,192,203],purple:[128,0,128],red:[255,0,0],skyblue:[135,206,235],tan:[210,180,140],turquoise:[64,224,208],transparent:[0,0,0,0],white:[255,255,255],violet:[238,130,238],yellow:[255,255,0]},e.color=(t,r,a,o)=>{let n=e.Color;if(t._q5Color)return new n(...t.levels);if(null==r){if("string"==typeof t){if("#"==t[0])t.length<=5?(t.length>4&&(o=parseInt(t[4]+t[4],16)),a=parseInt(t[3]+t[3],16),r=parseInt(t[2]+t[2],16),t=parseInt(t[1]+t[1],16)):(t.length>7&&(o=parseInt(t.slice(7,9),16)),a=parseInt(t.slice(5,7),16),r=parseInt(t.slice(3,5),16),t=parseInt(t.slice(1,3),16));else{if(!e._namedColors[t]){let e=new n(0,0,0);return e._css=t,e.toString=function(){return this._css},e}[t,r,a,o]=e._namedColors[t]}1==e._colorFormat&&(t/=255,r&&(r/=255),a&&(a/=255),o&&(o/=255))}(Array.isArray(t)||t.constructor==Float32Array)&&([t,r,a,o]=t)}return null==a?e._colorMode==Q5.OKLCH?new n(t,0,0,r):new n(t,t,t,r):new n(t,r,a,o)},e.red=e=>e.r,e.green=e=>e.g,e.blue=e=>e.b,e.alpha=e=>e.a,e.lightness=t=>{if(t.l)return t.l;let r=100*(.2126*t.r+.7152*t.g+.0722*t.b);return 255==e._colorFormat?r/255:r},e.hue=t=>{if(t.h)return t.h;let r=t.r,a=t.g,o=t.b;255==e._colorFormat&&(r/=255,a/=255,o/=255);let n,i=Math.max(r,a,o),s=Math.min(r,a,o);return n=i==s?0:i==r?60*(a-o)/(i-s):i==a?60*(o-r)/(i-s)+120:60*(r-a)/(i-s)+240,n<0&&(n+=360),n},e.lerpColor=(t,r,a)=>{if(a=Math.max(0,Math.min(1,a)),"rgb"==e._colorMode)return new e.Color(e.lerp(t.r,r.r,a),e.lerp(t.g,r.g,a),e.lerp(t.b,r.b,a),e.lerp(t.a,r.a,a));{let o=r.h-t.h;o>180&&(o-=360),o<-180&&(o+=360);let n=t.h+a*o;return n<0&&(n+=360),n>360&&(n-=360),new e.Color(e.lerp(t.l,r.l,a),e.lerp(t.c,r.c,a),n,e.lerp(t.a,r.a,a))}}},Q5.Color=class{constructor(){this._q5Color=!0}get alpha(){return this.a}set alpha(e){this.a=e}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,a){super(),this.l=e,this.c=t,this.h=r,this.a=a??1}get levels(){return[this.l,this.c,this.h,this.a]}equals(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h&&this.a==e.a}isSameColor(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h}toString(){return`oklch(${this.l} ${this.c} ${this.h} / ${this.a})`}get lightness(){return this.l}set lightness(e){this.l=e}get chroma(){return this.c}set chroma(e){this.c=e}get hue(){return this.h}set hue(e){this.h=e}},Q5.ColorRGB=class extends Q5.Color{constructor(e,t,r,a){super(),this.r=e,this.g=t,this.b=r,this.a=a??1}get levels(){return[this.r,this.g,this.b,this.a]}equals(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b}toString(){return`color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`}get red(){return this.r}set red(e){this.r=e}get green(){return this.g}set green(e){this.g=e}get blue(){return this.b}set blue(e){this.b=e}},Q5.ColorRGB_P3=class extends Q5.ColorRGB{toString(){return`color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGB_8=class extends Q5.ColorRGB{constructor(e,t,r,a){super(e,t,r,a??255)}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGB_P3_8=class extends Q5.ColorRGB_8{constructor(e,t,r,a){super(e,t,r,a??255),this._edited=!0}get r(){return this._r}set r(e){this._r=e,this._edited=!0}get g(){return this._g}set g(e){this._g=e,this._edited=!0}get b(){return this._b}set b(e){this._b=e,this._edited=!0}get a(){return this._a}set a(e){this._a=e,this._edited=!0}toString(){if(this._edited){let e=(this._r/255).toFixed(3),t=(this._g/255).toFixed(3),r=(this._b/255).toFixed(3),a=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${a})`,this._edited=!1}return this._css}},Q5.ColorHSL=class extends Q5.Color{constructor(e,t,r,a){super(),this.h=e,this.s=t,this.l=r,this.a=a??1}get levels(){return[this.h,this.s,this.l,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l}toString(){return`hsl(${this.h} ${this.s} ${this.l} / ${this.a})`}get hue(){return this.h}set hue(e){this.h=e}get saturation(){return this.s}set saturation(e){this.s=e}get lightness(){return this.l}set lightness(e){this.l=e}},Q5.ColorHSL_P3=class extends Q5.ColorHSL{toString(){return`color(display-p3 ${Q5.HSLtoRGB(this.h,this.s,this.l).join(" ")} / ${this.a})`}},Q5.ColorHSB=class extends Q5.ColorHSL{constructor(e,t,r,a){super(e,t,r,a),delete this.l,this.b=r}get levels(){return[this.h,this.s,this.b,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b}toString(){return`hsl(${Q5.HSBtoHSL(this.h,this.s,this.b).join(" ")} / ${this.a})`}get v(){return this.b}set v(e){this.b=e}get brightness(){return this.b}set brightness(e){this.b=e}get value(){return this.b}set value(e){this.b=e}},Q5.ColorHSB_P3=class extends Q5.ColorHSB{toString(){return`color(display-p3 ${Q5.HSLtoRGB(...Q5.HSBtoHSL(this.h,this.s,this.b)).join(" ")} / ${this.a})`}},Q5.HSLtoRGB=(e,t,r)=>{r/=100;let a=t/100*Math.min(r,1-r),o=(t,o=(t+e/30)%12)=>r-a*Math.max(Math.min(o-3,9-o,1),-1);return[o(0),o(8),o(4)]},Q5.HSBtoHSL=(e,t,r,a=r*(1-t/200))=>[e,a&&100!=a?(r-a)/Math.min(a,100-a)*100:0,a];{const e=(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2],e[3]*t[0]+e[4]*t[1]+e[5]*t[2],e[6]*t[0]+e[7]*t[1]+e[8]*t[2]],t=(e,t,r)=>[e,isNaN(r)?0:t*Math.cos(r*Math.PI/180),isNaN(r)?0:t*Math.sin(r*Math.PI/180)],r=e=>e.map((e=>Math.max(0,Math.min(1,Math.abs(e)>.0031308?(e<0?-1:1)*(1.055*Math.abs(e)**(1/2.4)-.055):12.92*e)))),a=t=>{const r=e([1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092],t);return e([1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],r.map((e=>e**3)))},o=t=>e([3.2409699419045226,-1.537383177570094,-.4986107602930034,-.9692436362808796,1.8759675015077202,.04155505740717559,.05563007969699366,-.20397695888897652,1.0569715142428786],t);Q5.OKLCHtoRGB=(e,n,i)=>r(o(a(t(e,n,i))))}Q5.modules.display=e=>{if(!e.canvas||"graphics"==e._scope)return;let t=e.canvas;e.CENTERED="centered",e.FULLSCREEN="fullscreen",e.MAXED="maxed",e.PIXELATED="pixelated",0!=Q5._instanceCount||Q5._server||document.head.insertAdjacentHTML("beforeend","<style>\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n}\n.q5Canvas {\n\toutline: none;\n\t-webkit-touch-callout: none;\n\t-webkit-text-size-adjust: none;\n\t-webkit-user-select: none;\n\toverscroll-behavior: none;\n}\n.q5-pixelated {\n\timage-rendering: pixelated;\n\tfont-smooth: never;\n\t-webkit-font-smoothing: none;\n}\n.q5-centered,\n.q5-maxed,\n.q5-fullscreen {\n display: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\nmain.q5-centered,\nmain.q5-maxed,\n.q5-fullscreen {\n\theight: 100vh;\n}\nmain {\n\toverscroll-behavior: none;\n}\n</style>"),e._adjustDisplay=()=>{let r=t.style,a=t.parentElement;r&&a&&t.displayMode&&("pixelated"==t.renderQuality&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.defaultImageScale(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),"default"==t.displayMode||"normal"==t.displayMode?(a.classList.remove("q5-centered","q5-maxed","q5-fullscreen"),r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"):(a.classList.add("q5-"+t.displayMode),a=a.getBoundingClientRect(),t.w/t.h>a.width/a.height?("centered"==t.displayMode?(r.width=t.w*t.displayScale+"px",r.maxWidth="100%"):r.width="100%",r.height="auto",r.maxHeight=""):(r.width="auto",r.maxWidth="","centered"==t.displayMode?(r.height=t.h*t.displayScale+"px",r.maxHeight="100%"):r.height="100%")))},e.displayMode=(r="normal",a="smooth",o=1)=>{"string"==typeof o&&(o=parseFloat(o.slice(1))),"center"==r&&(r="centered"),Object.assign(t,{displayMode:r,renderQuality:a,displayScale:o}),e.ctx&&e.pushStyles(),e._adjustDisplay(),e.ctx&&e.popStyles()},e.fullscreen=e=>{if(void 0===e)return document.fullscreenElement;e?document.body.requestFullscreen():document.body.exitFullscreen()}},Q5.modules.dom=(e,t)=>{e.elementMode=t=>e._elementMode=t,e.createElement=(t,r)=>{let a=document.createElement(t);return"center"==e._elementMode&&(a.style.transform="translate(-50%, -50%)"),r&&(a.innerHTML=r),Object.defineProperty(a,"x",{get:()=>a._x,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let o=e.canvas.offsetLeft+t;a.style.left=o+"px",a._x=o}}),Object.defineProperty(a,"y",{get:()=>a._y,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let o=e.canvas.offsetTop+t;a.style.top=o+"px",a._y=o}}),Object.defineProperty(a,"width",{get:()=>parseFloat(a.style.width||0),set:e=>a.style.width=e+"px"}),Object.defineProperty(a,"height",{get:()=>parseFloat(a.style.height||0),set:e=>a.style.height=e+"px"}),a.position=(e,t,r)=>(r&&(a.style.position=r),a.x=e,a.y=t,a),Object.defineProperty(a,"size",{writable:!0}),a.size=(e,t)=>(a.width=e,a.height=t,a),a.center=()=>(a.style.position="absolute",a.x=e.canvas.hw,a.y=e.canvas.hh,a),a.show=()=>(a.style.display="",a),a.hide=()=>(a.style.display="none",a),a.parent=e=>(e.append(a),a),e._addEventMethods(a),e._elements.push(a),e.canvas?e.canvas.parentElement.append(a):document.body.append(a),a},e.createEl=e.createElement,e._addEventMethods=e=>{let t=e.addEventListener;e.mousePressed=e=>t("mousedown",e),e.mouseReleased=e=>t("mouseup",e),e.mouseClicked=e=>t("click",e),e.mouseMoved=e=>t("mousemove",e),e.mouseWheel=e=>t("wheel",e)},e.createA=(t,r,a)=>{let o=e.createEl("a",r);return o.href=t,o.target=a?"_blank":"_self",o},e.createButton=t=>e.createEl("button",t),e.createCheckbox=(t="",r=!1)=>{let a=e.createEl("input");a.type="checkbox",a.checked=r;let o=e.createEl("label",t);return o.addEventListener("click",(()=>{a.checked=!a.checked,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}))})),a.insertAdjacentElement("afterend",o),a.label=o,a},e.createColorPicker=(t="#ffffff")=>{let r=e.createEl("input");return r.type="color",r.value=t.toString(),r},e.createDiv=t=>e.createEl("div",t),e.createImg=t=>{let r=e.createEl("img");return r.crossOrigin="anonymous",r.src=t,r},e.createInput=(t="",r="text")=>{let a=e.createEl("input");return a.value=t,a.type=r,a.style.boxSizing="border-box",a},e.createP=t=>e.createEl("p",t);let r=0;e.createRadio=t=>{let a=e.createEl("div");return a.name=t||"radio"+r++,a.buttons=[],Object.defineProperty(a,"value",{get:()=>a.selected?.value,set:e=>{let t=a.buttons.find((t=>t.value==e));t&&(t.checked=!0,a.selected=t)}}),a.option=(t,r)=>{let o=e.createEl("input");o.type="radio",o.name=a.name,o.value=r||t,o.addEventListener("input",(()=>a.selected=o));let n=e.createEl("label",t);return n.addEventListener("click",(()=>{o.checked=!0,a.selected=o,o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0}))})),o.label=n,a.append(o),a.append(n),a.buttons.push(o),a},a},e.createSelect=t=>{let r=e.createEl("select");if(t){let a=e.createEl("option",t);a.disabled=!0,a.selected=!0,r.append(a)}return Object.defineProperty(r,"selected",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.textContent)):r.selectedOptions[0]?.textContent,set:e=>{if(r.multiple)Array.from(r.options).forEach((t=>{t.selected=e.includes(t.textContent)}));else{const t=Array.from(r.options).find((t=>t.textContent===e));t&&(t.selected=!0)}}}),Object.defineProperty(r,"value",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.value)):r.selectedOptions[0]?.value,set:e=>{if(r.multiple)r.options.forEach((t=>t.selected=e.includes(t.value)));else{let t;for(let a=0;a<r.options.length;a++)if(r.options[a].value==e){t=r.options[a];break}t&&(t.selected=!0)}}}),r.option=(t,a)=>{let o=e.createEl("option",t);return o.value=a||t,r.append(o),r},r},e.createSlider=(t,r,a,o)=>{let n=e.createEl("input");return n.type="range",n.min=t,n.max=r,n.value=a,n.step=o,n.val=()=>parseFloat(n.value),n},e.createSpan=t=>e.createEl("span",t),e.createVideo=r=>{let a=e.createEl("video");return a.crossOrigin="anonymous",a._load=()=>{a.width||=a.videoWidth,a.height||=a.videoHeight,a.defaultWidth=a.width*e._defaultImageScale,a.defaultHeight=a.height*e._defaultImageScale,a.ready=!0},r&&(t._preloadCount++,a._loader=new Promise((e=>{a.addEventListener("loadeddata",(()=>{a._load(),t._preloadCount--,e(a)})),a.src=r})),!e._usePreload)?a._loader:a},e.createCapture=function(r,a=!0,o){t._preloadCount++;let n="string"==typeof r?{[r]:!0}:r||{video:!0,audio:!0};!0===n.video&&(n.video={width:3840,height:2160}),n.video.facingMode??="user";let i=e.createVideo();return i.playsinline=i.autoplay=!0,a&&(i.flipped=!0,i.style.transform="scale(-1, 1)"),i.loadPixels=()=>{let t=e.createGraphics(i.videoWidth,i.videoHeight,{renderer:"c2d"});t.image(i,0,0),t.loadPixels(),i.pixels=t.pixels,t.remove()},i._loader=(async()=>{let e;try{e=await navigator.mediaDevices.getUserMedia(n)}catch(e){throw t._preloadCount--,e}return i.srcObject=e,await new Promise((e=>i.addEventListener("loadeddata",e))),i._load(),o&&o(i),t._preloadCount--,i})(),e._usePreload?i:i._loader},e.findElement=e=>document.querySelector(e),e.findElements=e=>document.querySelectorAll(e)},Q5.modules.fes=e=>{e._fes=async e=>{if(Q5.disableFriendlyErrors)return;let t=e.stack?.split("\n");if(!e.stack||t.length<=1)return;let r=1,a="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(r=0,a="@");t[r].indexOf("q5")>=0;)r++;let o=t[r].split(a).at(-1);o.startsWith("blob:")&&(o=o.slice(5));let n=o.split(":"),i=parseInt(n.at(-2));n[n.length-1]=n.at(-1).split(")")[0];let s=n.slice(0,-2).join(":"),l=s.split("/").at(-1);try{let e=(await(await fetch(s)).text()).split("\n")[i-1].trim(),t=["🐛","🐞","🐜","🦗","🦋","🪲"][Math.floor(6*Math.random())];console.log("%cq5.js "+t+"%c Error in "+l+" on line "+i+":\n\n"+e,"background: #b7ebff; color: #000;","")}catch(e){}}},Q5.modules.input=(e,t)=>{if("graphics"==e._scope)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.mouseButton="",e.keyIsPressed=!1,e.mouseIsPressed=!1,e.key="",e.keyCode=0,e.UP_ARROW=38,e.DOWN_ARROW=40,e.LEFT_ARROW=37,e.RIGHT_ARROW=39,e.SHIFT=16,e.TAB=9,e.BACKSPACE=8,e.ENTER=e.RETURN=13,e.ALT=e.OPTION=18,e.CONTROL=17,e.DELETE=46,e.ESCAPE=27,e.ARROW="default",e.CROSS="crosshair",e.HAND="pointer",e.MOVE="move",e.TEXT="text";let r={},a=[Q5.LEFT,Q5.CENTER,Q5.RIGHT],o=e.canvas;e._startAudio=()=>{Q5.aud&&"running"==Q5.aud?.state||e.userStartAudio()},e._updateMouse=r=>{if(!r.changedTouches){if(o){let a=o.getBoundingClientRect(),n=o.scrollWidth/e.width||1,i=o.scrollHeight/e.height||1;t.mouseX=(r.clientX-a.left)/n,t.mouseY=(r.clientY-a.top)/i,e._webgpu&&(t.mouseX-=o.hw,t.mouseY-=o.hh)}else t.mouseX=r.clientX,t.mouseY=r.clientY;t.moveX=r.movementX,t.moveY=r.movementY}};let n=0;function i(t){const r=e.canvas.getBoundingClientRect(),a=e.canvas.scrollWidth/e.width||1,o=e.canvas.scrollHeight/e.height||1;let n=0,i=0;return e._webgpu&&(n=e.halfWidth,i=e.halfHeight),{x:(t.clientX-r.left)/a-n,y:(t.clientY-r.top)/o-i,id:t.identifier}}if(e._onmousedown=r=>{n++,e._startAudio(),e._updateMouse(r),t.mouseIsPressed=!0,t.mouseButton=a[r.button],e.mousePressed(r)},e._onmousemove=t=>{e._updateMouse(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t)},e._onmouseup=r=>{e._updateMouse(r),t.mouseIsPressed=!1,e.mouseReleased(r)},e._onclick=r=>{e._updateMouse(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e._onwheel=t=>{e._updateMouse(t),t.delta=t.deltaY,(0==e.mouseWheel(t)||e._noScroll)&&t.preventDefault()},e.cursor=(t,r,a)=>{let o="";t.includes(".")&&(t=`url("${t}")`,o=", auto"),void 0!==r&&(t+=" "+r+" "+a),e.canvas.style.cursor=t+o},e.noCursor=()=>e.canvas.style.cursor="none",e.noScroll=()=>e._noScroll=!0,window&&(e.lockMouse=document.body?.requestPointerLock,e.unlockMouse=document.exitPointerLock),e._onkeydown=a=>{a.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(a),1==a.key.length&&e.keyTyped(a))},e._onkeyup=a=>{t.keyIsPressed=!1,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(a)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._ontouchstart=r=>{e._startAudio(),t.touches=[...r.touches].map(i),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,t.mouseIsPressed=!0,t.mouseButton=e.LEFT,e.mousePressed(r)),e.touchStarted(r)},e._ontouchmove=r=>{t.touches=[...r.touches].map(i),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,e.mouseDragged(r)||r.preventDefault()),e.touchMoved(r)||r.preventDefault()},e._ontouchend=r=>{t.touches=[...r.touches].map(i),e._isTouchAware||e.touches.length||(t.mouseIsPressed=!1,e.mouseReleased(r)||r.preventDefault()),e.touchEnded(r)||r.preventDefault()},o){let t=o.addEventListener.bind(o);t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t))),t("touchstart",(t=>e._ontouchstart(t))),t("touchmove",(t=>e._ontouchmove(t))),t("touchend",(t=>e._ontouchend(t))),t("touchcancel",(t=>e._ontouchend(t)))}if(window){let t=window.addEventListener;t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1),o||(t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t)))),t("mousemove",(t=>e._onmousemove(t)),!1),t("mouseup",(t=>{n>0&&(n--,e._onmouseup(t))}))}},Q5.modules.math=(e,t)=>{e.RADIANS=0,e.DEGREES=1,e.PI=Math.PI,e.HALF_PI=Math.PI/2,e.QUARTER_PI=Math.PI/4,e.TWO_PI=e.TAU=2*Math.PI,e.abs=Math.abs,e.ceil=Math.ceil,e.exp=Math.exp,e.floor=e.int=Math.floor,e.loge=Math.log,e.mag=Math.hypot,e.max=Math.max,e.min=Math.min,e.pow=Math.pow,e.sqrt=Math.sqrt,e.SHR3=1,e.LCG=2,e.round=(e,t=0)=>{let r=10**t;return Math.round(e*r)/r};let r=e._angleMode=0;e.angleMode=t=>(r=e._angleMode=0==t||"radians"==t?0:1,r?"degrees":"radians");let a=e._DEGTORAD=Math.PI/180,o=e._RADTODEG=180/Math.PI;function n(){let e,t,r=4294967295;return{setSeed(a){e=t=(a??Math.random()*r)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/r)}}e.degrees=t=>t*e._RADTODEG,e.radians=t=>t*e._DEGTORAD,e.map=Q5.prototype.map=(e,t,r,a,o,n)=>{let i=a+1*(e-t)/(r-t)*(o-a);return n?a<o?Math.min(Math.max(i,a),o):Math.min(Math.max(i,o),a):i},e.dist=function(){let e=arguments;return 2==e.length?Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y):4==e.length?Math.hypot(e[0]-e[2],e[1]-e[3]):Math.hypot(e[0]-e[3],e[1]-e[4],e[2]-e[5])},e.lerp=(e,t,r)=>e*(1-r)+t*r,e.constrain=(e,t,r)=>Math.min(Math.max(e,t),r),e.norm=(t,r,a)=>e.map(t,r,a,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*a:e),e.cos=e=>Math.cos(r?e*a:e),e.tan=e=>Math.tan(r?e*a:e),e.asin=e=>{let t=Math.asin(e);return r?t*o:t},e.acos=e=>{let t=Math.acos(e);return r?t*o:t},e.atan=e=>{let t=Math.atan(e);return r?t*o:t},e.atan2=(e,t)=>{let a=Math.atan2(e,t);return r?a*o:a};let i=n();i.setSeed(),e.randomSeed=e=>i.setSeed(e),e.random=(e,t)=>void 0===e?i.rand():"number"==typeof e?void 0!==t?i.rand()*(t-e)+e:i.rand()*e:e[Math.trunc(e.length*i.rand())],e._c2d?(e.randomX=(t=0)=>e.random(-t,e.canvas.w+t),e.randomY=(t=0)=>e.random(-t,e.canvas.h+t)):(e.randomX=(t=0)=>e.random(-e.canvas.hw-t,e.canvas.hw+t),e.randomY=(t=0)=>e.random(-e.canvas.hh-t,e.canvas.hh+t)),e.randomGenerator=t=>{t==e.LCG?i=function(){const e=4294967296;let t,r;return{setSeed(a){r=t=(a??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(i=n()),i.setSeed()};var s=new function(){var e,t,r,a=new Array(128),o=new Array(256),n=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*i.rand()-2147483648,h=()=>.5+2.328306e-10*(c()|0),u=()=>{for(var t,o,i,l,d=3.44262;;){if(t=r*n[e],0==e){do{i=h(),l=h(),t=.2904764*-Math.log(i),o=-Math.log(l)}while(o+o<t*t);return r>0?d+t:-d-t}if(s[e]+h()*(s[e-1]-s[e])<Math.exp(-.5*t*t))return t;if(r=c(),e=127&r,Math.abs(r)<a[e])return r*n[e]}},p=()=>{for(var r;;){if(0==e)return 7.69711-Math.log(h());if(r=t*l[e],d[e]+h()*(d[e-1]-d[e])<Math.exp(-r))return r;if((t=c())<o[e=255&t])return t*l[e]}};this.SHR3=c,this.UNI=h,this.RNOR=()=>(r=c(),e=127&r,Math.abs(r)<a[e]?r*n[e]:u()),this.REXP=()=>(t=c()>>>0)<a[e=255&t]?t*l[e]:p(),this.zigset=()=>{var e,t,r=2147483648,i=4294967296,c=3.442619855899,h=c,u=.00991256303526217,p=7.697117470131487,f=p,_=.003949659822581572;for(e=u/Math.exp(-.5*c*c),a[0]=Math.floor(c/e*r),a[1]=0,n[0]=e/r,n[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),a[t+1]=Math.floor(c/h*r),h=c,s[t]=Math.exp(-.5*c*c),n[t]=c/r;for(e=_/Math.exp(-p),o[0]=Math.floor(p/e*i),o[1]=0,l[0]=e/i,l[255]=p/i,d[0]=1,d[255]=Math.exp(-p),t=254;t>=1;t--)p=-Math.log(_/p+Math.exp(-p)),o[t+1]=Math.floor(p/f*i),f=p,d[t]=Math.exp(-p),l[t]=p/i}};let l;s.hasInit=!1,e.randomGaussian=(e,t)=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.RNOR()*t+e),e.randomExponential=()=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.REXP()),e.PERLIN="perlin",e.SIMPLEX="simplex",e.BLOCKY="blocky",e.NoiseGenerator=Q5.PerlinNoise,e.noiseMode=e=>{t.NoiseGenerator=Q5[e[0].toUpperCase()+e.slice(1)+"Noise"],l=null},e.noiseSeed=t=>{l=new e.NoiseGenerator(t)},e.noise=(t=0,r=0,a=0)=>(l??=new e.NoiseGenerator,l.noise(t,r,a)),e.noiseDetail=(t,r)=>{l??=new e.NoiseGenerator,t>0&&(l.octaves=t),r>0&&(l.falloff=r)}},Q5.NoiseGenerator=class{},Q5.PerlinNoise=class extends Q5.NoiseGenerator{constructor(e){super(),this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.octaves=1,this.falloff=.5,this.p=null==e?Array.from({length:256},(()=>Math.floor(256*Math.random()))):this.seedPermutation(e),this.p=this.p.concat(this.p)}seedPermutation(e){let t,r,a=[];for(let e=0;e<256;e++)a[e]=e;for(let o=255;o>0;o--)t=(e=16807*e%2147483647)%(o+1),r=a[o],a[o]=a[t],a[t]=r;return a}dot(e,t,r,a){return e[0]*t+e[1]*r+e[2]*a}mix(e,t,r){return(1-r)*e+r*t}fade(e){return e*e*e*(e*(6*e-15)+10)}noise(e,t,r){let a=this,o=0,n=1,i=1,s=0;for(let l=0;l<a.octaves;l++){const l=255&Math.floor(e*n),d=255&Math.floor(t*n),c=255&Math.floor(r*n),h=e*n-Math.floor(e*n),u=t*n-Math.floor(t*n),p=r*n-Math.floor(r*n),f=a.fade(h),_=a.fade(u),g=a.fade(p),m=a.p[l]+d,x=a.p[m]+c,v=a.p[m+1]+c,y=a.p[l+1]+d,b=a.p[y]+c,w=a.p[y+1]+c,S=a.mix(a.dot(a.grad3[a.p[x]%12],h,u,p),a.dot(a.grad3[a.p[b]%12],h-1,u,p),f),C=a.mix(a.dot(a.grad3[a.p[v]%12],h,u-1,p),a.dot(a.grad3[a.p[w]%12],h-1,u-1,p),f),M=a.mix(a.dot(a.grad3[a.p[x+1]%12],h,u,p-1),a.dot(a.grad3[a.p[b+1]%12],h-1,u,p-1),f),Q=a.mix(a.dot(a.grad3[a.p[v+1]%12],h,u-1,p-1),a.dot(a.grad3[a.p[w+1]%12],h-1,u-1,p-1),f),P=a.mix(S,C,_),E=a.mix(M,Q,_);o+=a.mix(P,E,g)*i,s+=i,i*=a.falloff,n*=2}return(o/s+1)/2}},Q5.modules.record=(e,t)=>{let r,a,o,n,i,s,l;function d(t={}){document.head.insertAdjacentHTML("beforeend","<style>\n.rec {\n\tdisplay: flex;\n\tz-index: 1000;\n\tgap: 6px;\n\tbackground: #1a1b1d;\n\tpadding: 6px 8px;\n\tborder-radius: 21px;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 2px solid transparent; \n\topacity: 0.6;\n\ttransition: all 0.3s;\n\twidth: 134px;\n\toverflow: hidden;\n}\n\n.rec:hover {\n\twidth: unset;\n\topacity: 0.96;\n}\n\n.rec.recording { border-color: #cc3e44; }\n\n.rec button,\n.rec select { cursor: pointer; }\n\n.rec button,\n.rec select,\n.rec input,\n.rec span {\n\tfont-family: sans-serif;\n\tfont-size: 14px;\n\tpadding: 2px 10px;\n\tborder-radius: 18px;\n\toutline: none;\n\tbackground: #232529;\n\tcolor: #d4dae6;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 1px solid #46494e;\n\tvertical-align: middle;\n\tline-height: 18px;\n\ttransition: all 0.3s;\n}\n\n.rec .audio-toggle {\n\tfont-size: 16px;\n\tpadding: 2px 10px;\n}\n\n.rec .bitrate input {\n\tborder-radius: 18px 0 0 18px;\n\tborder-right: 0;\n\twidth: 40px;\n\tpadding: 2px 5px 2px 10px;\n\ttext-align: right;\n}\n\n.rec .bitrate span {\n\tborder-radius: 0 18px 18px 0;\n\tborder-left: 0;\n\tpadding: 2px 10px 2px 5px;\n\tbackground: #333;\n}\n\n.rec .record-button { \n\tcolor: #cc3e44;\n\tfont-size: 18px;\n}\n\n.rec select:hover,\n.rec button:hover { background: #32343b; }\n\n.rec button:disabled {\n\topacity: 0.5;\n\tcolor: #969ba5;\n\tcursor: not-allowed;\n}\n</style>"),r=e.createEl("div"),r.className="rec",r.innerHTML='\n<button class="record-button"></button>\n<span class="record-timer"></span>\n<button></button>\n',[a,n,o]=r.children,r.x=r.y=8,r.resetTimer=()=>r.time={hours:0,minutes:0,seconds:0,frames:0},r.resetTimer();let d="video/mp4; codecs=";r.formats={"H.264":d+'"avc1.42E01E"',VP9:d+"vp9"};let u=d+'"avc1.640034"';e.canvas.width*e.canvas.height>32e5&&MediaRecorder.isTypeSupported(u)&&(r.formats["H.264"]=u),Object.assign(r.formats,t.formats),i=e.createSelect("format");for(const e in r.formats)i.option(e,r.formats[e]);i.title="Video Format",r.append(i);let _=e.createEl("div");_.className="bitrate",_.style.display="flex",r.append(_),s=e.createInput();let g=document.createElement("span");function m(){r.encoderSettings.mimeType=i.value}function x(){r.encoderSettings.videoBitsPerSecond=1e6*s.value}g.textContent="mbps",s.title=g.title="Video Bitrate",_.append(s),_.append(g),l=e.createEl("button"),l.className="audio-toggle active",l.textContent="🔊",l.title="Toggle Audio Recording",r.append(l),r.captureAudio=!0,l.addEventListener("click",(()=>{r.captureAudio=!r.captureAudio,l.textContent=r.captureAudio?"🔊":"🔇",l.classList.toggle("active",r.captureAudio)})),r.encoderSettings={},i.addEventListener("change",m),s.addEventListener("change",x),Object.defineProperty(r,"bitrate",{get:()=>s.value,set:e=>{s.value=e,x()}}),Object.defineProperty(r,"format",{get:()=>i.selected,set:e=>{e=e.toUpperCase(),r.formats[e]&&(i.selected=e,m())}}),r.format="H.264";let v=e.canvas.height;r.bitrate=v>=4320?96:v>=2160?64:v>=1440?48:v>=1080?32:v>=720?26:16,a.addEventListener("click",(()=>{e.recording?r.paused?h():e.pauseRecording():c()})),o.addEventListener("click",(()=>{r.paused?e.saveRecording():e.deleteRecording()})),p(),e.registerMethod("post",f)}function c(){if(!e.recording){if(e.userStartAudio(),!r.stream){r.frameRate??=e.getTargetFrameRate();let t=e.canvas.captureStream(r.frameRate);if(r.videoTrack=t.getVideoTracks()[0],r.captureAudio&&e.getAudioContext){let t=e.getAudioContext(),a=t.createMediaStreamDestination();t.destination.input?t.destination.input.connect(a):Q5.soundOut.connect(a),r.audioTrack=a.stream.getAudioTracks()[0],r.stream=new MediaStream([r.videoTrack,r.audioTrack])}else r.stream=t}r.mediaRecorder=new MediaRecorder(r.stream,r.encoderSettings),r.chunks=[],r.mediaRecorder.addEventListener("dataavailable",(e=>{e.data.size>0&&r.chunks.push(e.data)})),r.mediaRecorder.start(),t.recording=!0,r.paused=!1,r.classList.add("recording"),r.resetTimer(),p(!0)}}function h(){e.recording&&r.paused&&(r.mediaRecorder.resume(),r.paused=!1,p(!0))}function u(){e.recording&&(r.resetTimer(),r.mediaRecorder.stop(),t.recording=!1,r.paused=!1,r.classList.remove("recording"))}function p(e){a.textContent=e?"⏸":"⏺",a.title=(e?"Pause":"Start")+" Recording",o.textContent=e?"🗑️":"💾",o.title=(e?"Delete":"Save")+" Recording",o.disabled=!e}function f(){if(e.recording&&!r.paused){r.time.frames++;let t=e.getTargetFrameRate();r.time.frames>=t&&(r.time.seconds+=Math.floor(r.time.frames/t),r.time.frames%=t,r.time.seconds>=60&&(r.time.minutes+=Math.floor(r.time.seconds/60),r.time.seconds%=60,r.time.minutes>=60&&(r.time.hours+=Math.floor(r.time.minutes/60),r.time.minutes%=60)))}n.textContent=function(){let{hours:e,minutes:t,seconds:a,frames:o}=r.time;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}:${String(a).padStart(2,"0")}:${String(o).padStart(2,"0")}`}()}e.recording=!1,e.createRecorder=e=>(r||d(e),r),e.record=t=>{r||(d(t),r.hide()),e.recording?r.paused&&h():c()},e.pauseRecording=()=>{e.recording&&!r.paused&&(r.mediaRecorder.pause(),r.paused=!0,p(),a.title="Resume Recording",o.disabled=!1)},e.deleteRecording=()=>{u(),p(),t.recording=!1},e.saveRecording=async a=>{if(!e.recording)return;await new Promise((e=>{r.mediaRecorder.onstop=e,u()}));let o=r.encoderSettings.mimeType,n=o.slice(6,o.indexOf(";")),i=URL.createObjectURL(new Blob(r.chunks,{type:o})),s=document.createElement("iframe"),l=document.createElement("a");s.style.display="none",s.name="download_"+Date.now(),document.body.append(s),l.target=s.name,l.href=i,a??=document.title+" "+(new Date).toLocaleString(void 0,{hour12:!1}).replace(","," at").replaceAll("/","-").replaceAll(":","_"),l.download=`${a}.${n}`,await new Promise((e=>{s.onload=()=>{document.body.removeChild(s),e()},l.click()})),setTimeout((()=>URL.revokeObjectURL(i)),1e3),p(),t.recording=!1}},Q5.modules.sound=(e,t)=>{e.Sound=Q5.Sound;let r=[];e.loadSound=(a,o)=>{t._preloadCount++;let n=new Q5.Sound;return r.push(n),n._loader=(async()=>{let e;try{await n.load(a)}catch(t){e=t}if(t._preloadCount--,delete n._loader,e)throw e;return o&&o(n),n})(),e._usePreload?n:n._loader},e.loadAudio=(e,r)=>{t._preloadCount++;let a=new Audio(e);a.crossOrigin="Anonymous",a.addEventListener("canplaythrough",(()=>{a.loaded||(t._preloadCount--,a.loaded=!0,r&&r(a))}));let o=()=>{a._preloadSkip=!0,t._preloadCount--};return a.addEventListener("suspend",o),a.addEventListener("error",(e=>{throw o(),e})),a},e.getAudioContext=()=>Q5.aud,e.userStartAudio=()=>{if(window.AudioContext){if(Q5._offlineAudio){Q5._offlineAudio=!1,Q5.aud=new window.AudioContext,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination);for(let e of r)e.init()}return Q5.aud.resume()}}},window.OfflineAudioContext&&(Q5.aud=new window.OfflineAudioContext(2,1,44100),Q5._offlineAudio=!0,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination)),Q5.Sound=class{constructor(){this.sources=new Set,this.loaded=this.paused=!1}async load(e){this.url=e;let t=await fetch(e);this.buffer=await t.arrayBuffer(),this.buffer=await Q5.aud.decodeAudioData(this.buffer)}init(){this.gainNode=Q5.aud.createGain(),this.pannerNode=Q5.aud.createStereoPanner(),this.gainNode.connect(this.pannerNode),this.pannerNode.connect(Q5.soundOut),this.loaded=!0,this._volume&&(this.volume=this._volume),this._pan&&(this.pan=this._pan)}_newSource(e,t){let r=Q5.aud.createBufferSource();r.buffer=this.buffer,r.connect(this.gainNode),r.loop=this._loop,r._startedAt=Q5.aud.currentTime,r._offset=e,r._duration=t,r.start(0,r._offset,r._duration),this.sources.add(r),r.onended=()=>{this.paused||(this.ended=!0,this.sources.delete(r))}}play(e=0,t){if(this.loaded){if(this.paused){let e=[];for(let t of this.sources)e.push(t._offset,t._duration),this.sources.delete(t);for(let t=0;t<e.length;t+=2)this._newSource(e[t],e[t+1])}else this._newSource(e,t);this.paused=this.ended=!1}}pause(){if(this.isPlaying()){for(let e of this.sources){e.stop();let t=Q5.aud.currentTime-e._startedAt;e._offset+=t,e._duration&&(e._duration-=t)}this.paused=!0}}stop(){for(let e of this.sources)e.stop(),this.sources.delete(e);this.paused=!1,this.ended=!0}get volume(){return this._volume}set volume(e){this.loaded&&(this.gainNode.gain.value=e),this._volume=e}get pan(){return this._pan}set pan(e){this.loaded&&(this.pannerNode.pan.value=e),this._pan=e}get loop(){return this._loop}set loop(e){this.sources.forEach((t=>t.loop=e)),this._loop=e}get playing(){return!this.paused&&this.sources.size>0}setVolume(e){this.volume=e}setPan(e){this.pan=e}setLoop(e){this.loop=e}isLoaded(){return this.loaded}isPlaying(){return this.playing}isPaused(){return this.paused}isLooping(){return this._loop}},Q5.modules.util=(e,t)=>{e._loadFile=(r,a,o)=>{t._preloadCount++;let n={};return n._loader=new Promise(((i,s)=>{fetch(r).then((e=>e.ok?"json"==o?e.json():e.text():(s("error loading file"),null))).then((r=>{"csv"==o&&(r=e.CSV.parse(r)),"string"==typeof r?n.text=r:Object.assign(n,r),delete n._loader,a&&a(r),t._preloadCount--,i(r)}))})),n},e.loadText=(t,r)=>e._loadFile(t,r,"text"),e.loadJSON=(t,r)=>e._loadFile(t,r,"json"),e.loadCSV=(t,r)=>e._loadFile(t,r,"csv");const r=/(jpe?g|png|gif|webp|avif|svg)/,a=/(ttf|otf|woff2?|eot|json)/,o=/(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/;async function n(t,a,o){if(a=a||"untitled",o=o||"png",r.test(o))t=await e._saveCanvas(t,o);else{let e="text/plain";"json"==o&&("string"!=typeof t&&(t=JSON.stringify(t)),e="text/json"),t=new Blob([t],{type:e}),t=URL.createObjectURL(t)}let n=document.createElement("a");n.href=t,n.download=a+"."+o,n.click(),setTimeout((()=>URL.revokeObjectURL(n.href)),1e3)}e.load=function(...t){Array.isArray(t[0])&&(t=t[0]);let n=[];for(let i of t){let t,s=i.split(".").pop().toLowerCase();t="json"!=s||i.includes("-msdf.")?"csv"==s?e.loadCSV(i):r.test(s)?e.loadImage(i):a.test(s)?e.loadFont(i):o.test(s)?e.loadSound(i):e.loadText(i):e.loadJSON(i),n.push(t._loader)}return 1==t.length?n[0]:Promise.all(n)},e.save=(t,r,a)=>{if((!t||"string"==typeof t&&(!r||!a&&r.length<5))&&(a=r,r=t,t=e.canvas),a)n(t,r,a);else if(r){let e=r.lastIndexOf(".");n(t,r.slice(0,e),r.slice(e+1))}else n(t)},e.CSV={},e.CSV.parse=(e,t=",",r="\n")=>{if(!e.length)return[];let a=[],o=e.split(r),n=o[0].split(t).map((e=>e.replaceAll('"',"")));for(let e=1;e<o.length;e++){let r={},i=o[e].split(t);n.forEach(((e,t)=>r[e]=JSON.parse(i[t]))),a.push(r)}return a},e.canvas&&!Q5._createServerCanvas&&(e.canvas.save=e.saveCanvas=e.save),"object"==typeof localStorage&&(e.storeItem=localStorage.setItem,e.getItem=localStorage.getItem,e.removeItem=localStorage.removeItem,e.clearStorage=localStorage.clear),e.year=()=>(new Date).getFullYear(),e.day=()=>(new Date).getDay(),e.hour=()=>(new Date).getHours(),e.minute=()=>(new Date).getMinutes(),e.second=()=>(new Date).getSeconds(),e.nf=(e,t,r)=>{let a=e<0,o=(e=Math.abs(e)).toFixed(r).split(".");o[0]=o[0].padStart(t,"0");let n=o.join(".");return a&&(n="-"+n),n},e.shuffle=(t,r)=>{r||(t=[...t]);for(let r=t.length-1;r>0;r--){let a=Math.floor(e.random()*(r+1));[t[r],t[a]]=[t[a],t[r]]}return t}},Q5.modules.vector=e=>{e.Vector=Q5.Vector,e.createVector=(t,r,a)=>new e.Vector(t,r,a,e)},Q5.Vector=class{constructor(e,t,r,a){this.x=e||0,this.y=t||0,this.z=r||0,this._$=a||window,this._cn=null,this._cnsq=null}set(e,t,r){return this.x=e?.x||e||0,this.y=e?.y||t||0,this.z=e?.z||r||0,this}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,r){return void 0!==e?.x?e:void 0!==t?{x:e,y:t,z:r||0}:{x:e,y:e,z:e}}_calcNorm(){this._cnsq=this.x*this.x+this.y*this.y+this.z*this.z,this._cn=Math.sqrt(this._cnsq)}add(){let e=this._arg2v(...arguments);return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}rem(){let e=this._arg2v(...arguments);return this.x%=e.x,this.y%=e.y,this.z%=e.z,this}sub(){let e=this._arg2v(...arguments);return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}mult(){let e=this._arg2v(...arguments);return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}div(){let e=this._arg2v(...arguments);return e.x?this.x/=e.x:this.x=0,e.y?this.y/=e.y:this.y=0,e.z?this.z/=e.z:this.z=0,this}mag(){return this._calcNorm(),this._cn}magSq(){return this._calcNorm(),this._cnsq}dot(){let e=this._arg2v(...arguments);return this.x*e.x+this.y*e.y+this.z*e.z}dist(){let e=this._arg2v(...arguments),t=this.x-e.x,r=this.y-e.y,a=this.z-e.z;return Math.sqrt(t*t+r*r+a*a)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,a=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=a,this}normalize(){this._calcNorm();let e=this._cn;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._cn=1,this._cnsq=1,this}limit(e){this._calcNorm();let t=this._cn;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._cn=e,this._cnsq=e*e}return this}setMag(e){this._calcNorm();let t=e/this._cn;return this.x*=t,this.y*=t,this.z*=t,this._cn=e,this._cnsq=e*e,this}heading(){return this._$.atan2(this.y,this.x)}setHeading(e){let t=this.mag();return this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),a=this.x*t-this.y*r,o=this.x*r+this.y*t;return this.x=a,this.y=o,this}angleBetween(){let e=this._arg2v(...arguments),t=Q5.Vector.cross(this,e);return this._$.atan2(t.mag(),this.dot(e))*Math.sign(t.z||1)}lerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));return this.x+=(r.x-this.x)*t,this.y+=(r.y-this.y)*t,this.z+=(r.z-this.z)*t,this}slerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));if(1==t)return this.set(r);let a=this.mag(),o=r.mag();if(0==a||0==o)return this.mult(1-t).add(r.mult(t));let n=Q5.Vector.cross(this,r),i=n.mag(),s=Math.atan2(i,this.dot(r));if(i>0)n.div(i);else{if(s<this._$.HALF_PI)return this.mult(1-t).add(r.mult(t));0==this.z&&0==r.z?n.set(0,0,1):0!=this.x?n.set(this.y,-this.x,0).normalize():n.set(1,0,0)}let l=n.cross(this),d=1-t+t*o/a,c=d*Math.cos(t*s),h=d*Math.sin(t*s);return this.x=this.x*c+l.x*h,this.y=this.y*c+l.y*h,this.z=this.z*c+l.z*h,this}reflect(e){return e.normalize(),this.sub(e.mult(2*this.dot(e)))}array(){return[this.x,this.y,this.z]}equals(e,t){return t??=Number.EPSILON||0,Math.abs(e.x-this.x)<t&&Math.abs(e.y-this.y)<t&&Math.abs(e.z-this.z)<t}fromAngle(e,t){return void 0===t&&(t=1),this._cn=t,this._cnsq=t*t,this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this.z=0,this}fromAngles(e,t,r){void 0===r&&(r=1),this._cn=r,this._cnsq=r*r;const a=this._$.cos(t),o=this._$.sin(t),n=this._$.cos(e),i=this._$.sin(e);return this.x=r*i*o,this.y=-r*n,this.z=r*i*a,this}random2D(){return this._cn=this._cnsq=1,this.fromAngle(Math.random()*Math.PI*2)}random3D(){return this._cn=this._cnsq=1,this.fromAngles(Math.random()*Math.PI*2,Math.random()*Math.PI*2)}toString(){return`[${this.x}, ${this.y}, ${this.z}]`}},Q5.Vector.add=(e,t)=>e.copy().add(t),Q5.Vector.cross=(e,t)=>e.copy().cross(t),Q5.Vector.dist=(e,t)=>Math.hypot(e.x-t.x,e.y-t.y,e.z-t.z),Q5.Vector.div=(e,t)=>e.copy().div(t),Q5.Vector.dot=(e,t)=>e.copy().dot(t),Q5.Vector.equals=(e,t,r)=>e.equals(t,r),Q5.Vector.lerp=(e,t,r)=>e.copy().lerp(t,r),Q5.Vector.slerp=(e,t,r)=>e.copy().slerp(t,r),Q5.Vector.limit=(e,t)=>e.copy().limit(t),Q5.Vector.heading=e=>this._$.atan2(e.y,e.x),Q5.Vector.magSq=e=>e.x*e.x+e.y*e.y+e.z*e.z,Q5.Vector.mag=e=>Math.sqrt(Q5.Vector.magSq(e)),Q5.Vector.mult=(e,t)=>e.copy().mult(t),Q5.Vector.normalize=e=>e.copy().normalize(),Q5.Vector.rem=(e,t)=>e.copy().rem(t),Q5.Vector.sub=(e,t)=>e.copy().sub(t);for(let e of["fromAngle","fromAngles","random2D","random3D"])Q5.Vector[e]=(t,r,a)=>(new Q5.Vector)[e](t,r,a);Q5.renderers.webgpu={},Q5.renderers.webgpu.canvas=(e,t)=>{let r=e.canvas;e.colorMode&&e.colorMode("rgb",1),e._baseShaderCode="\nstruct Q5 {\n\twidth: f32,\n\theight: f32,\n\thalfWidth: f32,\n\thalfHeight: f32,\n\tpixelDensity: f32,\n\tframeCount: f32,\n\ttime: f32,\n\tdeltaTime: f32,\n\tmouseX: f32,\n\tmouseY: f32,\n\tmouseIsPressed: f32,\n\tkeyCode: f32,\n\tkeyIsPressed: f32\n}",e._g=e.createGraphics(1,1,"c2d"),e._g.colorMode(e.RGB,1);let a,o,n,i,s,l,d,c,h=1,u=8;e._pipelineConfigs=[],e._pipelines=[],e._buffers=[],e._prevFramePL=0,e._framePL=0;let p=e._drawStack=[],f=e._colorStack=new Float32Array(1e6);f.set([0,0,0,1,1,1,1,1]);let _=Q5.device.createBindGroupLayout({label:"mainLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]});e._bindGroupLayouts=[_];let g=Q5.device.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),m=()=>{let t=[e.canvas.width,e.canvas.height],r="bgra8unorm";n=Q5.device.createTexture({size:t,sampleCount:4,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}).createView();let a=GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT;e._frameA=i=Q5.device.createTexture({size:t,format:r,usage:a}),e._frameB=s=Q5.device.createTexture({size:t,format:r,usage:a}),e._frameShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex: u32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f\n}\n\nconst ndc = array(vec2f(-1,-1), vec2f(1,-1), vec2f(-1,1), vec2f(1,1));\nconst quad = array(vec2f(0,1), vec2f(1,1), vec2f(0,0), vec2f(1,0));\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var samp: sampler;\n@group(0) @binding(2) var tex: texture_2d<f32>;\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar f: FragParams;\n\tf.position = vec4f(ndc[v.vertexIndex], 0.0, 1.0);\n\tf.texCoord = quad[v.vertexIndex];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams ) -> @location(0) vec4f {\n\treturn textureSample(tex, samp, f.texCoord);\n}";let o=Q5.device.createShaderModule({label:"frameShader",code:e._frameShaderCode});d=Q5.device.createSampler({magFilter:"linear",minFilter:"linear"}),l=Q5.device.createBindGroupLayout({label:"frameLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]});let c=Q5.device.createPipelineLayout({bindGroupLayouts:[l]});e._pipelineConfigs[0]={layout:c,vertex:{module:o,entryPoint:"vertexMain"},fragment:{module:o,entryPoint:"fragMain",targets:[{format:r}]},primitive:{topology:"triangle-strip"},multisample:{count:4}},e._pipelines[0]=Q5.device.createRenderPipeline(e._pipelineConfigs[0])};e._createCanvas=(a,o,n)=>(t.ctx=t.drawingContext=r.getContext("webgpu"),n.format??=navigator.gpu.getPreferredCanvasFormat(),n.device??=Q5.device,n.alpha&&(n.alphaMode="premultiplied"),e.ctx.configure(n),m(),r),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r),m()};let x=(t,r,a,o)=>{let n=e._colorFormat;if("string"==typeof t||"rgb"!=e._colorMode?t=e.color(t,r,a,o):null==a&&(o=r??n,r=a=t),o??=n,t._q5Color){let e=t;null!=e.r?({r:t,g:r,b:a,a:o}=e):(o=e.a,e=null!=e.c?Q5.OKLCHtoRGB(e.l,e.c,e.h):null!=e.l?Q5.HSLtoRGB(e.h,e.s,e.l):Q5.HSLtoRGB(...Q5.HSBtoHSL(e.h,e.s,e.b)),[t,r,a]=e)}255==n&&(t/=255,r/=255,a/=255,o/=255);let i=f,s=u;i[s++]=t,i[s++]=r,i[s++]=a,i[s++]=o,u=s,h++};e._stroke=0,e._fill=e._tint=e._globalAlpha=1,e._doFill=e._doStroke=!0,e.fill=(t,r,a,o)=>{x(t,r,a,o),e._doFill=e._fillSet=!0,e._fill=h},e.stroke=(t,r,a,o)=>{x(t,r,a,o),e._doStroke=e._strokeSet=!0,e._stroke=h},e.tint=(t,r,a,o)=>{x(t,r,a,o),e._tint=h},e.opacity=t=>e._globalAlpha=t,e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.noTint=()=>e._tint=1,e._strokeWeight=1,e._hsw=.5,e._scaledSW=1,e.strokeWeight=t=>{t=Math.abs(t),e._strokeWeight=t,e._scaledSW=t*e._scale,e._hsw=t/2};const v=e._graphics?1e3:1e7,y=new Float32Array(16*v);let b,w=[],S=[];e._matrixDirty=!1,w.push([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),y.set(w[0]),e.resetMatrix=()=>{b=w[0].slice(),e._matrixIndex=0},e.resetMatrix(),e.translate=(t,r,a=0)=>{if(!t&&!r&&!a)return;let o=b;o[12]+=t*o[0],o[13]-=r*o[5],o[14]+=a*o[10],e._matrixDirty=!0},e.rotate=e.rotateZ=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.cos(t),a=Math.sin(t),o=b,n=o[0],i=o[1],s=o[4],l=o[5];1!=n||i||s||1!=l?(o[0]=n*r+i*a,o[1]=i*r-n*a,o[4]=s*r+l*a,o[5]=l*r-s*a):(o[0]=r,o[1]=-a,o[4]=a,o[5]=r),e._matrixDirty=!0},e._scale=1,e.scale=(t=1,r,a=1)=>{r??=t,e._scale=Math.max(Math.abs(t),Math.abs(r)),e._scaledSW=e._strokeWeight*e._scale;let o=b;o[0]*=t,o[1]*=t,o[2]*=t,o[3]*=t,o[4]*=r,o[5]*=r,o[6]*=r,o[7]*=r,o[8]*=a,o[9]*=a,o[10]*=a,o[11]*=a,e._matrixDirty=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=b,o=a[0],n=a[1],i=a[4],s=a[5];a[0]=o+i*r,a[1]=n+s*r,e._matrixDirty=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=b,o=a[0],n=a[1],i=a[4],s=a[5];a[4]=i+o*r,a[5]=s+n*r,e._matrixDirty=!0},e.applyMatrix=(...t)=>{let r;if(r=1==t.length?t[0]:t,9==r.length)r=[r[0],r[1],0,r[2],r[3],r[4],0,r[5],0,0,1,0,r[6],r[7],0,r[8]];else if(16!=r.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");b=r.slice(),e._matrixDirty=!0},e._saveMatrix=()=>{y.set(b,16*w.length),e._matrixIndex=w.length,w.push(b.slice()),e._matrixDirty=!1},e.pushMatrix=()=>{e._matrixDirty&&e._saveMatrix(),S.push(e._matrixIndex)},e.popMatrix=()=>{if(!S.length)return console.warn("Matrix index stack is empty!");let t=S.pop();b=w[t].slice(),e._matrixIndex=t,e._matrixDirty=!1};let C=e.pushStyles;e.pushStyles=()=>{C(),e.strokeWeight(e._strokeWeight)},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()},e._calcBox=(e,t,r,a,o)=>{let n,i,s,l;if(o&&"corner"!=o)if("center"==o){let o=r/2,d=a/2;n=e-o,i=e+o,s=-(t-d),l=-(t+d)}else n=e,i=r,s=-t,l=-a;else n=e,i=e+r,s=-t,l=-(t+a);return[n,i,s,l]};let M=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],Q=["add","subtract","reverse-subtract","min","max"];const P={normal:[2,3,0,2,3,0],additive:[1,1,0,1,1,0]};e.blendConfigs={};for(const[t,r]of Object.entries(P))e.blendConfigs[t]={color:{srcFactor:M[r[0]],dstFactor:M[r[1]],operation:Q[r[2]]},alpha:{srcFactor:M[r[3]],dstFactor:M[r[4]],operation:Q[r[5]]}};let E;e._blendMode="normal",e.blendMode=t=>{if(t!=e._blendMode){"source-over"==t&&(t="normal"),"lighter"==t&&(t="additive"),t=t.toLowerCase().replace(/[ -]/g,"_"),e._blendMode=t;for(let r=0;r<e._pipelines.length;r++)e._pipelineConfigs[r].fragment.targets[0].blend=e.blendConfigs[t],e._pipelines[r]=Q5.device.createRenderPipeline(e._pipelineConfigs[r])}},e.clear=()=>{E=!0},e.background=(t,a,o,n)=>{if(e.push(),e.resetMatrix(),t.canvas){let a=t;e._imageMode="corner",e.image(a,-r.hw,-r.hh,r.w,r.h)}else e._rectMode="corner",e.fill(t,a,o,n),e._doStroke=!1,e.rect(-r.hw,-r.hh,r.w,r.h);e.pop()},e._beginRender=()=>{const t=i;i=s,s=t,a=Q5.device.createCommandEncoder(),e._pass=o=a.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:n,resolveTarget:i.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:d},{binding:2,resource:s.createView()}]}),E||(o.setPipeline(e._pipelines[e._prevFramePL]),o.setBindGroup(0,c),o.draw(4)),E=!1},e._render=()=>{let t=Q5.device.createBuffer({size:16*w.length*4,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(y.slice(0,16*w.length)),t.unmap(),e._buffers.push(t);let r=Q5.device.createBuffer({size:4*u,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(f.slice(0,u)),r.unmap(),e._buffers.push(r),e._uniforms=[e.width,e.height,e.halfWidth,e.halfHeight,e._pixelDensity,e.frameCount,performance.now(),e.deltaTime,e.mouseX,e.mouseY,e.mouseIsPressed?1:0,e.keyCode,e.keyIsPressed?1:0],Q5.device.queue.writeBuffer(g,0,new Float32Array(e._uniforms));let a=Q5.device.createBindGroup({layout:_,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:{buffer:t}},{binding:2,resource:{buffer:r}}]});o.setBindGroup(0,a);for(let t of e._hooks.preRender)t();let n=0,i=0,s=0,l=-1;for(let t=0;t<p.length;t+=2){let r=p[t+1];if(l!=p[t]&&(l=p[t],o.setPipeline(e._pipelines[l])),4==l||l>=4e3){let a=p[t+2];o.setBindGroup(1,e._fonts[a].bindGroup),o.setBindGroup(2,e._textBindGroup),o.draw(4,r,0,s),s+=r,t++}else 2==l||3==l||l>=2e3?(o.setBindGroup(1,e._textureBindGroups[r]),o.draw(4,1,i),i+=4):(o.draw(r,1,n),n+=r)}},e._finishRender=async()=>{o.end(),o=a.beginRenderPass({colorAttachments:[{view:n,resolveTarget:e.ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:d},{binding:2,resource:i.createView()}]}),o.setPipeline(e._pipelines[e._framePL]),o.setBindGroup(0,c),o.draw(4),o.end(),Q5.device.queue.submit([a.finish()]),e._pass=o=a=null,Q5.device.queue.onSubmittedWorkDone().then((()=>{for(let t of e._buffers)t.destroy();e._buffers=[]})),p.splice(0,p.length),h=1,u=8,w=[w[0]],S=[];for(let t of e._hooks.postRender)t()}},Q5.initWebGPU=async()=>{if(!navigator.gpu)return console.warn("q5 WebGPU not supported on this browser! Use Google Chrome or Edge."),!1;if(!Q5.requestedGPU){let e=await navigator.gpu.requestAdapter();if(!e)return console.warn("q5 WebGPU could not start! No appropriate GPUAdapter found, vulkan may need to be enabled."),!1;Q5.device=await e.requestDevice(),Q5.device.lost.then((e=>{console.error("WebGPU crashed!"),console.error(e)}))}return!0},Q5.WebGPU=async function(e,t){return e&&"global"!=e||(Q5._hasGlobal=!0),await Q5.initWebGPU()?new Q5(e,t,"webgpu"):new Q5(e,t,"webgpu-fallback")},Q5.webgpu=Q5.WebGPU,Q5.renderers.webgpu.shapes=e=>{e._shapesPL=1,e._shapesShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) colorIndex: f32,\n\t@location(2) matrixIndex: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) color: vec4f\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.color = colors[i32(v.colorIndex)];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\treturn f.color;\n}\n";let t=Q5.device.createShaderModule({label:"shapesShader",code:e._shapesShaderCode}),r=(e.canvas,e._drawStack),a=new Float32Array(e._graphics?1e3:1e7),o=0;const n=2*Math.PI,i=Math.PI/2;let s=Q5.device.createPipelineLayout({label:"shapesPipelineLayout",bindGroupLayouts:e._bindGroupLayouts});e._pipelineConfigs[1]={label:"shapesPipeline",layout:s,vertex:{module:t,entryPoint:"vertexMain",buffers:[{arrayStride:16,attributes:[{format:"float32x2",offset:0,shaderLocation:0},{format:"float32",offset:8,shaderLocation:1},{format:"float32",offset:12,shaderLocation:2}]}]},fragment:{module:t,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[1]=Q5.device.createRenderPipeline(e._pipelineConfigs[1]);const l=(e,t,r,n)=>{let i=a,s=o;i[s++]=e,i[s++]=t,i[s++]=r,i[s++]=n,o=s},d=(t,n,i,s,l,d,c,h,u,p)=>{let f=a,_=o;f[_++]=t,f[_++]=n,f[_++]=u,f[_++]=p,f[_++]=i,f[_++]=s,f[_++]=u,f[_++]=p,f[_++]=c,f[_++]=h,f[_++]=u,f[_++]=p,f[_++]=l,f[_++]=d,f[_++]=u,f[_++]=p,o=_,r.push(e._shapesPL,4)},c=(t,n,i,s,l,d,c,h,u)=>{let p=(d-l)/c,f=l,_=a,g=o;for(let e=0;e<=c;e++){_[g++]=t,_[g++]=n,_[g++]=h,_[g++]=u;let e=t+i*Math.cos(f),r=n-s*Math.sin(f);_[g++]=e,_[g++]=r,_[g++]=h,_[g++]=u,f+=p}o=g,r.push(e._shapesPL,2*(c+1))},h=(t,n,i,s,l,d,c,h,u,p,f)=>{let _=(h-c)/u,g=c,m=a,x=o;for(let e=0;e<=u;e++){let e=t+i*Math.cos(g),r=n-s*Math.sin(g),a=t+l*Math.cos(g),o=n-d*Math.sin(g);m[x++]=e,m[x++]=r,m[x++]=p,m[x++]=f,m[x++]=a,m[x++]=o,m[x++]=p,m[x++]=f,g+=_}o=x,r.push(e._shapesPL,2*(u+1))};e.rectMode=t=>e._rectMode=t,e.rect=(t,r,a,o,n=0)=>{let s,l,[p,f,_,g]=e._calcBox(t,r,a,o,e._rectMode);if(e._matrixDirty&&e._saveMatrix(),l=e._matrixIndex,!n){if(e._doFill&&(s=e._fill,d(p,_,f,_,f,g,p,g,s,l)),e._doStroke){s=e._stroke;let t=e._strokeWeight/2,r=p-t,a=f+t,o=_+t,n=g-t,i=p+t,c=f-t,h=_-t,u=g+t;d(r,h,a,h,a,o,r,o,s,l),d(r,n,a,n,a,u,r,u,s,l),o=_-t,n=g+t,d(r,o,i,o,i,n,r,n,s,l),d(c,o,a,o,a,n,c,n,s,l)}return}p+=n,f-=n,_-=n,g+=n,n=Math.min(n,Math.min(a,o)/2);let m=u(n*e._scale),x=_+n,v=g-n,y=p-n,b=f+n;if(e._doFill&&(s=e._fill,c(f,g,n,n,0,i,m,s,l),c(p,g,n,n,Math.PI,i,m,s,l),c(p,_,n,n,-Math.PI,-i,m,s,l),c(f,_,n,n,-i,0,m,s,l),d(p,x,f,x,f,v,p,v,s,l),d(p,_,y,_,y,g,p,g,s,l),d(b,_,f,_,f,g,b,g,s,l)),e._doStroke){s=e._stroke;let t=e._hsw,r=n+t,a=n+t,o=n-t,c=n-t;h(f,g,r,a,o,c,0,i,m,s,l),h(p,g,r,a,o,c,Math.PI,i,m,s,l),h(p,_,r,a,o,c,-Math.PI,-i,m,s,l),h(f,_,r,a,o,c,-i,0,m,s,l);let u=y-t,w=y+t,S=b-t,C=b+t,M=x-t,Q=x+t,P=v-t,E=v+t;d(u,_,w,_,w,g,u,g,s,l),d(S,_,C,_,C,g,S,g,s,l),d(p,M,f,M,f,Q,p,Q,s,l),d(p,P,f,P,f,E,p,E,s,l)}},e.square=(t,r,a)=>e.rect(t,r,a,a),e.plane=(t,r,a,o)=>{o??=a;let[n,i,s,l]=e._calcBox(t,r,a,o,"center");e._matrixDirty&&e._saveMatrix(),d(n,s,i,s,i,l,n,l,e._fill,e._matrixIndex)};const u=e=>e<4?6:e<6?8:e<10?10:e<16?12:e<20?14:e<22?16:e<24?18:e<28?20:e<34?22:e<42?24:e<48?26:e<56?28:e<64?30:e<72?32:e<84?34:e<96?36:e<98?38:e<113?40:e<149?44:e<199?48:e<261?52:e<353?56:e<461?60:e<585?64:e<1200?70:e<1800?80:e<2400?90:100;e._ellipseMode=Q5.CENTER,e.ellipseMode=t=>e._ellipseMode=t,e.ellipse=(t,r,a,o)=>{let i=u(Math.max(Math.abs(a),Math.abs(o))*e._scale),s=a/2,l=a==o?s:o/2;e._matrixDirty&&e._saveMatrix();let d=e._matrixIndex;if(e._doFill&&c(t,-r,s,l,0,n,i,e._fill,d),e._doStroke){let a=e._strokeWeight/2;h(t,-r,s+a,l+a,s-a,l-a,0,n,i,e._stroke,d)}},e.circle=(t,r,a)=>e.ellipse(t,r,a,a),e.arc=(t,r,a,o,i,s)=>{if(i===s)return e.ellipse(t,r,a,o);if(e._angleMode&&(i=e.radians(i),s=e.radians(s)),(i%=n)<0&&(i+=n),(s%=n)<0&&(s+=n),i>s&&(s+=n),i==s)return e.ellipse(t,r,a,o);let l,d;e._ellipseMode==e.CENTER?(l=a/2,d=o/2):e._ellipseMode==e.RADIUS?(l=a,d=o):e._ellipseMode==e.CORNER?(t+=a/2,r+=o/2,l=a/2,d=o/2):e._ellipseMode==e.CORNERS&&(l=(a-(t=(t+a)/2))/2,d=(o-(r=(r+o)/2))/2),e._matrixDirty&&e._saveMatrix();let p=e._matrixIndex,f=u(Math.max(Math.abs(a),Math.abs(o))*e._scale);if(e._doFill&&c(t,-r,l,d,i,s,f,e._fill,p),e._doStroke){let a=e._hsw;h(t,-r,l+a,d+a,l-a,d-a,i,s,f,e._stroke,p),"round"==e._strokeCap&&(c(t+l*Math.cos(i),-r-d*Math.sin(i),a,a,0,n,f,e._stroke,p),c(t+l*Math.cos(s),-r-d*Math.sin(s),a,a,0,n,f,e._stroke,p))}},e.point=(t,r)=>{e._matrixDirty&&e._saveMatrix();let a=e._matrixIndex,o=e._stroke,i=e._strokeWeight;if(e._scaledSW<2){let[n,s,l,c]=e._calcBox(t,r,i,i,"corner");d(n,l,s,l,s,c,n,c,o,a)}else{let s=u(e._scaledSW);i/=2,c(t,-r,i,i,0,n,s,o,a)}},e._strokeCap=e._strokeJoin="round",e.strokeCap=t=>e._strokeCap=t,e.strokeJoin=t=>e._strokeJoin=t,e.lineMode=()=>{e._strokeCap="square",e._strokeJoin="none"},e.line=(t,r,a,o)=>{e._matrixDirty&&e._saveMatrix();let i=e._matrixIndex,s=e._stroke,l=(e._strokeWeight,e._hsw),h=a-t,p=o-r,f=Math.hypot(h,p),_=-p/f*l,g=h/f*l;if(d(t+_,-r-g,t-_,-r+g,a-_,-o+g,a+_,-o-g,s,i),e._scaledSW>2&&"square"!=e._strokeCap){let d=u(e._scaledSW);c(t,-r,l,l,0,n,d,s,i),c(a,-o,l,l,0,n,d,s,i)}};let p,f=20;e.curveDetail=e=>f=e;let _=[],g=[];e.beginShape=()=>{p=0,_=[],g=[]},e.vertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),_.push(t,-r,e._fill,e._matrixIndex),p++},e.curveVertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),g.push({x:t,y:-r})},e.bezierVertex=function(t,r,a,o,n,i){if(0===p)throw new Error("Shape needs a vertex()");e._matrixDirty&&e._saveMatrix();let s,l,d=4*(p-1),c=_[d],h=_[d+1],u=1/f,g=4==arguments.length;g&&(n=a,i=o);let m=1+u;for(let d=u;d<=m;d+=u){let u=d*d,f=1-d,m=f*f;if(g)s=m*c+2*f*d*t+u*n,l=m*h+2*f*d*-r+u*-i;else{let e=u*d,p=m*f;s=p*c+3*m*d*t+3*f*u*a+e*n,l=p*h+3*m*d*-r+3*f*u*-o+e*-i}_.push(s,l,e._fill,e._matrixIndex),p++}},e.quadraticVertex=(t,r,a,o)=>e.bezierVertex(t,r,a,o),e.endShape=t=>{if(g.length>0){let t=[...g];if(t.length<4)for(;t.length<4;)t.unshift(t[0]),t.push(t[t.length-1]);for(let r=0;r<t.length-3;r++){let a=t[r],o=t[r+1],n=t[r+2],i=t[r+3];for(let t=0;t<=1;t+=.1){let r=t*t,s=r*t,l=.5*(2*o.x+(-a.x+n.x)*t+(2*a.x-5*o.x+4*n.x-i.x)*r+(-a.x+3*o.x-3*n.x+i.x)*s),d=.5*(2*o.y+(-a.y+n.y)*t+(2*a.y-5*o.y+4*n.y-i.y)*r+(-a.y+3*o.y-3*n.y+i.y)*s);_.push(l,d,e._fill,e._matrixIndex),p++}}}if(p<3)throw new Error("A shape must have at least 3 vertices.");if(t){let e=0,t=4*(p-1),r=_[e],a=_[e+1],o=_[t],n=_[t+1];r===o&&a===n||(_.push(r,a,_[e+2],_[e+3]),p++)}if(e._doFill)if(5==p)l(_[0],_[1],_[2],_[3]),l(_[4],_[5],_[6],_[7]),l(_[12],_[13],_[14],_[15]),l(_[8],_[9],_[10],_[11]),r.push(e._shapesPL,4);else{for(let e=1;e<p-1;e++){let t=0,r=4*e,a=4*(e+1);l(_[t],_[t+1],_[t+2],_[t+3]),l(_[r],_[r+1],_[r+2],_[r+3]),l(_[a],_[a+1],_[a+2],_[a+3])}r.push(e._shapesPL,3*(p-2))}if(e._doStroke){let r=e._hsw,a=u(e._scaledSW),o=e._matrixIndex,i=e._strokeCap;e._strokeCap="square";for(let t=0;t<p-1;t++){let i=4*t,s=4*(t+1);e.line(_[i],-_[i+1],_[s],-_[s+1]),c(_[i],_[i+1],r,r,0,n,a,e._stroke,o)}let s=4*(p-1),l=0;t&&e.line(_[s],-_[s+1],_[l],-_[l+1]),c(_[s],_[s+1],r,r,0,n,a,e._stroke,o),e._strokeCap=i}p=0,_=[],g=[]},e.curve=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,o),e.curveVertex(n,i),e.curveVertex(s,l),e.endShape()},e.bezier=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,o,n,i,s,l),e.endShape()},e.triangle=(t,r,a,o,n,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(!0)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(!0)},e._hooks.preRender.push((()=>{e._pass.setPipeline(e._pipelines[1]);let t=Q5.device.createBuffer({size:4*o,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(a.slice(0,o)),t.unmap(),e._pass.setVertexBuffer(0,t),e._buffers.push(t)})),e._hooks.postRender.push((()=>{o=0}))},Q5.renderers.webgpu.image=(e,t)=>{e._imagePL=2,e._videoPL=3,e._imageShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) texCoord: vec2f,\n\t@location(2) tintIndex: f32,\n\t@location(3) matrixIndex: f32,\n\t@location(4) imageAlpha: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f,\n\t@location(1) tintColor: vec4f,\n\t@location(2) imageAlpha: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var samp: sampler;\n@group(1) @binding(1) var tex: texture_2d<f32>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0f, 1f);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn applyTint(texColor: vec4f, tintColor: vec4f) -> vec4f {\n\t// apply the tint color to the sampled texture color at full strength\n\tlet tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a);\n\t// mix in the tint using the tint alpha as the blend strength\n\treturn mix(texColor, tinted, tintColor.a);\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.texCoord = v.texCoord;\n\tf.tintColor = colors[i32(v.tintIndex)];\n\tf.imageAlpha = v.imageAlpha;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tvar texColor = textureSample(tex, samp, f.texCoord);\n\ttexColor.a *= f.imageAlpha;\n\treturn applyTint(texColor, f.tintColor);\n}\n";let r=Q5.device.createShaderModule({label:"imageShader",code:e._imageShaderCode});e._videoShaderCode=e._imageShaderCode.replace("texture_2d<f32>","texture_external").replace("textureSample","textureSampleBaseClampToEdge");let a=Q5.device.createShaderModule({label:"videoShader",code:e._videoShaderCode}),o=new Float32Array(e._graphics?1e3:1e7),n=0,i={arrayStride:28,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"},{shaderLocation:2,offset:16,format:"float32"},{shaderLocation:3,offset:20,format:"float32"},{shaderLocation:4,offset:24,format:"float32"}]},s=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]}),l=Q5.device.createBindGroupLayout({label:"videoTextureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}}]}),d=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,s]}),c=Q5.device.createPipelineLayout({label:"videoPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,l]});e._pipelineConfigs[2]={label:"imagePipeline",layout:d,vertex:{module:r,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},i]},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[2]=Q5.device.createRenderPipeline(e._pipelineConfigs[2]),e._pipelineConfigs[3]={label:"videoPipeline",layout:c,vertex:{module:a,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},i]},fragment:{module:a,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[3]=Q5.device.createRenderPipeline(e._pipelineConfigs[3]),e._textureBindGroups=[],e._saveCanvas=async(t,r)=>{let a=t.texture,o=a.width,n=a.height,i=256*Math.ceil(4*o/256),s=Q5.device.createBuffer({size:i*n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});e._buffers.push(s);let l=Q5.device.createCommandEncoder();l.copyTextureToBuffer({texture:a},{buffer:s,bytesPerRow:i,rowsPerImage:n},{width:o,height:n}),Q5.device.queue.submit([l.finish()]),await s.mapAsync(GPUMapMode.READ);let d=new Uint8Array(s.getMappedRange());t=new Uint8Array(o*n*4);for(let e=0;e<n;e++){const r=e*i,a=e*o*4;for(let e=0;e<o;e++){const o=r+4*e,n=a+4*e;t[n+0]=d[o+2],t[n+1]=d[o+1],t[n+2]=d[o+0],t[n+3]=d[o+3]}}s.unmap();let c=e.canvas.colorSpace;t=new Uint8ClampedArray(t.buffer),t=new ImageData(t,o,n,{colorSpace:c});let h=new e._Canvas(o,n);h.getContext("2d",{colorSpace:c}).putImageData(t,0,0);let u=await h.convertToBlob({type:"image/"+r});return await new Promise((e=>{let t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(u)}))};let h=t=>{e._imageSampler=Q5.device.createSampler({magFilter:t,minFilter:t})};e.smooth=()=>h("linear"),e.noSmooth=()=>h("nearest"),e.smooth();let u=0,p=0;e._addTexture=(t,r)=>{let a=t.canvas||t,o=[a.width,a.height,1];r||(r=Q5.device.createTexture({size:o,format:"bgra8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),Q5.device.queue.copyExternalImageToTexture({source:a},{texture:r,colorSpace:e.canvas.colorSpace},o)),t.texture=r,t.textureIndex=u+p,e._textureBindGroups[t.textureIndex]=Q5.device.createBindGroup({label:t.src||"canvas",layout:s,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r.createView()}]}),u++};let f=Q5.Image;Q5.Image=function(t,r){let a=new f(...arguments);return t>1&&r>1&&(e._addTexture(a),a.modified=!0),a},e.loadImage=(r,a)=>{t._preloadCount++;let o=e._g.loadImage(r,(r=>{e._addTexture(r),t._preloadCount--,a&&a(o)}));return o},e.createImage=e._g.createImage;let _=e.createGraphics;e.createGraphics=(t,r,a)=>{let o=_(t,r,a);return o.canvas.webgpu&&(e._addTexture(o,o._frameA),e._addTexture(o,o._frameB),o._beginRender()),o},e.imageMode=t=>e._imageMode=t;const g=(e,t,r,a,i,s,l)=>{let d=o,c=n;d[c++]=e,d[c++]=t,d[c++]=r,d[c++]=a,d[c++]=i,d[c++]=s,d[c++]=l,n=c};e.image=(t,r=0,a=0,o,n,i=0,s=0,d,c)=>{let h;if(null==t.textureIndex){if(h="VIDEO"==t.tagName,!h||!t.width||!t.currentTime)return;t.flipped&&e.scale(-1,1)}let u=t.canvas||t;e._matrixDirty&&e._saveMatrix();let p=u.width,f=u.height,_=t._pixelDensity||1;if(t._graphics){let e=t;e.drawStack.length&&(e._render(),e._finishRender(),e.textureIndex+=e.frameCount%2==0?-1:1,e.resetMatrix(),e._beginRender(),e.frameCount++)}t.modified&&(Q5.device.queue.copyExternalImageToTexture({source:u},{texture:t.texture,colorSpace:e.canvas.colorSpace},[p,f,1]),t.modified=!1),o??=t.defaultWidth||t.videoWidth,n??=t.defaultHeight||t.videoHeight,d??=p,c??=f,i*=_,s*=_;let[m,x,v,y]=e._calcBox(r,a,o,n,e._imageMode),b=i/p,w=s/f,S=(i+d)/p,C=(s+c)/f,M=e._matrixIndex,Q=e._tint,P=e._globalAlpha;if(g(m,v,b,w,Q,M,P),g(x,v,S,w,Q,M,P),g(m,y,b,C,Q,M,P),g(x,y,S,C,Q,M,P),h){let r=Q5.device.importExternalTexture({source:t});e._textureBindGroups.push(Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r}]})),e._drawStack.push(e._videoPL,e._textureBindGroups.length-1),t.flipped&&e.scale(-1,1)}else e._drawStack.push(e._imagePL,t.textureIndex)},e._hooks.preRender.push((()=>{if(!n)return;e._pass.setPipeline(e._pipelines[2]);let t=Q5.device.createBuffer({size:5*n,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(o.slice(0,n)),t.unmap(),e._pass.setVertexBuffer(1,t),e._buffers.push(t),p&&(e._pass.setPipeline(e._pipelines[3]),e._pass.setVertexBuffer(1,t))})),e._hooks.postRender.push((()=>{n=0,e._textureBindGroups.splice(u,p),p=0}))},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.webgpu.text=(e,t)=>{e._textPL=4,e._textShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@builtin(instance_index) instanceIndex : u32\n}\nstruct FragParams {\n\t@builtin(position) position : vec4f,\n\t@location(0) texCoord : vec2f,\n\t@location(1) fillColor : vec4f,\n\t@location(2) strokeColor : vec4f,\n\t@location(3) strokeWeight : f32\n}\nstruct Char {\n\ttexOffset: vec2f,\n\ttexExtent: vec2f,\n\tsize: vec2f,\n\toffset: vec2f,\n}\nstruct Text {\n\tpos: vec2f,\n\tscale: f32,\n\tmatrixIndex: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tstrokeWeight: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var fontTexture: texture_2d<f32>;\n@group(1) @binding(1) var fontSampler: sampler;\n@group(1) @binding(2) var<storage> fontChars: array<Char>;\n\n@group(2) @binding(0) var<storage> textChars: array<vec4f>;\n@group(2) @binding(1) var<storage> textMetadata: array<Text>;\n\nconst quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));\nconst uvs = array(vec2f(0, 1), vec2f(1, 1), vec2f(0, 0), vec2f(1, 0));\n\nfn calcPos(i: u32, char: vec4f, fontChar: Char, text: Text) -> vec2f {\n\treturn ((quad[i] * fontChar.size + char.xy + fontChar.offset) *\n\t\ttext.scale) + text.pos;\n}\n\nfn calcUV(i: u32, fontChar: Char) -> vec2f {\n\treturn uvs[i] * fontChar.texExtent + fontChar.texOffset;\n}\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn calcDist(texCoord: vec2f, edgeWidth: f32) -> f32 {\n\tlet c = textureSample(fontTexture, fontSampler, texCoord);\n\tlet sigDist = max(min(c.r, c.g), min(max(c.r, c.g), c.b)) - edgeWidth;\n\n\tlet pxRange = 4.0;\n\tlet sz = vec2f(textureDimensions(fontTexture, 0));\n\tlet dx = sz.x * length(vec2f(dpdxFine(texCoord.x), dpdyFine(texCoord.x)));\n\tlet dy = sz.y * length(vec2f(dpdxFine(texCoord.y), dpdyFine(texCoord.y)));\n\tlet toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);\n\treturn sigDist * toPixels;\n}\n\n@vertex\nfn vertexMain(v : VertexParams) -> FragParams {\n\tlet char = textChars[v.instanceIndex];\n\tlet text = textMetadata[i32(char.w)];\n\tlet fontChar = fontChars[i32(char.z)];\n\tlet pos = calcPos(v.vertexIndex, char, fontChar, text);\n\n\tvar vert = transformVertex(pos, text.matrixIndex);\n\n\tvar f : FragParams;\n\tf.position = vert;\n\tf.texCoord = calcUV(v.vertexIndex, fontChar);\n\tf.fillColor = colors[i32(text.fillIndex)];\n\tf.strokeColor = colors[i32(text.strokeIndex)];\n\tf.strokeWeight = text.strokeWeight;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f : FragParams) -> @location(0) vec4f {\n\tlet edge = 0.5;\n\tlet dist = calcDist(f.texCoord, edge);\n\n\tif (f.strokeWeight == 0.0) {\n\t\tlet fillAlpha = smoothstep(-edge, edge, dist);\n\t\tlet color = vec4f(f.fillColor.rgb, f.fillColor.a * fillAlpha);\n\t\tif (color.a < 0.01) {\n\t\t\tdiscard;\n\t\t}\n\t\treturn color;\n\t}\n\n\tlet halfStroke = f.strokeWeight / 2.0;\n\tlet fillAlpha = smoothstep(-edge, edge, dist - halfStroke);\n\tlet strokeAlpha = smoothstep(-edge, edge, dist + halfStroke);\n\tvar color = mix(f.strokeColor, f.fillColor, fillAlpha);\n\tcolor = vec4f(color.rgb, color.a * strokeAlpha);\n\tif (color.a < 0.01) {\n\t\tdiscard;\n\t}\n\treturn color;\n}\n";let r=Q5.device.createShaderModule({label:"textShader",code:e._textShaderCode}),a=Q5.device.createBindGroupLayout({label:"textBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),o=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),n=Q5.device.createBindGroupLayout({label:"fontBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),i=Q5.device.createPipelineLayout({bindGroupLayouts:[...e._bindGroupLayouts,n,a]});e._pipelineConfigs[4]={label:"textPipeline",layout:i,vertex:{module:r,entryPoint:"vertexMain"},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[4]=Q5.device.createRenderPipeline(e._pipelineConfigs[4]);class s{constructor(e,t,r,a){this.bindGroup=e,this.lineHeight=t,this.chars=r,this.kernings=a;let o=Object.values(r);this.charCount=o.length,this.defaultChar=o[0]}getChar(e){return this.chars[e]??this.defaultChar}getXAdvance(e,t=-1){let r=this.getChar(e);if(t>=0){let a=this.kernings.get(e);if(a)return r.xadvance+(a.get(t)??0)}return r.xadvance}}e._fonts=[];let l={};e.loadFont=(r,a)=>{if("json"!=r.slice(r.lastIndexOf(".")+1))return e._g.loadFont(r,a);let i=r.slice(r.lastIndexOf("/")+1,r.lastIndexOf("-")),d={family:i};return d._loader=(async(r,a,i)=>{t._preloadCount++;let d=await fetch(r);if(404==d.status)return t._preloadCount--,"";let c=await d.json(),h=r.lastIndexOf("/"),u=-1!=h?r.substring(0,h+1):"";d=await fetch(u+c.pages[0]);let p=await createImageBitmap(await d.blob()),f=[p.width,p.height,1],_=Q5.device.createTexture({label:`MSDF ${a}`,size:f,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:p},{texture:_},f),"string"==typeof c.chars&&(c.chars=e.CSV.parse(c.chars," "),c.kernings=e.CSV.parse(c.kernings," "));let g=c.chars.length,m=Q5.device.createBuffer({size:32*g,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),x=new Float32Array(m.getMappedRange()),v=1/c.common.scaleW,y=1/c.common.scaleH,b={},w=0;for(let[e,t]of c.chars.entries())b[t.id]=t,b[t.id].charIndex=e,x[w]=t.x*v,x[w+1]=t.y*y,x[w+2]=t.width*v,x[w+3]=t.height*y,x[w+4]=t.width,x[w+5]=t.height,x[w+6]=t.xoffset,x[w+7]=-t.yoffset,w+=8;m.unmap();let S=Q5.device.createBindGroup({label:"fontBindGroup",layout:n,entries:[{binding:0,resource:_.createView()},{binding:1,resource:o},{binding:2,resource:{buffer:m}}]}),C=new Map;if(c.kernings)for(let e of c.kernings){let t=C.get(e.first);t||(t=new Map,C.set(e.first,t)),t.set(e.second,e.amount)}e._font=new s(S,c.common.lineHeight,b,C),e._font.index=e._fonts.length,e._fonts.push(e._font),l[a]=e._font,t._preloadCount--,i&&i(a)})(r,i,(()=>{delete d._loader,a&&a(d)})),e._usePreload?d:d._loader},e._loadDefaultFont=t=>{l[t]=null,navigator.onLine?e.loadFont(`https://q5js.org/fonts/${t}-msdf.json`):e.loadFont(`/node_modules/q5/builtinFonts/${t}-msdf.json`)},e._textSize=18,e._textAlign="left",e._textBaseline="alphabetic";let d=!1,c=22.5,h=4.5,u=1.25;e.textFont=t=>{if(!t)return e._font;"string"!=typeof t&&(t=t.family);let r=l[t];r?e._font=r:void 0===r&&e._loadDefaultFont(t)},e.textSize=t=>{if(null==t)return e._textSize;e._textSize=t,d||(c=t*u,h=c-t)},e.textLeading=t=>{e._font.lineHeight=c=t,h=c-e._textSize,u=c/e._textSize,d=!0},e.textAlign=(t,r)=>{e._textAlign=t,r&&(e._textBaseline=r)};let p=[],f=[],_=(e,t,r)=>{let a=0,o=0,n=0,i=0,s=0,l=[],d=t.charCodeAt(0);for(let c=0;c<t.length;++c){let h=d;switch(d=c<t.length-1?t.charCodeAt(c+1):-1,h){case 10:l.push(o),i++,a=Math.max(a,o),o=0,n-=e.lineHeight*u;break;case 13:break;case 32:o+=e.getXAdvance(h);break;case 9:o+=2*e.getXAdvance(h);break;default:r&&r(o,n,i,e.getChar(h)),o+=e.getXAdvance(h,d),s++}}return l.push(o),a=Math.max(a,o),{width:a,height:l.length*e.lineHeight*u,lineWidths:l,printedCharCount:s}};e.text=(t,r,a,o,n)=>{if(!e._font)return void(null!==e._font&&e.textFont("sans-serif"));let i=typeof t;if("string"!=i&&("object"==i?t=t.toString():t+=""),t.length>o){let e=[],r=0;for(;r<t.length&&e.length<n;){let a=r+o;if(a>=t.length){e.push(t.slice(r));break}let n=t.lastIndexOf(" ",a);(-1==n||n<r)&&(n=a),e.push(t.slice(r,n)),r=n+1}t=e.join("\n")}let s;for(let e=0;e<t.length;e++){switch(t[e]){case"\n":s=!0;case"\r":case"\t":case" ":0}}let l,d=[],h=e._textAlign,u=e._textBaseline,g=f.length,m=0;if("left"!=h||s){l=_(e._font,t);let r=0;"alphabetic"==u?a-=e._textSize:"center"==u?r=.5*l.height:"bottom"==u&&(r=l.height),_(e._font,t,((e,t,a,o)=>{let n=0;"center"==h?n=-.5*l.width- -.5*(l.width-l.lineWidths[a]):"right"==h&&(n=-l.lineWidths[a]),d[m]=e+n,d[m+1]=t+r,d[m+2]=o.charIndex,d[m+3]=g,m+=4}))}else l=_(e._font,t,((e,t,r,a)=>{d[m]=e,d[m+1]=t,d[m+2]=a.charIndex,d[m+3]=g,m+=4})),"alphabetic"==u?a-=e._textSize:"center"==u?a-=.5*e._textSize:"bottom"==u&&(a-=c);p.push(d);let x=[];e._matrixDirty&&e._saveMatrix(),x[0]=r,x[1]=-a,x[2]=e._textSize/44,x[3]=e._matrixIndex,x[4]=e._doFill&&e._fillSet?e._fill:0,x[5]=e._stroke,x[6]=e._doStroke&&e._strokeSet?e._strokeWeight:0,x[7]=0,f.push(x),e._drawStack.push(e._textPL,l.printedCharCount,e._font.index)},e.textWidth=t=>e._font?_(e._font,t).width:0,e.createTextImage=(t,r,a)=>{if(e._g.textSize(e._textSize),e._doFill&&e._fillSet){let t=4*e._fill;e._g.fill(e._colorStack.slice(t,t+4))}if(e._doStroke&&e._strokeSet){let t=4*e._stroke;e._g.stroke(e._colorStack.slice(t,t+4))}let o=e._g.createTextImage(t,r,a);if(null==o.textureIndex){e._createTexture(o);let t=o.copy;o.copy=function(){let r=t();return e._createTexture(r),r}}return o},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let o=e._imageMode;e._imageMode="corner";let n=e._textAlign;"center"==n?r-=t.canvas.hw:"right"==n&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"center"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=o},e._hooks.preRender.push((()=>{if(!p.length)return;let t=0;for(let e of p)t+=4*e.length;let r=Q5.device.createBuffer({size:t,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(p.flat()),r.unmap();let o=8*f.length*4,n=Q5.device.createBuffer({label:"textBuffer",size:o,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(n.getMappedRange()).set(f.flat()),n.unmap(),e._buffers.push(r,n),e._textBindGroup=Q5.device.createBindGroup({label:"textBindGroup",layout:a,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]})})),e._hooks.postRender.push((()=>{p=[],f=[]}))},Q5.renderers.webgpu.shaders=e=>{let t=["frame","shapes","image","video","text"],r={frame:10,shapes:1e3,image:2e3,video:3e3,text:4e3};e._createShader=(a,o="shapes")=>{a=a.trim();let n=e["_"+o+"ShaderCode"],i=n.indexOf("@vertex"),s=n.indexOf("@fragment");a=a.includes("@fragment")?a.includes("@vertex")?n.slice(0,i)+a:n.slice(0,s)+a:n.slice(0,i)+a+"\n\n"+n.slice(s);let l=Q5.device.createShaderModule({label:o+"Shader",code:a});l.type=o;let d=t.indexOf(o),c=Object.assign({},e._pipelineConfigs[d]);c.vertex.module=c.fragment.module=l;let h=r[o];return e._pipelines[h]=Q5.device.createRenderPipeline(c),e._pipelines[h].shader=l,l.pipelineIndex=h,r[o]++,l},e.createShader=e.createShapesShader=e._createShader,e.createFrameShader=t=>e._createShader(t,"frame"),e.createImageShader=t=>e._createShader(t,"image"),e.createVideoShader=t=>e._createShader(t,"video"),e.createTextShader=t=>e._createShader(t,"text"),e.shader=t=>{t.applyBeforeDraw?e._prevFramePL=t.pipelineIndex:e["_"+t.type+"PL"]=t.pipelineIndex},e.resetShader=(r="shapes")=>{"frame"==r&&(e._prevFramePL=0),e["_"+r+"PL"]=t.indexOf(r)},e.resetShaders=()=>{e._prevFramePL=e._framePL=0,e._shapesPL=1,e._imagePL=2,e._videoPL=3,e._textPL=4}};
|
|
8
|
+
function Q5(e,t,r){let a=this;a._q5=!0,a._parent=t,"webgpu-fallback"==r?(a._renderer="c2d",a._webgpu=a._webgpuFallback=!0):(a._renderer=r||Q5.render,a["_"+a._renderer]=!0);let o,n="auto"==e;if(e??="global","auto"==e){if(!(window.setup||window.update||window.draw))return;e="global"}a._scope=e,"global"==e&&(Q5._hasGlobal=a._isGlobal=!0,o=Q5._esm?globalThis:Q5._server?global:window),"graphics"==e&&(a._graphics=!0);let i=new Proxy(a,{set:(e,t,r)=>(a[t]=r,a._isGlobal&&(o[t]=r),!0)});a.canvas=a.ctx=a.drawingContext=null,a.pixels=[];let s=null,l=!0;a.frameCount=0,a.deltaTime=16,a._targetFrameRate=0,a._targetFrameDuration=16.666666666666668,a._frameRate=a._fps=60,a._loop=!0,a._hooks={postCanvas:[],preRender:[],postRender:[]};let d=0;a.millis=()=>performance.now()-d,a.noCanvas=()=>{a.canvas?.remove&&a.canvas.remove(),a.canvas=0,i.ctx=i.drawingContext=0},window&&(a.windowWidth=window.innerWidth,a.windowHeight=window.innerHeight,a.deviceOrientation=window.screen?.orientation?.type),a._preloadCount=0,a._incrementPreload=()=>i._preloadCount++,a._decrementPreload=()=>i._preloadCount--,a._usePreload=!0,a.usePreloadSystem=e=>a._usePreload=e,a.isPreloadSupported=()=>a._usePreload,a._draw=e=>{let t=e||performance.now();if(a._lastFrameTime??=t-a._targetFrameDuration,a._didResize&&(a.windowResized(),a._didResize=!1),a._loop)if(l)s=h(a._draw);else{let e=t+a._targetFrameDuration,r=e-performance.now();for(;r<0;)r+=a._targetFrameDuration;log(r),s=setTimeout((()=>a._draw(e)),r)}else if(a.frameCount&&!a._redraw)return;if(a.frameCount&&l&&!a._redraw){if(t-a._lastFrameTime<a._targetFrameDuration-4)return}i.deltaTime=t-a._lastFrameTime,a._frameRate=1e3/a.deltaTime,i.frameCount++;let r=performance.now();a.resetMatrix(),a._beginRender&&a._beginRender();for(let e of Q5.methods.pre)e.call(a);try{a.draw()}catch(e){throw Q5.errorTolerant||a.noLoop(),a._fes&&a._fes(e),e}for(let e of Q5.methods.post)e.call(a);a.postProcess(),a._render&&a._render(),a._finishRender&&a._finishRender(),i.pmouseX=a.mouseX,i.pmouseY=a.mouseY,i.moveX=i.moveY=0,a._lastFrameTime=t;let o=performance.now();a._fps=Math.round(1e3/(o-r))},a.noLoop=()=>{a._loop=!1,s&&(l?cancelAnimationFrame(s):clearTimeout(s)),s=null},a.loop=()=>{a._loop=!0,a._setupDone&&null==s&&a._draw()},a.isLooping=()=>a._loop,a.redraw=(e=1)=>{a._redraw=!0;for(let t=0;t<e;t++)a._draw();a._redraw=!1},a.remove=()=>{a.noLoop(),a.canvas.remove()},a.frameRate=e=>(e&&(a._targetFrameRate=e,a._targetFrameDuration=1e3/e,a._loop&&a._setupDone&&null!=s&&(l?cancelAnimationFrame(s):clearTimeout(s),s=null),l=e<=60,setTimeout((()=>a._draw()),a._targetFrameDuration)),a._frameRate),a.getTargetFrameRate=()=>a._targetFrameRate||60,a.getFPS=()=>a._fps,a.Element=function(e){this.elt=e},a._elements=[],a.describe=()=>{},a.log=a.print=console.log;for(let e in Q5.modules)Q5.modules[e](a,i);let c=Q5.renderers[a._renderer];for(let e in c)c[e](a,i);for(let e in Q5)"_"!=e[1]&&e[1]==e[1].toUpperCase()&&(a[e]=Q5[e]);if(a._graphics)return;if("global"==e){let e=Object.assign({},a);delete e.Color,Object.assign(Q5,e),delete Q5.Q5}for(let e of Q5.methods.init)e.call(a);for(let[e,t]of Object.entries(Q5.prototype))"_"!=e[0]&&"function"==typeof a[e]&&(a[e]=t.bind(a));if("global"==e){let e=Object.getOwnPropertyNames(a);for(let t of e)"_"!=t[0]&&(o[t]=a[t])}"function"==typeof e&&e(a),Q5._instanceCount++;let h=window.requestAnimationFrame||function(e){const t=a._lastFrameTime+a._targetFrameDuration;return setTimeout((()=>{e(t)}),t-performance.now())},u=o||a;a._isTouchAware=u.touchStarted||u.touchMoved||u.touchEnded,a._isGlobal&&(a.preload=u.preload,a.setup=u.setup,a.draw=u.draw,a.postProcess=u.postProcess),a.preload??=()=>{},a.setup??=()=>{},a.draw??=()=>{},a.postProcess??=()=>{};let p=["setup","postProcess","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","mouseWheel","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of p)u[e]?a._isGlobal&&(a[e]=t=>{try{return u[e](t)}catch(e){throw a._fes&&a._fes(e),e}}):a[e]=()=>{};async function f(){if(a._startDone=!0,a._preloadCount>0||a._g?._preloadCount>0)return h(f);d=performance.now(),await a.setup(),a._setupDone=!0,a.frameCount||(null===a.ctx&&a.createCanvas(200,200),h(a._draw))}function _(){try{a.preload(),a._startDone||f()}catch(e){throw a._fes&&a._fes(e),e}}n?_():setTimeout(_,32)}function createCanvas(e,t,r){if(!Q5._hasGlobal){(new Q5).createCanvas(e,t,r)}}Q5.render="c2d",Q5.renderers={},Q5.modules={},Q5._server="object"==typeof process,Q5._esm=void 0===this,Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{Q5.disableFriendlyErrors||console.error(t+": "+e)},Q5._validateParameters=()=>!0,Q5.methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],Q5._server&&(global.p5??=global.Q5=Q5),"object"==typeof window?window.p5??=window.Q5=Q5:global.window=0,Q5.version=Q5.VERSION="2.24","object"==typeof document&&document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})),Q5.modules.canvas=(e,t)=>{e._Canvas=window.OffscreenCanvas||function(){return document.createElement("canvas")},Q5._server?Q5._createServerCanvas&&(t.canvas=Q5._createServerCanvas(100,100)):"image"!=e._scope&&"graphics"!=e._scope||(t.canvas=new e._Canvas(100,100)),e.canvas||("object"==typeof document?(t.canvas=document.createElement("canvas"),e.canvas.id="q5Canvas"+Q5._instanceCount,e.canvas.classList.add("q5Canvas")):e.noCanvas());let r=e.canvas;if(e.width=200,e.height=200,e._pixelDensity=1,e.displayDensity=()=>window.devicePixelRatio||1,r&&(r.width=200,r.height=200,"image"!=e._scope&&(r.renderer=e._renderer,r[e._renderer]=!0,e._pixelDensity=Math.ceil(e.displayDensity()))),e._adjustDisplay=()=>{r.style&&(r.style.width=r.w+"px",r.style.height=r.h+"px")},e.createCanvas=function(t,a,o){"object"==typeof t&&(o=t,t=null),o??=arguments[3],"string"==typeof o&&(o={renderer:o});let n=Object.assign({},Q5.canvasOptions);if("object"==typeof o&&Object.assign(n,o),"image"!=e._scope)if("graphics"==e._scope)e._pixelDensity=this._pixelDensity;else if(window.IntersectionObserver){let t=!1;new IntersectionObserver((a=>{r.visible=a[0].isIntersecting,t||(e._wasLooping=e._loop,t=!0),r.visible?e._wasLooping&&!e._loop&&e.loop():(e._wasLooping=e._loop,e.noLoop())})).observe(r)}e._setCanvasSize(t,a),Object.assign(r,n);let i=e._createCanvas(r.w,r.h,n);if(e._hooks)for(let t of e._hooks.postCanvas)t();return e._addEventMethods&&e._addEventMethods(r),i},e.createGraphics=function(t,r,a={}){"string"==typeof a&&(a={renderer:a});let o=new Q5("graphics",void 0,a.renderer||(e._webgpuFallback?"webgpu-fallback":e._renderer));a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace,o.createCanvas.call(e,t,r,a);let n=o._pixelDensity*e._defaultImageScale;return o.defaultWidth=t*n,o.defaultHeight=r*n,o},e._setCanvasSize=(a,o)=>{o??=a??window.innerHeight,a??=window.innerWidth,r.w=a=Math.ceil(a),r.h=o=Math.ceil(o),t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=o/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(o*e._pixelDensity),e._da?e.flexibleCanvas(e._dau):(t.width=a,t.height=o),e.displayMode&&!r.displayMode?e.displayMode():e._adjustDisplay()},e._setImageSize=(a,o)=>{t.width=r.w=a,t.height=r.h=o,t.halfWidth=r.hw=a/2,t.halfHeight=r.hh=o/2,r.width=Math.ceil(a*e._pixelDensity),r.height=Math.ceil(o*e._pixelDensity)},e.defaultImageScale=t=>t?e._defaultImageScale=t:e._defaultImageScale,e.defaultImageScale(.5),"image"!=e._scope){if(r&&"graphics"!=e._scope){function a(){let t=e._parent;t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),r.parent(t)}r.parent=t=>{function a(){e.frameCount>1&&(e._didResize=!0,e._adjustDisplay())}r.parentElement&&r.parentElement.removeChild(r),"string"==typeof t&&(t=document.getElementById(t)),t.append(r),"function"==typeof ResizeObserver?(e._ro&&e._ro.disconnect(),e._ro=new ResizeObserver(a),e._ro.observe(t)):e.frameCount||window.addEventListener("resize",a)},document.body?a():document.addEventListener("DOMContentLoaded",a)}e.resizeCanvas=(t,a)=>{if(!e.ctx)return e.createCanvas(t,a);t==r.w&&a==r.h||e._resizeCanvas(t,a)},r&&!Q5._createServerCanvas&&(r.resize=e.resizeCanvas),e.pixelDensity=t=>t&&t!=e._pixelDensity?(e._pixelDensity=t,e._resizeCanvas(r.w,r.h),t):e._pixelDensity,e.flexibleCanvas=(a=400)=>{a?(e._da=r.width/(a*e._pixelDensity),t.width=e._dau=a,t.height=r.h/r.w*a):e._da=0},e._styleNames=["_fill","_stroke","_strokeWeight","_doStroke","_doFill","_strokeSet","_fillSet","_shadow","_doShadow","_shadowOffsetX","_shadowOffsetY","_shadowBlur","_tint","_colorMode","_colorFormat","Color","_imageMode","_rectMode","_ellipseMode","_textSize","_textAlign","_textBaseline"],e._styles=[],e.pushStyles=()=>{let t={};for(let r of e._styleNames)t[r]=e[r];e._styles.push(t)},e.popStyles=()=>{let r=e._styles.pop();for(let t of e._styleNames)e[t]=r[t];t.Color=r.Color},window&&"graphics"!=e._scope&&window.addEventListener("resize",(()=>{e._didResize=!0,t.windowWidth=window.innerWidth,t.windowHeight=window.innerHeight,t.deviceOrientation=window.screen?.orientation?.type}))}},Q5.CENTER="center",Q5.LEFT="left",Q5.RIGHT="right",Q5.TOP="top",Q5.BOTTOM="bottom",Q5.BASELINE="alphabetic",Q5.MIDDLE="middle",Q5.NORMAL="normal",Q5.ITALIC="italic",Q5.BOLD="bold",Q5.BOLDITALIC="italic bold",Q5.ROUND="round",Q5.SQUARE="butt",Q5.PROJECT="square",Q5.MITER="miter",Q5.BEVEL="bevel",Q5.NONE="none",Q5.SIMPLE="simple",Q5.CHORD_OPEN=0,Q5.PIE_OPEN=1,Q5.PIE=2,Q5.CHORD=3,Q5.RADIUS="radius",Q5.CORNER="corner",Q5.CORNERS="corners",Q5.OPEN=0,Q5.CLOSE=1,Q5.VIDEO="video",Q5.AUDIO="audio",Q5.LANDSCAPE="landscape",Q5.PORTRAIT="portrait",Q5.BLEND="source-over",Q5.REMOVE="destination-out",Q5.ADD="lighter",Q5.DARKEST="darken",Q5.LIGHTEST="lighten",Q5.DIFFERENCE="difference",Q5.SUBTRACT="subtract",Q5.EXCLUSION="exclusion",Q5.MULTIPLY="multiply",Q5.SCREEN="screen",Q5.REPLACE="copy",Q5.OVERLAY="overlay",Q5.HARD_LIGHT="hard-light",Q5.SOFT_LIGHT="soft-light",Q5.DODGE="color-dodge",Q5.BURN="color-burn",Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.SEPIA=9,Q5.BRIGHTNESS=10,Q5.SATURATION=11,Q5.CONTRAST=12,Q5.HUE_ROTATE=13,Q5.C2D=Q5.P2D=Q5.P2DHDR="c2d",Q5.WEBGL="webgl",Q5.WEBGPU="webgpu",Q5.canvasOptions={alpha:!1,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",Q5.renderers.c2d={},Q5.renderers.c2d.canvas=(e,t)=>{let r=e.canvas;if(e.colorMode&&e.colorMode("rgb",255),e._createCanvas=function(a,o,n){if(r)return t.ctx=t.drawingContext=r.getContext("2d",n),"image"!=e._scope&&(e.ctx.fillStyle=e._fill="white",e.ctx.strokeStyle=e._stroke="black",e.ctx.lineCap="round",e.ctx.lineJoin="miter",e.ctx.textAlign="left",e._strokeWeight=1),e.ctx.scale(e._pixelDensity,e._pixelDensity),e.ctx.save(),r;console.error("q5 canvas could not be created. skia-canvas and jsdom packages not found.")},e.clear=()=>{e.ctx.save(),e.ctx.resetTransform(),e.ctx.clearRect(0,0,e.canvas.width,e.canvas.height),e.ctx.restore()},"image"==e._scope)return;e.background=function(t){e.ctx.save(),e.ctx.resetTransform(),e.ctx.globalAlpha=1,t.canvas?e.image(t,0,0,e.canvas.width,e.canvas.height):(Q5.Color&&!t._q5Color&&(t=e.color(...arguments)),e.ctx.fillStyle=t.toString(),e.ctx.fillRect(0,0,e.canvas.width,e.canvas.height)),e.ctx.restore()},e._resizeCanvas=(t,a)=>{let o,n={};for(let t in e.ctx)"function"!=typeof e.ctx[t]&&(n[t]=e.ctx[t]);if(delete n.canvas,e.frameCount>1){o=new e._Canvas(r.width,r.height),o.w=r.w,o.h=r.h,o.getContext("2d").drawImage(r,0,0)}e._setCanvasSize(t,a);for(let t in n)e.ctx[t]=n[t];e.scale(e._pixelDensity),o&&e.ctx.drawImage(o,0,0,o.w,o.h)},e.fill=function(t){if(e._doFill=e._fillSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doFill=!1;e.ctx.fillStyle=e._fill=t.toString()},e.stroke=function(t){if(e._doStroke=e._strokeSet=!0,Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doStroke=!1;e.ctx.strokeStyle=e._stroke=t.toString()},e.strokeWeight=t=>{t||(e._doStroke=!1),e._da&&(t*=e._da),e.ctx.lineWidth=e._strokeWeight=t||1e-4},e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.opacity=t=>e.ctx.globalAlpha=t,e._doShadow=!1,e._shadowOffsetX=e._shadowOffsetY=e._shadowBlur=10,e.shadow=function(t){if(Q5.Color&&(t._q5Color||"string"==typeof t&&!e._namedColors[t]||(t=e.color(...arguments)),t.a<=0))return e._doShadow=!1;e.ctx.shadowColor=e._shadow=t.toString(),e._doShadow=!0,e.ctx.shadowOffsetX||=e._shadowOffsetX,e.ctx.shadowOffsetY||=e._shadowOffsetY,e.ctx.shadowBlur||=e._shadowBlur},e.shadowBox=(t,r,a)=>{e.ctx.shadowOffsetX=e._shadowOffsetX=t,e.ctx.shadowOffsetY=e._shadowOffsetY=r||t,e.ctx.shadowBlur=e._shadowBlur=a||0},e.noShadow=()=>{e._doShadow=!1,e.ctx.shadowOffsetX=e.ctx.shadowOffsetY=e.ctx.shadowBlur=0},e.translate=(t,r)=>{e._da&&(t*=e._da,r*=e._da),e.ctx.translate(t,r)},e.rotate=t=>{e._angleMode&&(t=e.radians(t)),e.ctx.rotate(t)},e.scale=(t,r)=>{t.x&&(r=t.y,t=t.x),r??=t,e.ctx.scale(t,r)},e.applyMatrix=(t,r,a,o,n,i)=>e.ctx.transform(t,r,a,o,n,i),e.shearX=t=>e.ctx.transform(1,0,e.tan(t),1,0,0),e.shearY=t=>e.ctx.transform(1,e.tan(t),0,1,0,0),e.resetMatrix=()=>{e.ctx&&(e.ctx.resetTransform(),e.scale(e._pixelDensity),e._webgpu&&e.translate(e.halfWidth,e.halfHeight))},e.pushMatrix=()=>e.ctx.save(),e.popMatrix=()=>e.ctx.restore();let a=e.popStyles;e.popStyles=()=>{a(),e.ctx.fillStyle=e._fill,e.ctx.strokeStyle=e._stroke,e.ctx.lineWidth=e._strokeWeight,e.ctx.shadowColor=e._shadow,e.ctx.shadowOffsetX=e._doShadow?e._shadowOffsetX:0,e.ctx.shadowOffsetY=e._doShadow?e._shadowOffsetY:0,e.ctx.shadowBlur=e._doShadow?e._shadowBlur:0},e.push=()=>{e.ctx.save(),e.pushStyles()},e.pop=()=>{e.ctx.restore(),a()}},Q5.renderers.c2d.shapes=e=>{e._doStroke=!0,e._doFill=!0,e._strokeSet=!1,e._fillSet=!1,e._ellipseMode=Q5.CENTER,e._rectMode=Q5.CORNER;let t=!0,r=[];function a(){e._doFill&&e.ctx.fill(),e._doStroke&&e.ctx.stroke()}e.blendMode=t=>e.ctx.globalCompositeOperation=t,e.strokeCap=t=>e.ctx.lineCap=t,e.strokeJoin=t=>e.ctx.lineJoin=t,e.ellipseMode=t=>e._ellipseMode=t,e.rectMode=t=>e._rectMode=t,e.curveDetail=()=>{},e.line=(t,r,a,o)=>{e._doStroke&&(e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(a,o),e.ctx.stroke())};const o=2*Math.PI;function n(t,r,a,n,i,s,l){if(e._angleMode&&(i=e.radians(i),s=e.radians(s)),(i%=o)<0&&(i+=o),(s%=o)<0&&(s+=o),i>s&&(s+=o),i==s)return e.ellipse(t,r,a,n);if(a/=2,n/=2,e._doFill||l!=e.PIE_OPEN||(l=e.CHORD_OPEN),e.ctx.beginPath(),e.ctx.ellipse(t,r,a,n,0,i,s),l!=e.PIE&&l!=e.PIE_OPEN||e.ctx.lineTo(t,r),e._doFill&&e.ctx.fill(),e._doStroke){if(l!=e.PIE&&l!=e.CHORD||e.ctx.closePath(),l!=e.PIE_OPEN)return e.ctx.stroke();e.ctx.beginPath(),e.ctx.ellipse(t,r,a,n,0,i,s),e.ctx.stroke()}}function i(t,r,n,i){e.ctx.beginPath(),e.ctx.ellipse(t,r,n/2,i/2,0,0,o),a()}function s(t,r,o,n,i,l,d,c){return void 0===i?function(t,r,o,n){e._da&&(t*=e._da,r*=e._da,o*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.rect(t,r,o,n),a()}(t,r,o,n):void 0===l?s(t,r,o,n,i,i,i,i):(e._da&&(t*=e._da,r*=e._da,o*=e._da,n*=e._da,i*=e._da,l*=e._da,c*=e._da,d*=e._da),e.ctx.roundRect(t,r,o,n,[i,l,d,c]),void a())}e.arc=(t,r,a,o,i,s,l)=>{if(i==s)return e.ellipse(t,r,a,o);e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),l??=e.PIE_OPEN,e._ellipseMode==e.CENTER?n(t,r,a,o,i,s,l):e._ellipseMode==e.RADIUS?n(t,r,2*a,2*o,i,s,l):e._ellipseMode==e.CORNER?n(t+a/2,r+o/2,a,o,i,s,l):e._ellipseMode==e.CORNERS&&n((t+a)/2,(r+o)/2,a-t,o-r,i,s,l)},e.ellipse=(t,r,a,o)=>{o??=a,e._da&&(t*=e._da,r*=e._da,a*=e._da,o*=e._da),e._ellipseMode==e.CENTER?i(t,r,a,o):e._ellipseMode==e.RADIUS?i(t,r,2*a,2*o):e._ellipseMode==e.CORNER?i(t+a/2,r+o/2,a,o):e._ellipseMode==e.CORNERS&&i((t+a)/2,(r+o)/2,a-t,o-r)},e.circle=(t,r,n)=>{e._ellipseMode==e.CENTER?(e._da&&(t*=e._da,r*=e._da,n*=e._da),e.ctx.beginPath(),e.ctx.arc(t,r,n/2,0,o),a()):e.ellipse(t,r,n,n)},e.point=(t,r)=>{e._doStroke&&(t.x&&(r=t.y,t=t.x),e._da&&(t*=e._da,r*=e._da),e.ctx.beginPath(),e.ctx.moveTo(t,r),e.ctx.lineTo(t,r),e.ctx.stroke())},e.rect=(t,r,a,o=a,n,i,l,d)=>{e._rectMode==e.CENTER?s(t-a/2,r-o/2,a,o,n,i,l,d):e._rectMode==e.RADIUS?s(t-a,r-o,2*a,2*o,n,i,l,d):e._rectMode==e.CORNER?s(t,r,a,o,n,i,l,d):e._rectMode==e.CORNERS&&s(t,r,a-t,o-r,n,i,l,d)},e.square=(t,r,a,o,n,i,s)=>e.rect(t,r,a,a,o,n,i,s),e.beginShape=()=>{r=[],e.ctx.beginPath(),t=!0},e.beginContour=()=>{e.ctx.closePath(),r=[],t=!0},e.endContour=()=>{r=[],t=!0},e.vertex=(a,o)=>{e._da&&(a*=e._da,o*=e._da),r=[],t?e.ctx.moveTo(a,o):e.ctx.lineTo(a,o),t=!1},e.bezierVertex=(t,a,o,n,i,s)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da),r=[],e.ctx.bezierCurveTo(t,a,o,n,i,s)},e.quadraticVertex=(t,a,o,n)=>{e._da&&(t*=e._da,a*=e._da,o*=e._da,n*=e._da),r=[],e.ctx.quadraticCurveTo(t,a,o,n)},e.bezier=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,o,n,i,s,l),e.endShape()},e.triangle=(t,r,a,o,n,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(e.CLOSE)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(e.CLOSE)},e.endShape=t=>{r=[],t&&e.ctx.closePath(),a()},e.curveVertex=(a,o)=>{if(e._da&&(a*=e._da,o*=e._da),r.push([a,o]),r.length<4)return;let n=r.at(-4),i=r.at(-3),s=r.at(-2),l=r.at(-1),d=i[0]+(s[0]-n[0])/6,c=i[1]+(s[1]-n[1])/6,h=s[0]-(l[0]-i[0])/6,u=s[1]-(l[1]-i[1])/6;t&&(e.ctx.moveTo(i[0],i[1]),t=!1),e.ctx.bezierCurveTo(d,c,h,u,s[0],s[1])},e.curve=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,o),e.curveVertex(n,i),e.curveVertex(s,l),e.endShape()},e.curvePoint=(e,t,r,a,o)=>{const n=o*o*o,i=o*o;return e*(-.5*n+i-.5*o)+t*(1.5*n-2.5*i+1)+r*(-1.5*n+2*i+.5*o)+a*(.5*n-.5*i)},e.bezierPoint=(e,t,r,a,o)=>{const n=1-o;return Math.pow(n,3)*e+3*Math.pow(n,2)*o*t+3*n*Math.pow(o,2)*r+Math.pow(o,3)*a},e.curveTangent=(e,t,r,a,o)=>{const n=o*o;return e*(-3*n/2+2*o-.5)+t*(9*n/2-5*o)+r*(-9*n/2+4*o+.5)+a*(3*n/2-o)},e.bezierTangent=(e,t,r,a,o)=>{const n=1-o;return 3*a*Math.pow(o,2)-3*r*Math.pow(o,2)+6*r*n*o-6*t*n*o+3*t*Math.pow(n,2)-3*e*Math.pow(n,2)},e.erase=function(t,r){255==e._colorFormat&&(t&&(t/=255),r&&(r/=255)),e.ctx.save(),e.ctx.globalCompositeOperation="destination-out",e.ctx.fillStyle=`rgb(0 0 0 / ${t||1})`,e.ctx.strokeStyle=`rgb(0 0 0 / ${r||1})`},e.noErase=function(){e.ctx.globalCompositeOperation="source-over",e.ctx.restore()},e.inFill=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInPath(t*a,r*a)},e.inStroke=(t,r)=>{const a=e._pixelDensity;return e.ctx.isPointInStroke(t*a,r*a)}},Q5.renderers.c2d.image=(e,t)=>{Q5.Image??=class{constructor(e,r,a={}){let o=this;o._scope="image",o.canvas=o.ctx=o.drawingContext=null,o.pixels=[],Q5.modules.canvas(o,o);let n=Q5.renderers.c2d;for(let e of["canvas","image","soft_filters"])n[e]&&n[e](o,o);o._pixelDensity=a.pixelDensity||1,o.createCanvas(e,r,a);let i=o._pixelDensity*t._defaultImageScale;o.defaultWidth=e*i,o.defaultHeight=r*i,delete o.createCanvas,o._loop=!1}get w(){return this.width}get h(){return this.height}},e._tint=null;let r=null;e.createImage=(t,r,a)=>(a??={},a.alpha??=!0,a.colorSpace??=e.canvas.colorSpace||Q5.canvasOptions.colorSpace,new Q5.Image(t,r,a)),e.loadImage=function(r,a,o){if(r.canvas)return r;if("gif"==r.slice(-3).toLowerCase())throw new Error("q5 doesn't support GIFs. Use a video or p5play animation instead. https://github.com/q5js/q5.js/issues/84");t._preloadCount++;let n=[...arguments].at(-1);"object"==typeof n?(o=n,a=null):o=null;let i=e.createImage(1,1,o),s=i._pixelDensity,l=new window.Image;return l.crossOrigin="Anonymous",i._loader=new Promise(((r,o)=>{l.onload=()=>{l._pixelDensity=s,i.defaultWidth=l.width*e._defaultImageScale,i.defaultHeight=l.height*e._defaultImageScale,i.naturalWidth=l.naturalWidth||l.width,i.naturalHeight=l.naturalHeight||l.height,i._setImageSize(Math.ceil(i.naturalWidth/s),Math.ceil(i.naturalHeight/s)),i.ctx.drawImage(l,0,0),t._preloadCount--,a&&a(i),delete i._loader,r(i)},l.onerror=e=>{t._preloadCount--,o(e)}})),i.src=l.src=r,e._usePreload?i:i._loader},e.imageMode=t=>e._imageMode=t,e.image=(t,r,a,o,n,i=0,s=0,l,d)=>{if(!t)return;let c=t.canvas||t;o??=t.defaultWidth||c.width||t.videoWidth,n??=t.defaultHeight||c.height||t.videoHeight,"center"==e._imageMode&&(r-=.5*o,a-=.5*n),e._da&&(r*=e._da,a*=e._da,o*=e._da,n*=e._da,i*=e._da,s*=e._da,l*=e._da,d*=e._da);let h=t._pixelDensity||1;if(l?l*=h:l=c.width||c.videoWidth,d?d*=h:d=c.height||c.videoHeight,e._tint){if(t._retint||t._tint!=e._tint){t._tintImg??=e.createImage(t.w,t.h,{pixelDensity:h}),t._tintImg.width==t.width&&t._tintImg.height==t.height||t._tintImg.resize(t.w,t.h);let r=t._tintImg.ctx;r.globalCompositeOperation="copy",r.fillStyle=e._tint,r.fillRect(0,0,t.width,t.height),t.canvas.alpha&&(r.globalCompositeOperation="destination-in",r.drawImage(c,0,0,t.width,t.height)),r.globalCompositeOperation="multiply",r.drawImage(c,0,0,t.width,t.height),t._tint=e._tint,t._retint=!1}c=t._tintImg.canvas}t.flipped&&(e.ctx.save(),e.ctx.translate(r+o,0),e.ctx.scale(-1,1),r=0),e.ctx.drawImage(c,i*h,s*h,l,d,r,a,o,n),t.flipped&&e.ctx.restore()},e.filter=(t,r)=>{e.ctx.save();let a="";if(e.ctx.filter){if("string"==typeof t)a=t;else if(t==Q5.GRAY)a="saturate(0%)";else if(t==Q5.INVERT)a="invert(100%)";else if(t==Q5.BLUR){a=`blur(${Math.ceil(r*e._pixelDensity)||1}px)`}else if(t==Q5.THRESHOLD){r??=.5,a=`saturate(0%) brightness(${Math.floor(.5/Math.max(r,1e-5)*100)}%) contrast(1000000%)`}else if(t==Q5.SEPIA)a=`sepia(${r??1})`;else if(t==Q5.BRIGHTNESS)a=`brightness(${r??1})`;else if(t==Q5.SATURATION)a=`saturate(${r??1})`;else if(t==Q5.CONTRAST)a=`contrast(${r??1})`;else if(t==Q5.HUE_ROTATE){a=`hue-rotate(${r}${0==e._angleMode?"rad":"deg"})`}if(a&&(e.ctx.filter=a,"none"==e.ctx.filter))throw new Error(`Invalid filter format: ${t}`)}a||e._softFilter(t,r),e.ctx.globalCompositeOperation="source-over",e.ctx.drawImage(e.canvas,0,0,e.canvas.w,e.canvas.h),e.ctx.restore(),e.modified=e._retint=!0},"image"==e._scope&&(e.resize=(t,r)=>{let a=e.canvas,o=new e._Canvas(a.width,a.height);o.getContext("2d",{colorSpace:a.colorSpace}).drawImage(a,0,0),e._setImageSize(t,r),e.defaultWidth=a.width*e._defaultImageScale,e.defaultHeight=a.height*e._defaultImageScale,e.ctx.clearRect(0,0,a.width,a.height),e.ctx.drawImage(o,0,0,a.width,a.height),e.modified=e._retint=!0}),e._getImageData=(t,r,a,o)=>e.ctx.getImageData(t,r,a,o,{colorSpace:e.canvas.colorSpace}),e.trim=()=>{let t=e._pixelDensity||1,r=e.canvas.width,a=e.canvas.height,o=e._getImageData(0,0,r,a).data,n=r,i=0,s=a,l=0,d=3;for(let e=0;e<a;e++)for(let t=0;t<r;t++)0!==o[d]&&(t<n&&(n=t),t>i&&(i=t),e<s&&(s=e),e>l&&(l=e)),d+=4;return s=Math.floor(s/t),l=Math.floor(l/t),n=Math.floor(n/t),i=Math.floor(i/t),e.get(n,s,i-n+1,l-s+1)},e.mask=t=>{e.ctx.save(),e.ctx.resetTransform();let r=e.ctx.globalCompositeOperation;e.ctx.globalCompositeOperation="destination-in",e.ctx.drawImage(t.canvas,0,0),e.ctx.globalCompositeOperation=r,e.ctx.restore(),e.modified=e._retint=!0},e.inset=(t,r,a,o,n,i,s,l)=>{let d=e._pixelDensity||1;e.ctx.drawImage(e.canvas,t*d,r*d,a*d,o*d,n,i,s,l),e.modified=e._retint=!0},e.copy=()=>{let t=e.get();for(let r in e)"function"==typeof e[r]||/(canvas|ctx|texture|textureIndex)/.test(r)||(t[r]=e[r]);return t},e.get=(t,r,a,o)=>{let n=e._pixelDensity||1;if(void 0!==t&&void 0===a){let a=e._getImageData(t*n,r*n,1,1).data;return[a[0],a[1],a[2],a[3]/255]}t=Math.floor(t||0)*n,r=Math.floor(r||0)*n,a??=e.width,o??=e.height;let i=e.createImage(a,o,{pixelDensity:n});return i.ctx.drawImage(e.canvas,t,r,a*n,o*n,0,0,a,o),i.width=a,i.height=o,i},e.set=(t,r,a)=>{if(t=Math.floor(t),r=Math.floor(r),e.modified=e._retint=!0,a.canvas){let o=e._tint;return e._tint=null,e.image(a,t,r),void(e._tint=o)}e.pixels.length||e.loadPixels();let o=e._pixelDensity||1;for(let n=0;n<o;n++)for(let i=0;i<o;i++){let s=4*((r*o+n)*e.canvas.width+t*o+i);e.pixels[s]=a.r,e.pixels[s+1]=a.g,e.pixels[s+2]=a.b,e.pixels[s+3]=a.a}},e.loadPixels=()=>{r=e._getImageData(0,0,e.canvas.width,e.canvas.height),t.pixels=r.data},e.updatePixels=()=>{null!=r&&(e.ctx.putImageData(r,0,0),e.modified=e._retint=!0)},e.smooth=()=>e.ctx.imageSmoothingEnabled=!0,e.noSmooth=()=>e.ctx.imageSmoothingEnabled=!1,"image"!=e._scope&&(e._saveCanvas=async(e,t)=>{if((e=e.canvas||e)instanceof OffscreenCanvas){const r=await e.convertToBlob({type:"image/"+t});return await new Promise((e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(r)}))}return e.toDataURL("image/"+t)},e.tint=function(t){e._tint=(t._q5Color?t:e.color(...arguments)).toString()},e.noTint=()=>e._tint=null)},Q5.renderers.c2d.soft_filters=e=>{let t=null;function r(){let r=e.canvas.width*e.canvas.height*4;t&&t.length==r||(t=new Uint8ClampedArray(r))}e._softFilter=(a,o)=>{e._filters||(e._filters=[],e._filters[Q5.THRESHOLD]=(e,t)=>{void 0===t?t=127.5:t*=255;for(let r=0;r<e.length;r+=4){const a=.2126*e[r]+.7152*e[r+1]+.0722*e[r+2];e[r]=e[r+1]=e[r+2]=a>=t?255:0}},e._filters[Q5.GRAY]=e=>{for(let t=0;t<e.length;t+=4){const r=.2126*e[t]+.7152*e[t+1]+.0722*e[t+2];e[t]=e[t+1]=e[t+2]=r}},e._filters[Q5.OPAQUE]=e=>{for(let t=0;t<e.length;t+=4)e[t+3]=255},e._filters[Q5.INVERT]=e=>{for(let t=0;t<e.length;t+=4)e[t]=255-e[t],e[t+1]=255-e[t+1],e[t+2]=255-e[t+2]},e._filters[Q5.POSTERIZE]=(e,t=4)=>{let r=t-1;for(let a=0;a<e.length;a+=4)e[a]=255*(e[a]*t>>8)/r,e[a+1]=255*(e[a+1]*t>>8)/r,e[a+2]=255*(e[a+2]*t>>8)/r},e._filters[Q5.DILATE]=(a,o)=>{o??=Math.max,r(),t.set(a);let[n,i]=[e.canvas.width,e.canvas.height];for(let e=0;e<i;e++)for(let r=0;r<n;r++){let s=4*Math.max(r-1,0),l=4*Math.min(r+1,n-1),d=4*Math.max(e-1,0)*n,c=4*Math.min(e+1,i-1)*n,h=4*e*n,u=4*r;for(let e=0;e<4;e++){let r=e+d,n=e+c,i=e+h;a[h+u+e]=o(t[r+u],t[i+s],t[i+u],t[i+l],t[n+u])}}},e._filters[Q5.ERODE]=t=>{e._filters[Q5.DILATE](t,Math.min)},e._filters[Q5.BLUR]=(a,o)=>{o=o||1,o=Math.floor(o*e._pixelDensity),r(),t.set(a);let n=2*o+1,i=function(e){let t=new Float32Array(e),r=.3*o+.8,a=r*r*2;for(let o=0;o<e;o++){let n=o-e/2,i=Math.exp(-n*n/a)/(2.5066282746*r);t[o]=i}return t}(n),[s,l]=[e.canvas.width,e.canvas.height];for(let e=0;e<l;e++)for(let r=0;r<s;r++){let l=0,d=0,c=0,h=0;for(let a=0;a<n;a++){let n=4*(e*s+Math.min(Math.max(r-o+a,0),s-1));l+=t[n]*i[a],d+=t[n+1]*i[a],c+=t[n+2]*i[a],h+=t[n+3]*i[a]}let u=4*(e*s+r);a[u]=l,a[u+1]=d,a[u+2]=c,a[u+3]=h}t.set(a);for(let e=0;e<l;e++)for(let r=0;r<s;r++){let d=0,c=0,h=0,u=0;for(let a=0;a<n;a++){let n=4*(Math.min(Math.max(e-o+a,0),l-1)*s+r);d+=t[n]*i[a],c+=t[n+1]*i[a],h+=t[n+2]*i[a],u+=t[n+3]*i[a]}let p=4*(e*s+r);a[p]=d,a[p+1]=c,a[p+2]=h,a[p+3]=u}});let n=e._getImageData(0,0,e.canvas.width,e.canvas.height);e._filters[a](n.data,o),e.ctx.putImageData(n,0,0)}},Q5.renderers.c2d.text=(e,t)=>{e._textAlign="left",e._textBaseline="alphabetic",e._textSize=12;let r="sans-serif",a=!1,o=15,n=3,i="normal",s="normal",l=!1,d=0,c=[],h=!1,u=!1,p=0,f=12e3,_=e._textCache={};e.loadFont=(r,a)=>{t._preloadCount++;let o=r.split("/").pop().split(".")[0].replace(" ",""),n=new FontFace(o,`url(${r})`);return document.fonts.add(n),n._loader=(async()=>{let e;try{await n.load()}catch(t){e=t}if(t._preloadCount--,delete n._loader,e)throw e;return a&&a(n),n})(),e.textFont(o),e._usePreload?n:n._loader},e.textFont=e=>{if(e&&"string"!=typeof e&&(e=e.family),!e||e==r)return r;r=e,l=!0,d=-1},e.textSize=t=>{if(null==t)return e._textSize;e._da&&(t*=e._da),e._textSize=t,l=!0,d=-1,a||(o=1.25*t,n=o-t)},e.textStyle=e=>{if(!e)return i;i=e,l=!0,d=-1},e.textWeight=e=>{if(!e)return s;s=e,l=!0,d=-1},e.textLeading=t=>null==t?o||1.25*e._textSize:(a=!0,t==o?o:(e._da&&(t*=e._da),o=t,n=t-e._textSize,void(d=-1))),e.textAlign=(t,r)=>{e.ctx.textAlign=e._textAlign=t,r&&(e.ctx.textBaseline=e._textBaseline=r==e.CENTER?"middle":r)};const g=()=>{e.ctx.font=`${i} ${s} ${e._textSize}px ${r}`,l=!1};e.textWidth=t=>(l&&g(),e.ctx.measureText(t).width),e.textAscent=t=>(l&&g(),e.ctx.measureText(t).actualBoundingBoxAscent),e.textDescent=t=>(l&&g(),e.ctx.measureText(t).actualBoundingBoxDescent),e.textFill=e.fill,e.textStroke=e.stroke;e.textCache=(e,t)=>(t&&(f=t),void 0!==e&&(h=e),h),e.createTextImage=(t,r,a)=>{u=!0;let o=e.text(t,0,0,r,a);return u=!1,o};let m=[];e.text=(t,a,s,x,v)=>{if(void 0===t||!e._doFill&&!e._doStroke)return;t=t.toString(),e._da&&(a*=e._da,s*=e._da);let y,b,w,S,C=e.ctx;if(l&&g(),(h||u)&&(-1==d&&(()=>{let t=r+e._textSize+i+o,a=5381;for(let e=0;e<t.length;e++)a=33*a^t.charCodeAt(e);d=a>>>0})(),y=_[t],y&&(y=y[d]),y)){if(y._fill==e._fill&&y._stroke==e._stroke&&y._strokeWeight==e._strokeWeight)return u?y:e.textImage(y,a,s);y.clear()}if(-1==t.indexOf("\n")?m[0]=t:m=t.split("\n"),t.length>x){let e=[];for(let t of m){let r=0;for(;r<t.length;){let a=r+x;if(a>=t.length){e.push(t.slice(r));break}let o=t.lastIndexOf(" ",a);(-1===o||o<r)&&(o=a),e.push(t.slice(r,o)),r=o+1}}m=e}if(h||u){if(b=0,w=o*m.length,y)y.modified=!0;else{let r=e.ctx.textBaseline;e.ctx.textBaseline="alphabetic";let a=C.measureText(" "),i=a.fontBoundingBoxAscent,s=a.fontBoundingBoxDescent;e.ctx.textBaseline=r,y=e.createImage.call(e,Math.ceil(C.measureText(t).width),Math.ceil(w+s),{pixelDensity:e._pixelDensity}),y._ascent=i,y._descent=s,y._top=s+n,y._middle=y._top+.5*i,y._bottom=y._top+i,y._leading=o}y._fill=e._fill,y._stroke=e._stroke,y._strokeWeight=e._strokeWeight,C=y.ctx,C.font=e.ctx.font,C.fillStyle=e._fill,C.strokeStyle=e._stroke,C.lineWidth=e.ctx.lineWidth}else b=a,w=s;e._fillSet||(S=C.fillStyle,C.fillStyle="black");let M=0;for(let t of m)if(e._doStroke&&e._strokeSet&&C.strokeText(t,b,w),e._doFill&&C.fillText(t,b,w),w+=o,M++,M>=v)break;if(m=[],e._fillSet||(C.fillStyle=S),h||u){if(c.push(d),(_[t]??={})[d]=y,p++,p>f){let e=Math.ceil(p/2),t=c.splice(0,e);for(let e in _){e=_[e];for(let r of t)delete e[r]}p-=e}if(u)return y;e.textImage(y,a,s)}},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let o=e._imageMode;e._imageMode="corner";let n=e._textAlign;"center"==n?r-=t.canvas.hw:"right"==n&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"middle"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=o}},Q5.fonts=[],Q5.modules.color=(e,t)=>{e.RGB=e.RGBA=e.RGBHDR=e._colorMode="rgb",e.HSL="hsl",e.HSB="hsb",e.OKLCH="oklch",e.SRGB="srgb",e.DISPLAY_P3="display-p3",e.colorMode=(r,a,o)=>{e._colorMode=r;let n="srgb"==e.canvas.colorSpace||"srgb"==o;a??="rgb"==r&&(e._c2d||n)?255:1,e._colorFormat="integer"==a||255==a?255:1,"oklch"==r?t.Color=Q5.ColorOKLCH:"hsl"==r?t.Color=n?Q5.ColorHSL:Q5.ColorHSL_P3:"hsb"==r?t.Color=n?Q5.ColorHSB:Q5.ColorHSB_P3:(255==e._colorFormat?t.Color=n?Q5.ColorRGB_8:Q5.ColorRGB_P3_8:t.Color=n?Q5.ColorRGB:Q5.ColorRGB_P3,e._colorMode="rgb")},e._namedColors={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],cyan:[0,255,255],darkviolet:[148,0,211],gold:[255,215,0],green:[0,128,0],gray:[128,128,128],grey:[128,128,128],hotpink:[255,105,180],indigo:[75,0,130],khaki:[240,230,140],lightgreen:[144,238,144],lime:[0,255,0],magenta:[255,0,255],navy:[0,0,128],orange:[255,165,0],olive:[128,128,0],peachpuff:[255,218,185],pink:[255,192,203],purple:[128,0,128],red:[255,0,0],skyblue:[135,206,235],tan:[210,180,140],turquoise:[64,224,208],transparent:[0,0,0,0],white:[255,255,255],violet:[238,130,238],yellow:[255,255,0]},e.color=(t,r,a,o)=>{let n=e.Color;if(t._q5Color)return new n(...t.levels);if(null==r){if("string"==typeof t){if("#"==t[0])t.length<=5?(t.length>4&&(o=parseInt(t[4]+t[4],16)),a=parseInt(t[3]+t[3],16),r=parseInt(t[2]+t[2],16),t=parseInt(t[1]+t[1],16)):(t.length>7&&(o=parseInt(t.slice(7,9),16)),a=parseInt(t.slice(5,7),16),r=parseInt(t.slice(3,5),16),t=parseInt(t.slice(1,3),16));else{if(!e._namedColors[t]){let e=new n(0,0,0);return e._css=t,e.toString=function(){return this._css},e}[t,r,a,o]=e._namedColors[t]}1==e._colorFormat&&(t/=255,r&&(r/=255),a&&(a/=255),o&&(o/=255))}(Array.isArray(t)||t.constructor==Float32Array)&&([t,r,a,o]=t)}return null==a?e._colorMode==Q5.OKLCH?new n(t,0,0,r):new n(t,t,t,r):new n(t,r,a,o)},e.red=e=>e.r,e.green=e=>e.g,e.blue=e=>e.b,e.alpha=e=>e.a,e.lightness=t=>{if(t.l)return t.l;let r=100*(.2126*t.r+.7152*t.g+.0722*t.b);return 255==e._colorFormat?r/255:r},e.hue=t=>{if(t.h)return t.h;let r=t.r,a=t.g,o=t.b;255==e._colorFormat&&(r/=255,a/=255,o/=255);let n,i=Math.max(r,a,o),s=Math.min(r,a,o);return n=i==s?0:i==r?60*(a-o)/(i-s):i==a?60*(o-r)/(i-s)+120:60*(r-a)/(i-s)+240,n<0&&(n+=360),n},e.lerpColor=(t,r,a)=>{if(a=Math.max(0,Math.min(1,a)),"rgb"==e._colorMode)return new e.Color(e.lerp(t.r,r.r,a),e.lerp(t.g,r.g,a),e.lerp(t.b,r.b,a),e.lerp(t.a,r.a,a));{let o=r.h-t.h;o>180&&(o-=360),o<-180&&(o+=360);let n=t.h+a*o;return n<0&&(n+=360),n>360&&(n-=360),new e.Color(e.lerp(t.l,r.l,a),e.lerp(t.c,r.c,a),n,e.lerp(t.a,r.a,a))}}},Q5.Color=class{constructor(){this._q5Color=!0}get alpha(){return this.a}set alpha(e){this.a=e}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,r,a){super(),this.l=e,this.c=t,this.h=r,this.a=a??1}get levels(){return[this.l,this.c,this.h,this.a]}equals(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h&&this.a==e.a}isSameColor(e){return e&&this.l==e.l&&this.c==e.c&&this.h==e.h}toString(){return`oklch(${this.l} ${this.c} ${this.h} / ${this.a})`}get lightness(){return this.l}set lightness(e){this.l=e}get chroma(){return this.c}set chroma(e){this.c=e}get hue(){return this.h}set hue(e){this.h=e}},Q5.ColorRGB=class extends Q5.Color{constructor(e,t,r,a){super(),this.r=e,this.g=t,this.b=r,this.a=a??1}get levels(){return[this.r,this.g,this.b,this.a]}equals(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.r==e.r&&this.g==e.g&&this.b==e.b}toString(){return`color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`}get red(){return this.r}set red(e){this.r=e}get green(){return this.g}set green(e){this.g=e}get blue(){return this.b}set blue(e){this.b=e}},Q5.ColorRGB_P3=class extends Q5.ColorRGB{toString(){return`color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`}},Q5.ColorRGB_8=class extends Q5.ColorRGB{constructor(e,t,r,a){super(e,t,r,a??255)}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGB_P3_8=class extends Q5.ColorRGB_8{constructor(e,t,r,a){super(e,t,r,a??255),this._edited=!0}get r(){return this._r}set r(e){this._r=e,this._edited=!0}get g(){return this._g}set g(e){this._g=e,this._edited=!0}get b(){return this._b}set b(e){this._b=e,this._edited=!0}get a(){return this._a}set a(e){this._a=e,this._edited=!0}toString(){if(this._edited){let e=(this._r/255).toFixed(3),t=(this._g/255).toFixed(3),r=(this._b/255).toFixed(3),a=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${r} / ${a})`,this._edited=!1}return this._css}},Q5.ColorHSL=class extends Q5.Color{constructor(e,t,r,a){super(),this.h=e,this.s=t,this.l=r,this.a=a??1}get levels(){return[this.h,this.s,this.l,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.l==e.l}toString(){return`hsl(${this.h} ${this.s} ${this.l} / ${this.a})`}get hue(){return this.h}set hue(e){this.h=e}get saturation(){return this.s}set saturation(e){this.s=e}get lightness(){return this.l}set lightness(e){this.l=e}},Q5.ColorHSL_P3=class extends Q5.ColorHSL{toString(){return`color(display-p3 ${Q5.HSLtoRGB(this.h,this.s,this.l).join(" ")} / ${this.a})`}},Q5.ColorHSB=class extends Q5.ColorHSL{constructor(e,t,r,a){super(e,t,r,a),delete this.l,this.b=r}get levels(){return[this.h,this.s,this.b,this.a]}equals(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b&&this.a==e.a}isSameColor(e){return e&&this.h==e.h&&this.s==e.s&&this.b==e.b}toString(){return`hsl(${Q5.HSBtoHSL(this.h,this.s,this.b).join(" ")} / ${this.a})`}get v(){return this.b}set v(e){this.b=e}get brightness(){return this.b}set brightness(e){this.b=e}get value(){return this.b}set value(e){this.b=e}},Q5.ColorHSB_P3=class extends Q5.ColorHSB{toString(){return`color(display-p3 ${Q5.HSLtoRGB(...Q5.HSBtoHSL(this.h,this.s,this.b)).join(" ")} / ${this.a})`}},Q5.HSLtoRGB=(e,t,r)=>{r/=100;let a=t/100*Math.min(r,1-r),o=(t,o=(t+e/30)%12)=>r-a*Math.max(Math.min(o-3,9-o,1),-1);return[o(0),o(8),o(4)]},Q5.HSBtoHSL=(e,t,r,a=r*(1-t/200))=>[e,a&&100!=a?(r-a)/Math.min(a,100-a)*100:0,a];{const e=(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2],e[3]*t[0]+e[4]*t[1]+e[5]*t[2],e[6]*t[0]+e[7]*t[1]+e[8]*t[2]],t=(e,t,r)=>[e,isNaN(r)?0:t*Math.cos(r*Math.PI/180),isNaN(r)?0:t*Math.sin(r*Math.PI/180)],r=e=>e.map((e=>Math.max(0,Math.min(1,Math.abs(e)>.0031308?(e<0?-1:1)*(1.055*Math.abs(e)**(1/2.4)-.055):12.92*e)))),a=t=>{const r=e([1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092],t);return e([1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],r.map((e=>e**3)))},o=t=>e([3.2409699419045226,-1.537383177570094,-.4986107602930034,-.9692436362808796,1.8759675015077202,.04155505740717559,.05563007969699366,-.20397695888897652,1.0569715142428786],t);Q5.OKLCHtoRGB=(e,n,i)=>r(o(a(t(e,n,i))))}Q5.modules.display=e=>{if(!e.canvas||"graphics"==e._scope)return;let t=e.canvas;e.CENTERED="centered",e.FULLSCREEN="fullscreen",e.MAXED="maxed",e.PIXELATED="pixelated",0!=Q5._instanceCount||Q5._server||document.head.insertAdjacentHTML("beforeend","<style>\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n}\n.q5Canvas {\n\toutline: none;\n\t-webkit-touch-callout: none;\n\t-webkit-text-size-adjust: none;\n\t-webkit-user-select: none;\n\toverscroll-behavior: none;\n}\n.q5-pixelated {\n\timage-rendering: pixelated;\n\tfont-smooth: never;\n\t-webkit-font-smoothing: none;\n}\n.q5-centered,\n.q5-maxed,\n.q5-fullscreen {\n display: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\nmain.q5-centered,\nmain.q5-maxed,\n.q5-fullscreen {\n\theight: 100vh;\n}\nmain {\n\toverscroll-behavior: none;\n}\n</style>"),e._adjustDisplay=()=>{let r=t.style,a=t.parentElement;r&&a&&t.displayMode&&("pixelated"==t.renderQuality&&(t.classList.add("q5-pixelated"),e.pixelDensity(1),e.defaultImageScale(1),e.noSmooth&&e.noSmooth(),e.textFont&&e.textFont("monospace")),"default"==t.displayMode||"normal"==t.displayMode?(a.classList.remove("q5-centered","q5-maxed","q5-fullscreen"),r.width=t.w*t.displayScale+"px",r.height=t.h*t.displayScale+"px"):(a.classList.add("q5-"+t.displayMode),a=a.getBoundingClientRect(),t.w/t.h>a.width/a.height?("centered"==t.displayMode?(r.width=t.w*t.displayScale+"px",r.maxWidth="100%"):r.width="100%",r.height="auto",r.maxHeight=""):(r.width="auto",r.maxWidth="","centered"==t.displayMode?(r.height=t.h*t.displayScale+"px",r.maxHeight="100%"):r.height="100%")))},e.displayMode=(r="normal",a="smooth",o=1)=>{"string"==typeof o&&(o=parseFloat(o.slice(1))),"center"==r&&(r="centered"),Object.assign(t,{displayMode:r,renderQuality:a,displayScale:o}),e.ctx&&e.pushStyles(),e._adjustDisplay(),e.ctx&&e.popStyles()},e.fullscreen=e=>{if(void 0===e)return document.fullscreenElement;e?document.body.requestFullscreen():document.body.exitFullscreen()}},Q5.modules.dom=(e,t)=>{e.elementMode=t=>e._elementMode=t,e.createElement=(t,r)=>{let a=document.createElement(t);return"center"==e._elementMode&&(a.style.transform="translate(-50%, -50%)"),r&&(a.innerHTML=r),Object.defineProperty(a,"x",{get:()=>a._x,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let o=e.canvas.offsetLeft+t;a.style.left=o+"px",a._x=o}}),Object.defineProperty(a,"y",{get:()=>a._y,set:t=>{let r=a.style.position;r&&"relative"!=r||(a.style.position="absolute");let o=e.canvas.offsetTop+t;a.style.top=o+"px",a._y=o}}),Object.defineProperty(a,"width",{get:()=>parseFloat(a.style.width||0),set:e=>a.style.width=e+"px"}),Object.defineProperty(a,"height",{get:()=>parseFloat(a.style.height||0),set:e=>a.style.height=e+"px"}),a.position=(e,t,r)=>(r&&(a.style.position=r),a.x=e,a.y=t,a),Object.defineProperty(a,"size",{writable:!0}),a.size=(e,t)=>(a.width=e,a.height=t,a),a.center=()=>(a.style.position="absolute",a.x=e.canvas.hw,a.y=e.canvas.hh,a),a.show=()=>(a.style.display="",a),a.hide=()=>(a.style.display="none",a),a.parent=e=>(e.append(a),a),e._addEventMethods(a),e._elements.push(a),e.canvas?e.canvas.parentElement.append(a):document.body.append(a),a.elt=a,a},e.createEl=e.createElement,e._addEventMethods=e=>{let t=e.addEventListener;e.mousePressed=e=>t("mousedown",e),e.mouseReleased=e=>t("mouseup",e),e.mouseClicked=e=>t("click",e),e.mouseMoved=e=>t("mousemove",e),e.mouseWheel=e=>t("wheel",e)},e.createA=(t,r,a)=>{let o=e.createEl("a",r);return o.href=t,o.target=a?"_blank":"_self",o},e.createButton=t=>e.createEl("button",t),e.createCheckbox=(t="",r=!1)=>{let a=e.createEl("input");a.type="checkbox",a.checked=r;let o=e.createEl("label",t);return o.addEventListener("click",(()=>{a.checked=!a.checked,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}))})),a.insertAdjacentElement("afterend",o),a.label=o,a},e.createColorPicker=(t="#ffffff")=>{let r=e.createEl("input");return r.type="color",r.value=t.toString(),r},e.createDiv=t=>e.createEl("div",t),e.createImg=t=>{let r=e.createEl("img");return r.crossOrigin="anonymous",r.src=t,r},e.createInput=(t="",r="text")=>{let a=e.createEl("input");return a.value=t,a.type=r,a.style.boxSizing="border-box",a},e.createP=t=>e.createEl("p",t);let r=0;e.createRadio=t=>{let a=e.createEl("div");return a.name=t||"radio"+r++,a.buttons=[],Object.defineProperty(a,"value",{get:()=>a.selected?.value,set:e=>{let t=a.buttons.find((t=>t.value==e));t&&(t.checked=!0,a.selected=t)}}),a.option=(t,r)=>{let o=e.createEl("input");o.type="radio",o.name=a.name,o.value=r||t,o.addEventListener("input",(()=>a.selected=o));let n=e.createEl("label",t);return n.addEventListener("click",(()=>{o.checked=!0,a.selected=o,o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0}))})),o.label=n,a.append(o),a.append(n),a.buttons.push(o),a},a},e.createSelect=t=>{let r=e.createEl("select");if(t){let a=e.createEl("option",t);a.disabled=!0,a.selected=!0,r.append(a)}return Object.defineProperty(r,"selected",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.textContent)):r.selectedOptions[0]?.textContent,set:e=>{if(r.multiple)Array.from(r.options).forEach((t=>{t.selected=e.includes(t.textContent)}));else{const t=Array.from(r.options).find((t=>t.textContent===e));t&&(t.selected=!0)}}}),Object.defineProperty(r,"value",{get:()=>r.multiple?Array.from(r.selectedOptions).map((e=>e.value)):r.selectedOptions[0]?.value,set:e=>{if(r.multiple)r.options.forEach((t=>t.selected=e.includes(t.value)));else{let t;for(let a=0;a<r.options.length;a++)if(r.options[a].value==e){t=r.options[a];break}t&&(t.selected=!0)}}}),r.option=(t,a)=>{let o=e.createEl("option",t);return o.value=a||t,r.append(o),r},r},e.createSlider=(t,r,a,o)=>{let n=e.createEl("input");return n.type="range",n.min=t,n.max=r,n.value=a,n.step=o,n.val=()=>parseFloat(n.value),n},e.createSpan=t=>e.createEl("span",t),e.createVideo=r=>{let a=e.createEl("video");return a.crossOrigin="anonymous",a._load=()=>{a.width||=a.videoWidth,a.height||=a.videoHeight,a.defaultWidth=a.width*e._defaultImageScale,a.defaultHeight=a.height*e._defaultImageScale,a.ready=!0},r&&(t._preloadCount++,a._loader=new Promise((e=>{a.addEventListener("loadeddata",(()=>{a._load(),t._preloadCount--,e(a)})),a.src=r})),!e._usePreload)?a._loader:a},e.createCapture=function(r,a=!0,o){t._preloadCount++;let n="string"==typeof r?{[r]:!0}:r||{video:!0,audio:!0};!0===n.video&&(n.video={width:3840,height:2160}),n.video.facingMode??="user";let i=e.createVideo();return i.playsinline=i.autoplay=!0,a&&(i.flipped=!0,i.style.transform="scale(-1, 1)"),i.loadPixels=()=>{let t=e.createGraphics(i.videoWidth,i.videoHeight,{renderer:"c2d"});t.image(i,0,0),t.loadPixels(),i.pixels=t.pixels,t.remove()},i._loader=(async()=>{let e;try{e=await navigator.mediaDevices.getUserMedia(n)}catch(e){throw t._preloadCount--,e}return i.srcObject=e,await new Promise((e=>i.addEventListener("loadeddata",e))),i._load(),o&&o(i),t._preloadCount--,i})(),e._usePreload?i:i._loader},e.findElement=e=>document.querySelector(e),e.findElements=e=>document.querySelectorAll(e)},Q5.modules.fes=e=>{e._fes=async e=>{if(Q5.disableFriendlyErrors)return;let t=e.stack?.split("\n");if(!e.stack||t.length<=1)return;let r=1,a="(";for(-1==navigator.userAgent.indexOf("Chrome")&&(r=0,a="@");t[r].indexOf("q5")>=0;)r++;let o=t[r].split(a).at(-1);o.startsWith("blob:")&&(o=o.slice(5));let n=o.split(":"),i=parseInt(n.at(-2));n[n.length-1]=n.at(-1).split(")")[0];let s=n.slice(0,-2).join(":"),l=s.split("/").at(-1);try{let e=(await(await fetch(s)).text()).split("\n")[i-1].trim(),t=["🐛","🐞","🐜","🦗","🦋","🪲"][Math.floor(6*Math.random())];console.log("%cq5.js "+t+"%c Error in "+l+" on line "+i+":\n\n"+e,"background: #b7ebff; color: #000;","")}catch(e){}}},Q5.modules.input=(e,t)=>{if("graphics"==e._scope)return;e.mouseX=0,e.mouseY=0,e.pmouseX=0,e.pmouseY=0,e.touches=[],e.mouseButton="",e.keyIsPressed=!1,e.mouseIsPressed=!1,e.key="",e.keyCode=0,e.UP_ARROW=38,e.DOWN_ARROW=40,e.LEFT_ARROW=37,e.RIGHT_ARROW=39,e.SHIFT=16,e.TAB=9,e.BACKSPACE=8,e.ENTER=e.RETURN=13,e.ALT=e.OPTION=18,e.CONTROL=17,e.DELETE=46,e.ESCAPE=27,e.ARROW="default",e.CROSS="crosshair",e.HAND="pointer",e.MOVE="move",e.TEXT="text";let r={},a=[Q5.LEFT,Q5.CENTER,Q5.RIGHT],o=e.canvas;e._startAudio=()=>{Q5.aud&&"running"==Q5.aud?.state||e.userStartAudio()},e._updateMouse=r=>{if(!r.changedTouches){if(o){let a=o.getBoundingClientRect(),n=o.scrollWidth/e.width||1,i=o.scrollHeight/e.height||1;t.mouseX=(r.clientX-a.left)/n,t.mouseY=(r.clientY-a.top)/i,e._webgpu&&(t.mouseX-=o.hw,t.mouseY-=o.hh)}else t.mouseX=r.clientX,t.mouseY=r.clientY;t.moveX=r.movementX,t.moveY=r.movementY}};let n=0;function i(t){const r=e.canvas.getBoundingClientRect(),a=e.canvas.scrollWidth/e.width||1,o=e.canvas.scrollHeight/e.height||1;let n=0,i=0;return e._webgpu&&(n=e.halfWidth,i=e.halfHeight),{x:(t.clientX-r.left)/a-n,y:(t.clientY-r.top)/o-i,id:t.identifier}}if(e._onmousedown=r=>{n++,e._startAudio(),e._updateMouse(r),t.mouseIsPressed=!0,t.mouseButton=a[r.button],e.mousePressed(r)},e._onmousemove=t=>{e._updateMouse(t),e.mouseIsPressed?e.mouseDragged(t):e.mouseMoved(t)},e._onmouseup=r=>{e._updateMouse(r),t.mouseIsPressed=!1,e.mouseReleased(r)},e._onclick=r=>{e._updateMouse(r),t.mouseIsPressed=!0,e.mouseClicked(r),t.mouseIsPressed=!1},e._onwheel=t=>{e._updateMouse(t),t.delta=t.deltaY,(0==e.mouseWheel(t)||e._noScroll)&&t.preventDefault()},e.cursor=(t,r,a)=>{let o="";t.includes(".")&&(t=`url("${t}")`,o=", auto"),void 0!==r&&(t+=" "+r+" "+a),e.canvas.style.cursor=t+o},e.noCursor=()=>e.canvas.style.cursor="none",e.noScroll=()=>e._noScroll=!0,window&&(e.lockMouse=document.body?.requestPointerLock,e.unlockMouse=document.exitPointerLock),e._onkeydown=a=>{a.repeat||(e._startAudio(),t.keyIsPressed=!0,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!0,e.keyPressed(a),1==a.key.length&&e.keyTyped(a))},e._onkeyup=a=>{t.keyIsPressed=!1,t.key=a.key,t.keyCode=a.keyCode,r[e.keyCode]=r[e.key.toLowerCase()]=!1,e.keyReleased(a)},e.keyIsDown=e=>!!r["string"==typeof e?e.toLowerCase():e],e._ontouchstart=r=>{e._startAudio(),t.touches=[...r.touches].map(i),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,t.mouseIsPressed=!0,t.mouseButton=e.LEFT,e.mousePressed(r)),e.touchStarted(r)},e._ontouchmove=r=>{t.touches=[...r.touches].map(i),e._isTouchAware||(t.mouseX=e.touches[0].x,t.mouseY=e.touches[0].y,e.mouseDragged(r)||r.preventDefault()),e.touchMoved(r)||r.preventDefault()},e._ontouchend=r=>{t.touches=[...r.touches].map(i),e._isTouchAware||e.touches.length||(t.mouseIsPressed=!1,e.mouseReleased(r)||r.preventDefault()),e.touchEnded(r)||r.preventDefault()},o){let t=o.addEventListener.bind(o);t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t))),t("touchstart",(t=>e._ontouchstart(t))),t("touchmove",(t=>e._ontouchmove(t))),t("touchend",(t=>e._ontouchend(t))),t("touchcancel",(t=>e._ontouchend(t)))}if(window){let t=window.addEventListener;t("keydown",(t=>e._onkeydown(t)),!1),t("keyup",(t=>e._onkeyup(t)),!1),o||(t("mousedown",(t=>e._onmousedown(t))),t("wheel",(t=>e._onwheel(t))),t("click",(t=>e._onclick(t)))),t("mousemove",(t=>e._onmousemove(t)),!1),t("mouseup",(t=>{n>0&&(n--,e._onmouseup(t))}))}},Q5.modules.math=(e,t)=>{e.RADIANS=0,e.DEGREES=1,e.PI=Math.PI,e.HALF_PI=Math.PI/2,e.QUARTER_PI=Math.PI/4,e.TWO_PI=e.TAU=2*Math.PI,e.abs=Math.abs,e.ceil=Math.ceil,e.exp=Math.exp,e.floor=e.int=Math.floor,e.loge=Math.log,e.mag=Math.hypot,e.max=Math.max,e.min=Math.min,e.pow=Math.pow,e.sqrt=Math.sqrt,e.SHR3=1,e.LCG=2,e.round=(e,t=0)=>{let r=10**t;return Math.round(e*r)/r};let r=e._angleMode=0;e.angleMode=t=>(r=e._angleMode=0==t||"radians"==t?0:1,r?"degrees":"radians");let a=e._DEGTORAD=Math.PI/180,o=e._RADTODEG=180/Math.PI;function n(){let e,t,r=4294967295;return{setSeed(a){e=t=(a??Math.random()*r)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/r)}}e.degrees=t=>t*e._RADTODEG,e.radians=t=>t*e._DEGTORAD,e.map=Q5.prototype.map=(e,t,r,a,o,n)=>{let i=a+1*(e-t)/(r-t)*(o-a);return n?a<o?Math.min(Math.max(i,a),o):Math.min(Math.max(i,o),a):i},e.dist=function(){let e=arguments;return 2==e.length?Math.hypot(e[0].x-e[1].x,e[0].y-e[1].y):4==e.length?Math.hypot(e[0]-e[2],e[1]-e[3]):Math.hypot(e[0]-e[3],e[1]-e[4],e[2]-e[5])},e.lerp=(e,t,r)=>e*(1-r)+t*r,e.constrain=(e,t,r)=>Math.min(Math.max(e,t),r),e.norm=(t,r,a)=>e.map(t,r,a,0,1),e.sq=e=>e*e,e.fract=e=>e-Math.floor(e),e.sin=e=>Math.sin(r?e*a:e),e.cos=e=>Math.cos(r?e*a:e),e.tan=e=>Math.tan(r?e*a:e),e.asin=e=>{let t=Math.asin(e);return r?t*o:t},e.acos=e=>{let t=Math.acos(e);return r?t*o:t},e.atan=e=>{let t=Math.atan(e);return r?t*o:t},e.atan2=(e,t)=>{let a=Math.atan2(e,t);return r?a*o:a};let i=n();i.setSeed(),e.randomSeed=e=>i.setSeed(e),e.random=(e,t)=>void 0===e?i.rand():"number"==typeof e?void 0!==t?i.rand()*(t-e)+e:i.rand()*e:e[Math.trunc(e.length*i.rand())],e.randSym=(t=1)=>e.random(-t,t),e.randomGenerator=t=>{t==e.LCG?i=function(){const e=4294967296;let t,r;return{setSeed(a){r=t=(a??Math.random()*e)>>>0},getSeed:()=>t,rand:()=>(r=(1664525*r+1013904223)%e,r/e)}}():t==e.SHR3&&(i=n()),i.setSeed()};var s=new function(){var e,t,r,a=new Array(128),o=new Array(256),n=new Array(128),s=new Array(128),l=new Array(256),d=new Array(256),c=()=>4294967296*i.rand()-2147483648,h=()=>.5+2.328306e-10*(c()|0),u=()=>{for(var t,o,i,l,d=3.44262;;){if(t=r*n[e],0==e){do{i=h(),l=h(),t=.2904764*-Math.log(i),o=-Math.log(l)}while(o+o<t*t);return r>0?d+t:-d-t}if(s[e]+h()*(s[e-1]-s[e])<Math.exp(-.5*t*t))return t;if(r=c(),e=127&r,Math.abs(r)<a[e])return r*n[e]}},p=()=>{for(var r;;){if(0==e)return 7.69711-Math.log(h());if(r=t*l[e],d[e]+h()*(d[e-1]-d[e])<Math.exp(-r))return r;if((t=c())<o[e=255&t])return t*l[e]}};this.SHR3=c,this.UNI=h,this.RNOR=()=>(r=c(),e=127&r,Math.abs(r)<a[e]?r*n[e]:u()),this.REXP=()=>(t=c()>>>0)<a[e=255&t]?t*l[e]:p(),this.zigset=()=>{var e,t,r=2147483648,i=4294967296,c=3.442619855899,h=c,u=.00991256303526217,p=7.697117470131487,f=p,_=.003949659822581572;for(e=u/Math.exp(-.5*c*c),a[0]=Math.floor(c/e*r),a[1]=0,n[0]=e/r,n[127]=c/r,s[0]=1,s[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),a[t+1]=Math.floor(c/h*r),h=c,s[t]=Math.exp(-.5*c*c),n[t]=c/r;for(e=_/Math.exp(-p),o[0]=Math.floor(p/e*i),o[1]=0,l[0]=e/i,l[255]=p/i,d[0]=1,d[255]=Math.exp(-p),t=254;t>=1;t--)p=-Math.log(_/p+Math.exp(-p)),o[t+1]=Math.floor(p/f*i),f=p,d[t]=Math.exp(-p),l[t]=p/i}};let l;s.hasInit=!1,e.randomGaussian=(e,t)=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.RNOR()*t+e),e.randomExponential=()=>(s.hasInit||(s.zigset(),s.hasInit=!0),s.REXP()),e.PERLIN="perlin",e.SIMPLEX="simplex",e.BLOCKY="blocky",e.NoiseGenerator=Q5.PerlinNoise,e.noiseMode=e=>{t.NoiseGenerator=Q5[e[0].toUpperCase()+e.slice(1)+"Noise"],l=null},e.noiseSeed=t=>{l=new e.NoiseGenerator(t)},e.noise=(t=0,r=0,a=0)=>(l??=new e.NoiseGenerator,l.noise(t,r,a)),e.noiseDetail=(t,r)=>{l??=new e.NoiseGenerator,t>0&&(l.octaves=t),r>0&&(l.falloff=r)}},Q5.NoiseGenerator=class{},Q5.PerlinNoise=class extends Q5.NoiseGenerator{constructor(e){super(),this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.octaves=1,this.falloff=.5,this.p=null==e?Array.from({length:256},(()=>Math.floor(256*Math.random()))):this.seedPermutation(e),this.p=this.p.concat(this.p)}seedPermutation(e){let t,r,a=[];for(let e=0;e<256;e++)a[e]=e;for(let o=255;o>0;o--)t=(e=16807*e%2147483647)%(o+1),r=a[o],a[o]=a[t],a[t]=r;return a}dot(e,t,r,a){return e[0]*t+e[1]*r+e[2]*a}mix(e,t,r){return(1-r)*e+r*t}fade(e){return e*e*e*(e*(6*e-15)+10)}noise(e,t,r){let a=this,o=0,n=1,i=1,s=0;for(let l=0;l<a.octaves;l++){const l=255&Math.floor(e*n),d=255&Math.floor(t*n),c=255&Math.floor(r*n),h=e*n-Math.floor(e*n),u=t*n-Math.floor(t*n),p=r*n-Math.floor(r*n),f=a.fade(h),_=a.fade(u),g=a.fade(p),m=a.p[l]+d,x=a.p[m]+c,v=a.p[m+1]+c,y=a.p[l+1]+d,b=a.p[y]+c,w=a.p[y+1]+c,S=a.mix(a.dot(a.grad3[a.p[x]%12],h,u,p),a.dot(a.grad3[a.p[b]%12],h-1,u,p),f),C=a.mix(a.dot(a.grad3[a.p[v]%12],h,u-1,p),a.dot(a.grad3[a.p[w]%12],h-1,u-1,p),f),M=a.mix(a.dot(a.grad3[a.p[x+1]%12],h,u,p-1),a.dot(a.grad3[a.p[b+1]%12],h-1,u,p-1),f),Q=a.mix(a.dot(a.grad3[a.p[v+1]%12],h,u-1,p-1),a.dot(a.grad3[a.p[w+1]%12],h-1,u-1,p-1),f),P=a.mix(S,C,_),E=a.mix(M,Q,_);o+=a.mix(P,E,g)*i,s+=i,i*=a.falloff,n*=2}return(o/s+1)/2}},Q5.modules.record=(e,t)=>{let r,a,o,n,i,s,l;function d(t={}){document.head.insertAdjacentHTML("beforeend","<style>\n.rec {\n\tdisplay: flex;\n\tz-index: 1000;\n\tgap: 6px;\n\tbackground: #1a1b1d;\n\tpadding: 6px 8px;\n\tborder-radius: 21px;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 2px solid transparent; \n\topacity: 0.6;\n\ttransition: all 0.3s;\n\twidth: 134px;\n\toverflow: hidden;\n}\n\n.rec:hover {\n\twidth: unset;\n\topacity: 0.96;\n}\n\n.rec.recording { border-color: #cc3e44; }\n\n.rec button,\n.rec select { cursor: pointer; }\n\n.rec button,\n.rec select,\n.rec input,\n.rec span {\n\tfont-family: sans-serif;\n\tfont-size: 14px;\n\tpadding: 2px 10px;\n\tborder-radius: 18px;\n\toutline: none;\n\tbackground: #232529;\n\tcolor: #d4dae6;\n\tbox-shadow: #0000001a 0px 4px 12px;\n\tborder: 1px solid #46494e;\n\tvertical-align: middle;\n\tline-height: 18px;\n\ttransition: all 0.3s;\n}\n\n.rec .audio-toggle {\n\tfont-size: 16px;\n\tpadding: 2px 10px;\n}\n\n.rec .bitrate input {\n\tborder-radius: 18px 0 0 18px;\n\tborder-right: 0;\n\twidth: 40px;\n\tpadding: 2px 5px 2px 10px;\n\ttext-align: right;\n}\n\n.rec .bitrate span {\n\tborder-radius: 0 18px 18px 0;\n\tborder-left: 0;\n\tpadding: 2px 10px 2px 5px;\n\tbackground: #333;\n}\n\n.rec .record-button { \n\tcolor: #cc3e44;\n\tfont-size: 18px;\n}\n\n.rec select:hover,\n.rec button:hover { background: #32343b; }\n\n.rec button:disabled {\n\topacity: 0.5;\n\tcolor: #969ba5;\n\tcursor: not-allowed;\n}\n</style>"),r=e.createEl("div"),r.className="rec",r.innerHTML='\n<button class="record-button"></button>\n<span class="record-timer"></span>\n<button></button>\n',[a,n,o]=r.children,r.x=r.y=8,r.resetTimer=()=>r.time={hours:0,minutes:0,seconds:0,frames:0},r.resetTimer();let d="video/mp4; codecs=";r.formats={"H.264":d+'"avc1.42E01E"',VP9:d+"vp9"};let u=d+'"avc1.640034"';e.canvas.width*e.canvas.height>32e5&&MediaRecorder.isTypeSupported(u)&&(r.formats["H.264"]=u),Object.assign(r.formats,t.formats),i=e.createSelect("format");for(const e in r.formats)i.option(e,r.formats[e]);i.title="Video Format",r.append(i);let _=e.createEl("div");_.className="bitrate",_.style.display="flex",r.append(_),s=e.createInput();let g=document.createElement("span");function m(){r.encoderSettings.mimeType=i.value}function x(){r.encoderSettings.videoBitsPerSecond=1e6*s.value}g.textContent="mbps",s.title=g.title="Video Bitrate",_.append(s),_.append(g),l=e.createEl("button"),l.className="audio-toggle active",l.textContent="🔊",l.title="Toggle Audio Recording",r.append(l),r.captureAudio=!0,l.addEventListener("click",(()=>{r.captureAudio=!r.captureAudio,l.textContent=r.captureAudio?"🔊":"🔇",l.classList.toggle("active",r.captureAudio)})),r.encoderSettings={},i.addEventListener("change",m),s.addEventListener("change",x),Object.defineProperty(r,"bitrate",{get:()=>s.value,set:e=>{s.value=e,x()}}),Object.defineProperty(r,"format",{get:()=>i.selected,set:e=>{e=e.toUpperCase(),r.formats[e]&&(i.selected=e,m())}}),r.format="H.264";let v=e.canvas.height;r.bitrate=v>=4320?96:v>=2160?64:v>=1440?48:v>=1080?32:v>=720?26:16,a.addEventListener("click",(()=>{e.recording?r.paused?h():e.pauseRecording():c()})),o.addEventListener("click",(()=>{r.paused?e.saveRecording():e.deleteRecording()})),p(),e.registerMethod("post",f)}function c(){if(!e.recording){if(e.userStartAudio(),!r.stream){r.frameRate??=e.getTargetFrameRate();let t=e.canvas.captureStream(r.frameRate);if(r.videoTrack=t.getVideoTracks()[0],r.captureAudio&&e.getAudioContext){let t=e.getAudioContext(),a=t.createMediaStreamDestination();t.destination.input?t.destination.input.connect(a):Q5.soundOut.connect(a),r.audioTrack=a.stream.getAudioTracks()[0],r.stream=new MediaStream([r.videoTrack,r.audioTrack])}else r.stream=t}r.mediaRecorder=new MediaRecorder(r.stream,r.encoderSettings),r.chunks=[],r.mediaRecorder.addEventListener("dataavailable",(e=>{e.data.size>0&&r.chunks.push(e.data)})),r.mediaRecorder.start(),t.recording=!0,r.paused=!1,r.classList.add("recording"),r.resetTimer(),p(!0)}}function h(){e.recording&&r.paused&&(r.mediaRecorder.resume(),r.paused=!1,p(!0))}function u(){e.recording&&(r.resetTimer(),r.mediaRecorder.stop(),t.recording=!1,r.paused=!1,r.classList.remove("recording"))}function p(e){a.textContent=e?"⏸":"⏺",a.title=(e?"Pause":"Start")+" Recording",o.textContent=e?"🗑️":"💾",o.title=(e?"Delete":"Save")+" Recording",o.disabled=!e}function f(){if(e.recording&&!r.paused){r.time.frames++;let t=e.getTargetFrameRate();r.time.frames>=t&&(r.time.seconds+=Math.floor(r.time.frames/t),r.time.frames%=t,r.time.seconds>=60&&(r.time.minutes+=Math.floor(r.time.seconds/60),r.time.seconds%=60,r.time.minutes>=60&&(r.time.hours+=Math.floor(r.time.minutes/60),r.time.minutes%=60)))}n.textContent=function(){let{hours:e,minutes:t,seconds:a,frames:o}=r.time;return`${String(e).padStart(2,"0")}:${String(t).padStart(2,"0")}:${String(a).padStart(2,"0")}:${String(o).padStart(2,"0")}`}()}e.recording=!1,e.createRecorder=e=>(r||d(e),r),e.record=t=>{r||(d(t),r.hide()),e.recording?r.paused&&h():c()},e.pauseRecording=()=>{e.recording&&!r.paused&&(r.mediaRecorder.pause(),r.paused=!0,p(),a.title="Resume Recording",o.disabled=!1)},e.deleteRecording=()=>{u(),p(),t.recording=!1},e.saveRecording=async a=>{if(!e.recording)return;await new Promise((e=>{r.mediaRecorder.onstop=e,u()}));let o=r.encoderSettings.mimeType,n=o.slice(6,o.indexOf(";")),i=URL.createObjectURL(new Blob(r.chunks,{type:o})),s=document.createElement("iframe"),l=document.createElement("a");s.style.display="none",s.name="download_"+Date.now(),document.body.append(s),l.target=s.name,l.href=i,a??=document.title+" "+(new Date).toLocaleString(void 0,{hour12:!1}).replace(","," at").replaceAll("/","-").replaceAll(":","_"),l.download=`${a}.${n}`,await new Promise((e=>{s.onload=()=>{document.body.removeChild(s),e()},l.click()})),setTimeout((()=>URL.revokeObjectURL(i)),1e3),p(),t.recording=!1}},Q5.modules.sound=(e,t)=>{e.Sound=Q5.Sound;let r=[];e.loadSound=(a,o)=>{t._preloadCount++;let n=new Q5.Sound;return r.push(n),n._loader=(async()=>{let e;try{await n.load(a)}catch(t){e=t}if(t._preloadCount--,delete n._loader,e)throw e;return o&&o(n),n})(),e._usePreload?n:n._loader},e.loadAudio=(e,r)=>{t._preloadCount++;let a=new Audio(e);a.crossOrigin="Anonymous",a.addEventListener("canplaythrough",(()=>{a.loaded||(t._preloadCount--,a.loaded=!0,r&&r(a))}));let o=()=>{a._preloadSkip=!0,t._preloadCount--};return a.addEventListener("suspend",o),a.addEventListener("error",(e=>{throw o(),e})),a},e.getAudioContext=()=>Q5.aud,e.userStartAudio=()=>{if(window.AudioContext){if(Q5._offlineAudio){Q5._offlineAudio=!1,Q5.aud=new window.AudioContext,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination);for(let e of r)e.init()}return Q5.aud.resume()}}},window.OfflineAudioContext&&(Q5.aud=new window.OfflineAudioContext(2,1,44100),Q5._offlineAudio=!0,Q5.soundOut=Q5.aud.createGain(),Q5.soundOut.connect(Q5.aud.destination)),Q5.Sound=class{constructor(){this.sources=new Set,this.loaded=this.paused=!1}async load(e){this.url=e;let t=await fetch(e);this.buffer=await t.arrayBuffer(),this.buffer=await Q5.aud.decodeAudioData(this.buffer)}init(){this.gainNode=Q5.aud.createGain(),this.pannerNode=Q5.aud.createStereoPanner(),this.gainNode.connect(this.pannerNode),this.pannerNode.connect(Q5.soundOut),this.loaded=!0,this._volume&&(this.volume=this._volume),this._pan&&(this.pan=this._pan)}_newSource(e,t){let r=Q5.aud.createBufferSource();r.buffer=this.buffer,r.connect(this.gainNode),r.loop=this._loop,r._startedAt=Q5.aud.currentTime,r._offset=e,r._duration=t,r.start(0,r._offset,r._duration),this.sources.add(r),r.onended=()=>{this.paused||(this.ended=!0,this.sources.delete(r))}}play(e=0,t){if(this.loaded){if(this.paused){let e=[];for(let t of this.sources)e.push(t._offset,t._duration),this.sources.delete(t);for(let t=0;t<e.length;t+=2)this._newSource(e[t],e[t+1])}else this._newSource(e,t);this.paused=this.ended=!1}}pause(){if(this.isPlaying()){for(let e of this.sources){e.stop();let t=Q5.aud.currentTime-e._startedAt;e._offset+=t,e._duration&&(e._duration-=t)}this.paused=!0}}stop(){for(let e of this.sources)e.stop(),this.sources.delete(e);this.paused=!1,this.ended=!0}get volume(){return this._volume}set volume(e){this.loaded&&(this.gainNode.gain.value=e),this._volume=e}get pan(){return this._pan}set pan(e){this.loaded&&(this.pannerNode.pan.value=e),this._pan=e}get loop(){return this._loop}set loop(e){this.sources.forEach((t=>t.loop=e)),this._loop=e}get playing(){return!this.paused&&this.sources.size>0}setVolume(e){this.volume=e}setPan(e){this.pan=e}setLoop(e){this.loop=e}isLoaded(){return this.loaded}isPlaying(){return this.playing}isPaused(){return this.paused}isLooping(){return this._loop}},Q5.modules.util=(e,t)=>{e._loadFile=(r,a,o)=>{t._preloadCount++;let n={};return n._loader=new Promise(((i,s)=>{fetch(r).then((e=>e.ok?"json"==o?e.json():e.text():(s("error loading file"),null))).then((r=>{"csv"==o&&(r=e.CSV.parse(r)),"string"==typeof r?n.text=r:Object.assign(n,r),delete n._loader,a&&a(r),t._preloadCount--,i(r)}))})),n},e.loadText=(t,r)=>e._loadFile(t,r,"text"),e.loadJSON=(t,r)=>e._loadFile(t,r,"json"),e.loadCSV=(t,r)=>e._loadFile(t,r,"csv");const r=/(jpe?g|png|gif|webp|avif|svg)/,a=/(ttf|otf|woff2?|eot|json)/,o=/(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/;async function n(t,a,o){if(a=a||"untitled",o=o||"png",r.test(o))t=await e._saveCanvas(t,o);else{let e="text/plain";"json"==o&&("string"!=typeof t&&(t=JSON.stringify(t)),e="text/json"),t=new Blob([t],{type:e}),t=URL.createObjectURL(t)}let n=document.createElement("a");n.href=t,n.download=a+"."+o,n.click(),setTimeout((()=>URL.revokeObjectURL(n.href)),1e3)}e.load=function(...t){Array.isArray(t[0])&&(t=t[0]);let n=[];for(let i of t){let t,s=i.split(".").pop().toLowerCase();t="json"!=s||i.includes("-msdf.")?"csv"==s?e.loadCSV(i):r.test(s)?e.loadImage(i):a.test(s)?e.loadFont(i):o.test(s)?e.loadSound(i):e.loadText(i):e.loadJSON(i),n.push(t._loader)}return 1==t.length?n[0]:Promise.all(n)},e.save=(t,r,a)=>{if((!t||"string"==typeof t&&(!r||!a&&r.length<5))&&(a=r,r=t,t=e.canvas),a)n(t,r,a);else if(r){let e=r.lastIndexOf(".");n(t,r.slice(0,e),r.slice(e+1))}else n(t)},e.CSV={},e.CSV.parse=(e,t=",",r="\n")=>{if(!e.length)return[];let a=[],o=e.split(r),n=o[0].split(t).map((e=>e.replaceAll('"',"")));for(let e=1;e<o.length;e++){let r={},i=o[e].split(t);n.forEach(((e,t)=>r[e]=JSON.parse(i[t]))),a.push(r)}return a},e.canvas&&!Q5._createServerCanvas&&(e.canvas.save=e.saveCanvas=e.save),"object"==typeof localStorage&&(e.storeItem=localStorage.setItem,e.getItem=localStorage.getItem,e.removeItem=localStorage.removeItem,e.clearStorage=localStorage.clear),e.year=()=>(new Date).getFullYear(),e.day=()=>(new Date).getDay(),e.hour=()=>(new Date).getHours(),e.minute=()=>(new Date).getMinutes(),e.second=()=>(new Date).getSeconds(),e.nf=(e,t,r)=>{let a=e<0,o=(e=Math.abs(e)).toFixed(r).split(".");o[0]=o[0].padStart(t,"0");let n=o.join(".");return a&&(n="-"+n),n},e.shuffle=(t,r)=>{r||(t=[...t]);for(let r=t.length-1;r>0;r--){let a=Math.floor(e.random()*(r+1));[t[r],t[a]]=[t[a],t[r]]}return t}},Q5.modules.vector=e=>{e.Vector=Q5.Vector,e.createVector=(t,r,a)=>new e.Vector(t,r,a,e)},Q5.Vector=class{constructor(e,t,r,a){this.x=e||0,this.y=t||0,this.z=r||0,this._$=a||window,this._cn=null,this._cnsq=null}set(e,t,r){return this.x=e?.x||e||0,this.y=e?.y||t||0,this.z=e?.z||r||0,this}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,r){return void 0!==e?.x?e:void 0!==t?{x:e,y:t,z:r||0}:{x:e,y:e,z:e}}_calcNorm(){this._cnsq=this.x*this.x+this.y*this.y+this.z*this.z,this._cn=Math.sqrt(this._cnsq)}add(){let e=this._arg2v(...arguments);return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}rem(){let e=this._arg2v(...arguments);return this.x%=e.x,this.y%=e.y,this.z%=e.z,this}sub(){let e=this._arg2v(...arguments);return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}mult(){let e=this._arg2v(...arguments);return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}div(){let e=this._arg2v(...arguments);return e.x?this.x/=e.x:this.x=0,e.y?this.y/=e.y:this.y=0,e.z?this.z/=e.z:this.z=0,this}mag(){return this._calcNorm(),this._cn}magSq(){return this._calcNorm(),this._cnsq}dot(){let e=this._arg2v(...arguments);return this.x*e.x+this.y*e.y+this.z*e.z}dist(){let e=this._arg2v(...arguments),t=this.x-e.x,r=this.y-e.y,a=this.z-e.z;return Math.sqrt(t*t+r*r+a*a)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,a=this.x*e.y-this.y*e.x;return this.x=t,this.y=r,this.z=a,this}normalize(){this._calcNorm();let e=this._cn;return 0!=e&&(this.x/=e,this.y/=e,this.z/=e),this._cn=1,this._cnsq=1,this}limit(e){this._calcNorm();let t=this._cn;if(t>e){let r=e/t;this.x*=r,this.y*=r,this.z*=r,this._cn=e,this._cnsq=e*e}return this}setMag(e){this._calcNorm();let t=e/this._cn;return this.x*=t,this.y*=t,this.z*=t,this._cn=e,this._cnsq=e*e,this}heading(){return this._$.atan2(this.y,this.x)}setHeading(e){let t=this.mag();return this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this}rotate(e){let t=this._$.cos(e),r=this._$.sin(e),a=this.x*t-this.y*r,o=this.x*r+this.y*t;return this.x=a,this.y=o,this}angleBetween(){let e=this._arg2v(...arguments),t=Q5.Vector.cross(this,e);return this._$.atan2(t.mag(),this.dot(e))*Math.sign(t.z||1)}lerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));return this.x+=(r.x-this.x)*t,this.y+=(r.y-this.y)*t,this.z+=(r.z-this.z)*t,this}slerp(){let e=[...arguments],t=e.at(-1);if(0==t)return this;let r=this._arg2v(...e.slice(0,-1));if(1==t)return this.set(r);let a=this.mag(),o=r.mag();if(0==a||0==o)return this.mult(1-t).add(r.mult(t));let n=Q5.Vector.cross(this,r),i=n.mag(),s=Math.atan2(i,this.dot(r));if(i>0)n.div(i);else{if(s<this._$.HALF_PI)return this.mult(1-t).add(r.mult(t));0==this.z&&0==r.z?n.set(0,0,1):0!=this.x?n.set(this.y,-this.x,0).normalize():n.set(1,0,0)}let l=n.cross(this),d=1-t+t*o/a,c=d*Math.cos(t*s),h=d*Math.sin(t*s);return this.x=this.x*c+l.x*h,this.y=this.y*c+l.y*h,this.z=this.z*c+l.z*h,this}reflect(e){return e.normalize(),this.sub(e.mult(2*this.dot(e)))}array(){return[this.x,this.y,this.z]}equals(e,t){return t??=Number.EPSILON||0,Math.abs(e.x-this.x)<t&&Math.abs(e.y-this.y)<t&&Math.abs(e.z-this.z)<t}fromAngle(e,t){return void 0===t&&(t=1),this._cn=t,this._cnsq=t*t,this.x=t*this._$.cos(e),this.y=t*this._$.sin(e),this.z=0,this}fromAngles(e,t,r){void 0===r&&(r=1),this._cn=r,this._cnsq=r*r;const a=this._$.cos(t),o=this._$.sin(t),n=this._$.cos(e),i=this._$.sin(e);return this.x=r*i*o,this.y=-r*n,this.z=r*i*a,this}random2D(){return this._cn=this._cnsq=1,this.fromAngle(Math.random()*Math.PI*2)}random3D(){return this._cn=this._cnsq=1,this.fromAngles(Math.random()*Math.PI*2,Math.random()*Math.PI*2)}toString(){return`[${this.x}, ${this.y}, ${this.z}]`}},Q5.Vector.add=(e,t)=>e.copy().add(t),Q5.Vector.cross=(e,t)=>e.copy().cross(t),Q5.Vector.dist=(e,t)=>Math.hypot(e.x-t.x,e.y-t.y,e.z-t.z),Q5.Vector.div=(e,t)=>e.copy().div(t),Q5.Vector.dot=(e,t)=>e.copy().dot(t),Q5.Vector.equals=(e,t,r)=>e.equals(t,r),Q5.Vector.lerp=(e,t,r)=>e.copy().lerp(t,r),Q5.Vector.slerp=(e,t,r)=>e.copy().slerp(t,r),Q5.Vector.limit=(e,t)=>e.copy().limit(t),Q5.Vector.heading=e=>this._$.atan2(e.y,e.x),Q5.Vector.magSq=e=>e.x*e.x+e.y*e.y+e.z*e.z,Q5.Vector.mag=e=>Math.sqrt(Q5.Vector.magSq(e)),Q5.Vector.mult=(e,t)=>e.copy().mult(t),Q5.Vector.normalize=e=>e.copy().normalize(),Q5.Vector.rem=(e,t)=>e.copy().rem(t),Q5.Vector.sub=(e,t)=>e.copy().sub(t),Q5.Vector.reflect=(e,t)=>e.copy().reflect(t),Q5.Vector.random2D=()=>(new Q5.Vector).random2D(),Q5.Vector.random3D=()=>(new Q5.Vector).random3D(),Q5.Vector.fromAngle=(e,t)=>(new Q5.Vector).fromAngle(e,t),Q5.Vector.fromAngles=(e,t,r)=>(new Q5.Vector).fromAngles(e,t,r),Q5.renderers.webgpu={},Q5.renderers.webgpu.canvas=(e,t)=>{let r=e.canvas;e.colorMode&&e.colorMode("rgb",1),e._baseShaderCode="\nstruct Q5 {\n\twidth: f32,\n\theight: f32,\n\thalfWidth: f32,\n\thalfHeight: f32,\n\tpixelDensity: f32,\n\tframeCount: f32,\n\ttime: f32,\n\tdeltaTime: f32,\n\tmouseX: f32,\n\tmouseY: f32,\n\tmouseIsPressed: f32,\n\tkeyCode: f32,\n\tkeyIsPressed: f32\n}",e._g=e.createGraphics(1,1,"c2d"),e._g.colorMode(e.RGB,1);let a,o,n,i,s,l,d,c,h=1,u=8;e._pipelineConfigs=[],e._pipelines=[],e._buffers=[],e._prevFramePL=0,e._framePL=0;let p=e._drawStack=[],f=e._colorStack=new Float32Array(1e6);f.set([0,0,0,1,1,1,1,1]);let _=Q5.device.createBindGroupLayout({label:"mainLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]});e._bindGroupLayouts=[_];let g=Q5.device.createBuffer({size:64,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),m=()=>{let t=[e.canvas.width,e.canvas.height],r="bgra8unorm";n=Q5.device.createTexture({size:t,sampleCount:4,format:r,usage:GPUTextureUsage.RENDER_ATTACHMENT}).createView();let a=GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT;e._frameA=i=Q5.device.createTexture({size:t,format:r,usage:a}),e._frameB=s=Q5.device.createTexture({size:t,format:r,usage:a}),e._frameShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex: u32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f\n}\n\nconst ndc = array(vec2f(-1,-1), vec2f(1,-1), vec2f(-1,1), vec2f(1,1));\nconst quad = array(vec2f(0,1), vec2f(1,1), vec2f(0,0), vec2f(1,0));\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var samp: sampler;\n@group(0) @binding(2) var tex: texture_2d<f32>;\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar f: FragParams;\n\tf.position = vec4f(ndc[v.vertexIndex], 0.0, 1.0);\n\tf.texCoord = quad[v.vertexIndex];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams ) -> @location(0) vec4f {\n\treturn textureSample(tex, samp, f.texCoord);\n}";let o=Q5.device.createShaderModule({label:"frameShader",code:e._frameShaderCode});d=Q5.device.createSampler({magFilter:"linear",minFilter:"linear"}),l=Q5.device.createBindGroupLayout({label:"frameLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]});let c=Q5.device.createPipelineLayout({bindGroupLayouts:[l]});e._pipelineConfigs[0]={layout:c,vertex:{module:o,entryPoint:"vertexMain"},fragment:{module:o,entryPoint:"fragMain",targets:[{format:r}]},primitive:{topology:"triangle-strip"},multisample:{count:4}},e._pipelines[0]=Q5.device.createRenderPipeline(e._pipelineConfigs[0])};e._createCanvas=(a,o,n)=>(t.ctx=t.drawingContext=r.getContext("webgpu"),n.format??=navigator.gpu.getPreferredCanvasFormat(),n.device??=Q5.device,n.alpha&&(n.alphaMode="premultiplied"),e.ctx.configure(n),m(),r),e._resizeCanvas=(t,r)=>{e._setCanvasSize(t,r),m()};let x=(t,r,a,o)=>{let n=e._colorFormat;if("string"==typeof t||"rgb"!=e._colorMode?t=e.color(t,r,a,o):null==a&&(o=r??n,r=a=t),o??=n,t._q5Color){let e=t;null!=e.r?({r:t,g:r,b:a,a:o}=e):(o=e.a,e=null!=e.c?Q5.OKLCHtoRGB(e.l,e.c,e.h):null!=e.l?Q5.HSLtoRGB(e.h,e.s,e.l):Q5.HSLtoRGB(...Q5.HSBtoHSL(e.h,e.s,e.b)),[t,r,a]=e)}255==n&&(t/=255,r/=255,a/=255,o/=255);let i=f,s=u;i[s++]=t,i[s++]=r,i[s++]=a,i[s++]=o,u=s,h++};e._stroke=0,e._fill=e._tint=e._globalAlpha=1,e._doFill=e._doStroke=!0,e.fill=(t,r,a,o)=>{x(t,r,a,o),e._doFill=e._fillSet=!0,e._fill=h},e.stroke=(t,r,a,o)=>{x(t,r,a,o),e._doStroke=e._strokeSet=!0,e._stroke=h},e.tint=(t,r,a,o)=>{x(t,r,a,o),e._tint=h},e.opacity=t=>e._globalAlpha=t,e.noFill=()=>e._doFill=!1,e.noStroke=()=>e._doStroke=!1,e.noTint=()=>e._tint=1,e._strokeWeight=1,e._hsw=.5,e._scaledSW=1,e.strokeWeight=t=>{t=Math.abs(t),e._strokeWeight=t,e._scaledSW=t*e._scale,e._hsw=t/2};const v=e._graphics?1e3:1e7,y=new Float32Array(16*v);let b,w=[],S=[];e._matrixDirty=!1,w.push([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),y.set(w[0]),e.resetMatrix=()=>{b=w[0].slice(),e._matrixIndex=0},e.resetMatrix(),e.translate=(t,r,a=0)=>{if(!t&&!r&&!a)return;let o=b;o[12]+=t*o[0],o[13]-=r*o[5],o[14]+=a*o[10],e._matrixDirty=!0},e.rotate=e.rotateZ=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.cos(t),a=Math.sin(t),o=b,n=o[0],i=o[1],s=o[4],l=o[5];1!=n||i||s||1!=l?(o[0]=n*r+i*a,o[1]=i*r-n*a,o[4]=s*r+l*a,o[5]=l*r-s*a):(o[0]=r,o[1]=-a,o[4]=a,o[5]=r),e._matrixDirty=!0},e._scale=1,e.scale=(t=1,r,a=1)=>{r??=t,e._scale=Math.max(Math.abs(t),Math.abs(r)),e._scaledSW=e._strokeWeight*e._scale;let o=b;o[0]*=t,o[1]*=t,o[2]*=t,o[3]*=t,o[4]*=r,o[5]*=r,o[6]*=r,o[7]*=r,o[8]*=a,o[9]*=a,o[10]*=a,o[11]*=a,e._matrixDirty=!0},e.shearX=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=b,o=a[0],n=a[1],i=a[4],s=a[5];a[0]=o+i*r,a[1]=n+s*r,e._matrixDirty=!0},e.shearY=t=>{if(!t)return;e._angleMode&&(t*=e._DEGTORAD);let r=Math.tan(t),a=b,o=a[0],n=a[1],i=a[4],s=a[5];a[4]=i+o*r,a[5]=s+n*r,e._matrixDirty=!0},e.applyMatrix=(...t)=>{let r;if(r=1==t.length?t[0]:t,9==r.length)r=[r[0],r[1],0,r[2],r[3],r[4],0,r[5],0,0,1,0,r[6],r[7],0,r[8]];else if(16!=r.length)throw new Error("Matrix must be a 3x3 or 4x4 array.");b=r.slice(),e._matrixDirty=!0},e._saveMatrix=()=>{y.set(b,16*w.length),e._matrixIndex=w.length,w.push(b.slice()),e._matrixDirty=!1},e.pushMatrix=()=>{e._matrixDirty&&e._saveMatrix(),S.push(e._matrixIndex)},e.popMatrix=()=>{if(!S.length)return console.warn("Matrix index stack is empty!");let t=S.pop();b=w[t].slice(),e._matrixIndex=t,e._matrixDirty=!1};let C=e.pushStyles;e.pushStyles=()=>{C(),e.strokeWeight(e._strokeWeight)},e.push=()=>{e.pushMatrix(),e.pushStyles()},e.pop=()=>{e.popMatrix(),e.popStyles()},e._calcBox=(e,t,r,a,o)=>{let n,i,s,l;if(o&&"corner"!=o)if("center"==o){let o=r/2,d=a/2;n=e-o,i=e+o,s=-(t-d),l=-(t+d)}else n=e,i=r,s=-t,l=-a;else n=e,i=e+r,s=-t,l=-(t+a);return[n,i,s,l]};let M=["zero","one","src-alpha","one-minus-src-alpha","dst","dst-alpha","one-minus-dst-alpha","one-minus-src"],Q=["add","subtract","reverse-subtract","min","max"];const P={normal:[2,3,0,2,3,0],additive:[1,1,0,1,1,0]};e.blendConfigs={};for(const[t,r]of Object.entries(P))e.blendConfigs[t]={color:{srcFactor:M[r[0]],dstFactor:M[r[1]],operation:Q[r[2]]},alpha:{srcFactor:M[r[3]],dstFactor:M[r[4]],operation:Q[r[5]]}};let E;e._blendMode="normal",e.blendMode=t=>{if(t!=e._blendMode){"source-over"==t&&(t="normal"),"lighter"==t&&(t="additive"),t=t.toLowerCase().replace(/[ -]/g,"_"),e._blendMode=t;for(let r=0;r<e._pipelines.length;r++)e._pipelineConfigs[r].fragment.targets[0].blend=e.blendConfigs[t],e._pipelines[r]=Q5.device.createRenderPipeline(e._pipelineConfigs[r])}},e.clear=()=>{E=!0},e.background=(t,a,o,n)=>{if(e.push(),e.resetMatrix(),t.canvas){let a=t;e._imageMode="corner",e.image(a,-r.hw,-r.hh,r.w,r.h)}else e._rectMode="corner",e.fill(t,a,o,n),e._doStroke=!1,e.rect(-r.hw,-r.hh,r.w,r.h);e.pop()},e._beginRender=()=>{const t=i;i=s,s=t,a=Q5.device.createCommandEncoder(),e._pass=o=a.beginRenderPass({label:"q5-webgpu",colorAttachments:[{view:n,resolveTarget:i.createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:d},{binding:2,resource:s.createView()}]}),E||(o.setPipeline(e._pipelines[e._prevFramePL]),o.setBindGroup(0,c),o.draw(4)),E=!1},e._render=()=>{let t=Q5.device.createBuffer({size:16*w.length*4,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(y.slice(0,16*w.length)),t.unmap(),e._buffers.push(t);let r=Q5.device.createBuffer({size:4*u,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(f.slice(0,u)),r.unmap(),e._buffers.push(r),e._uniforms=[e.width,e.height,e.halfWidth,e.halfHeight,e._pixelDensity,e.frameCount,performance.now(),e.deltaTime,e.mouseX,e.mouseY,e.mouseIsPressed?1:0,e.keyCode,e.keyIsPressed?1:0],Q5.device.queue.writeBuffer(g,0,new Float32Array(e._uniforms));let a=Q5.device.createBindGroup({layout:_,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:{buffer:t}},{binding:2,resource:{buffer:r}}]});o.setBindGroup(0,a);for(let t of e._hooks.preRender)t();let n=0,i=0,s=0,l=-1;for(let t=0;t<p.length;t+=2){let r=p[t+1];if(l!=p[t]&&(l=p[t],o.setPipeline(e._pipelines[l])),4==l||l>=4e3){let a=p[t+2];o.setBindGroup(1,e._fonts[a].bindGroup),o.setBindGroup(2,e._textBindGroup),o.draw(4,r,0,s),s+=r,t++}else 2==l||3==l||l>=2e3?(o.setBindGroup(1,e._textureBindGroups[r]),o.draw(4,1,i),i+=4):(o.draw(r,1,n),n+=r)}},e._finishRender=async()=>{o.end(),o=a.beginRenderPass({colorAttachments:[{view:n,resolveTarget:e.ctx.getCurrentTexture().createView(),loadOp:"clear",storeOp:"store",clearValue:[0,0,0,0]}]}),c=Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:d},{binding:2,resource:i.createView()}]}),o.setPipeline(e._pipelines[e._framePL]),o.setBindGroup(0,c),o.draw(4),o.end(),Q5.device.queue.submit([a.finish()]),e._pass=o=a=null,Q5.device.queue.onSubmittedWorkDone().then((()=>{for(let t of e._buffers)t.destroy();e._buffers=[]})),p.splice(0,p.length),h=1,u=8,w=[w[0]],S=[];for(let t of e._hooks.postRender)t()}},Q5.initWebGPU=async()=>{if(!navigator.gpu)return console.warn("q5 WebGPU not supported on this browser! Use Google Chrome or Edge."),!1;if(!Q5.requestedGPU){let e=await navigator.gpu.requestAdapter();if(!e)return console.warn("q5 WebGPU could not start! No appropriate GPUAdapter found, vulkan may need to be enabled."),!1;Q5.device=await e.requestDevice(),Q5.device.lost.then((e=>{console.error("WebGPU crashed!"),console.error(e)}))}return!0},Q5.WebGPU=async function(e,t){return e&&"global"!=e||(Q5._hasGlobal=!0),await Q5.initWebGPU()?new Q5(e,t,"webgpu"):new Q5(e,t,"webgpu-fallback")},Q5.webgpu=Q5.WebGPU,Q5.renderers.webgpu.shapes=e=>{e._shapesPL=1,e._shapesShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) colorIndex: f32,\n\t@location(2) matrixIndex: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) color: vec4f\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.color = colors[i32(v.colorIndex)];\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\treturn f.color;\n}\n";let t=Q5.device.createShaderModule({label:"shapesShader",code:e._shapesShaderCode}),r=(e.canvas,e._drawStack),a=new Float32Array(e._graphics?1e3:1e7),o=0;const n=2*Math.PI,i=Math.PI/2;let s=Q5.device.createPipelineLayout({label:"shapesPipelineLayout",bindGroupLayouts:e._bindGroupLayouts});e._pipelineConfigs[1]={label:"shapesPipeline",layout:s,vertex:{module:t,entryPoint:"vertexMain",buffers:[{arrayStride:16,attributes:[{format:"float32x2",offset:0,shaderLocation:0},{format:"float32",offset:8,shaderLocation:1},{format:"float32",offset:12,shaderLocation:2}]}]},fragment:{module:t,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[1]=Q5.device.createRenderPipeline(e._pipelineConfigs[1]);const l=(e,t,r,n)=>{let i=a,s=o;i[s++]=e,i[s++]=t,i[s++]=r,i[s++]=n,o=s},d=(t,n,i,s,l,d,c,h,u,p)=>{let f=a,_=o;f[_++]=t,f[_++]=n,f[_++]=u,f[_++]=p,f[_++]=i,f[_++]=s,f[_++]=u,f[_++]=p,f[_++]=c,f[_++]=h,f[_++]=u,f[_++]=p,f[_++]=l,f[_++]=d,f[_++]=u,f[_++]=p,o=_,r.push(e._shapesPL,4)},c=(t,n,i,s,l,d,c,h,u)=>{let p=(d-l)/c,f=l,_=a,g=o;for(let e=0;e<=c;e++){_[g++]=t,_[g++]=n,_[g++]=h,_[g++]=u;let e=t+i*Math.cos(f),r=n-s*Math.sin(f);_[g++]=e,_[g++]=r,_[g++]=h,_[g++]=u,f+=p}o=g,r.push(e._shapesPL,2*(c+1))},h=(t,n,i,s,l,d,c,h,u,p,f)=>{let _=(h-c)/u,g=c,m=a,x=o;for(let e=0;e<=u;e++){let e=t+i*Math.cos(g),r=n-s*Math.sin(g),a=t+l*Math.cos(g),o=n-d*Math.sin(g);m[x++]=e,m[x++]=r,m[x++]=p,m[x++]=f,m[x++]=a,m[x++]=o,m[x++]=p,m[x++]=f,g+=_}o=x,r.push(e._shapesPL,2*(u+1))};e.rectMode=t=>e._rectMode=t,e.rect=(t,r,a,o,n=0)=>{let s,l,[p,f,_,g]=e._calcBox(t,r,a,o,e._rectMode);if(e._matrixDirty&&e._saveMatrix(),l=e._matrixIndex,!n){if(e._doFill&&(s=e._fill,d(p,_,f,_,f,g,p,g,s,l)),e._doStroke){s=e._stroke;let t=e._strokeWeight/2,r=p-t,a=f+t,o=_+t,n=g-t,i=p+t,c=f-t,h=_-t,u=g+t;d(r,h,a,h,a,o,r,o,s,l),d(r,n,a,n,a,u,r,u,s,l),o=_-t,n=g+t,d(r,o,i,o,i,n,r,n,s,l),d(c,o,a,o,a,n,c,n,s,l)}return}p+=n,f-=n,_-=n,g+=n,n=Math.min(n,Math.min(a,o)/2);let m=u(n*e._scale),x=_+n,v=g-n,y=p-n,b=f+n;if(e._doFill&&(s=e._fill,c(f,g,n,n,0,i,m,s,l),c(p,g,n,n,Math.PI,i,m,s,l),c(p,_,n,n,-Math.PI,-i,m,s,l),c(f,_,n,n,-i,0,m,s,l),d(p,x,f,x,f,v,p,v,s,l),d(p,_,y,_,y,g,p,g,s,l),d(b,_,f,_,f,g,b,g,s,l)),e._doStroke){s=e._stroke;let t=e._hsw,r=n+t,a=n+t,o=n-t,c=n-t;h(f,g,r,a,o,c,0,i,m,s,l),h(p,g,r,a,o,c,Math.PI,i,m,s,l),h(p,_,r,a,o,c,-Math.PI,-i,m,s,l),h(f,_,r,a,o,c,-i,0,m,s,l);let u=y-t,w=y+t,S=b-t,C=b+t,M=x-t,Q=x+t,P=v-t,E=v+t;d(u,_,w,_,w,g,u,g,s,l),d(S,_,C,_,C,g,S,g,s,l),d(p,M,f,M,f,Q,p,Q,s,l),d(p,P,f,P,f,E,p,E,s,l)}},e.square=(t,r,a)=>e.rect(t,r,a,a),e.plane=(t,r,a,o)=>{o??=a;let[n,i,s,l]=e._calcBox(t,r,a,o,"center");e._matrixDirty&&e._saveMatrix(),d(n,s,i,s,i,l,n,l,e._fill,e._matrixIndex)};const u=e=>e<4?6:e<6?8:e<10?10:e<16?12:e<20?14:e<22?16:e<24?18:e<28?20:e<34?22:e<42?24:e<48?26:e<56?28:e<64?30:e<72?32:e<84?34:e<96?36:e<98?38:e<113?40:e<149?44:e<199?48:e<261?52:e<353?56:e<461?60:e<585?64:e<1200?70:e<1800?80:e<2400?90:100;e._ellipseMode=Q5.CENTER,e.ellipseMode=t=>e._ellipseMode=t,e.ellipse=(t,r,a,o)=>{let i=u(Math.max(Math.abs(a),Math.abs(o))*e._scale),s=a/2,l=a==o?s:o/2;e._matrixDirty&&e._saveMatrix();let d=e._matrixIndex;if(e._doFill&&c(t,-r,s,l,0,n,i,e._fill,d),e._doStroke){let a=e._strokeWeight/2;h(t,-r,s+a,l+a,s-a,l-a,0,n,i,e._stroke,d)}},e.circle=(t,r,a)=>e.ellipse(t,r,a,a),e.arc=(t,r,a,o,i,s)=>{if(i===s)return e.ellipse(t,r,a,o);if(e._angleMode&&(i=e.radians(i),s=e.radians(s)),(i%=n)<0&&(i+=n),(s%=n)<0&&(s+=n),i>s&&(s+=n),i==s)return e.ellipse(t,r,a,o);let l,d;e._ellipseMode==e.CENTER?(l=a/2,d=o/2):e._ellipseMode==e.RADIUS?(l=a,d=o):e._ellipseMode==e.CORNER?(t+=a/2,r+=o/2,l=a/2,d=o/2):e._ellipseMode==e.CORNERS&&(l=(a-(t=(t+a)/2))/2,d=(o-(r=(r+o)/2))/2),e._matrixDirty&&e._saveMatrix();let p=e._matrixIndex,f=u(Math.max(Math.abs(a),Math.abs(o))*e._scale);if(e._doFill&&c(t,-r,l,d,i,s,f,e._fill,p),e._doStroke){let a=e._hsw;h(t,-r,l+a,d+a,l-a,d-a,i,s,f,e._stroke,p),"round"==e._strokeCap&&(c(t+l*Math.cos(i),-r-d*Math.sin(i),a,a,0,n,f,e._stroke,p),c(t+l*Math.cos(s),-r-d*Math.sin(s),a,a,0,n,f,e._stroke,p))}},e.point=(t,r)=>{e._matrixDirty&&e._saveMatrix();let a=e._matrixIndex,o=e._stroke,i=e._strokeWeight;if(e._scaledSW<2){let[n,s,l,c]=e._calcBox(t,r,i,i,"corner");d(n,l,s,l,s,c,n,c,o,a)}else{let s=u(e._scaledSW);i/=2,c(t,-r,i,i,0,n,s,o,a)}},e._strokeCap=e._strokeJoin="round",e.strokeCap=t=>e._strokeCap=t,e.strokeJoin=t=>e._strokeJoin=t,e.lineMode=()=>{e._strokeCap="square",e._strokeJoin="none"},e.line=(t,r,a,o)=>{e._matrixDirty&&e._saveMatrix();let i=e._matrixIndex,s=e._stroke,l=(e._strokeWeight,e._hsw),h=a-t,p=o-r,f=Math.hypot(h,p),_=-p/f*l,g=h/f*l;if(d(t+_,-r-g,t-_,-r+g,a-_,-o+g,a+_,-o-g,s,i),e._scaledSW>2&&"square"!=e._strokeCap){let d=u(e._scaledSW);c(t,-r,l,l,0,n,d,s,i),c(a,-o,l,l,0,n,d,s,i)}};let p,f=20;e.curveDetail=e=>f=e;let _=[],g=[];e.beginShape=()=>{p=0,_=[],g=[]},e.vertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),_.push(t,-r,e._fill,e._matrixIndex),p++},e.curveVertex=(t,r)=>{e._matrixDirty&&e._saveMatrix(),g.push({x:t,y:-r})},e.bezierVertex=function(t,r,a,o,n,i){if(0===p)throw new Error("Shape needs a vertex()");e._matrixDirty&&e._saveMatrix();let s,l,d=4*(p-1),c=_[d],h=_[d+1],u=1/f,g=4==arguments.length;g&&(n=a,i=o);let m=1+u;for(let d=u;d<=m;d+=u){let u=d*d,f=1-d,m=f*f;if(g)s=m*c+2*f*d*t+u*n,l=m*h+2*f*d*-r+u*-i;else{let e=u*d,p=m*f;s=p*c+3*m*d*t+3*f*u*a+e*n,l=p*h+3*m*d*-r+3*f*u*-o+e*-i}_.push(s,l,e._fill,e._matrixIndex),p++}},e.quadraticVertex=(t,r,a,o)=>e.bezierVertex(t,r,a,o),e.endShape=t=>{if(g.length>0){let t=[...g];if(t.length<4)for(;t.length<4;)t.unshift(t[0]),t.push(t[t.length-1]);for(let r=0;r<t.length-3;r++){let a=t[r],o=t[r+1],n=t[r+2],i=t[r+3];for(let t=0;t<=1;t+=.1){let r=t*t,s=r*t,l=.5*(2*o.x+(-a.x+n.x)*t+(2*a.x-5*o.x+4*n.x-i.x)*r+(-a.x+3*o.x-3*n.x+i.x)*s),d=.5*(2*o.y+(-a.y+n.y)*t+(2*a.y-5*o.y+4*n.y-i.y)*r+(-a.y+3*o.y-3*n.y+i.y)*s);_.push(l,d,e._fill,e._matrixIndex),p++}}}if(p){if(1==p)return e.point(_[0],-_[1]);if(2==p)return e.line(_[0],-_[1],_[4],-_[5]);if(t){let e=0,t=4*(p-1),r=_[e],a=_[e+1],o=_[t],n=_[t+1];r===o&&a===n||(_.push(r,a,_[e+2],_[e+3]),p++)}if(e._doFill)if(5==p)l(_[0],_[1],_[2],_[3]),l(_[4],_[5],_[6],_[7]),l(_[12],_[13],_[14],_[15]),l(_[8],_[9],_[10],_[11]),r.push(e._shapesPL,4);else{for(let e=1;e<p-1;e++){let t=0,r=4*e,a=4*(e+1);l(_[t],_[t+1],_[t+2],_[t+3]),l(_[r],_[r+1],_[r+2],_[r+3]),l(_[a],_[a+1],_[a+2],_[a+3])}r.push(e._shapesPL,3*(p-2))}if(e._doStroke){let r=e._hsw,a=u(e._scaledSW),o=e._matrixIndex,i=e._strokeCap;e._strokeCap="square";for(let t=0;t<p-1;t++){let i=4*t,s=4*(t+1);e.line(_[i],-_[i+1],_[s],-_[s+1]),c(_[i],_[i+1],r,r,0,n,a,e._stroke,o)}let s=4*(p-1),l=0;t&&e.line(_[s],-_[s+1],_[l],-_[l+1]),c(_[s],_[s+1],r,r,0,n,a,e._stroke,o),e._strokeCap=i}p=0,_=[],g=[]}},e.curve=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.curveVertex(t,r),e.curveVertex(a,o),e.curveVertex(n,i),e.curveVertex(s,l),e.endShape()},e.bezier=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.bezierVertex(a,o,n,i,s,l),e.endShape()},e.triangle=(t,r,a,o,n,i)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.endShape(!0)},e.quad=(t,r,a,o,n,i,s,l)=>{e.beginShape(),e.vertex(t,r),e.vertex(a,o),e.vertex(n,i),e.vertex(s,l),e.endShape(!0)},e._hooks.preRender.push((()=>{e._pass.setPipeline(e._pipelines[1]);let t=Q5.device.createBuffer({size:4*o,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(a.slice(0,o)),t.unmap(),e._pass.setVertexBuffer(0,t),e._buffers.push(t)})),e._hooks.postRender.push((()=>{o=0}))},Q5.renderers.webgpu.image=(e,t)=>{e._imagePL=2,e._videoPL=3,e._imageShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@location(0) pos: vec2f,\n\t@location(1) texCoord: vec2f,\n\t@location(2) tintIndex: f32,\n\t@location(3) matrixIndex: f32,\n\t@location(4) imageAlpha: f32\n}\nstruct FragParams {\n\t@builtin(position) position: vec4f,\n\t@location(0) texCoord: vec2f,\n\t@location(1) tintColor: vec4f,\n\t@location(2) imageAlpha: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var samp: sampler;\n@group(1) @binding(1) var tex: texture_2d<f32>;\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0f, 1f);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn applyTint(texColor: vec4f, tintColor: vec4f) -> vec4f {\n\t// apply the tint color to the sampled texture color at full strength\n\tlet tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a);\n\t// mix in the tint using the tint alpha as the blend strength\n\treturn mix(texColor, tinted, tintColor.a);\n}\n\n@vertex\nfn vertexMain(v: VertexParams) -> FragParams {\n\tvar vert = transformVertex(v.pos, v.matrixIndex);\n\n\tvar f: FragParams;\n\tf.position = vert;\n\tf.texCoord = v.texCoord;\n\tf.tintColor = colors[i32(v.tintIndex)];\n\tf.imageAlpha = v.imageAlpha;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f: FragParams) -> @location(0) vec4f {\n\tvar texColor = textureSample(tex, samp, f.texCoord);\n\ttexColor.a *= f.imageAlpha;\n\treturn applyTint(texColor, f.tintColor);\n}\n";let r=Q5.device.createShaderModule({label:"imageShader",code:e._imageShaderCode});e._videoShaderCode=e._imageShaderCode.replace("texture_2d<f32>","texture_external").replace("textureSample","textureSampleBaseClampToEdge");let a=Q5.device.createShaderModule({label:"videoShader",code:e._videoShaderCode}),o=new Float32Array(e._graphics?1e3:1e7),n=0,i={arrayStride:28,attributes:[{shaderLocation:0,offset:0,format:"float32x2"},{shaderLocation:1,offset:8,format:"float32x2"},{shaderLocation:2,offset:16,format:"float32"},{shaderLocation:3,offset:20,format:"float32"},{shaderLocation:4,offset:24,format:"float32"}]},s=Q5.device.createBindGroupLayout({label:"textureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d",sampleType:"float"}}]}),l=Q5.device.createBindGroupLayout({label:"videoTextureLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,externalTexture:{}}]}),d=Q5.device.createPipelineLayout({label:"imagePipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,s]}),c=Q5.device.createPipelineLayout({label:"videoPipelineLayout",bindGroupLayouts:[...e._bindGroupLayouts,l]});e._pipelineConfigs[2]={label:"imagePipeline",layout:d,vertex:{module:r,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},i]},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[2]=Q5.device.createRenderPipeline(e._pipelineConfigs[2]),e._pipelineConfigs[3]={label:"videoPipeline",layout:c,vertex:{module:a,entryPoint:"vertexMain",buffers:[{arrayStride:0,attributes:[]},i]},fragment:{module:a,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[3]=Q5.device.createRenderPipeline(e._pipelineConfigs[3]),e._textureBindGroups=[],e._saveCanvas=async(t,r)=>{let a=t.texture,o=a.width,n=a.height,i=256*Math.ceil(4*o/256),s=Q5.device.createBuffer({size:i*n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});e._buffers.push(s);let l=Q5.device.createCommandEncoder();l.copyTextureToBuffer({texture:a},{buffer:s,bytesPerRow:i,rowsPerImage:n},{width:o,height:n}),Q5.device.queue.submit([l.finish()]),await s.mapAsync(GPUMapMode.READ);let d=new Uint8Array(s.getMappedRange());t=new Uint8Array(o*n*4);for(let e=0;e<n;e++){const r=e*i,a=e*o*4;for(let e=0;e<o;e++){const o=r+4*e,n=a+4*e;t[n+0]=d[o+2],t[n+1]=d[o+1],t[n+2]=d[o+0],t[n+3]=d[o+3]}}s.unmap();let c=e.canvas.colorSpace;t=new Uint8ClampedArray(t.buffer),t=new ImageData(t,o,n,{colorSpace:c});let h=new e._Canvas(o,n);h.getContext("2d",{colorSpace:c}).putImageData(t,0,0);let u=await h.convertToBlob({type:"image/"+r});return await new Promise((e=>{let t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(u)}))};let h=t=>{e._imageSampler=Q5.device.createSampler({magFilter:t,minFilter:t})};e.smooth=()=>h("linear"),e.noSmooth=()=>h("nearest"),e.smooth();let u=0,p=0;e._addTexture=(t,r)=>{let a=t.canvas||t,o=[a.width,a.height,1];r||(r=Q5.device.createTexture({size:o,format:"bgra8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),Q5.device.queue.copyExternalImageToTexture({source:a},{texture:r,colorSpace:e.canvas.colorSpace},o)),t.texture=r,t.textureIndex=u+p,e._textureBindGroups[t.textureIndex]=Q5.device.createBindGroup({label:t.src||"canvas",layout:s,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r.createView()}]}),u++};let f=Q5.Image;Q5.Image=function(t,r){let a=new f(...arguments);return t>1&&r>1&&(e._addTexture(a),a.modified=!0),a},e.loadImage=(r,a)=>{t._preloadCount++;let o=e._g.loadImage(r,(r=>{e._addTexture(r),t._preloadCount--,a&&a(o)}));return o},e.createImage=e._g.createImage;let _=e.createGraphics;e.createGraphics=(t,r,a)=>{let o=_(t,r,a);return o.canvas.webgpu&&(e._addTexture(o,o._frameA),e._addTexture(o,o._frameB),o._beginRender()),o},e.imageMode=t=>e._imageMode=t;const g=(e,t,r,a,i,s,l)=>{let d=o,c=n;d[c++]=e,d[c++]=t,d[c++]=r,d[c++]=a,d[c++]=i,d[c++]=s,d[c++]=l,n=c};e.image=(t,r=0,a=0,o,n,i=0,s=0,d,c)=>{let h;if(null==t.textureIndex){if(h="VIDEO"==t.tagName,!h||!t.width||!t.currentTime)return;t.flipped&&e.scale(-1,1)}let u=t.canvas||t;e._matrixDirty&&e._saveMatrix();let p=u.width,f=u.height,_=t._pixelDensity||1;if(t._graphics){let e=t;e.drawStack.length&&(e._render(),e._finishRender(),e.textureIndex+=e.frameCount%2==0?-1:1,e.resetMatrix(),e._beginRender(),e.frameCount++)}t.modified&&(Q5.device.queue.copyExternalImageToTexture({source:u},{texture:t.texture,colorSpace:e.canvas.colorSpace},[p,f,1]),t.modified=!1),o??=t.defaultWidth||t.videoWidth,n??=t.defaultHeight||t.videoHeight,d??=p,c??=f,i*=_,s*=_;let[m,x,v,y]=e._calcBox(r,a,o,n,e._imageMode),b=i/p,w=s/f,S=(i+d)/p,C=(s+c)/f,M=e._matrixIndex,Q=e._tint,P=e._globalAlpha;if(g(m,v,b,w,Q,M,P),g(x,v,S,w,Q,M,P),g(m,y,b,C,Q,M,P),g(x,y,S,C,Q,M,P),h){let r=Q5.device.importExternalTexture({source:t});e._textureBindGroups.push(Q5.device.createBindGroup({layout:l,entries:[{binding:0,resource:e._imageSampler},{binding:1,resource:r}]})),e._drawStack.push(e._videoPL,e._textureBindGroups.length-1),t.flipped&&e.scale(-1,1)}else e._drawStack.push(e._imagePL,t.textureIndex)},e._hooks.preRender.push((()=>{if(!n)return;e._pass.setPipeline(e._pipelines[2]);let t=Q5.device.createBuffer({size:5*n,usage:GPUBufferUsage.VERTEX,mappedAtCreation:!0});new Float32Array(t.getMappedRange()).set(o.slice(0,n)),t.unmap(),e._pass.setVertexBuffer(1,t),e._buffers.push(t),p&&(e._pass.setPipeline(e._pipelines[3]),e._pass.setVertexBuffer(1,t))})),e._hooks.postRender.push((()=>{n=0,e._textureBindGroups.splice(u,p),p=0}))},Q5.THRESHOLD=1,Q5.GRAY=2,Q5.OPAQUE=3,Q5.INVERT=4,Q5.POSTERIZE=5,Q5.DILATE=6,Q5.ERODE=7,Q5.BLUR=8,Q5.renderers.webgpu.text=(e,t)=>{e._textPL=4,e._textShaderCode=e._baseShaderCode+"\nstruct VertexParams {\n\t@builtin(vertex_index) vertexIndex : u32,\n\t@builtin(instance_index) instanceIndex : u32\n}\nstruct FragParams {\n\t@builtin(position) position : vec4f,\n\t@location(0) texCoord : vec2f,\n\t@location(1) fillColor : vec4f,\n\t@location(2) strokeColor : vec4f,\n\t@location(3) strokeWeight : f32\n}\nstruct Char {\n\ttexOffset: vec2f,\n\ttexExtent: vec2f,\n\tsize: vec2f,\n\toffset: vec2f,\n}\nstruct Text {\n\tpos: vec2f,\n\tscale: f32,\n\tmatrixIndex: f32,\n\tfillIndex: f32,\n\tstrokeIndex: f32,\n\tstrokeWeight: f32\n}\n\n@group(0) @binding(0) var<uniform> q: Q5;\n@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;\n@group(0) @binding(2) var<storage> colors : array<vec4f>;\n\n@group(1) @binding(0) var fontTexture: texture_2d<f32>;\n@group(1) @binding(1) var fontSampler: sampler;\n@group(1) @binding(2) var<storage> fontChars: array<Char>;\n\n@group(2) @binding(0) var<storage> textChars: array<vec4f>;\n@group(2) @binding(1) var<storage> textMetadata: array<Text>;\n\nconst quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));\nconst uvs = array(vec2f(0, 1), vec2f(1, 1), vec2f(0, 0), vec2f(1, 0));\n\nfn calcPos(i: u32, char: vec4f, fontChar: Char, text: Text) -> vec2f {\n\treturn ((quad[i] * fontChar.size + char.xy + fontChar.offset) *\n\t\ttext.scale) + text.pos;\n}\n\nfn calcUV(i: u32, fontChar: Char) -> vec2f {\n\treturn uvs[i] * fontChar.texExtent + fontChar.texOffset;\n}\n\nfn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {\n\tvar vert = vec4f(pos, 0.0, 1.0);\n\tvert = transforms[i32(matrixIndex)] * vert;\n\tvert.x /= q.halfWidth;\n\tvert.y /= q.halfHeight;\n\treturn vert;\n}\n\nfn calcDist(texCoord: vec2f, edgeWidth: f32) -> f32 {\n\tlet c = textureSample(fontTexture, fontSampler, texCoord);\n\tlet sigDist = max(min(c.r, c.g), min(max(c.r, c.g), c.b)) - edgeWidth;\n\n\tlet pxRange = 4.0;\n\tlet sz = vec2f(textureDimensions(fontTexture, 0));\n\tlet dx = sz.x * length(vec2f(dpdxFine(texCoord.x), dpdyFine(texCoord.x)));\n\tlet dy = sz.y * length(vec2f(dpdxFine(texCoord.y), dpdyFine(texCoord.y)));\n\tlet toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);\n\treturn sigDist * toPixels;\n}\n\n@vertex\nfn vertexMain(v : VertexParams) -> FragParams {\n\tlet char = textChars[v.instanceIndex];\n\tlet text = textMetadata[i32(char.w)];\n\tlet fontChar = fontChars[i32(char.z)];\n\tlet pos = calcPos(v.vertexIndex, char, fontChar, text);\n\n\tvar vert = transformVertex(pos, text.matrixIndex);\n\n\tvar f : FragParams;\n\tf.position = vert;\n\tf.texCoord = calcUV(v.vertexIndex, fontChar);\n\tf.fillColor = colors[i32(text.fillIndex)];\n\tf.strokeColor = colors[i32(text.strokeIndex)];\n\tf.strokeWeight = text.strokeWeight;\n\treturn f;\n}\n\n@fragment\nfn fragMain(f : FragParams) -> @location(0) vec4f {\n\tlet edge = 0.5;\n\tlet dist = calcDist(f.texCoord, edge);\n\n\tif (f.strokeWeight == 0.0) {\n\t\tlet fillAlpha = smoothstep(-edge, edge, dist);\n\t\tlet color = vec4f(f.fillColor.rgb, f.fillColor.a * fillAlpha);\n\t\tif (color.a < 0.01) {\n\t\t\tdiscard;\n\t\t}\n\t\treturn color;\n\t}\n\n\tlet halfStroke = f.strokeWeight / 2.0;\n\tlet fillAlpha = smoothstep(-edge, edge, dist - halfStroke);\n\tlet strokeAlpha = smoothstep(-edge, edge, dist + halfStroke);\n\tvar color = mix(f.strokeColor, f.fillColor, fillAlpha);\n\tcolor = vec4f(color.rgb, color.a * strokeAlpha);\n\tif (color.a < 0.01) {\n\t\tdiscard;\n\t}\n\treturn color;\n}\n";let r=Q5.device.createShaderModule({label:"textShader",code:e._textShaderCode}),a=Q5.device.createBindGroupLayout({label:"textBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),o=Q5.device.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:16}),n=Q5.device.createBindGroupLayout({label:"fontBindGroupLayout",entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:2,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}]}),i=Q5.device.createPipelineLayout({bindGroupLayouts:[...e._bindGroupLayouts,n,a]});e._pipelineConfigs[4]={label:"textPipeline",layout:i,vertex:{module:r,entryPoint:"vertexMain"},fragment:{module:r,entryPoint:"fragMain",targets:[{format:"bgra8unorm",blend:e.blendConfigs.normal}]},primitive:{topology:"triangle-strip",stripIndexFormat:"uint32"},multisample:{count:4}},e._pipelines[4]=Q5.device.createRenderPipeline(e._pipelineConfigs[4]);class s{constructor(e,t,r,a){this.bindGroup=e,this.lineHeight=t,this.chars=r,this.kernings=a;let o=Object.values(r);this.charCount=o.length,this.defaultChar=o[0]}getChar(e){return this.chars[e]??this.defaultChar}getXAdvance(e,t=-1){let r=this.getChar(e);if(t>=0){let a=this.kernings.get(e);if(a)return r.xadvance+(a.get(t)??0)}return r.xadvance}}e._fonts=[];let l={};e.loadFont=(r,a)=>{if("json"!=r.slice(r.lastIndexOf(".")+1))return e._g.loadFont(r,a);let i=r.slice(r.lastIndexOf("/")+1,r.lastIndexOf("-")),d={family:i};return d._loader=(async(r,a,i)=>{t._preloadCount++;let d=await fetch(r);if(404==d.status)return t._preloadCount--,"";let c=await d.json(),h=r.lastIndexOf("/"),u=-1!=h?r.substring(0,h+1):"";d=await fetch(u+c.pages[0]);let p=await createImageBitmap(await d.blob()),f=[p.width,p.height,1],_=Q5.device.createTexture({label:`MSDF ${a}`,size:f,format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});Q5.device.queue.copyExternalImageToTexture({source:p},{texture:_},f),"string"==typeof c.chars&&(c.chars=e.CSV.parse(c.chars," "),c.kernings=e.CSV.parse(c.kernings," "));let g=c.chars.length,m=Q5.device.createBuffer({size:32*g,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),x=new Float32Array(m.getMappedRange()),v=1/c.common.scaleW,y=1/c.common.scaleH,b={},w=0;for(let[e,t]of c.chars.entries())b[t.id]=t,b[t.id].charIndex=e,x[w]=t.x*v,x[w+1]=t.y*y,x[w+2]=t.width*v,x[w+3]=t.height*y,x[w+4]=t.width,x[w+5]=t.height,x[w+6]=t.xoffset,x[w+7]=-t.yoffset,w+=8;m.unmap();let S=Q5.device.createBindGroup({label:"fontBindGroup",layout:n,entries:[{binding:0,resource:_.createView()},{binding:1,resource:o},{binding:2,resource:{buffer:m}}]}),C=new Map;if(c.kernings)for(let e of c.kernings){let t=C.get(e.first);t||(t=new Map,C.set(e.first,t)),t.set(e.second,e.amount)}e._font=new s(S,c.common.lineHeight,b,C),e._font.index=e._fonts.length,e._fonts.push(e._font),l[a]=e._font,t._preloadCount--,i&&i(a)})(r,i,(()=>{delete d._loader,a&&a(d)})),e._usePreload?d:d._loader},e._loadDefaultFont=t=>{l[t]=null,navigator.onLine?e.loadFont(`https://q5js.org/fonts/${t}-msdf.json`):e.loadFont(`/node_modules/q5/builtinFonts/${t}-msdf.json`)},e._textSize=18,e._textAlign="left",e._textBaseline="alphabetic";let d=!1,c=22.5,h=4.5,u=1.25;e.textFont=t=>{if(!t)return e._font;"string"!=typeof t&&(t=t.family);let r=l[t];r?e._font=r:void 0===r&&e._loadDefaultFont(t)},e.textSize=t=>{if(null==t)return e._textSize;e._textSize=t,d||(c=t*u,h=c-t)},e.textLeading=t=>{e._font.lineHeight=c=t,h=c-e._textSize,u=c/e._textSize,d=!0},e.textAlign=(t,r)=>{e._textAlign=t,r&&(e._textBaseline=r)};let p=[],f=[],_=(e,t,r)=>{let a=0,o=0,n=0,i=0,s=0,l=[],d=t.charCodeAt(0);for(let c=0;c<t.length;++c){let h=d;switch(d=c<t.length-1?t.charCodeAt(c+1):-1,h){case 10:l.push(o),i++,a=Math.max(a,o),o=0,n-=e.lineHeight*u;break;case 13:break;case 32:o+=e.getXAdvance(h);break;case 9:o+=2*e.getXAdvance(h);break;default:r&&r(o,n,i,e.getChar(h)),o+=e.getXAdvance(h,d),s++}}return l.push(o),a=Math.max(a,o),{width:a,height:l.length*e.lineHeight*u,lineWidths:l,printedCharCount:s}};e.text=(t,r,a,o,n)=>{if(!e._font)return void(null!==e._font&&e.textFont("sans-serif"));let i=typeof t;if("string"!=i&&("object"==i?t=t.toString():t+=""),t.length>o){let e=[],r=0;for(;r<t.length&&e.length<n;){let a=r+o;if(a>=t.length){e.push(t.slice(r));break}let n=t.lastIndexOf(" ",a);(-1==n||n<r)&&(n=a),e.push(t.slice(r,n)),r=n+1}t=e.join("\n")}let s;for(let e=0;e<t.length;e++){switch(t[e]){case"\n":s=!0;case"\r":case"\t":case" ":0}}let l,d=[],h=e._textAlign,u=e._textBaseline,g=f.length,m=0;if("left"!=h||s){l=_(e._font,t);let r=0;"alphabetic"==u?a-=e._textSize:"center"==u?r=.5*l.height:"bottom"==u&&(r=l.height),_(e._font,t,((e,t,a,o)=>{let n=0;"center"==h?n=-.5*l.width- -.5*(l.width-l.lineWidths[a]):"right"==h&&(n=-l.lineWidths[a]),d[m]=e+n,d[m+1]=t+r,d[m+2]=o.charIndex,d[m+3]=g,m+=4}))}else l=_(e._font,t,((e,t,r,a)=>{d[m]=e,d[m+1]=t,d[m+2]=a.charIndex,d[m+3]=g,m+=4})),"alphabetic"==u?a-=e._textSize:"center"==u?a-=.5*e._textSize:"bottom"==u&&(a-=c);p.push(d);let x=[];e._matrixDirty&&e._saveMatrix(),x[0]=r,x[1]=-a,x[2]=e._textSize/44,x[3]=e._matrixIndex,x[4]=e._doFill&&e._fillSet?e._fill:0,x[5]=e._stroke,x[6]=e._doStroke&&e._strokeSet?e._strokeWeight:0,x[7]=0,f.push(x),e._drawStack.push(e._textPL,l.printedCharCount,e._font.index)},e.textWidth=t=>e._font?_(e._font,t).width:0,e.createTextImage=(t,r,a)=>{if(e._g.textSize(e._textSize),e._doFill&&e._fillSet){let t=4*e._fill;e._g.fill(e._colorStack.slice(t,t+4))}if(e._doStroke&&e._strokeSet){let t=4*e._stroke;e._g.stroke(e._colorStack.slice(t,t+4))}let o=e._g.createTextImage(t,r,a);if(null==o.textureIndex){e._createTexture(o);let t=o.copy;o.copy=function(){let r=t();return e._createTexture(r),r}}return o},e.textImage=(t,r,a)=>{"string"==typeof t&&(t=e.createTextImage(t));let o=e._imageMode;e._imageMode="corner";let n=e._textAlign;"center"==n?r-=t.canvas.hw:"right"==n&&(r-=t.width);let i=e._textBaseline;"alphabetic"==i?a-=t._leading:"center"==i?a-=t._middle:"bottom"==i?a-=t._bottom:"top"==i&&(a-=t._top),e.image(t,r,a),e._imageMode=o},e._hooks.preRender.push((()=>{if(!p.length)return;let t=0;for(let e of p)t+=4*e.length;let r=Q5.device.createBuffer({size:t,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(r.getMappedRange()).set(p.flat()),r.unmap();let o=8*f.length*4,n=Q5.device.createBuffer({label:"textBuffer",size:o,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0});new Float32Array(n.getMappedRange()).set(f.flat()),n.unmap(),e._buffers.push(r,n),e._textBindGroup=Q5.device.createBindGroup({label:"textBindGroup",layout:a,entries:[{binding:0,resource:{buffer:r}},{binding:1,resource:{buffer:n}}]})})),e._hooks.postRender.push((()=>{p=[],f=[]}))},Q5.renderers.webgpu.shaders=e=>{let t=["frame","shapes","image","video","text"],r={frame:10,shapes:1e3,image:2e3,video:3e3,text:4e3};e._createShader=(a,o="shapes")=>{a=a.trim();let n=e["_"+o+"ShaderCode"],i=n.indexOf("@vertex"),s=n.indexOf("@fragment");a=a.includes("@fragment")?a.includes("@vertex")?n.slice(0,i)+a:n.slice(0,s)+a:n.slice(0,i)+a+"\n\n"+n.slice(s);let l=Q5.device.createShaderModule({label:o+"Shader",code:a});l.type=o;let d=t.indexOf(o),c=Object.assign({},e._pipelineConfigs[d]);c.vertex.module=c.fragment.module=l;let h=r[o];return e._pipelines[h]=Q5.device.createRenderPipeline(c),e._pipelines[h].shader=l,l.pipelineIndex=h,r[o]++,l},e.createShader=e.createShapesShader=e._createShader,e.createFrameShader=t=>e._createShader(t,"frame"),e.createImageShader=t=>e._createShader(t,"image"),e.createVideoShader=t=>e._createShader(t,"video"),e.createTextShader=t=>e._createShader(t,"text"),e.shader=t=>{t.applyBeforeDraw?e._prevFramePL=t.pipelineIndex:e["_"+t.type+"PL"]=t.pipelineIndex},e.resetShader=(r="shapes")=>{"frame"==r&&(e._prevFramePL=0),e["_"+r+"PL"]=t.indexOf(r)},e.resetShaders=()=>{e._prevFramePL=e._framePL=0,e._shapesPL=1,e._imagePL=2,e._videoPL=3,e._textPL=4}};
|