From 889418b27e9f1ed19ac4d8fb8cee1f6ba6c86a46 Mon Sep 17 00:00:00 2001 From: Quinton Ashley Date: Sat, 27 Jan 2024 12:52:32 -0500 Subject: [PATCH] 1.9.4 --- README.md | 35 +++++-- package.json | 2 +- q5.js | 264 ++++++++++++++++++++++++++------------------------- q5.min.js | 2 +- 4 files changed, 166 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 3d98dca..4ace1fb 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,11 @@ This is great because you don't have to declare variables on the file level and Most modern devices support the "display-p3" HDR color space. If a device doesn't support it, q5 will fall back to "srgb". -**q5** now supports the [oklch](https://oklch.com/#63.65,0.2872,16.57,100) color format which is capable of representing HDR colors. +In **q5**, `colorMode` accepts 'rgb', 'srgb', and 'oklch'. The default mode is 'rgb', which upgrades rgb colors to HDR on supported displays. Specifying 'srgb' on an HDR capable device enables sRGB gamut correction for rgb colors. + +The [oklch](https://oklch.com/#63.65,0.2872,16.57,100) color format is the best way to work with HDR colors! + +https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl ```js colorMode('oklch'); @@ -77,11 +81,15 @@ colorMode('oklch'); let c = color(0.637, 0.287, 16.57, 1); ``` -Support for the HSV color format was removed in q5 v1.9.3 because color experts thought HSV was flawed, outdated, and ought to be abandoned way back in 1997! +The `color` function doesn't accept percentages so you'll have to convert those to decimal values. Also its string parsing capability is limited to the "#RRGGBB" or "#RRGGBBAA" formats. + +Use `new Color()` to create color objects without any parsing overhead. -The `color` function does accept strings but only hex strings in "#RRGGBB" or "#RRGGBBAA" format. It also does not accept percentages so you'll have to convert those to decimal values. +q5 also exposes color components as single letter properties of `Color` objects. For example, you can easily change the red of rgb colors like this `c.r = 128` or the hue of oklch colors like this `c.h = 180`. -`colorMode` accepts 'rgb', 'oklch', or 'srgb'. The default mode is 'rgb', which upgrades rgb colors to HDR on supported displays. Specifying 'srgb' enables sRGB gamut correction for rgb colors on HDR displays. +Support for the HSV color format was removed in q5 v1.9.3 because color experts thought HSV was flawed, outdated, and ought to be abandoned way back in 1997! oklch is superior in every way. + +https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages ## New Features: Customize Canvas Context Attributes @@ -159,7 +167,7 @@ In fact, its not uncommon for successful software systems to have multiple imple > This section was written by @quinton-ashley, co-creator of q5. -I thought @LingDong-'s work on q5 and the idea itself had great potential. So I decided to upgrade its compatibility with p5.js. My main goal was to make it work with [p5play](https://p5play.org)! +I thought @LingDong-'s work on q5 and the idea itself had great potential, so I decided to implement more of the p5.js API. My main goal was to make it work with [p5play](https://p5play.org)! An increase in performance of even a few frames per second can make a significant difference in the user experience of a work of interactive art or a game, especially on mobile devices. @@ -167,15 +175,18 @@ I was also interested in working on q5 because for a lot of p5.js users, the lib I think it'd be better if the canvas mode, webgl mode, Friendly Error System, and accessibility features of p5 were offered in separate files. Yet, the powers that be at the Processing Foundation have made it clear that they don't want to do that. Instead they insist on adding more accessibility features to the base library, which the majority of people just don't need. So q5 is a good alternative that trims out the fat. -Thanks in large part to @LingDong-'s design, q5 is well organized, concise, and utilizes many modern JS features! I think even without documentation, the source code is easier for experienced JS programmers to comprehend. +Thanks in large part to @LingDong-'s design, q5 is well organized, concise, and utilizes many modern JS features! I think even without inline documentation, the source code is easier for experienced JS programmers to comprehend. ## More exclusive features -q5.js provides some other features that are not in p5.js: +Features added by @quinton-ashley: - `textCache(true)`: Text image caching is enabled by default. Rotated text is only rendered once, and then cached as an image. This can result in ridiculously high 90x performance boosts for text-heavy sketches. Users don't need to change their code, the `text` function can be used as normal, q5 takes care of everything behind the scenes. -- `loadSound()`: Basic sound support in q5.js, returns a Web Audio object. Not as powerful as p5.sound, but it's good enough for simple sketches. Includes `sound.setVolume()`. +- `loadSound()`: Basic sound support in q5.js, returns a Web Audio object with `setVolume()` and `setLoop()` functions added. Not as powerful as p5.sound, but it's good enough in many cases. - `ctx`: an alias for `drawingContext` + +Features added by @LingDong-: + - `randomExponential()` in addition to `randomGaussian()`: a random distribution that resembles exponential decay. - `curveAlpha()`: manipulate the `α` parameter of Catmull-Rom curves. - `relRotationX`, `relRotationY` and `relRotationZ`: Similar to `rotationX/Y/Z`, but are relative to the orientation of the mobile device. @@ -241,6 +252,14 @@ Higher FPS (frames per second) is better. Speed is a goal for q5.js, and we would very much like to see the above list grow. If you know how to make something faster, advice/pull requests are very welcome! +## Licensing + +q5.js is not affiliated with the Processing Foundation. p5.js is licensed under the LGPLv2, the two small sections of p5.js' code were directly copied into q5.js are credited below. The rest of q5 is a partial re-implementation of the p5.js API. APIs are not copyrightable in the United States, as decided by the Supreme Court in the Oracle v Google case. + +@LingDong- created the original q5xjs library and licensed it under the MIT license. + +@quinton-ashley created q5.js (this project) and implemented more of the p5.js API and added several exclusive features. q5.js is licensed under the AGPLv3. + ## Credits catmullRomSpline: diff --git a/package.json b/package.json index 1707688..5d1c7da 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "author": "quinton-ashley", "name": "q5", - "version": "1.9.3", + "version": "1.9.4", "description": "An implementation of the p5.js 2D API that's smaller and faster", "main": "q5.js", "scripts": { diff --git a/q5.js b/q5.js index 4e28541..d8c1b24 100644 --- a/q5.js +++ b/q5.js @@ -16,7 +16,7 @@ function Q5(scope, parent) { setTimeout(() => preloadCnt--, 32); } if (scope == 'auto') { - if (typeof window != 'object' || !(window.setup || window.draw)) return; + if (!(window.setup || window.draw)) return; else scope = 'global'; } if (scope == 'global') Q5._hasGlobal = true; @@ -24,14 +24,16 @@ function Q5(scope, parent) { // CANVAS let $ = this; - $.canvas = document.createElement('canvas'); - $.canvas.id = 'defaultCanvas' + Q5._instanceCount++; - $.canvas.classList.add('p5Canvas', 'q5Canvas'); - - $.width = 100; - $.height = 100; - $.canvas.width = $.width; - $.canvas.height = $.height; + if (scope == 'image' || scope == 'graphics') { + $.canvas = new OffscreenCanvas(100, 100); + } else { + $.canvas = document.createElement('canvas'); + $.canvas.id = 'defaultCanvas' + Q5._instanceCount++; + $.canvas.classList.add('p5Canvas', 'q5Canvas'); + } + + $.canvas.width = $.width = 100; + $.canvas.height = $.height = 100; $._windowResizedFn = () => {}; if (scope != 'graphics' && scope != 'image') { @@ -70,19 +72,17 @@ function Q5(scope, parent) { $.pixels = []; let imgData = null; let ctx; + $.ctx = $.drawingContext = null; $.createCanvas = function (width, height, renderer, options) { if (renderer == 'webgl') throw `webgl renderer is not supported in q5, use '2d'`; - $.width = width; - $.height = height; - $.canvas.width = width; - $.canvas.height = height; + $.width = $.canvas.width = width; + $.height = $.canvas.height = height; $.canvas.renderer = '2d'; let opt = Object.assign({}, Q5.canvasOptions); if (options) Object.assign(opt, options); ctx = $.ctx = $.drawingContext = $.canvas.getContext('2d', opt); - if (scope == 'global') window.ctx = window.drawingContext = ctx; Object.assign($.canvas, opt); defaultStyle(); ctx.save(); @@ -105,7 +105,7 @@ function Q5(scope, parent) { if (imgData != null) ctx.putImageData(imgData, 0, 0); }; - let filterImpl = {}; + let filterImpl = []; filterImpl[$.THRESHOLD] = (data, thresh) => { if (thresh === undefined) thresh = 127.5; else thresh *= 255; @@ -144,7 +144,7 @@ function Q5(scope, parent) { filterImpl[$.DILATE] = (data) => { makeTmpBuf(); tmpBuf.set(data); - let [w, h] = [ctx.canvas.width, ctx.canvas.height]; + let [w, h] = [$.canvas.width, $.canvas.height]; for (let i = 0; i < h; i++) { for (let j = 0; j < w; j++) { let l = 4 * Math.max(j - 1, 0); @@ -171,7 +171,7 @@ function Q5(scope, parent) { filterImpl[$.ERODE] = (data) => { makeTmpBuf(); tmpBuf.set(data); - let [w, h] = [ctx.canvas.width, ctx.canvas.height]; + let [w, h] = [$.canvas.width, $.canvas.height]; for (let i = 0; i < h; i++) { for (let j = 0; j < w; j++) { let l = 4 * Math.max(j - 1, 0); @@ -216,7 +216,7 @@ function Q5(scope, parent) { } let kern = gauss1d(ksize); - let [w, h] = [ctx.canvas.width, ctx.canvas.height]; + let [w, h] = [$.canvas.width, $.canvas.height]; for (let i = 0; i < h; i++) { for (let j = 0; j < w; j++) { let s0 = 0, @@ -263,11 +263,13 @@ function Q5(scope, parent) { }; function makeTmpCtx(w, h) { + h ??= w || $.canvas.height; + w ??= $.canvas.width; if (tmpCtx == null) { - tmpCtx = document.createElement('canvas').getContext('2d'); + tmpCtx = new OffscreenCanvas(w, h).getContext('2d', { + colorSpace: $.canvas.colorSpace + }); } - h ??= w || ctx.canvas.height; - w ??= ctx.canvas.width; if (tmpCtx.canvas.width != w || tmpCtx.canvas.height != h) { tmpCtx.canvas.width = w; tmpCtx.canvas.height = h; @@ -275,11 +277,13 @@ function Q5(scope, parent) { } function makeTmpCt2(w, h) { + h ??= w || $.canvas.height; + w ??= $.canvas.width; if (tmpCt2 == null) { - tmpCt2 = document.createElement('canvas').getContext('2d'); + tmpCt2 = new OffscreenCanvas(w, h).getContext('2d', { + colorSpace: $.canvas.colorSpace + }); } - h ??= w || ctx.canvas.height; - w ??= ctx.canvas.width; if (tmpCt2.canvas.width != w || tmpCt2.canvas.height != h) { tmpCt2.canvas.width = w; tmpCt2.canvas.height = h; @@ -287,7 +291,7 @@ function Q5(scope, parent) { } function makeTmpBuf() { - let l = ctx.canvas.width * ctx.canvas.height * 4; + let l = $.canvas.width * $.canvas.height * 4; if (!tmpBuf || l != tmpBuf.length) { tmpBuf = new Uint8ClampedArray(l); } @@ -296,16 +300,16 @@ function Q5(scope, parent) { function nativeFilter(filtstr) { tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); tmpCtx.filter = filtstr; - tmpCtx.drawImage(ctx.canvas, 0, 0); + tmpCtx.drawImage($.canvas, 0, 0); ctx.save(); ctx.resetTransform(); - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + ctx.clearRect(0, 0, $.canvas.width, $.canvas.height); ctx.drawImage(tmpCtx.canvas, 0, 0); ctx.restore(); } function softFilter(typ, x) { - let imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); + let imgData = ctx.getImageData(0, 0, $.canvas.width, $.canvas.height); filterImpl[typ](imgData.data, x); ctx.putImageData(imgData, 0, 0); } @@ -325,7 +329,7 @@ function Q5(scope, parent) { } else if (typ == $.OPAQUE) { tmpCtx.fillStyle = 'black'; tmpCtx.fillRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); - tmpCtx.drawImage(ctx.canvas, 0, 0); + tmpCtx.drawImage($.canvas, 0, 0); ctx.save(); ctx.resetTransform(); ctx.drawImage(tmpCtx.canvas, 0, 0); @@ -341,15 +345,15 @@ function Q5(scope, parent) { $.resize = (w, h) => { makeTmpCtx(); - tmpCtx.drawImage(ctx.canvas, 0, 0); + tmpCtx.drawImage($.canvas, 0, 0); $.width = w; $.height = h; - ctx.canvas.width = w * $._pixelDensity; - ctx.canvas.height = h * $._pixelDensity; + $.canvas.width = w * $._pixelDensity; + $.canvas.height = h * $._pixelDensity; ctx.save(); ctx.resetTransform(); - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - ctx.drawImage(tmpCtx.canvas, 0, 0, ctx.canvas.width, ctx.canvas.height); + ctx.clearRect(0, 0, $.canvas.width, $.canvas.height); + ctx.drawImage(tmpCtx.canvas, 0, 0, $.canvas.width, $.canvas.height); ctx.restore(); }; @@ -367,7 +371,7 @@ function Q5(scope, parent) { h *= pd; let img = $.createImage(w, h); let imgData = ctx.getImageData(x, y, w, h); - img.canvas.getContext('2d').putImageData(imgData, 0, 0); + img.ctx.putImageData(imgData, 0, 0); img._pixelDensity = pd; img.width = _w; img.height = _h; @@ -382,21 +386,22 @@ function Q5(scope, parent) { $._tint = old; return; } + if (!$.pixels.length) $.loadPixels(); let mod = $._pixelDensity || 1; for (let i = 0; i < mod; i++) { for (let j = 0; j < mod; j++) { - let idx = 4 * ((y * mod + i) * ctx.canvas.width + x * mod + j); - $.pixels[idx] = c._r; - $.pixels[idx + 1] = c._g; - $.pixels[idx + 2] = c._b; - $.pixels[idx + 3] = c._a * 255; + let idx = 4 * ((y * mod + i) * $.canvas.width + x * mod + j); + $.pixels[idx] = c.r ?? c.l; + $.pixels[idx + 1] = c.g ?? c.c; + $.pixels[idx + 2] = c.b ?? c.h; + $.pixels[idx + 3] = c.a; } } }; $.tinted = function (col) { - let alpha = col._a; - col._a = 1; + let alpha = col.a; + col.a = 255; makeTmpCtx(); tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); tmpCtx.fillStyle = col; @@ -413,7 +418,7 @@ function Q5(scope, parent) { ctx.globalCompositeOperation = old; ctx.restore(); - tmpCtx.globalAlpha = alpha; + tmpCtx.globalAlpha = alpha / 255; tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); tmpCtx.drawImage(ctx.canvas, 0, 0); tmpCtx.globalAlpha = 1; @@ -424,7 +429,7 @@ function Q5(scope, parent) { ctx.drawImage(tmpCtx.canvas, 0, 0); ctx.restore(); }; - $.tint = (c) => { + $.tint = function (c) { $._tint = c._q5Color ? c : $.color(...arguments); }; $.noTint = () => ($._tint = null); @@ -464,7 +469,7 @@ function Q5(scope, parent) { if (!a || (typeof a == 'string' && (!b || (!c && b.length < 5)))) { c = b; b = a; - a = ctx.canvas; + a = $.canvas; } if (c) return $._save(a, b, c); if (b) { @@ -486,9 +491,35 @@ function Q5(scope, parent) { let tmpCt2 = null; let tmpBuf = null; + // CONSTANTS + + $.THRESHOLD = 1; + $.GRAY = 2; + $.OPAQUE = 3; + $.INVERT = 4; + $.POSTERIZE = 5; + $.DILATE = 6; + $.ERODE = 7; + $.BLUR = 8; + if (scope == 'image') return; - // CONSTANTS + $.BLEND = 'source-over'; + $.REMOVE = 'destination-out'; + $.ADD = 'lighter'; + $.DARKEST = 'darken'; + $.LIGHTEST = 'lighten'; + $.DIFFERENCE = 'difference'; + $.SUBTRACT = 'subtract'; + $.EXCLUSION = 'exclusion'; + $.MULTIPLY = 'multiply'; + $.SCREEN = 'screen'; + $.REPLACE = 'copy'; + $.OVERLAY = 'overlay'; + $.HARD_LIGHT = 'hard-light'; + $.SOFT_LIGHT = 'soft-light'; + $.DODGE = 'color-dodge'; + $.BURN = 'color-burn'; $.RGB = 'rgb'; $.RGBA = 'rgb'; @@ -510,23 +541,6 @@ function Q5(scope, parent) { $.CLOSE = 1; - $.BLEND = 'source-over'; - $.REMOVE = 'destination-out'; - $.ADD = 'lighter'; - $.DARKEST = 'darken'; - $.LIGHTEST = 'lighten'; - $.DIFFERENCE = 'difference'; - $.SUBTRACT = 'subtract'; - $.EXCLUSION = 'exclusion'; - $.MULTIPLY = 'multiply'; - $.SCREEN = 'screen'; - $.REPLACE = 'copy'; - $.OVERLAY = 'overlay'; - $.HARD_LIGHT = 'hard-light'; - $.SOFT_LIGHT = 'soft-light'; - $.DODGE = 'color-dodge'; - $.BURN = 'color-burn'; - $.NORMAL = 'normal'; $.ITALIC = 'italic'; $.BOLD = 'bold'; @@ -566,15 +580,6 @@ function Q5(scope, parent) { $.TAU = Math.PI * 2; $.TWO_PI = Math.PI * 2; - $.THRESHOLD = 1; - $.GRAY = 2; - $.OPAQUE = 3; - $.INVERT = 4; - $.POSTERIZE = 5; - $.DILATE = 6; - $.ERODE = 7; - $.BLUR = 8; - $.ARROW = 'default'; $.CROSS = 'crosshair'; $.HAND = 'pointer'; @@ -668,23 +673,23 @@ function Q5(scope, parent) { return c; } - $.resizeCanvas = (width, height) => { - $.width = width; - $.height = height; + $.resizeCanvas = (w, h) => { + $.width = w; + $.height = h; let c = cloneCtx(); - $.canvas.width = width * $._pixelDensity; - $.canvas.height = height * $._pixelDensity; + $.canvas.width = w * $._pixelDensity; + $.canvas.height = h * $._pixelDensity; for (let prop in c) $.ctx[prop] = c[prop]; if (scope != 'image') $.pixelDensity($._pixelDensity); }; - $.createGraphics = function (width, height) { + $.createGraphics = function (w, h) { let g = new Q5('graphics'); - g._createCanvas.call($, width, height); + g._createCanvas.call($, w, h); return g; }; - $.createImage = (width, height) => { - return new Q5.Image(width, height); + $.createImage = (w, h) => { + return new Q5.Image(w, h); }; $.displayDensity = () => window.devicePixelRatio; @@ -719,11 +724,9 @@ function Q5(scope, parent) { $.lerp = (a, b, t) => a * (1 - t) + b * t; $.constrain = (x, lo, hi) => Math.min(Math.max(x, lo), hi); $.dist = function () { - if (arguments.length == 4) { - return Math.hypot(arguments[0] - arguments[2], arguments[1] - arguments[3]); - } else { - return Math.hypot(arguments[0] - arguments[3], arguments[1] - arguments[4], arguments[2] - arguments[5]); - } + let a = arguments; + if (a.length == 4) return Math.hypot(a[0] - a[2], a[1] - a[3]); + else return Math.hypot(a[0] - a[3], a[1] - a[4], a[2] - a[5]); }; $.norm = (value, start, stop) => $.map(value, start, stop, 0, 1); $.sq = (x) => x * x; @@ -905,12 +908,12 @@ function Q5(scope, parent) { } }; - $.red = (c) => c._r; - $.green = (c) => c._g; - $.blue = (c) => c._b; - $.alpha = (c) => c._a; + $.red = (c) => c.r; + $.green = (c) => c.g; + $.blue = (c) => c.b; + $.alpha = (c) => c.a; $.lightness = (c) => { - return ((0.2126 * c._r + 0.7152 * c._g + 0.0722 * c._b) * 100) / 255; + return ((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * 100) / 255; }; $.lerpColor = (a, b, t) => { @@ -955,7 +958,7 @@ function Q5(scope, parent) { $._doStroke = true; $._strokeSet = true; if (!c._q5Color) c = $.color(...arguments); - if (c._a <= 0) return ($._doStroke = false); + if (c.a <= 0) return ($._doStroke = false); ctx.strokeStyle = c; }; $.noStroke = () => ($._doStroke = false); @@ -963,7 +966,7 @@ function Q5(scope, parent) { $._doFill = true; $._fillSet = true; if (!c._q5Color) c = $.color(...arguments); - if (c._a <= 0) return ($._doFill = false); + if (c.a <= 0) return ($._doFill = false); ctx.fillStyle = c; }; $.noFill = () => ($._doFill = false); @@ -1349,7 +1352,7 @@ function Q5(scope, parent) { let drawable = img._q5 ? img.canvas : img; function reset() { if (!img._q5 || !$._tint) return; - let c = img.canvas.getContext('2d'); + let c = img.ctx; c.save(); c.resetTransform(); c.clearRect(0, 0, c.canvas.width, c.canvas.height); @@ -1391,7 +1394,7 @@ function Q5(scope, parent) { $.loadImage = (url, cb) => { preloadCnt++; let g = $.createImage(1, 1); - let c = g.canvas.getContext('2d'); + let c = g.ctx; let img = new window.Image(); img.src = url; img.crossOrigin = 'Anonymous'; @@ -1915,6 +1918,7 @@ function Q5(scope, parent) { // ENVIRONMENT $.print = console.log; + $.describe = () => {}; function _draw() { let pre = performance.now(); @@ -2143,34 +2147,32 @@ function Q5(scope, parent) { (A[8] * v[0] + A[9] * v[1] + A[10] * v[2] + A[11]) / (A[12] * v[0] + A[13] * v[1] + A[14] * v[2] + A[15]) ]; - if (typeof window != 'undefined') { - window.ondeviceorientation = (e) => { - $.pRotationX = $.rotationX; - $.pRotationY = $.rotationY; - $.pRotationZ = $.rotationZ; - $.pRelRotationX = $.relRotationX; - $.pRelRotationY = $.relRotationY; - $.pRelRotationZ = $.relRotationZ; - - $.rotationX = e.beta * (Math.PI / 180.0); - $.rotationY = e.gamma * (Math.PI / 180.0); - $.rotationZ = e.alpha * (Math.PI / 180.0); - $.relRotationX = [-$.rotationY, -$.rotationX, $.rotationY][Math.trunc(window.orientation / 90) + 1]; - $.relRotationY = [-$.rotationX, $.rotationY, $.rotationX][Math.trunc(window.orientation / 90) + 1]; - $.relRotationZ = $.rotationZ; - }; - window.ondevicemotion = (e) => { - $.pAccelerationX = $.accelerationX; - $.pAccelerationY = $.accelerationY; - $.pAccelerationZ = $.accelerationZ; - if (!e.acceleration) { - let grav = TRFM(MULT(ROTY($.rotationY), ROTX($.rotationX)), [0, 0, -9.80665]); - $.accelerationX = e.accelerationIncludingGravity.x + grav[0]; - $.accelerationY = e.accelerationIncludingGravity.y + grav[1]; - $.accelerationZ = e.accelerationIncludingGravity.z - grav[2]; - } - }; - } + window.ondeviceorientation = (e) => { + $.pRotationX = $.rotationX; + $.pRotationY = $.rotationY; + $.pRotationZ = $.rotationZ; + $.pRelRotationX = $.relRotationX; + $.pRelRotationY = $.relRotationY; + $.pRelRotationZ = $.relRotationZ; + + $.rotationX = e.beta * (Math.PI / 180.0); + $.rotationY = e.gamma * (Math.PI / 180.0); + $.rotationZ = e.alpha * (Math.PI / 180.0); + $.relRotationX = [-$.rotationY, -$.rotationX, $.rotationY][Math.trunc(window.orientation / 90) + 1]; + $.relRotationY = [-$.rotationX, $.rotationY, $.rotationX][Math.trunc(window.orientation / 90) + 1]; + $.relRotationZ = $.rotationZ; + }; + window.ondevicemotion = (e) => { + $.pAccelerationX = $.accelerationX; + $.pAccelerationY = $.accelerationY; + $.pAccelerationZ = $.accelerationZ; + if (!e.acceleration) { + let grav = TRFM(MULT(ROTY($.rotationY), ROTX($.rotationX)), [0, 0, -9.80665]); + $.accelerationX = e.accelerationIncludingGravity.x + grav[0]; + $.accelerationY = e.accelerationIncludingGravity.y + grav[1]; + $.accelerationZ = e.accelerationIncludingGravity.z - grav[2]; + } + }; // TIME @@ -2618,9 +2620,9 @@ for (let k of ['fromAngle', 'fromAngles', 'random2D', 'random3D']) { // IMAGE CLASS class _Q5Image extends Q5 { - constructor(width, height) { + constructor(w, h) { super('image'); - this.createCanvas(width, height); + this.createCanvas(w, h); delete this.createCanvas; this._loop = false; } @@ -2634,15 +2636,23 @@ class _Q5Image extends Q5 { // Q5 +if (typeof window == 'undefined') { + throw 'q5 requires you to define a window object.'; +} + Q5.canvasOptions = { alpha: false, desynchronized: true, colorSpace: 'display-p3' }; -if (typeof matchMedia == 'undefined' || !matchMedia('(dynamic-range: high) and (color-gamut: p3)').matches) { +if (!window.matchMedia || !matchMedia('(dynamic-range: high) and (color-gamut: p3)').matches) { Q5.canvasOptions.colorSpace = 'srgb'; -} +} else Q5.supportsHDR = true; + +window.OffscreenCanvas ??= function () { + return document.createElement('canvas'); +}; Q5._instanceCount = 0; Q5._friendlyError = (msg, func) => { diff --git a/q5.min.js b/q5.min.js index c51a9a3..706c27e 100644 --- a/q5.min.js +++ b/q5.min.js @@ -4,4 +4,4 @@ * @author quinton-ashley and LingDong- * @license AGPL-3.0 */ -function Q5(e,t){let a=0;if(e||(e="global",a++,setTimeout((()=>a--),32)),"auto"==e){if("object"!=typeof window||!window.setup&&!window.draw)return;e="global"}"global"==e&&(Q5._hasGlobal=!0);let o=this;if(o.canvas=document.createElement("canvas"),o.canvas.id="defaultCanvas"+Q5._instanceCount++,o.canvas.classList.add("p5Canvas","q5Canvas"),o.width=100,o.height=100,o.canvas.width=o.width,o.canvas.height=o.height,o._windowResizedFn=()=>{},"graphics"!=e&&"image"!=e){function n(){t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),o.canvas.parent(t)}o._setupDone=!1,o._resize=()=>{o.frameCount>1&&(o._shouldResize=!0)},t&&"string"==typeof t&&(t=document.getElementById(t)),o.canvas.parent=e=>{"string"==typeof e&&(e=document.getElementById(e)),e.append(o.canvas),"undefined"!=typeof ResizeObserver?(o._ro&&o._ro.disconnect(),o._ro=new ResizeObserver(o._resize),o._ro.observe(t)):0==o.frameCount&&addEventListener("resize",o._resize)},document.body?n():document.addEventListener("DOMContentLoaded",n)}o._q5=!0,o.pixels=[];let i,r=null;o.createCanvas=function(t,a,n,r){if("webgl"==n)throw"webgl renderer is not supported in q5, use '2d'";o.width=t,o.height=a,o.canvas.width=t,o.canvas.height=a,o.canvas.renderer="2d";let s=Object.assign({},Q5.canvasOptions);if(r&&Object.assign(s,r),i=o.ctx=o.drawingContext=o.canvas.getContext("2d",s),"global"==e&&(window.ctx=window.drawingContext=i),Object.assign(o.canvas,s),i.fillStyle="white",i.strokeStyle="black",i.lineCap="round",i.lineJoin="miter",i.textAlign="left",i.save(),"image"!=e){let t=o.displayDensity();"graphics"==e&&(t=this._pixelDensity),o.pixelDensity(Math.ceil(t))}else this._pixelDensity=1;return o.canvas},o._createCanvas=o.createCanvas,o.loadPixels=()=>{r=i.getImageData(0,0,o.canvas.width,o.canvas.height),o.pixels=r.data},o.updatePixels=()=>{null!=r&&i.putImageData(r,0,0)};let s={};function l(e,t){null==f&&(f=document.createElement("canvas").getContext("2d")),t??=e||i.canvas.height,e??=i.canvas.width,f.canvas.width==e&&f.canvas.height==t||(f.canvas.width=e,f.canvas.height=t)}function h(){let e=i.canvas.width*i.canvas.height*4;x&&e==x.length||(x=new Uint8ClampedArray(e))}function c(e){f.clearRect(0,0,f.canvas.width,f.canvas.height),f.filter=e,f.drawImage(i.canvas,0,0),i.save(),i.resetTransform(),i.clearRect(0,0,i.canvas.width,i.canvas.height),i.drawImage(f.canvas,0,0),i.restore()}function d(e,t){let a=i.getImageData(0,0,i.canvas.width,i.canvas.height);s[e](a.data,t),i.putImageData(a,0,0)}s[o.THRESHOLD]=(e,t)=>{void 0===t?t=127.5:t*=255;for(let a=0;a=t?255:0}},s[o.GRAY]=e=>{for(let t=0;t{for(let t=0;t{for(let t=0;t{let a=t-1;for(let o=0;o>8)/a,e[o+1]=255*(e[o+1]*t>>8)/a,e[o+2]=255*(e[o+2]*t>>8)/a},s[o.DILATE]=e=>{h(),x.set(e);let[t,a]=[i.canvas.width,i.canvas.height];for(let o=0;o{h(),x.set(e);let[t,a]=[i.canvas.width,i.canvas.height];for(let o=0;o{t=t||1,t=Math.floor(t*o._pixelDensity),h(),x.set(e);let a=2*t+1;let n=function(e){let a=new Float32Array(e),o=.3*t+.8,n=o*o*2;for(let t=0;t{if(!i.filter)return d(e,t);if(l(),"string"==typeof e)c(e);else if(e==o.THRESHOLD){t??=.5,t=Math.max(t,1e-5),c(`saturate(0%) brightness(${Math.floor(.5/t*100)}%) contrast(1000000%)`)}else e==o.GRAY?c("saturate(0%)"):e==o.OPAQUE?(f.fillStyle="black",f.fillRect(0,0,f.canvas.width,f.canvas.height),f.drawImage(i.canvas,0,0),i.save(),i.resetTransform(),i.drawImage(f.canvas,0,0),i.restore()):e==o.INVERT?c("invert(100%)"):e==o.BLUR?c(`blur(${Math.ceil(t*o._pixelDensity/1)||1}px)`):d(e,t)},o.resize=(e,t)=>{l(),f.drawImage(i.canvas,0,0),o.width=e,o.height=t,i.canvas.width=e*o._pixelDensity,i.canvas.height=t*o._pixelDensity,i.save(),i.resetTransform(),i.clearRect(0,0,i.canvas.width,i.canvas.height),i.drawImage(f.canvas,0,0,i.canvas.width,i.canvas.height),i.restore()},o.get=(e,t,a,n)=>{let r=o._pixelDensity||1;if(void 0!==e&&void 0===a){let a=i.getImageData(e*r,t*r,1,1).data;return new o.Color(a[0],a[1],a[2],a[3]/255)}e=(e||0)*r,t=(t||0)*r;let s=a=a||o.width,l=n=n||o.height;a*=r,n*=r;let h=o.createImage(a,n),c=i.getImageData(e,t,a,n);return h.canvas.getContext("2d").putImageData(c,0,0),h._pixelDensity=r,h.width=s,h.height=l,h},o.set=(e,t,a)=>{if(a._q5){let n=o._tint;return o._tint=null,o.image(a,e,t),void(o._tint=n)}let n=o._pixelDensity||1;for(let r=0;r{o._tint=e._q5Color?e:o.color(...arguments)},o.noTint=()=>o._tint=null,o.mask=e=>{i.save(),i.resetTransform();let t=i.globalCompositeOperation;i.globalCompositeOperation="destination-in",i.drawImage(e.canvas,0,0),i.globalCompositeOperation=t,i.restore()},o._save=(e,t,a)=>{if(t=t||"untitled","jpg"==(a=a||"png")||"png"==a)e=e.toDataURL();else{let t="text/plain";"json"==a&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),e=new Blob([e],{type:t}),e=URL.createObjectURL(e)}let o=document.createElement("a");o.href=e,o.download=t+"."+a,document.body.append(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(o.href)},o.save=(e,t,a)=>{if((!e||"string"==typeof e&&(!t||!a&&t.length<5))&&(a=t,t=e,e=i.canvas),a)return o._save(e,t,a);t?(t=t.split("."),o._save(e,t[0],t.at(-1))):o._save(e)},o.canvas.save=o.save,o.saveCanvas=o.save;let u=null,_=!0,g=[],p={},m=0,f=null,v=null,x=null;if("image"==e)return;function y(){let e={};for(let t in i)"function"!=typeof i[t]&&(e[t]=i[t]);return delete e.canvas,e}o.RGB="rgb",o.RGBA="rgb",o.HSB="hsb",o.CHORD=0,o.PIE=1,o.OPEN=2,o.RADIUS="radius",o.CORNER="corner",o.CORNERS="corners",o.ROUND="round",o.SQUARE="butt",o.PROJECT="square",o.MITER="miter",o.BEVEL="bevel",o.CLOSE=1,o.BLEND="source-over",o.REMOVE="destination-out",o.ADD="lighter",o.DARKEST="darken",o.LIGHTEST="lighten",o.DIFFERENCE="difference",o.SUBTRACT="subtract",o.EXCLUSION="exclusion",o.MULTIPLY="multiply",o.SCREEN="screen",o.REPLACE="copy",o.OVERLAY="overlay",o.HARD_LIGHT="hard-light",o.SOFT_LIGHT="soft-light",o.DODGE="color-dodge",o.BURN="color-burn",o.NORMAL="normal",o.ITALIC="italic",o.BOLD="bold",o.BOLDITALIC="italic bold",o.CENTER="center",o.LEFT="left",o.RIGHT="right",o.TOP="top",o.BOTTOM="bottom",o.BASELINE="alphabetic",o.LANDSCAPE="landscape",o.PORTRAIT="portrait",o.ALT=18,o.BACKSPACE=8,o.CONTROL=17,o.DELETE=46,o.DOWN_ARROW=40,o.ENTER=13,o.ESCAPE=27,o.LEFT_ARROW=37,o.OPTION=18,o.RETURN=13,o.RIGHT_ARROW=39,o.SHIFT=16,o.TAB=9,o.UP_ARROW=38,o.DEGREES="degrees",o.RADIANS="radians",o.HALF_PI=Math.PI/2,o.PI=Math.PI,o.QUARTER_PI=Math.PI/4,o.TAU=2*Math.PI,o.TWO_PI=2*Math.PI,o.THRESHOLD=1,o.GRAY=2,o.OPAQUE=3,o.INVERT=4,o.POSTERIZE=5,o.DILATE=6,o.ERODE=7,o.BLUR=8,o.ARROW="default",o.CROSS="crosshair",o.HAND="pointer",o.MOVE="move",o.TEXT="text",o.VIDEO={video:!0,audio:!1},o.AUDIO={video:!1,audio:!0},o.SHR3=1,o.LCG=2,o.hint=(e,t)=>{o[e]=t},o.frameCount=0,o.deltaTime=16,o.mouseX=0,o.mouseY=0,o.touches=[],o.mouseButton=null,o.keyIsPressed=!1,o.mouseIsPressed=!1,o.key=null,o.keyCode=null,o.accelerationX=0,o.accelerationY=0,o.accelerationZ=0,o.rotationX=0,o.rotationY=0,o.rotationZ=0,o.relRotationX=0,o.relRotationY=0,o.relRotationZ=0,o.pmouseX=0,o.pmouseY=0,o.pAccelerationX=0,o.pAccelerationY=0,o.pAccelerationZ=0,o.pRotationX=0,o.pRotationY=0,o.pRotationZ=0,o.pRelRotationX=0,o.pRelRotationY=0,o.pRelRotationZ=0,Object.defineProperty(o,"deviceOrientation",{get:()=>window.screen?.orientation?.type}),Object.defineProperty(o,"windowWidth",{get:()=>window.innerWidth}),Object.defineProperty(o,"windowHeight",{get:()=>window.innerHeight}),o._colorMode="rgb",o._doStroke=!0,o._doFill=!0,o._strokeSet=!1,o._fillSet=!1,o._tint=null,o._ellipseMode=o.CENTER,o._rectMode=o.CORNER,o._curveDetail=20,o._curveAlpha=0,o._loop=!0,o._textFont="sans-serif",o._textSize=12,o._textLeading=15,o._textLeadDiff=3,o._textStyle="normal",o._pixelDensity=1,o._lastFrameTime=0,o._targetFrameRate=null,o._frameRate=o._fps=60,o.resizeCanvas=(t,a)=>{o.width=t,o.height=a;let n=y();o.canvas.width=t*o._pixelDensity,o.canvas.height=a*o._pixelDensity;for(let e in n)o.ctx[e]=n[e];"image"!=e&&o.pixelDensity(o._pixelDensity)},o.createGraphics=function(e,t){let a=new Q5("graphics");return a._createCanvas.call(o,e,t),a},o.createImage=(e,t)=>new Q5.Image(e,t),o.displayDensity=()=>window.devicePixelRatio,o.pixelDensity=e=>{if(void 0===e)return o._pixelDensity;o._pixelDensity=e;let t=y();o.canvas.width=Math.ceil(o.width*e),o.canvas.height=Math.ceil(o.height*e),o.canvas.style.width=o.width+"px",o.canvas.style.height=o.height+"px";for(let e in t)o.ctx[e]=t[e];return i.scale(o._pixelDensity,o._pixelDensity),o._pixelDensity},o.map=(e,t,a,o,n,i)=>{let r=o+1*(e-t)/(a-t)*(n-o);return i?oe*(1-a)+t*a,o.constrain=(e,t,a)=>Math.min(Math.max(e,t),a),o.dist=function(){return 4==arguments.length?Math.hypot(arguments[0]-arguments[2],arguments[1]-arguments[3]):Math.hypot(arguments[0]-arguments[3],arguments[1]-arguments[4],arguments[2]-arguments[5])},o.norm=(e,t,a)=>o.map(e,t,a,0,1),o.sq=e=>e*e,o.fract=e=>e-Math.floor(e),o.angleMode=e=>o._angleMode=e,o._DEGTORAD=Math.PI/180,o._RADTODEG=180/Math.PI,o.degrees=e=>e*o._RADTODEG,o.radians=e=>e*o._DEGTORAD,o.abs=Math.abs,o.ceil=Math.ceil,o.exp=Math.exp,o.floor=Math.floor,o.log=Math.log,o.mag=Math.hypot,o.max=Math.max,o.min=Math.min,o.round=Math.round,o.pow=Math.pow,o.sqrt=Math.sqrt,o.sin=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.sin(e)),o.cos=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.cos(e)),o.tan=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.tan(e)),o.asin=e=>{let t=Math.asin(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.acos=e=>{let t=Math.acos(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.atan=e=>{let t=Math.atan(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.atan2=(e,t)=>{let a=Math.atan2(e,t);return"degrees"==o._angleMode&&(a=o.degrees(a)),a},o.nf=(e,t,a)=>{let o=e<0,n=e.toString();return o&&(n=n.slice(1)),n=n.padStart(t,"0"),a>0&&(-1==n.indexOf(".")&&(n+="."),n=n.padEnd(t+1+a,"0")),o&&(n="-"+n),n},o.createVector=(e,t,a)=>new Q5.Vector(e,t,a,o),o.curvePoint=(e,t,a,o,n)=>{const i=n*n*n,r=n*n;return e*(-.5*i+r-.5*n)+t*(1.5*i-2.5*r+1)+a*(-1.5*i+2*r+.5*n)+o*(.5*i-.5*r)},o.bezierPoint=(e,t,a,o,n)=>{const i=1-n;return Math.pow(i,3)*e+3*Math.pow(i,2)*n*t+3*i*Math.pow(n,2)*a+Math.pow(n,3)*o},o.curveTangent=(e,t,a,o,n)=>{const i=n*n;return e*(-3*i/2+2*n-.5)+t*(9*i/2-5*n)+a*(-9*i/2+4*n+.5)+o*(3*i/2-n)},o.bezierTangent=(e,t,a,o,n)=>{const i=1-n;return 3*o*Math.pow(n,2)-3*a*Math.pow(n,2)+6*a*i*n-6*t*i*n+3*t*Math.pow(i,2)-3*e*Math.pow(i,2)},o.Color=Q5.ColorRGBA_P3,o.colorMode=e=>{o._colorMode=e,"oklch"==e?o.Color=Q5.ColorOKLCH:"rgb"==e?"srgb"==o.canvas.colorSpace?o.Color=Q5.ColorRGBA:o.Color=Q5.ColorRGBA_P3:"srgb"==e&&(o.Color=Q5.ColorRGBA,o._colorMode="rgb")};let M={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],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]};function w(e){let t=o._angleMode==o.DEGREES?180:Math.PI,a=2*t;if(0<=e&&e<=a)return e;for(;e<0;)e+=a;for(;e>=t;)e-=a;return e}function R(e,t,a,n,r,s,l,h){if(!o._doFill&&!o._doStroke)return;let c=w(r),d=w(s);if(c>d&&([c,d]=[d,c]),0==c){if(0==d)return;if(o._angleMode==o.DEGREES&&360==d||d==o.TAU)return o.ellipse(e,t,a,n)}i.beginPath();for(let r=0;re._r,o.green=e=>e._g,o.blue=e=>e._b,o.alpha=e=>e._a,o.lightness=e=>100*(.2126*e._r+.7152*e._g+.0722*e._b)/255,o.lerpColor=(e,t,a)=>{if("rgb"==o._colorMode)return new o.Color(o.constrain(o.lerp(e.r,t.r,a),0,255),o.constrain(o.lerp(e.g,t.g,a),0,255),o.constrain(o.lerp(e.b,t.b,a),0,255),o.constrain(o.lerp(e.a,t.a,a),0,255));{let n=t.h-e.h;n>180&&(n-=360),n<-180&&(n+=360);let i=e.h+a*n;return i<0&&(i+=360),i>360&&(i-=360),new o.Color(o.constrain(o.lerp(e.l,t.l,a),0,100),o.constrain(o.lerp(e.c,t.c,a),0,100),i,o.constrain(o.lerp(e.a,t.a,a),0,255))}},o.strokeWeight=e=>{e||(o._doStroke=!1),i.lineWidth=e||1e-4},o.stroke=function(e){if(o._doStroke=!0,o._strokeSet=!0,e._q5Color||(e=o.color(...arguments)),e._a<=0)return o._doStroke=!1;i.strokeStyle=e},o.noStroke=()=>o._doStroke=!1,o.fill=function(e){if(o._doFill=!0,o._fillSet=!0,e._q5Color||(e=o.color(...arguments)),e._a<=0)return o._doFill=!1;i.fillStyle=e},o.noFill=()=>o._doFill=!1,o.smooth=()=>o._smooth=!0,o.noSmooth=()=>o._smooth=!1,o.blendMode=e=>i.globalCompositeOperation=e,o.strokeCap=e=>i.lineCap=e,o.strokeJoin=e=>i.lineJoin=e,o.ellipseMode=e=>o._ellipseMode=e,o.rectMode=e=>o._rectMode=e,o.curveDetail=e=>o._curveDetail=e,o.curveAlpha=e=>o._curveAlpha=e,o.curveTightness=e=>o._curveAlpha=e,o.clear=()=>{i.clearRect(0,0,o.canvas.width,o.canvas.height)},o.background=function(e){if(e._q5)return o.image(e,0,0,o.width,o.height);i.save(),i.resetTransform(),e._q5color||(e=o.color(...arguments)),i.fillStyle=e,i.fillRect(0,0,o.canvas.width,o.canvas.height),i.restore()},o.line=(e,t,a,n)=>{o._doStroke&&(i.beginPath(),i.moveTo(e,t),i.lineTo(a,n),i.stroke())},o.arc=(e,t,a,n,i,r,s,l)=>{if(i==r)return o.ellipse(e,t,a,n);l??=25,s??=o.PIE,o._ellipseMode==o.CENTER?R(e,t,a,n,i,r,s,l):o._ellipseMode==o.RADIUS?R(e,t,2*a,2*n,i,r,s,l):o._ellipseMode==o.CORNER?R(e+a/2,t+n/2,a,n,i,r,s,l):o._ellipseMode==o.CORNERS&&R((e+a)/2,(t+n)/2,a-e,n-t,i,r,s,l)},o.ellipse=(e,t,a,n)=>{n??=a,o._ellipseMode==o.CENTER?S(e,t,a,n):o._ellipseMode==o.RADIUS?S(e,t,2*a,2*n):o._ellipseMode==o.CORNER?S(e+a/2,t+n/2,a,n):o._ellipseMode==o.CORNERS&&S((e+a)/2,(t+n)/2,a-e,n-t)},o.circle=(e,t,a)=>o.ellipse(e,t,a,a),o.point=(e,t)=>{e.x&&(t=e.y,e=e.x),i.beginPath(),i.ellipse(e,t,.4,.4,0,0,o.TAU),i.stroke()},o.rect=(e,t,a,n,i,r,s,l)=>{o._rectMode==o.CENTER?C(e-a/2,t-n/2,a,n,i,r,s,l):o._rectMode==o.RADIUS?C(e-a,t-n,2*a,2*n,i,r,s,l):o._rectMode==o.CORNER?C(e,t,a,n,i,r,s,l):o._rectMode==o.CORNERS&&C(e,t,a-e,n-t,i,r,s,l)},o.square=(e,t,a,n,i,r,s)=>o.rect(e,t,a,a,n,i,r,s),o.beginShape=()=>{b(),i.beginPath(),_=!0},o.beginContour=()=>{i.closePath(),b(),_=!0},o.endContour=()=>{b(),_=!0},o.vertex=(e,t)=>{b(),_?i.moveTo(e,t):i.lineTo(e,t),_=!1},o.bezierVertex=(e,t,a,o,n,r)=>{b(),i.bezierCurveTo(e,t,a,o,n,r)},o.quadraticVertex=(e,t,a,o)=>{b(),i.quadraticCurveTo(e,t,a,o)},o.bezier=(e,t,a,n,i,r,s,l)=>{o.beginShape(),o.vertex(e,t),o.bezierVertex(a,n,i,r,s,l),o.endShape()},o.triangle=(e,t,a,n,i,r)=>{o.beginShape(),o.vertex(e,t),o.vertex(a,n),o.vertex(i,r),o.endShape(o.CLOSE)},o.quad=(e,t,a,n,i,r,s,l)=>{o.beginShape(),o.vertex(e,t),o.vertex(a,n),o.vertex(i,r),o.vertex(s,l),o.endShape(o.CLOSE)},o.endShape=e=>{b(),e&&i.closePath(),o._doFill&&i.fill(),o._doStroke&&i.stroke(),o._doFill||o._doStroke||(i.save(),i.fillStyle="none",i.fill(),i.restore())},o.curveVertex=(e,t)=>{if(g.push([e,t]),g.length<4)return;let a=function(e,t,a,o,n,i,r,s,l,h){function c(e,t,a,o,n,i){let r=Math.pow(o-t,2)+Math.pow(n-a,2);return Math.pow(r,.5*i)+e}let d=[],u=c(0,e,t,a,o,h),_=c(u,a,o,n,i,h),g=c(_,n,i,r,s,h);for(let h=0;h0?(p[e]=1,p[e+1]=0):(p[e]=0,p[e+1]=1));let m=e*p[0]+a*p[1],f=t*p[0]+o*p[1],v=a*p[2]+n*p[3],x=o*p[2]+i*p[3],y=n*p[4]+r*p[5],M=i*p[4]+s*p[5],w=m*p[6]+v*p[7],R=f*p[6]+x*p[7],S=v*p[8]+y*p[9],C=x*p[8]+M*p[9],b=w*p[2]+S*p[3],E=R*p[2]+C*p[3];d.push([b,E])}return d}(...g[g.length-4],...g[g.length-3],...g[g.length-2],...g[g.length-1],o._curveDetail,o._curveAlpha);for(let e=0;e{o.beginShape(),o.curveVertex(e,t),o.curveVertex(a,n),o.curveVertex(i,r),o.curveVertex(s,l),o.endShape()},o.opacity=e=>i.globalAlpha=e,o.translate=(e,t)=>i.translate(e,t),o.rotate=e=>{"degrees"==o._angleMode&&(e=o.radians(e)),i.rotate(e)},o.scale=(e,t)=>{t??=e,i.scale(e,t)},o.applyMatrix=(e,t,a,o,n,r)=>i.transform(e,t,a,o,n,r),o.shearX=e=>i.transform(1,0,o.tan(e),1,0,0),o.shearY=e=>i.transform(1,o.tan(e),0,1,0,0),o.resetMatrix=()=>{i.resetTransform(),i.scale(o._pixelDensity,o._pixelDensity)},o._styleNames=["_doStroke","_doFill","_strokeSet","_fillSet","_tint","_imageMode","_rectMode","_ellipseMode","_textFont","_textLeading","_leadingSet","_textSize","_textAlign","_textBaseline","_textStyle","_textWrap"],o._styles=[],o.push=o.pushMatrix=()=>{i.save();let e={};for(let t of o._styleNames)e[t]=o[t];o._styles.push(e)},o.pop=o.popMatrix=()=>{i.restore();let e=o._styles.pop();for(let t of o._styleNames)o[t]=e[t]},o.imageMode=e=>o._imageMode=e,o.image=(e,t,a,n,r,s,l,h,c)=>{let d=e._q5?e.canvas:e;var u,_;e._q5&&null!=o._tint&&(u=e.canvas.width,_=e.canvas.height,null==v&&(v=document.createElement("canvas").getContext("2d")),_??=u||i.canvas.height,u??=i.canvas.width,v.canvas.width==u&&v.canvas.height==_||(v.canvas.width=u,v.canvas.height=_),v.drawImage(e.canvas,0,0),e.tinted(o._tint)),n||(e._q5||e.width?(n=e.width,r=e.height):(n=e.videoWidth,r=e.videoHeight)),"center"==o._imageMode&&(t-=.5*n,a-=.5*r);let g=e._pixelDensity;s??=0,l??=0,h?h*=g:h=d.width,c?c*=g:c=d.height,i.drawImage(d,s*g,l*g,h,c,t,a,n,r),function(){if(!e._q5||!o._tint)return;let t=e.canvas.getContext("2d");t.save(),t.resetTransform(),t.clearRect(0,0,t.canvas.width,t.canvas.height),t.drawImage(v.canvas,0,0),t.restore()}()},o._incrementPreload=()=>a++,o._decrementPreload=()=>a--,o.loadImage=(e,t)=>{a++;let n=o.createImage(1,1),i=n.canvas.getContext("2d"),r=new window.Image;return r.src=e,r.crossOrigin="Anonymous",r._pixelDensity=1,r.onload=()=>{n.width=i.canvas.width=r.naturalWidth,n.height=i.canvas.height=r.naturalHeight,i.drawImage(r,0,0),a--,t&&t(n)},r.onerror=e=>{throw a--,e},n},o._clearTemporaryBuffers=()=>{f=null,v=null,x=null},o.loadFont=(e,t)=>{a++;let o=e.split("/"),n=o[o.length-1].split(".")[0].replace(" ",""),i=new FontFace(n,"url("+e+")");return document.fonts.add(i),i.load().then((()=>{a--,t&&t(n)})),n},o.textFont=e=>o._textFont=e,o.textSize=e=>{if(void 0===e)return o._textSize;o._textSize=e,o._leadingSet||(o._textLeading=1.25*e,o._textLeadDiff=o._textLeading-e)},o.textLeading=e=>{if(void 0===e)return o._textLeading;o._textLeading=e,o._textLeadDiff=e-o._textSize,o._leadingSet=!0},o.textStyle=e=>o._textStyle=e,o.textAlign=(e,t)=>{i.textAlign=e,t&&(i.textBaseline=t==o.CENTER?"middle":t)},o.textWidth=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).width),o.textAscent=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).actualBoundingBoxAscent),o.textDescent=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).actualBoundingBoxDescent),o._textCache=!0,o._TimedCache=class extends Map{constructor(){super(),this.maxSize=500}set(e,t){t.lastAccessed=Date.now(),super.set(e,t),this.size>this.maxSize&&this.gc()}get(e){const t=super.get(e);return t&&(t.lastAccessed=Date.now()),t}gc(){let e,t=1/0,a=0;for(const[o,n]of this.entries())n.lastAccessed(t&&(o._tic.maxSize=t),void 0!==e&&(o._textCache=e),o._textCache),o.createTextImage=(e,t,a)=>{let n=o._textCache;o._textCache=!0,o._useCache=!0,o.text(e,0,0,t,a),o._useCache=!1;let i=E(e,t,a);return o._textCache=n,o._tic.get(i)},o.text=(e,t,a,n,r)=>{if(void 0===e)return;if(e=e.toString(),!o._doFill&&!o._doStroke)return;let s,l,h,c,d,u,_,g,p=1,m=i.getTransform(),f=o._useCache||o._textCache&&(0!=m.b||0!=m.c);if(f){if(c=E(e,n,r),l=o._tic.get(c),l)return void o.textImage(l,t,a);h=o.createGraphics.call(o,1,1),s=h.ctx,p=o._pixelDensity}else s=i,d=t,u=a;s.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`;let v=e.split("\n");if(f){d=0,u=o._textLeading*v.length;let t=s.measureText(" ");_=t.fontBoundingBoxAscent,g=t.fontBoundingBoxDescent,r??=u+g,h.resizeCanvas(Math.ceil(s.measureText(e).width),Math.ceil(r)),s.fillStyle=i.fillStyle,s.strokeStyle=i.strokeStyle,s.lineWidth=i.lineWidth}let x=s.fillStyle;o._fillSet||(s.fillStyle="black");for(let e=0;er));e++);o._fillSet||(s.fillStyle=x),f&&(l=h.get(),l._ascent=_,l._descent=g,o._tic.set(c,l),o.textImage(l,t,a))},o.textImage=(e,t,a)=>{let n=o._imageMode;o._imageMode="corner","center"==i.textAlign?t-=.5*e.width:"right"==i.textAlign&&(t-=e.width),"alphabetic"==i.textBaseline&&(a-=o._textLeading),"middle"==i.textBaseline?a-=e._descent+.5*e._ascent+o._textLeadDiff:"bottom"==i.textBaseline?a-=e._ascent+e._descent+o._textLeadDiff:"top"==i.textBaseline&&(a-=e._descent+o._textLeadDiff),o.image(e,t,a),o._imageMode=n};var D,I=4095,T=4,A=.5,O=e=>.5*(1-Math.cos(e*Math.PI));o.noise=(e,t,a)=>{if(t??=0,a??=0,null==D){D=new Array(4096);for(var o=0;o<4096;o++)D[o]=Math.random()}e<0&&(e=-e),t<0&&(t=-t),a<0&&(a=-a);for(var n,i,r,s,l,h=Math.floor(e),c=Math.floor(t),d=Math.floor(a),u=e-h,_=t-c,g=a-d,p=0,m=.5,f=0;f=1&&(h++,u--),(_*=2)>=1&&(c++,_--),(g*=2)>=1&&(d++,g--)}return p},o.noiseDetail=(e,t)=>{e>0&&(T=e),t>0&&(A=t)};const P=()=>{let e,t,a=4294967295;return{setSeed(o){e=t=(null==o?Math.random()*a:o)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/a)}};let k=P();k.setSeed(),o.noiseSeed=e=>{let t=void 0===e?4294967295*Math.random():e;D||(D=new Float32Array(4096));for(var a=0;a<4096;a++)t^=t<<17,t^=t>>13,t^=t<<5,D[a]=(t>>>0)/4294967295},o.randomSeed=e=>k.setSeed(e),o.random=(e,t)=>void 0===e?k.rand():"number"==typeof e?void 0!==t?k.rand()*(t-e)+e:k.rand()*e:e[Math.trunc(e.length*k.rand())],o.randomGenerator=e=>{e==o.LCG?k=(()=>{const e=4294967296;let t,a;return{setSeed(o){a=t=(null==o?Math.random()*e:o)>>>0},getSeed:()=>t,rand:()=>(a=(1664525*a+1013904223)%e,a/e)}})():e==o.SHR3&&(k=P()),k.setSeed()};var z=new function(){var e,t,a,o=new Array(128),n=new Array(256),i=new Array(128),r=new Array(128),s=new Array(256),l=new Array(256),h=()=>4294967296*k.rand()-2147483648,c=()=>.5+2.328306e-10*(h()<<0),d=()=>{for(var t,n,s,l,d=3.44262;;){if(t=a*i[e],0==e){do{s=c(),l=c(),t=.2904764*-Math.log(s),n=-Math.log(l)}while(n+n0?d+t:-d-t}if(r[e]+c()*(r[e-1]-r[e]){for(var a;;){if(0==e)return 7.69711-Math.log(c());if(a=t*s[e],l[e]+c()*(l[e-1]-l[e])(a=h(),e=127&a,Math.abs(a)(t=h()>>>0){var e,t,a=2147483648,h=4294967296,c=3.442619855899,d=c,u=.00991256303526217,_=7.697117470131487,g=_,p=.003949659822581572;for(e=u/Math.exp(-.5*c*c),o[0]=Math.floor(c/e*a),o[1]=0,i[0]=e/a,i[127]=c/a,r[0]=1,r[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),o[t+1]=Math.floor(c/d*a),d=c,r[t]=Math.exp(-.5*c*c),i[t]=c/a;for(e=p/Math.exp(-_),n[0]=Math.floor(_/e*h),n[1]=0,s[0]=e/h,s[255]=_/h,l[0]=1,l[255]=Math.exp(-_),t=254;t>=1;t--)_=-Math.log(p/_+Math.exp(-_)),n[t+1]=Math.floor(_/g*h),g=_,l[t]=Math.exp(-_),s[t]=_/h}};function F(){let e=performance.now();if(o._loop)u=o._targetFrameRate?setTimeout(F,1e3/o._targetFrameRate):requestAnimationFrame(F);else if(o.frameCount>0)return;if(u&&0!=o.frameCount){if(e-o._lastFrameTime<1e3/(o._targetFrameRate||60)-5)return}o.deltaTime=e-o._lastFrameTime,o._frameRate=1e3/o.deltaTime,o.frameCount++,o._shouldResize&&(o._windowResizedFn(),o._shouldResize=!1);for(let e of Q5.prototype._methods.pre)e.call(o);b(),_=!0,i.save(),o._drawFn();for(let e of Q5.prototype._methods.post)e.call(o);i.restore(),o.resetMatrix();let t=performance.now();o._fps=Math.round(1e3/(t-e)),o._lastFrameTime=e,o.pmouseX=o.mouseX,o.pmouseY=o.mouseY}function L(e){const t=o.canvas.getBoundingClientRect(),a=o.canvas.scrollWidth/o.width||1,n=o.canvas.scrollHeight/o.height||1;return{x:(e.clientX-t.left)/a,y:(e.clientY-t.top)/n,id:e.identifier}}function Q(){return o._touchStartedFn.isPlaceHolder&&o._touchMovedFn.isPlaceHolder&&o._touchEndedFn.isPlaceHolder}z.hasInit=!1,o.randomGaussian=(e,t)=>(z.hasInit||(z.zigset(),z.hasInit=!0),z.RNOR()*t+e),o.randomExponential=()=>(z.hasInit||(z.zigset(),z.hasInit=!0),z.REXP()),o.Element=function(e){this.elt=e},o._elements=[],o.createCapture=e=>{var t=document.createElement("video");return t.playsinline="playsinline",t.autoplay="autoplay",navigator.mediaDevices.getUserMedia(e).then((e=>{t.srcObject=e})),t.style.position="absolute",t.style.opacity=1e-5,t.style.zIndex=-1e3,document.body.append(t),t},o.print=console.log,o.noLoop=()=>{o._loop=!1,u=null},o.loop=()=>{o._loop=!0,null==u&&F()},o.redraw=()=>F(),o.remove=()=>{o.noLoop(),o.canvas.remove()},o.frameRate=e=>(e&&(o._targetFrameRate=e),o._frameRate),o.getFrameRate=()=>o._frameRate,o.getFPS=()=>o._fps,o.storeItem=localStorage.setItem,o.getItem=localStorage.getItem,o.removeItem=localStorage.removeItem,o.clearStorage=localStorage.clear,o._updateMouse=e=>{let t=o.canvas.getBoundingClientRect(),a=o.canvas.scrollWidth/o.width||1,n=o.canvas.scrollHeight/o.height||1;o.mouseX=(e.clientX-t.left)/a,o.mouseY=(e.clientY-t.top)/n},o._onmousedown=e=>{o._updateMouse(e),o.mouseIsPressed=!0,o.mouseButton=[o.LEFT,o.CENTER,o.RIGHT][e.button],o._mousePressedFn(e)},o._onmousemove=e=>{o._updateMouse(e),o.mouseIsPressed?o._mouseDraggedFn(e):o._mouseMovedFn(e)},o._onmouseup=e=>{o._updateMouse(e),o.mouseIsPressed=!1,o._mouseReleasedFn(e)},o._onclick=e=>{o._updateMouse(e),o.mouseIsPressed=!0,o._mouseClickedFn(e),o.mouseIsPressed=!1},o.cursor=(e,t,a)=>{let n="";e.includes(".")&&(e=`url("${e}")`,n=", auto"),void 0!==t&&(e+=" "+t+" "+a),o.canvas.style.cursor=e+n},o.noCursor=()=>{o.canvas.style.cursor="none"},o._onkeydown=e=>{e.repeat||(o.keyIsPressed=!0,o.key=e.key,o.keyCode=e.keyCode,p[o.keyCode]=!0,o._keyPressedFn(e),1==e.key.length&&o._keyTypedFn(e))},o._onkeyup=e=>{o.keyIsPressed=!1,o.key=e.key,o.keyCode=e.keyCode,p[o.keyCode]=!1,o._keyReleasedFn(e)},o.canvas.onmousedown=e=>o._onmousedown(e),o.canvas.onmouseup=e=>o._onmouseup(e),o.canvas.onclick=e=>o._onclick(e),o.keyIsDown=e=>!!p[e],o._ontouchstart=e=>{o.touches=[...e.touches].map(L),Q()&&(o.mouseX=o.touches[0].x,o.mouseY=o.touches[0].y,o.mouseIsPressed=!0,o.mouseButton=o.LEFT,o._mousePressedFn(e)||e.preventDefault()),o._touchStartedFn(e)||e.preventDefault()},o._ontouchmove=e=>{o.touches=[...e.touches].map(L),Q()&&(o.mouseX=o.touches[0].x,o.mouseY=o.touches[0].y,o._mouseDraggedFn(e)||e.preventDefault()),o._touchMovedFn(e)||e.preventDefault()},o._ontouchend=e=>{o.touches=[...e.touches].map(L),Q()&&!o.touches.length&&(o.mouseIsPressed=!1,o._mouseReleasedFn(e)||e.preventDefault()),o._touchEndedFn(e)||e.preventDefault()},o.canvas.ontouchstart=e=>o._ontouchstart(e),o.canvas.ontouchmove=e=>o._ontouchmove(e),o.canvas.ontouchcancel=o.canvas.ontouchend=e=>o._ontouchend(e),o.hasSensorPermission=!window.DeviceOrientationEvent&&!window.DeviceMotionEvent||!(DeviceOrientationEvent.requestPermission||DeviceMotionEvent.requestPermission),o.requestSensorPermissions=()=>{DeviceOrientationEvent.requestPermission&&DeviceOrientationEvent.requestPermission().then((e=>{"granted"==e&&DeviceMotionEvent.requestPermission&&DeviceMotionEvent.requestPermission().then((e=>{"granted"==e&&(o.hasSensorPermission=!0)})).catch(alert)})).catch(alert)};"undefined"!=typeof window&&(window.ondeviceorientation=e=>{o.pRotationX=o.rotationX,o.pRotationY=o.rotationY,o.pRotationZ=o.rotationZ,o.pRelRotationX=o.relRotationX,o.pRelRotationY=o.relRotationY,o.pRelRotationZ=o.relRotationZ,o.rotationX=e.beta*(Math.PI/180),o.rotationY=e.gamma*(Math.PI/180),o.rotationZ=e.alpha*(Math.PI/180),o.relRotationX=[-o.rotationY,-o.rotationX,o.rotationY][Math.trunc(window.orientation/90)+1],o.relRotationY=[-o.rotationX,o.rotationY,o.rotationX][Math.trunc(window.orientation/90)+1],o.relRotationZ=o.rotationZ},window.ondevicemotion=e=>{if(o.pAccelerationX=o.accelerationX,o.pAccelerationY=o.accelerationY,o.pAccelerationZ=o.accelerationZ,!e.acceleration){let i=((e,t)=>[(e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]),(e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]),(e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15])])((n=o.rotationY,t=[o.cos(n),0,o.sin(n),0,0,1,0,0,-o.sin(n),0,o.cos(n),0,0,0,0,1],a=(e=>[1,0,0,0,0,o.cos(e),-o.sin(e),0,0,o.sin(e),o.cos(e),0,0,0,0,1])(o.rotationX),[t[0]*a[0]+t[1]*a[4]+t[2]*a[8]+t[3]*a[12],t[0]*a[1]+t[1]*a[5]+t[2]*a[9]+t[3]*a[13],t[0]*a[2]+t[1]*a[6]+t[2]*a[10]+t[3]*a[14],t[0]*a[3]+t[1]*a[7]+t[2]*a[11]+t[3]*a[15],t[4]*a[0]+t[5]*a[4]+t[6]*a[8]+t[7]*a[12],t[4]*a[1]+t[5]*a[5]+t[6]*a[9]+t[7]*a[13],t[4]*a[2]+t[5]*a[6]+t[6]*a[10]+t[7]*a[14],t[4]*a[3]+t[5]*a[7]+t[6]*a[11]+t[7]*a[15],t[8]*a[0]+t[9]*a[4]+t[10]*a[8]+t[11]*a[12],t[8]*a[1]+t[9]*a[5]+t[10]*a[9]+t[11]*a[13],t[8]*a[2]+t[9]*a[6]+t[10]*a[10]+t[11]*a[14],t[8]*a[3]+t[9]*a[7]+t[10]*a[11]+t[11]*a[15],t[12]*a[0]+t[13]*a[4]+t[14]*a[8]+t[15]*a[12],t[12]*a[1]+t[13]*a[5]+t[14]*a[9]+t[15]*a[13],t[12]*a[2]+t[13]*a[6]+t[14]*a[10]+t[15]*a[14],t[12]*a[3]+t[13]*a[7]+t[14]*a[11]+t[15]*a[15]]),[0,0,-9.80665]);o.accelerationX=e.accelerationIncludingGravity.x+i[0],o.accelerationY=e.accelerationIncludingGravity.y+i[1],o.accelerationZ=e.accelerationIncludingGravity.z-i[2]}var t,a,n}),o.year=()=>(new Date).getFullYear(),o.day=()=>(new Date).getDay(),o.hour=()=>(new Date).getHours(),o.minute=()=>(new Date).getMinutes(),o.second=()=>(new Date).getSeconds(),o.millis=()=>performance.now()-m,o._loadFile=(e,t,o)=>{a++;let n={};return fetch(e).then((e=>"json"==o?e.json():"text"==o?e.text():void 0)).then((e=>{a--,Object.assign(n,e),t&&t(e)})),n},o.loadStrings=(e,t)=>o._loadFile(e,t,"text"),o.loadJSON=(e,t)=>o._loadFile(e,t,"json"),o.loadSound=(e,t)=>{a++;let o=new Audio(e);return o.addEventListener("canplaythrough",(()=>{a--,t&&t(o)})),o.load(),o.setVolume=e=>o.volume=e,o.setLoop=e=>o.loop=e,o},"global"==e&&(Object.assign(Q5,o),delete Q5.Q5),Q5.Image??=_Q5Image;for(let N of Q5.prototype._methods.init)N.call(o);for(let[B,$]of Object.entries(Q5.prototype))"_"!=B[0]&&"function"==typeof o[B]&&(o[B]=$.bind(o));if("global"==e){let V=Object.getOwnPropertyNames(o);for(let G of V)"function"==typeof o[G]?window[G]=o[G]:Object.defineProperty(window,G,{get:()=>o[G],set:e=>o[G]=e})}function q(){let t="global"==e?window:o,n=["setup","draw","preload","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of n){let a="_"+e+"Fn";o[a]=()=>{},o[a].isPlaceHolder=!0,t[e]?o[a]=t[e]:Object.defineProperty(o,e,{set:e=>{o[a]=e}})}if("graphics"!=e||"image"!=e){o._preloadFn(),m=performance.now(),function e(){if(a>0)return requestAnimationFrame(e);o._setupFn(),i||o.createCanvas(100,100),o._setupDone=!0,i.restore(),o.resetMatrix(),requestAnimationFrame(F)}()}addEventListener("mousemove",(e=>o._onmousemove(e)),!1),addEventListener("keydown",(e=>o._onkeydown(e)),!1),addEventListener("keyup",(e=>o._onkeyup(e)),!1)}"function"==typeof e&&e(o),"global"==e?q():requestAnimationFrame(q)}Q5.Color=class{constructor(){this._q5Color=!0}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,a,o){super(),this.l=e,this.c=t,this.h=a,this.a=o??1}toString(){return`color(oklch ${this.l} ${this.c} ${this.h} / ${this.a})`}},Q5.ColorRGBA=class extends Q5.Color{constructor(e,t,a,o){super(),this.r=e,this.g=t,this.b=a,this.a=o??255}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGBA_P3=class extends Q5.ColorRGBA{constructor(e,t,a,o){super(e,t,a,o),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),a=(this._b/255).toFixed(3),o=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${a} / ${o})`,this._edited=!1}return this._css}},Q5.Vector=class{constructor(e,t,a,o){this.x=e||0,this.y=t||0,this.z=a||0,this._$=o||window,this._cn=null,this._cnsq=null}set(e,t,a){this.x=e||0,this.y=t||0,this.z=a||0}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,a){return void 0!==e.x?e:void 0!==t?{x:e,y:t,z:a||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,a=this.y-e.y,o=this.z-e.z;return Math.sqrt(t*t+a*a+o*o)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,a=this.z*e.x-this.x*e.z,o=this.x*e.y-this.y*e.x;return this.x=t,this.y=a,this.z=o,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 a=e/t;this.x*=a,this.y*=a,this.z*=a,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)}rotate(e){let t=this._$.cos(e),a=this._$.sin(e),o=this.x*t-this.y*a,n=this.x*a+this.y*t;return this.x=o,this.y=n,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=this._arg2v(...e.slice(0,-1)),a=e[e.length-1];return this.x+=(t.x-this.x)*a,this.y+=(t.y-this.y)*a,this.z+=(t.z-this.z)*a,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)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,a)=>e.equals(t,a),Q5.Vector.lerp=(e,t,a)=>e.copy().lerp(t,a),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,a,o)=>(new Q5.Vector)[e](t,a,o);class _Q5Image extends Q5{constructor(e,t){super("image"),this.createCanvas(e,t),delete this.createCanvas,this._loop=!1}get w(){return this.width}get h(){return this.height}}Q5.canvasOptions={alpha:!1,desynchronized:!0,colorSpace:"display-p3"},"undefined"!=typeof matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches||(Q5.canvasOptions.colorSpace="srgb"),Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{throw t+": "+e},Q5._validateParameters=()=>!0,Q5.prototype._methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.prototype._methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],"undefined"!=typeof module?module.exports=Q5:window.p5??=Q5,document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")})); +function Q5(e,t){let a=0;if(e||(e="global",a++,setTimeout((()=>a--),32)),"auto"==e){if(!window.setup&&!window.draw)return;e="global"}"global"==e&&(Q5._hasGlobal=!0);let o=this;if("image"==e||"graphics"==e?o.canvas=new OffscreenCanvas(100,100):(o.canvas=document.createElement("canvas"),o.canvas.id="defaultCanvas"+Q5._instanceCount++,o.canvas.classList.add("p5Canvas","q5Canvas")),o.canvas.width=o.width=100,o.canvas.height=o.height=100,o._windowResizedFn=()=>{},"graphics"!=e&&"image"!=e){function n(){t??=document.getElementsByTagName("main")[0],t||(t=document.createElement("main"),document.body.append(t)),o.canvas.parent(t)}o._setupDone=!1,o._resize=()=>{o.frameCount>1&&(o._shouldResize=!0)},t&&"string"==typeof t&&(t=document.getElementById(t)),o.canvas.parent=e=>{"string"==typeof e&&(e=document.getElementById(e)),e.append(o.canvas),"undefined"!=typeof ResizeObserver?(o._ro&&o._ro.disconnect(),o._ro=new ResizeObserver(o._resize),o._ro.observe(t)):0==o.frameCount&&addEventListener("resize",o._resize)},document.body?n():document.addEventListener("DOMContentLoaded",n)}o._q5=!0,o.pixels=[];let i,r=null;o.ctx=o.drawingContext=null,o.createCanvas=function(t,a,n,r){if("webgl"==n)throw"webgl renderer is not supported in q5, use '2d'";o.width=o.canvas.width=t,o.height=o.canvas.height=a,o.canvas.renderer="2d";let s=Object.assign({},Q5.canvasOptions);if(r&&Object.assign(s,r),i=o.ctx=o.drawingContext=o.canvas.getContext("2d",s),Object.assign(o.canvas,s),i.fillStyle="white",i.strokeStyle="black",i.lineCap="round",i.lineJoin="miter",i.textAlign="left",i.save(),"image"!=e){let t=o.displayDensity();"graphics"==e&&(t=this._pixelDensity),o.pixelDensity(Math.ceil(t))}else this._pixelDensity=1;return o.canvas},o._createCanvas=o.createCanvas,o.loadPixels=()=>{r=i.getImageData(0,0,o.canvas.width,o.canvas.height),o.pixels=r.data},o.updatePixels=()=>{null!=r&&i.putImageData(r,0,0)};let s=[];function l(e,t){t??=e||o.canvas.height,e??=o.canvas.width,null==f&&(f=new OffscreenCanvas(e,t).getContext("2d",{colorSpace:o.canvas.colorSpace})),f.canvas.width==e&&f.canvas.height==t||(f.canvas.width=e,f.canvas.height=t)}function h(){let e=o.canvas.width*o.canvas.height*4;x&&e==x.length||(x=new Uint8ClampedArray(e))}function c(e){f.clearRect(0,0,f.canvas.width,f.canvas.height),f.filter=e,f.drawImage(o.canvas,0,0),i.save(),i.resetTransform(),i.clearRect(0,0,o.canvas.width,o.canvas.height),i.drawImage(f.canvas,0,0),i.restore()}function d(e,t){let a=i.getImageData(0,0,o.canvas.width,o.canvas.height);s[e](a.data,t),i.putImageData(a,0,0)}s[o.THRESHOLD]=(e,t)=>{void 0===t?t=127.5:t*=255;for(let a=0;a=t?255:0}},s[o.GRAY]=e=>{for(let t=0;t{for(let t=0;t{for(let t=0;t{let a=t-1;for(let o=0;o>8)/a,e[o+1]=255*(e[o+1]*t>>8)/a,e[o+2]=255*(e[o+2]*t>>8)/a},s[o.DILATE]=e=>{h(),x.set(e);let[t,a]=[o.canvas.width,o.canvas.height];for(let o=0;o{h(),x.set(e);let[t,a]=[o.canvas.width,o.canvas.height];for(let o=0;o{t=t||1,t=Math.floor(t*o._pixelDensity),h(),x.set(e);let a=2*t+1;let n=function(e){let a=new Float32Array(e),o=.3*t+.8,n=o*o*2;for(let t=0;t{if(!i.filter)return d(e,t);if(l(),"string"==typeof e)c(e);else if(e==o.THRESHOLD){t??=.5,t=Math.max(t,1e-5),c(`saturate(0%) brightness(${Math.floor(.5/t*100)}%) contrast(1000000%)`)}else e==o.GRAY?c("saturate(0%)"):e==o.OPAQUE?(f.fillStyle="black",f.fillRect(0,0,f.canvas.width,f.canvas.height),f.drawImage(o.canvas,0,0),i.save(),i.resetTransform(),i.drawImage(f.canvas,0,0),i.restore()):e==o.INVERT?c("invert(100%)"):e==o.BLUR?c(`blur(${Math.ceil(t*o._pixelDensity/1)||1}px)`):d(e,t)},o.resize=(e,t)=>{l(),f.drawImage(o.canvas,0,0),o.width=e,o.height=t,o.canvas.width=e*o._pixelDensity,o.canvas.height=t*o._pixelDensity,i.save(),i.resetTransform(),i.clearRect(0,0,o.canvas.width,o.canvas.height),i.drawImage(f.canvas,0,0,o.canvas.width,o.canvas.height),i.restore()},o.get=(e,t,a,n)=>{let r=o._pixelDensity||1;if(void 0!==e&&void 0===a){let a=i.getImageData(e*r,t*r,1,1).data;return new o.Color(a[0],a[1],a[2],a[3]/255)}e=(e||0)*r,t=(t||0)*r;let s=a=a||o.width,l=n=n||o.height;a*=r,n*=r;let h=o.createImage(a,n),c=i.getImageData(e,t,a,n);return h.ctx.putImageData(c,0,0),h._pixelDensity=r,h.width=s,h.height=l,h},o.set=(e,t,a)=>{if(a._q5){let n=o._tint;return o._tint=null,o.image(a,e,t),void(o._tint=n)}o.pixels.length||o.loadPixels();let n=o._pixelDensity||1;for(let i=0;io._tint=null,o.mask=e=>{i.save(),i.resetTransform();let t=i.globalCompositeOperation;i.globalCompositeOperation="destination-in",i.drawImage(e.canvas,0,0),i.globalCompositeOperation=t,i.restore()},o._save=(e,t,a)=>{if(t=t||"untitled","jpg"==(a=a||"png")||"png"==a)e=e.toDataURL();else{let t="text/plain";"json"==a&&("string"!=typeof e&&(e=JSON.stringify(e)),t="text/json"),e=new Blob([e],{type:t}),e=URL.createObjectURL(e)}let o=document.createElement("a");o.href=e,o.download=t+"."+a,document.body.append(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(o.href)},o.save=(e,t,a)=>{if((!e||"string"==typeof e&&(!t||!a&&t.length<5))&&(a=t,t=e,e=o.canvas),a)return o._save(e,t,a);t?(t=t.split("."),o._save(e,t[0],t.at(-1))):o._save(e)},o.canvas.save=o.save,o.saveCanvas=o.save;let u=null,_=!0,g=[],p={},m=0,f=null,v=null,x=null;if(o.THRESHOLD=1,o.GRAY=2,o.OPAQUE=3,o.INVERT=4,o.POSTERIZE=5,o.DILATE=6,o.ERODE=7,o.BLUR=8,"image"==e)return;function y(){let e={};for(let t in i)"function"!=typeof i[t]&&(e[t]=i[t]);return delete e.canvas,e}o.BLEND="source-over",o.REMOVE="destination-out",o.ADD="lighter",o.DARKEST="darken",o.LIGHTEST="lighten",o.DIFFERENCE="difference",o.SUBTRACT="subtract",o.EXCLUSION="exclusion",o.MULTIPLY="multiply",o.SCREEN="screen",o.REPLACE="copy",o.OVERLAY="overlay",o.HARD_LIGHT="hard-light",o.SOFT_LIGHT="soft-light",o.DODGE="color-dodge",o.BURN="color-burn",o.RGB="rgb",o.RGBA="rgb",o.HSB="hsb",o.CHORD=0,o.PIE=1,o.OPEN=2,o.RADIUS="radius",o.CORNER="corner",o.CORNERS="corners",o.ROUND="round",o.SQUARE="butt",o.PROJECT="square",o.MITER="miter",o.BEVEL="bevel",o.CLOSE=1,o.NORMAL="normal",o.ITALIC="italic",o.BOLD="bold",o.BOLDITALIC="italic bold",o.CENTER="center",o.LEFT="left",o.RIGHT="right",o.TOP="top",o.BOTTOM="bottom",o.BASELINE="alphabetic",o.LANDSCAPE="landscape",o.PORTRAIT="portrait",o.ALT=18,o.BACKSPACE=8,o.CONTROL=17,o.DELETE=46,o.DOWN_ARROW=40,o.ENTER=13,o.ESCAPE=27,o.LEFT_ARROW=37,o.OPTION=18,o.RETURN=13,o.RIGHT_ARROW=39,o.SHIFT=16,o.TAB=9,o.UP_ARROW=38,o.DEGREES="degrees",o.RADIANS="radians",o.HALF_PI=Math.PI/2,o.PI=Math.PI,o.QUARTER_PI=Math.PI/4,o.TAU=2*Math.PI,o.TWO_PI=2*Math.PI,o.ARROW="default",o.CROSS="crosshair",o.HAND="pointer",o.MOVE="move",o.TEXT="text",o.VIDEO={video:!0,audio:!1},o.AUDIO={video:!1,audio:!0},o.SHR3=1,o.LCG=2,o.hint=(e,t)=>{o[e]=t},o.frameCount=0,o.deltaTime=16,o.mouseX=0,o.mouseY=0,o.touches=[],o.mouseButton=null,o.keyIsPressed=!1,o.mouseIsPressed=!1,o.key=null,o.keyCode=null,o.accelerationX=0,o.accelerationY=0,o.accelerationZ=0,o.rotationX=0,o.rotationY=0,o.rotationZ=0,o.relRotationX=0,o.relRotationY=0,o.relRotationZ=0,o.pmouseX=0,o.pmouseY=0,o.pAccelerationX=0,o.pAccelerationY=0,o.pAccelerationZ=0,o.pRotationX=0,o.pRotationY=0,o.pRotationZ=0,o.pRelRotationX=0,o.pRelRotationY=0,o.pRelRotationZ=0,Object.defineProperty(o,"deviceOrientation",{get:()=>window.screen?.orientation?.type}),Object.defineProperty(o,"windowWidth",{get:()=>window.innerWidth}),Object.defineProperty(o,"windowHeight",{get:()=>window.innerHeight}),o._colorMode="rgb",o._doStroke=!0,o._doFill=!0,o._strokeSet=!1,o._fillSet=!1,o._tint=null,o._ellipseMode=o.CENTER,o._rectMode=o.CORNER,o._curveDetail=20,o._curveAlpha=0,o._loop=!0,o._textFont="sans-serif",o._textSize=12,o._textLeading=15,o._textLeadDiff=3,o._textStyle="normal",o._pixelDensity=1,o._lastFrameTime=0,o._targetFrameRate=null,o._frameRate=o._fps=60,o.resizeCanvas=(t,a)=>{o.width=t,o.height=a;let n=y();o.canvas.width=t*o._pixelDensity,o.canvas.height=a*o._pixelDensity;for(let e in n)o.ctx[e]=n[e];"image"!=e&&o.pixelDensity(o._pixelDensity)},o.createGraphics=function(e,t){let a=new Q5("graphics");return a._createCanvas.call(o,e,t),a},o.createImage=(e,t)=>new Q5.Image(e,t),o.displayDensity=()=>window.devicePixelRatio,o.pixelDensity=e=>{if(void 0===e)return o._pixelDensity;o._pixelDensity=e;let t=y();o.canvas.width=Math.ceil(o.width*e),o.canvas.height=Math.ceil(o.height*e),o.canvas.style.width=o.width+"px",o.canvas.style.height=o.height+"px";for(let e in t)o.ctx[e]=t[e];return i.scale(o._pixelDensity,o._pixelDensity),o._pixelDensity},o.map=(e,t,a,o,n,i)=>{let r=o+1*(e-t)/(a-t)*(n-o);return i?oe*(1-a)+t*a,o.constrain=(e,t,a)=>Math.min(Math.max(e,t),a),o.dist=function(){let e=arguments;return 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])},o.norm=(e,t,a)=>o.map(e,t,a,0,1),o.sq=e=>e*e,o.fract=e=>e-Math.floor(e),o.angleMode=e=>o._angleMode=e,o._DEGTORAD=Math.PI/180,o._RADTODEG=180/Math.PI,o.degrees=e=>e*o._RADTODEG,o.radians=e=>e*o._DEGTORAD,o.abs=Math.abs,o.ceil=Math.ceil,o.exp=Math.exp,o.floor=Math.floor,o.log=Math.log,o.mag=Math.hypot,o.max=Math.max,o.min=Math.min,o.round=Math.round,o.pow=Math.pow,o.sqrt=Math.sqrt,o.sin=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.sin(e)),o.cos=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.cos(e)),o.tan=e=>("degrees"==o._angleMode&&(e=o.radians(e)),Math.tan(e)),o.asin=e=>{let t=Math.asin(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.acos=e=>{let t=Math.acos(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.atan=e=>{let t=Math.atan(e);return"degrees"==o._angleMode&&(t=o.degrees(t)),t},o.atan2=(e,t)=>{let a=Math.atan2(e,t);return"degrees"==o._angleMode&&(a=o.degrees(a)),a},o.nf=(e,t,a)=>{let o=e<0,n=e.toString();return o&&(n=n.slice(1)),n=n.padStart(t,"0"),a>0&&(-1==n.indexOf(".")&&(n+="."),n=n.padEnd(t+1+a,"0")),o&&(n="-"+n),n},o.createVector=(e,t,a)=>new Q5.Vector(e,t,a,o),o.curvePoint=(e,t,a,o,n)=>{const i=n*n*n,r=n*n;return e*(-.5*i+r-.5*n)+t*(1.5*i-2.5*r+1)+a*(-1.5*i+2*r+.5*n)+o*(.5*i-.5*r)},o.bezierPoint=(e,t,a,o,n)=>{const i=1-n;return Math.pow(i,3)*e+3*Math.pow(i,2)*n*t+3*i*Math.pow(n,2)*a+Math.pow(n,3)*o},o.curveTangent=(e,t,a,o,n)=>{const i=n*n;return e*(-3*i/2+2*n-.5)+t*(9*i/2-5*n)+a*(-9*i/2+4*n+.5)+o*(3*i/2-n)},o.bezierTangent=(e,t,a,o,n)=>{const i=1-n;return 3*o*Math.pow(n,2)-3*a*Math.pow(n,2)+6*a*i*n-6*t*i*n+3*t*Math.pow(i,2)-3*e*Math.pow(i,2)},o.Color=Q5.ColorRGBA_P3,o.colorMode=e=>{o._colorMode=e,"oklch"==e?o.Color=Q5.ColorOKLCH:"rgb"==e?"srgb"==o.canvas.colorSpace?o.Color=Q5.ColorRGBA:o.Color=Q5.ColorRGBA_P3:"srgb"==e&&(o.Color=Q5.ColorRGBA,o._colorMode="rgb")};let w={aqua:[0,255,255],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],crimson:[220,20,60],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]};function M(e){let t=o._angleMode==o.DEGREES?180:Math.PI,a=2*t;if(0<=e&&e<=a)return e;for(;e<0;)e+=a;for(;e>=t;)e-=a;return e}function R(e,t,a,n,r,s,l,h){if(!o._doFill&&!o._doStroke)return;let c=M(r),d=M(s);if(c>d&&([c,d]=[d,c]),0==c){if(0==d)return;if(o._angleMode==o.DEGREES&&360==d||d==o.TAU)return o.ellipse(e,t,a,n)}i.beginPath();for(let r=0;re.r,o.green=e=>e.g,o.blue=e=>e.b,o.alpha=e=>e.a,o.lightness=e=>100*(.2126*e.r+.7152*e.g+.0722*e.b)/255,o.lerpColor=(e,t,a)=>{if("rgb"==o._colorMode)return new o.Color(o.constrain(o.lerp(e.r,t.r,a),0,255),o.constrain(o.lerp(e.g,t.g,a),0,255),o.constrain(o.lerp(e.b,t.b,a),0,255),o.constrain(o.lerp(e.a,t.a,a),0,255));{let n=t.h-e.h;n>180&&(n-=360),n<-180&&(n+=360);let i=e.h+a*n;return i<0&&(i+=360),i>360&&(i-=360),new o.Color(o.constrain(o.lerp(e.l,t.l,a),0,100),o.constrain(o.lerp(e.c,t.c,a),0,100),i,o.constrain(o.lerp(e.a,t.a,a),0,255))}},o.strokeWeight=e=>{e||(o._doStroke=!1),i.lineWidth=e||1e-4},o.stroke=function(e){if(o._doStroke=!0,o._strokeSet=!0,e._q5Color||(e=o.color(...arguments)),e.a<=0)return o._doStroke=!1;i.strokeStyle=e},o.noStroke=()=>o._doStroke=!1,o.fill=function(e){if(o._doFill=!0,o._fillSet=!0,e._q5Color||(e=o.color(...arguments)),e.a<=0)return o._doFill=!1;i.fillStyle=e},o.noFill=()=>o._doFill=!1,o.smooth=()=>o._smooth=!0,o.noSmooth=()=>o._smooth=!1,o.blendMode=e=>i.globalCompositeOperation=e,o.strokeCap=e=>i.lineCap=e,o.strokeJoin=e=>i.lineJoin=e,o.ellipseMode=e=>o._ellipseMode=e,o.rectMode=e=>o._rectMode=e,o.curveDetail=e=>o._curveDetail=e,o.curveAlpha=e=>o._curveAlpha=e,o.curveTightness=e=>o._curveAlpha=e,o.clear=()=>{i.clearRect(0,0,o.canvas.width,o.canvas.height)},o.background=function(e){if(e._q5)return o.image(e,0,0,o.width,o.height);i.save(),i.resetTransform(),e._q5color||(e=o.color(...arguments)),i.fillStyle=e,i.fillRect(0,0,o.canvas.width,o.canvas.height),i.restore()},o.line=(e,t,a,n)=>{o._doStroke&&(i.beginPath(),i.moveTo(e,t),i.lineTo(a,n),i.stroke())},o.arc=(e,t,a,n,i,r,s,l)=>{if(i==r)return o.ellipse(e,t,a,n);l??=25,s??=o.PIE,o._ellipseMode==o.CENTER?R(e,t,a,n,i,r,s,l):o._ellipseMode==o.RADIUS?R(e,t,2*a,2*n,i,r,s,l):o._ellipseMode==o.CORNER?R(e+a/2,t+n/2,a,n,i,r,s,l):o._ellipseMode==o.CORNERS&&R((e+a)/2,(t+n)/2,a-e,n-t,i,r,s,l)},o.ellipse=(e,t,a,n)=>{n??=a,o._ellipseMode==o.CENTER?S(e,t,a,n):o._ellipseMode==o.RADIUS?S(e,t,2*a,2*n):o._ellipseMode==o.CORNER?S(e+a/2,t+n/2,a,n):o._ellipseMode==o.CORNERS&&S((e+a)/2,(t+n)/2,a-e,n-t)},o.circle=(e,t,a)=>o.ellipse(e,t,a,a),o.point=(e,t)=>{e.x&&(t=e.y,e=e.x),i.beginPath(),i.ellipse(e,t,.4,.4,0,0,o.TAU),i.stroke()},o.rect=(e,t,a,n,i,r,s,l)=>{o._rectMode==o.CENTER?C(e-a/2,t-n/2,a,n,i,r,s,l):o._rectMode==o.RADIUS?C(e-a,t-n,2*a,2*n,i,r,s,l):o._rectMode==o.CORNER?C(e,t,a,n,i,r,s,l):o._rectMode==o.CORNERS&&C(e,t,a-e,n-t,i,r,s,l)},o.square=(e,t,a,n,i,r,s)=>o.rect(e,t,a,a,n,i,r,s),o.beginShape=()=>{b(),i.beginPath(),_=!0},o.beginContour=()=>{i.closePath(),b(),_=!0},o.endContour=()=>{b(),_=!0},o.vertex=(e,t)=>{b(),_?i.moveTo(e,t):i.lineTo(e,t),_=!1},o.bezierVertex=(e,t,a,o,n,r)=>{b(),i.bezierCurveTo(e,t,a,o,n,r)},o.quadraticVertex=(e,t,a,o)=>{b(),i.quadraticCurveTo(e,t,a,o)},o.bezier=(e,t,a,n,i,r,s,l)=>{o.beginShape(),o.vertex(e,t),o.bezierVertex(a,n,i,r,s,l),o.endShape()},o.triangle=(e,t,a,n,i,r)=>{o.beginShape(),o.vertex(e,t),o.vertex(a,n),o.vertex(i,r),o.endShape(o.CLOSE)},o.quad=(e,t,a,n,i,r,s,l)=>{o.beginShape(),o.vertex(e,t),o.vertex(a,n),o.vertex(i,r),o.vertex(s,l),o.endShape(o.CLOSE)},o.endShape=e=>{b(),e&&i.closePath(),o._doFill&&i.fill(),o._doStroke&&i.stroke(),o._doFill||o._doStroke||(i.save(),i.fillStyle="none",i.fill(),i.restore())},o.curveVertex=(e,t)=>{if(g.push([e,t]),g.length<4)return;let a=function(e,t,a,o,n,i,r,s,l,h){function c(e,t,a,o,n,i){let r=Math.pow(o-t,2)+Math.pow(n-a,2);return Math.pow(r,.5*i)+e}let d=[],u=c(0,e,t,a,o,h),_=c(u,a,o,n,i,h),g=c(_,n,i,r,s,h);for(let h=0;h0?(p[e]=1,p[e+1]=0):(p[e]=0,p[e+1]=1));let m=e*p[0]+a*p[1],f=t*p[0]+o*p[1],v=a*p[2]+n*p[3],x=o*p[2]+i*p[3],y=n*p[4]+r*p[5],w=i*p[4]+s*p[5],M=m*p[6]+v*p[7],R=f*p[6]+x*p[7],S=v*p[8]+y*p[9],C=x*p[8]+w*p[9],b=M*p[2]+S*p[3],E=R*p[2]+C*p[3];d.push([b,E])}return d}(...g[g.length-4],...g[g.length-3],...g[g.length-2],...g[g.length-1],o._curveDetail,o._curveAlpha);for(let e=0;e{o.beginShape(),o.curveVertex(e,t),o.curveVertex(a,n),o.curveVertex(i,r),o.curveVertex(s,l),o.endShape()},o.opacity=e=>i.globalAlpha=e,o.translate=(e,t)=>i.translate(e,t),o.rotate=e=>{"degrees"==o._angleMode&&(e=o.radians(e)),i.rotate(e)},o.scale=(e,t)=>{t??=e,i.scale(e,t)},o.applyMatrix=(e,t,a,o,n,r)=>i.transform(e,t,a,o,n,r),o.shearX=e=>i.transform(1,0,o.tan(e),1,0,0),o.shearY=e=>i.transform(1,o.tan(e),0,1,0,0),o.resetMatrix=()=>{i.resetTransform(),i.scale(o._pixelDensity,o._pixelDensity)},o._styleNames=["_doStroke","_doFill","_strokeSet","_fillSet","_tint","_imageMode","_rectMode","_ellipseMode","_textFont","_textLeading","_leadingSet","_textSize","_textAlign","_textBaseline","_textStyle","_textWrap"],o._styles=[],o.push=o.pushMatrix=()=>{i.save();let e={};for(let t of o._styleNames)e[t]=o[t];o._styles.push(e)},o.pop=o.popMatrix=()=>{i.restore();let e=o._styles.pop();for(let t of o._styleNames)o[t]=e[t]},o.imageMode=e=>o._imageMode=e,o.image=(e,t,a,n,r,s,l,h,c)=>{let d=e._q5?e.canvas:e;var u,_;e._q5&&null!=o._tint&&(u=e.canvas.width,_=e.canvas.height,_??=u||o.canvas.height,u??=o.canvas.width,null==v&&(v=new OffscreenCanvas(u,_).getContext("2d",{colorSpace:o.canvas.colorSpace})),v.canvas.width==u&&v.canvas.height==_||(v.canvas.width=u,v.canvas.height=_),v.drawImage(e.canvas,0,0),e.tinted(o._tint)),n||(e._q5||e.width?(n=e.width,r=e.height):(n=e.videoWidth,r=e.videoHeight)),"center"==o._imageMode&&(t-=.5*n,a-=.5*r);let g=e._pixelDensity;s??=0,l??=0,h?h*=g:h=d.width,c?c*=g:c=d.height,i.drawImage(d,s*g,l*g,h,c,t,a,n,r),function(){if(!e._q5||!o._tint)return;let t=e.ctx;t.save(),t.resetTransform(),t.clearRect(0,0,t.canvas.width,t.canvas.height),t.drawImage(v.canvas,0,0),t.restore()}()},o._incrementPreload=()=>a++,o._decrementPreload=()=>a--,o.loadImage=(e,t)=>{a++;let n=o.createImage(1,1),i=n.ctx,r=new window.Image;return r.src=e,r.crossOrigin="Anonymous",r._pixelDensity=1,r.onload=()=>{n.width=i.canvas.width=r.naturalWidth,n.height=i.canvas.height=r.naturalHeight,i.drawImage(r,0,0),a--,t&&t(n)},r.onerror=e=>{throw a--,e},n},o._clearTemporaryBuffers=()=>{f=null,v=null,x=null},o.loadFont=(e,t)=>{a++;let o=e.split("/"),n=o[o.length-1].split(".")[0].replace(" ",""),i=new FontFace(n,"url("+e+")");return document.fonts.add(i),i.load().then((()=>{a--,t&&t(n)})),n},o.textFont=e=>o._textFont=e,o.textSize=e=>{if(void 0===e)return o._textSize;o._textSize=e,o._leadingSet||(o._textLeading=1.25*e,o._textLeadDiff=o._textLeading-e)},o.textLeading=e=>{if(void 0===e)return o._textLeading;o._textLeading=e,o._textLeadDiff=e-o._textSize,o._leadingSet=!0},o.textStyle=e=>o._textStyle=e,o.textAlign=(e,t)=>{i.textAlign=e,t&&(i.textBaseline=t==o.CENTER?"middle":t)},o.textWidth=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).width),o.textAscent=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).actualBoundingBoxAscent),o.textDescent=e=>(i.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`,i.measureText(e).actualBoundingBoxDescent),o._textCache=!0,o._TimedCache=class extends Map{constructor(){super(),this.maxSize=500}set(e,t){t.lastAccessed=Date.now(),super.set(e,t),this.size>this.maxSize&&this.gc()}get(e){const t=super.get(e);return t&&(t.lastAccessed=Date.now()),t}gc(){let e,t=1/0,a=0;for(const[o,n]of this.entries())n.lastAccessed(t&&(o._tic.maxSize=t),void 0!==e&&(o._textCache=e),o._textCache),o.createTextImage=(e,t,a)=>{let n=o._textCache;o._textCache=!0,o._useCache=!0,o.text(e,0,0,t,a),o._useCache=!1;let i=E(e,t,a);return o._textCache=n,o._tic.get(i)},o.text=(e,t,a,n,r)=>{if(void 0===e)return;if(e=e.toString(),!o._doFill&&!o._doStroke)return;let s,l,h,c,d,u,_,g,p=1,m=i.getTransform(),f=o._useCache||o._textCache&&(0!=m.b||0!=m.c);if(f){if(c=E(e,n,r),l=o._tic.get(c),l)return void o.textImage(l,t,a);h=o.createGraphics.call(o,1,1),s=h.ctx,p=o._pixelDensity}else s=i,d=t,u=a;s.font=`${o._textStyle} ${o._textSize}px ${o._textFont}`;let v=e.split("\n");if(f){d=0,u=o._textLeading*v.length;let t=s.measureText(" ");_=t.fontBoundingBoxAscent,g=t.fontBoundingBoxDescent,r??=u+g,h.resizeCanvas(Math.ceil(s.measureText(e).width),Math.ceil(r)),s.fillStyle=i.fillStyle,s.strokeStyle=i.strokeStyle,s.lineWidth=i.lineWidth}let x=s.fillStyle;o._fillSet||(s.fillStyle="black");for(let e=0;er));e++);o._fillSet||(s.fillStyle=x),f&&(l=h.get(),l._ascent=_,l._descent=g,o._tic.set(c,l),o.textImage(l,t,a))},o.textImage=(e,t,a)=>{let n=o._imageMode;o._imageMode="corner","center"==i.textAlign?t-=.5*e.width:"right"==i.textAlign&&(t-=e.width),"alphabetic"==i.textBaseline&&(a-=o._textLeading),"middle"==i.textBaseline?a-=e._descent+.5*e._ascent+o._textLeadDiff:"bottom"==i.textBaseline?a-=e._ascent+e._descent+o._textLeadDiff:"top"==i.textBaseline&&(a-=e._descent+o._textLeadDiff),o.image(e,t,a),o._imageMode=n};var D,I=4095,T=4,A=.5,O=e=>.5*(1-Math.cos(e*Math.PI));o.noise=(e,t,a)=>{if(t??=0,a??=0,null==D){D=new Array(4096);for(var o=0;o<4096;o++)D[o]=Math.random()}e<0&&(e=-e),t<0&&(t=-t),a<0&&(a=-a);for(var n,i,r,s,l,h=Math.floor(e),c=Math.floor(t),d=Math.floor(a),u=e-h,_=t-c,g=a-d,p=0,m=.5,f=0;f=1&&(h++,u--),(_*=2)>=1&&(c++,_--),(g*=2)>=1&&(d++,g--)}return p},o.noiseDetail=(e,t)=>{e>0&&(T=e),t>0&&(A=t)};const P=()=>{let e,t,a=4294967295;return{setSeed(o){e=t=(null==o?Math.random()*a:o)>>>0},getSeed:()=>t,rand:()=>(e^=e<<17,e^=e>>13,e^=e<<5,(e>>>0)/a)}};let k=P();k.setSeed(),o.noiseSeed=e=>{let t=void 0===e?4294967295*Math.random():e;D||(D=new Float32Array(4096));for(var a=0;a<4096;a++)t^=t<<17,t^=t>>13,t^=t<<5,D[a]=(t>>>0)/4294967295},o.randomSeed=e=>k.setSeed(e),o.random=(e,t)=>void 0===e?k.rand():"number"==typeof e?void 0!==t?k.rand()*(t-e)+e:k.rand()*e:e[Math.trunc(e.length*k.rand())],o.randomGenerator=e=>{e==o.LCG?k=(()=>{const e=4294967296;let t,a;return{setSeed(o){a=t=(null==o?Math.random()*e:o)>>>0},getSeed:()=>t,rand:()=>(a=(1664525*a+1013904223)%e,a/e)}})():e==o.SHR3&&(k=P()),k.setSeed()};var z=new function(){var e,t,a,o=new Array(128),n=new Array(256),i=new Array(128),r=new Array(128),s=new Array(256),l=new Array(256),h=()=>4294967296*k.rand()-2147483648,c=()=>.5+2.328306e-10*(h()<<0),d=()=>{for(var t,n,s,l,d=3.44262;;){if(t=a*i[e],0==e){do{s=c(),l=c(),t=.2904764*-Math.log(s),n=-Math.log(l)}while(n+n0?d+t:-d-t}if(r[e]+c()*(r[e-1]-r[e]){for(var a;;){if(0==e)return 7.69711-Math.log(c());if(a=t*s[e],l[e]+c()*(l[e-1]-l[e])(a=h(),e=127&a,Math.abs(a)(t=h()>>>0){var e,t,a=2147483648,h=4294967296,c=3.442619855899,d=c,u=.00991256303526217,_=7.697117470131487,g=_,p=.003949659822581572;for(e=u/Math.exp(-.5*c*c),o[0]=Math.floor(c/e*a),o[1]=0,i[0]=e/a,i[127]=c/a,r[0]=1,r[127]=Math.exp(-.5*c*c),t=126;t>=1;t--)c=Math.sqrt(-2*Math.log(u/c+Math.exp(-.5*c*c))),o[t+1]=Math.floor(c/d*a),d=c,r[t]=Math.exp(-.5*c*c),i[t]=c/a;for(e=p/Math.exp(-_),n[0]=Math.floor(_/e*h),n[1]=0,s[0]=e/h,s[255]=_/h,l[0]=1,l[255]=Math.exp(-_),t=254;t>=1;t--)_=-Math.log(p/_+Math.exp(-_)),n[t+1]=Math.floor(_/g*h),g=_,l[t]=Math.exp(-_),s[t]=_/h}};function F(){let e=performance.now();if(o._loop)u=o._targetFrameRate?setTimeout(F,1e3/o._targetFrameRate):requestAnimationFrame(F);else if(o.frameCount>0)return;if(u&&0!=o.frameCount){if(e-o._lastFrameTime<1e3/(o._targetFrameRate||60)-5)return}o.deltaTime=e-o._lastFrameTime,o._frameRate=1e3/o.deltaTime,o.frameCount++,o._shouldResize&&(o._windowResizedFn(),o._shouldResize=!1);for(let e of Q5.prototype._methods.pre)e.call(o);b(),_=!0,i.save(),o._drawFn();for(let e of Q5.prototype._methods.post)e.call(o);i.restore(),o.resetMatrix();let t=performance.now();o._fps=Math.round(1e3/(t-e)),o._lastFrameTime=e,o.pmouseX=o.mouseX,o.pmouseY=o.mouseY}function L(e){const t=o.canvas.getBoundingClientRect(),a=o.canvas.scrollWidth/o.width||1,n=o.canvas.scrollHeight/o.height||1;return{x:(e.clientX-t.left)/a,y:(e.clientY-t.top)/n,id:e.identifier}}function Q(){return o._touchStartedFn.isPlaceHolder&&o._touchMovedFn.isPlaceHolder&&o._touchEndedFn.isPlaceHolder}z.hasInit=!1,o.randomGaussian=(e,t)=>(z.hasInit||(z.zigset(),z.hasInit=!0),z.RNOR()*t+e),o.randomExponential=()=>(z.hasInit||(z.zigset(),z.hasInit=!0),z.REXP()),o.Element=function(e){this.elt=e},o._elements=[],o.createCapture=e=>{var t=document.createElement("video");return t.playsinline="playsinline",t.autoplay="autoplay",navigator.mediaDevices.getUserMedia(e).then((e=>{t.srcObject=e})),t.style.position="absolute",t.style.opacity=1e-5,t.style.zIndex=-1e3,document.body.append(t),t},o.print=console.log,o.describe=()=>{},o.noLoop=()=>{o._loop=!1,u=null},o.loop=()=>{o._loop=!0,null==u&&F()},o.redraw=()=>F(),o.remove=()=>{o.noLoop(),o.canvas.remove()},o.frameRate=e=>(e&&(o._targetFrameRate=e),o._frameRate),o.getFrameRate=()=>o._frameRate,o.getFPS=()=>o._fps,o.storeItem=localStorage.setItem,o.getItem=localStorage.getItem,o.removeItem=localStorage.removeItem,o.clearStorage=localStorage.clear,o._updateMouse=e=>{let t=o.canvas.getBoundingClientRect(),a=o.canvas.scrollWidth/o.width||1,n=o.canvas.scrollHeight/o.height||1;o.mouseX=(e.clientX-t.left)/a,o.mouseY=(e.clientY-t.top)/n},o._onmousedown=e=>{o._updateMouse(e),o.mouseIsPressed=!0,o.mouseButton=[o.LEFT,o.CENTER,o.RIGHT][e.button],o._mousePressedFn(e)},o._onmousemove=e=>{o._updateMouse(e),o.mouseIsPressed?o._mouseDraggedFn(e):o._mouseMovedFn(e)},o._onmouseup=e=>{o._updateMouse(e),o.mouseIsPressed=!1,o._mouseReleasedFn(e)},o._onclick=e=>{o._updateMouse(e),o.mouseIsPressed=!0,o._mouseClickedFn(e),o.mouseIsPressed=!1},o.cursor=(e,t,a)=>{let n="";e.includes(".")&&(e=`url("${e}")`,n=", auto"),void 0!==t&&(e+=" "+t+" "+a),o.canvas.style.cursor=e+n},o.noCursor=()=>{o.canvas.style.cursor="none"},o._onkeydown=e=>{e.repeat||(o.keyIsPressed=!0,o.key=e.key,o.keyCode=e.keyCode,p[o.keyCode]=!0,o._keyPressedFn(e),1==e.key.length&&o._keyTypedFn(e))},o._onkeyup=e=>{o.keyIsPressed=!1,o.key=e.key,o.keyCode=e.keyCode,p[o.keyCode]=!1,o._keyReleasedFn(e)},o.canvas.onmousedown=e=>o._onmousedown(e),o.canvas.onmouseup=e=>o._onmouseup(e),o.canvas.onclick=e=>o._onclick(e),o.keyIsDown=e=>!!p[e],o._ontouchstart=e=>{o.touches=[...e.touches].map(L),Q()&&(o.mouseX=o.touches[0].x,o.mouseY=o.touches[0].y,o.mouseIsPressed=!0,o.mouseButton=o.LEFT,o._mousePressedFn(e)||e.preventDefault()),o._touchStartedFn(e)||e.preventDefault()},o._ontouchmove=e=>{o.touches=[...e.touches].map(L),Q()&&(o.mouseX=o.touches[0].x,o.mouseY=o.touches[0].y,o._mouseDraggedFn(e)||e.preventDefault()),o._touchMovedFn(e)||e.preventDefault()},o._ontouchend=e=>{o.touches=[...e.touches].map(L),Q()&&!o.touches.length&&(o.mouseIsPressed=!1,o._mouseReleasedFn(e)||e.preventDefault()),o._touchEndedFn(e)||e.preventDefault()},o.canvas.ontouchstart=e=>o._ontouchstart(e),o.canvas.ontouchmove=e=>o._ontouchmove(e),o.canvas.ontouchcancel=o.canvas.ontouchend=e=>o._ontouchend(e),o.hasSensorPermission=!window.DeviceOrientationEvent&&!window.DeviceMotionEvent||!(DeviceOrientationEvent.requestPermission||DeviceMotionEvent.requestPermission),o.requestSensorPermissions=()=>{DeviceOrientationEvent.requestPermission&&DeviceOrientationEvent.requestPermission().then((e=>{"granted"==e&&DeviceMotionEvent.requestPermission&&DeviceMotionEvent.requestPermission().then((e=>{"granted"==e&&(o.hasSensorPermission=!0)})).catch(alert)})).catch(alert)};window.ondeviceorientation=e=>{o.pRotationX=o.rotationX,o.pRotationY=o.rotationY,o.pRotationZ=o.rotationZ,o.pRelRotationX=o.relRotationX,o.pRelRotationY=o.relRotationY,o.pRelRotationZ=o.relRotationZ,o.rotationX=e.beta*(Math.PI/180),o.rotationY=e.gamma*(Math.PI/180),o.rotationZ=e.alpha*(Math.PI/180),o.relRotationX=[-o.rotationY,-o.rotationX,o.rotationY][Math.trunc(window.orientation/90)+1],o.relRotationY=[-o.rotationX,o.rotationY,o.rotationX][Math.trunc(window.orientation/90)+1],o.relRotationZ=o.rotationZ},window.ondevicemotion=e=>{if(o.pAccelerationX=o.accelerationX,o.pAccelerationY=o.accelerationY,o.pAccelerationZ=o.accelerationZ,!e.acceleration){let i=((e,t)=>[(e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]),(e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]),(e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11])/(e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15])])((n=o.rotationY,t=[o.cos(n),0,o.sin(n),0,0,1,0,0,-o.sin(n),0,o.cos(n),0,0,0,0,1],a=(e=>[1,0,0,0,0,o.cos(e),-o.sin(e),0,0,o.sin(e),o.cos(e),0,0,0,0,1])(o.rotationX),[t[0]*a[0]+t[1]*a[4]+t[2]*a[8]+t[3]*a[12],t[0]*a[1]+t[1]*a[5]+t[2]*a[9]+t[3]*a[13],t[0]*a[2]+t[1]*a[6]+t[2]*a[10]+t[3]*a[14],t[0]*a[3]+t[1]*a[7]+t[2]*a[11]+t[3]*a[15],t[4]*a[0]+t[5]*a[4]+t[6]*a[8]+t[7]*a[12],t[4]*a[1]+t[5]*a[5]+t[6]*a[9]+t[7]*a[13],t[4]*a[2]+t[5]*a[6]+t[6]*a[10]+t[7]*a[14],t[4]*a[3]+t[5]*a[7]+t[6]*a[11]+t[7]*a[15],t[8]*a[0]+t[9]*a[4]+t[10]*a[8]+t[11]*a[12],t[8]*a[1]+t[9]*a[5]+t[10]*a[9]+t[11]*a[13],t[8]*a[2]+t[9]*a[6]+t[10]*a[10]+t[11]*a[14],t[8]*a[3]+t[9]*a[7]+t[10]*a[11]+t[11]*a[15],t[12]*a[0]+t[13]*a[4]+t[14]*a[8]+t[15]*a[12],t[12]*a[1]+t[13]*a[5]+t[14]*a[9]+t[15]*a[13],t[12]*a[2]+t[13]*a[6]+t[14]*a[10]+t[15]*a[14],t[12]*a[3]+t[13]*a[7]+t[14]*a[11]+t[15]*a[15]]),[0,0,-9.80665]);o.accelerationX=e.accelerationIncludingGravity.x+i[0],o.accelerationY=e.accelerationIncludingGravity.y+i[1],o.accelerationZ=e.accelerationIncludingGravity.z-i[2]}var t,a,n},o.year=()=>(new Date).getFullYear(),o.day=()=>(new Date).getDay(),o.hour=()=>(new Date).getHours(),o.minute=()=>(new Date).getMinutes(),o.second=()=>(new Date).getSeconds(),o.millis=()=>performance.now()-m,o._loadFile=(e,t,o)=>{a++;let n={};return fetch(e).then((e=>"json"==o?e.json():"text"==o?e.text():void 0)).then((e=>{a--,Object.assign(n,e),t&&t(e)})),n},o.loadStrings=(e,t)=>o._loadFile(e,t,"text"),o.loadJSON=(e,t)=>o._loadFile(e,t,"json"),o.loadSound=(e,t)=>{a++;let o=new Audio(e);return o.addEventListener("canplaythrough",(()=>{a--,t&&t(o)})),o.load(),o.setVolume=e=>o.volume=e,o.setLoop=e=>o.loop=e,o},"global"==e&&(Object.assign(Q5,o),delete Q5.Q5),Q5.Image??=_Q5Image;for(let N of Q5.prototype._methods.init)N.call(o);for(let[B,$]of Object.entries(Q5.prototype))"_"!=B[0]&&"function"==typeof o[B]&&(o[B]=$.bind(o));if("global"==e){let V=Object.getOwnPropertyNames(o);for(let G of V)"function"==typeof o[G]?window[G]=o[G]:Object.defineProperty(window,G,{get:()=>o[G],set:e=>o[G]=e})}function q(){let t="global"==e?window:o,n=["setup","draw","preload","mouseMoved","mousePressed","mouseReleased","mouseDragged","mouseClicked","keyPressed","keyReleased","keyTyped","touchStarted","touchMoved","touchEnded","windowResized"];for(let e of n){let a="_"+e+"Fn";o[a]=()=>{},o[a].isPlaceHolder=!0,t[e]?o[a]=t[e]:Object.defineProperty(o,e,{set:e=>{o[a]=e}})}if("graphics"!=e||"image"!=e){o._preloadFn(),m=performance.now(),function e(){if(a>0)return requestAnimationFrame(e);o._setupFn(),i||o.createCanvas(100,100),o._setupDone=!0,i.restore(),o.resetMatrix(),requestAnimationFrame(F)}()}addEventListener("mousemove",(e=>o._onmousemove(e)),!1),addEventListener("keydown",(e=>o._onkeydown(e)),!1),addEventListener("keyup",(e=>o._onkeyup(e)),!1)}"function"==typeof e&&e(o),"global"==e?q():requestAnimationFrame(q)}Q5.Color=class{constructor(){this._q5Color=!0}},Q5.ColorOKLCH=class extends Q5.Color{constructor(e,t,a,o){super(),this.l=e,this.c=t,this.h=a,this.a=o??1}toString(){return`color(oklch ${this.l} ${this.c} ${this.h} / ${this.a})`}},Q5.ColorRGBA=class extends Q5.Color{constructor(e,t,a,o){super(),this.r=e,this.g=t,this.b=a,this.a=o??255}setRed(e){this.r=e}setGreen(e){this.g=e}setBlue(e){this.b=e}setAlpha(e){this.a=e}get levels(){return[this.r,this.g,this.b,this.a]}toString(){return`rgb(${this.r} ${this.g} ${this.b} / ${this.a/255})`}},Q5.ColorRGBA_P3=class extends Q5.ColorRGBA{constructor(e,t,a,o){super(e,t,a,o),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),a=(this._b/255).toFixed(3),o=(this._a/255).toFixed(3);this._css=`color(display-p3 ${e} ${t} ${a} / ${o})`,this._edited=!1}return this._css}},Q5.Vector=class{constructor(e,t,a,o){this.x=e||0,this.y=t||0,this.z=a||0,this._$=o||window,this._cn=null,this._cnsq=null}set(e,t,a){this.x=e||0,this.y=t||0,this.z=a||0}copy(){return new Q5.Vector(this.x,this.y,this.z)}_arg2v(e,t,a){return void 0!==e.x?e:void 0!==t?{x:e,y:t,z:a||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,a=this.y-e.y,o=this.z-e.z;return Math.sqrt(t*t+a*a+o*o)}cross(){let e=this._arg2v(...arguments),t=this.y*e.z-this.z*e.y,a=this.z*e.x-this.x*e.z,o=this.x*e.y-this.y*e.x;return this.x=t,this.y=a,this.z=o,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 a=e/t;this.x*=a,this.y*=a,this.z*=a,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)}rotate(e){let t=this._$.cos(e),a=this._$.sin(e),o=this.x*t-this.y*a,n=this.x*a+this.y*t;return this.x=o,this.y=n,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=this._arg2v(...e.slice(0,-1)),a=e[e.length-1];return this.x+=(t.x-this.x)*a,this.y+=(t.y-this.y)*a,this.z+=(t.z-this.z)*a,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)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,a)=>e.equals(t,a),Q5.Vector.lerp=(e,t,a)=>e.copy().lerp(t,a),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,a,o)=>(new Q5.Vector)[e](t,a,o);class _Q5Image extends Q5{constructor(e,t){super("image"),this.createCanvas(e,t),delete this.createCanvas,this._loop=!1}get w(){return this.width}get h(){return this.height}}if("undefined"==typeof window)throw"q5 requires you to define a window object.";Q5.canvasOptions={alpha:!1,desynchronized:!0,colorSpace:"display-p3"},window.matchMedia&&matchMedia("(dynamic-range: high) and (color-gamut: p3)").matches?Q5.supportsHDR=!0:Q5.canvasOptions.colorSpace="srgb",window.OffscreenCanvas??=function(){return document.createElement("canvas")},Q5._instanceCount=0,Q5._friendlyError=(e,t)=>{throw t+": "+e},Q5._validateParameters=()=>!0,Q5.prototype._methods={init:[],pre:[],post:[],remove:[]},Q5.prototype.registerMethod=(e,t)=>Q5.prototype._methods[e].push(t),Q5.prototype.registerPreloadMethod=(e,t)=>Q5.prototype[e]=t[e],"undefined"!=typeof module?module.exports=Q5:window.p5??=Q5,document.addEventListener("DOMContentLoaded",(()=>{Q5._hasGlobal||new Q5("auto")}));