function kv(i) {
  return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, "default") ? i.default : i;
}
/**
 * @license
 * Copyright 2010-2026 Three.js Authors
 * SPDX-License-Identifier: MIT
 */
const za = "183", Fn = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }, es = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }, Gv = 0, Mp = 1, Vv = 2, aM = 0, Ro = 1, zv = 2, br = 3, ai = 0, Ft = 1, Rn = 2, Nn = 0, ei = 1, Ns = 2, Ps = 3, Ds = 4, ya = 5, Hv = 6, Xn = 100, vm = 101, ym = 102, $v = 103, Wv = 104, jr = 200, bm = 201, Sm = 202, Tm = 203, Rc = 204, Cc = 205, Mm = 206, Em = 207, wm = 208, Am = 209, Rm = 210, oM = 211, lM = 212, cM = 213, uM = 214, Nc = 0, Pc = 1, Dc = 2, Hs = 3, Lc = 4, Fc = 5, Ic = 6, Uc = 7, Qc = 0, qv = 1, Xv = 2, In = 0, Cm = 1, Nm = 2, Pm = 3, Dm = 4, jv = 5, Lm = 6, Fm = 7, Im = 300, nr = 301, Rr = 302, Co = 303, No = 304, Ra = 306, Ca = 1e3, fi = 1001, Na = 1002, Tt = 1003, Um = 1004, ts = 1005, Ot = 1006, Po = 1007, pi = 1008, Zt = 1009, ba = 1010, Sa = 1011, Ji = 1012, wn = 1013, Dt = 1014, ln = 1015, nn = 1016, rd = 1017, sd = 1018, Ci = 1020, ad = 35902, od = 35899, Bm = 1021, Jc = 1022, cn = 1023, Un = 1026, ii = 1027, eu = 1028, _l = 1029, ri = 1030, xl = 1031, hM = 1032, vl = 1033, Us = 33776, Bs = 33777, Os = 33778, ks = 33779, Bc = 35840, Oc = 35841, kc = 35842, Gc = 35843, Oo = 36196, ko = 37492, Go = 37496, Vo = 37488, zo = 37489, Pa = 37490, Ho = 37491, $o = 37808, Wo = 37809, qo = 37810, Xo = 37811, jo = 37812, Yo = 37813, Ko = 37814, Zo = 37815, Qo = 37816, Jo = 37817, el = 37818, tl = 37819, nl = 37820, il = 37821, rl = 36492, Ep = 36494, wp = 36495, sl = 36283, al = 36284, Da = 36285, ol = 36286, dM = 3200, wr = 0, Yv = 1, hi = "", Jn = "srgb", La = "srgb-linear", ll = "linear", Te = "srgb", Od = "", Kv = "rg", fM = "ga", pM = 0, ha = 7680, mM = 7681, gM = 7682, _M = 7683, xM = 34055, vM = 34056, yM = 5386, bM = 512, SM = 513, TM = 514, MM = 515, EM = 516, wM = 517, AM = 518, Ap = 519, Om = 512, ld = 513, km = 514, Xs = 515, Vc = 516, Gm = 517, us = 518, Vm = 519, cl = 35044, Dh = 35048, l_ = "300 es", si = 2e3, Cr = 2001, Sr = {
  COMPUTE: "compute",
  RENDER: "render"
}, rs = {
  TEXTURE_COMPARE: "depthTextureCompare"
};
function RM(i) {
  for (let e = i.length - 1; e >= 0; --e)
    if (i[e] >= 65535)
      return !0;
  return !1;
}
function Lh(i) {
  return ArrayBuffer.isView(i) && !(i instanceof DataView);
}
function zc(i) {
  return document.createElementNS("http://www.w3.org/1999/xhtml", i);
}
function Zv() {
  const i = zc("canvas");
  return i.style.display = "block", i;
}
const c_ = {};
function Hc(...i) {
  const e = "THREE." + i.shift();
  console.log(e, ...i);
}
function Qv(i) {
  const e = i[0];
  if (typeof e == "string" && e.startsWith("TSL:")) {
    const t = i[1];
    t && t.isStackTrace ? i[0] += " " + t.getLocation() : i[1] = 'Stack trace not available. Enable "THREE.Node.captureStackTrace" to capture stack traces.';
  }
  return i;
}
function oe(...i) {
  i = Qv(i);
  const e = "THREE." + i.shift();
  {
    const t = i[0];
    t && t.isStackTrace ? console.warn(t.getError(e)) : console.warn(e, ...i);
  }
}
function le(...i) {
  i = Qv(i);
  const e = "THREE." + i.shift();
  {
    const t = i[0];
    t && t.isStackTrace ? console.error(t.getError(e)) : console.error(e, ...i);
  }
}
function Pt(...i) {
  const e = i.join(" ");
  e in c_ || (c_[e] = !0, oe(...i));
}
function CM(i, e, t) {
  return new Promise(function(n, r) {
    function s() {
      switch (i.clientWaitSync(e, i.SYNC_FLUSH_COMMANDS_BIT, 0)) {
        case i.WAIT_FAILED:
          r();
          break;
        case i.TIMEOUT_EXPIRED:
          setTimeout(s, t);
          break;
        default:
          n();
      }
    }
    setTimeout(s, t);
  });
}
const zm = {
  [Nc]: Pc,
  [Dc]: Ic,
  [Lc]: Uc,
  [Hs]: Fc,
  [Pc]: Nc,
  [Ic]: Dc,
  [Uc]: Lc,
  [Fc]: Hs
};
class Fr {
  /**
   * Adds the given event listener to the given event type.
   *
   * @param {string} type - The type of event to listen to.
   * @param {Function} listener - The function that gets called when the event is fired.
   */
  addEventListener(e, t) {
    this._listeners === void 0 && (this._listeners = {});
    const n = this._listeners;
    n[e] === void 0 && (n[e] = []), n[e].indexOf(t) === -1 && n[e].push(t);
  }
  /**
   * Returns `true` if the given event listener has been added to the given event type.
   *
   * @param {string} type - The type of event.
   * @param {Function} listener - The listener to check.
   * @return {boolean} Whether the given event listener has been added to the given event type.
   */
  hasEventListener(e, t) {
    const n = this._listeners;
    return n === void 0 ? !1 : n[e] !== void 0 && n[e].indexOf(t) !== -1;
  }
  /**
   * Removes the given event listener from the given event type.
   *
   * @param {string} type - The type of event.
   * @param {Function} listener - The listener to remove.
   */
  removeEventListener(e, t) {
    const n = this._listeners;
    if (n === void 0)
      return;
    const r = n[e];
    if (r !== void 0) {
      const s = r.indexOf(t);
      s !== -1 && r.splice(s, 1);
    }
  }
  /**
   * Dispatches an event object.
   *
   * @param {Object} event - The event that gets fired.
   */
  dispatchEvent(e) {
    const t = this._listeners;
    if (t === void 0)
      return;
    const n = t[e.type];
    if (n !== void 0) {
      e.target = this;
      const r = n.slice(0);
      for (let s = 0, a = r.length; s < a; s++)
        r[s].call(this, e);
      e.target = null;
    }
  }
}
const zn = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"];
let u_ = 1234567;
const fc = Math.PI / 180, Fa = 180 / Math.PI;
function ss() {
  const i = Math.random() * 4294967295 | 0, e = Math.random() * 4294967295 | 0, t = Math.random() * 4294967295 | 0, n = Math.random() * 4294967295 | 0;
  return (zn[i & 255] + zn[i >> 8 & 255] + zn[i >> 16 & 255] + zn[i >> 24 & 255] + "-" + zn[e & 255] + zn[e >> 8 & 255] + "-" + zn[e >> 16 & 15 | 64] + zn[e >> 24 & 255] + "-" + zn[t & 63 | 128] + zn[t >> 8 & 255] + "-" + zn[t >> 16 & 255] + zn[t >> 24 & 255] + zn[n & 255] + zn[n >> 8 & 255] + zn[n >> 16 & 255] + zn[n >> 24 & 255]).toLowerCase();
}
function ct(i, e, t) {
  return Math.max(e, Math.min(t, i));
}
function Hm(i, e) {
  return (i % e + e) % e;
}
function NM(i, e, t, n, r) {
  return n + (i - e) * (r - n) / (t - e);
}
function PM(i, e, t) {
  return i !== e ? (t - i) / (e - i) : 0;
}
function pc(i, e, t) {
  return (1 - t) * i + t * e;
}
function DM(i, e, t, n) {
  return pc(i, e, 1 - Math.exp(-t * n));
}
function LM(i, e = 1) {
  return e - Math.abs(Hm(i, e * 2) - e);
}
function FM(i, e, t) {
  return i <= e ? 0 : i >= t ? 1 : (i = (i - e) / (t - e), i * i * (3 - 2 * i));
}
function IM(i, e, t) {
  return i <= e ? 0 : i >= t ? 1 : (i = (i - e) / (t - e), i * i * i * (i * (i * 6 - 15) + 10));
}
function UM(i, e) {
  return i + Math.floor(Math.random() * (e - i + 1));
}
function BM(i, e) {
  return i + Math.random() * (e - i);
}
function OM(i) {
  return i * (0.5 - Math.random());
}
function kM(i) {
  i !== void 0 && (u_ = i);
  let e = u_ += 1831565813;
  return e = Math.imul(e ^ e >>> 15, e | 1), e ^= e + Math.imul(e ^ e >>> 7, e | 61), ((e ^ e >>> 14) >>> 0) / 4294967296;
}
function GM(i) {
  return i * fc;
}
function VM(i) {
  return i * Fa;
}
function zM(i) {
  return (i & i - 1) === 0 && i !== 0;
}
function HM(i) {
  return Math.pow(2, Math.ceil(Math.log(i) / Math.LN2));
}
function $M(i) {
  return Math.pow(2, Math.floor(Math.log(i) / Math.LN2));
}
function WM(i, e, t, n, r) {
  const s = Math.cos, a = Math.sin, o = s(t / 2), l = a(t / 2), c = s((e + n) / 2), u = a((e + n) / 2), h = s((e - n) / 2), d = a((e - n) / 2), f = s((n - e) / 2), p = a((n - e) / 2);
  switch (r) {
    case "XYX":
      i.set(o * u, l * h, l * d, o * c);
      break;
    case "YZY":
      i.set(l * d, o * u, l * h, o * c);
      break;
    case "ZXZ":
      i.set(l * h, l * d, o * u, o * c);
      break;
    case "XZX":
      i.set(o * u, l * p, l * f, o * c);
      break;
    case "YXY":
      i.set(l * f, o * u, l * p, o * c);
      break;
    case "ZYZ":
      i.set(l * p, l * f, o * u, o * c);
      break;
    default:
      oe("MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + r);
  }
}
function ti(i, e) {
  switch (e.constructor) {
    case Float32Array:
      return i;
    case Uint32Array:
      return i / 4294967295;
    case Uint16Array:
      return i / 65535;
    case Uint8Array:
      return i / 255;
    case Int32Array:
      return Math.max(i / 2147483647, -1);
    case Int16Array:
      return Math.max(i / 32767, -1);
    case Int8Array:
      return Math.max(i / 127, -1);
    default:
      throw new Error("Invalid component type.");
  }
}
function lt(i, e) {
  switch (e.constructor) {
    case Float32Array:
      return i;
    case Uint32Array:
      return Math.round(i * 4294967295);
    case Uint16Array:
      return Math.round(i * 65535);
    case Uint8Array:
      return Math.round(i * 255);
    case Int32Array:
      return Math.round(i * 2147483647);
    case Int16Array:
      return Math.round(i * 32767);
    case Int8Array:
      return Math.round(i * 127);
    default:
      throw new Error("Invalid component type.");
  }
}
const Fh = {
  DEG2RAD: fc,
  RAD2DEG: Fa,
  /**
   * Generate a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier)
   * (universally unique identifier).
   *
   * @static
   * @method
   * @return {string} The UUID.
   */
  generateUUID: ss,
  /**
   * Clamps the given value between min and max.
   *
   * @static
   * @method
   * @param {number} value - The value to clamp.
   * @param {number} min - The min value.
   * @param {number} max - The max value.
   * @return {number} The clamped value.
   */
  clamp: ct,
  /**
   * Computes the Euclidean modulo of the given parameters that
   * is `( ( n % m ) + m ) % m`.
   *
   * @static
   * @method
   * @param {number} n - The first parameter.
   * @param {number} m - The second parameter.
   * @return {number} The Euclidean modulo.
   */
  euclideanModulo: Hm,
  /**
   * Performs a linear mapping from range `<a1, a2>` to range `<b1, b2>`
   * for the given value.
   *
   * @static
   * @method
   * @param {number} x - The value to be mapped.
   * @param {number} a1 - Minimum value for range A.
   * @param {number} a2 - Maximum value for range A.
   * @param {number} b1 - Minimum value for range B.
   * @param {number} b2 - Maximum value for range B.
   * @return {number} The mapped value.
   */
  mapLinear: NM,
  /**
   * Returns the percentage in the closed interval `[0, 1]` of the given value
   * between the start and end point.
   *
   * @static
   * @method
   * @param {number} x - The start point
   * @param {number} y - The end point.
   * @param {number} value - A value between start and end.
   * @return {number} The interpolation factor.
   */
  inverseLerp: PM,
  /**
   * Returns a value linearly interpolated from two known points based on the given interval -
   * `t = 0` will return `x` and `t = 1` will return `y`.
   *
   * @static
   * @method
   * @param {number} x - The start point
   * @param {number} y - The end point.
   * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
   * @return {number} The interpolated value.
   */
  lerp: pc,
  /**
   * Smoothly interpolate a number from `x` to `y` in  a spring-like manner using a delta
   * time to maintain frame rate independent movement. For details, see
   * [Frame rate independent damping using lerp](http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/).
   *
   * @static
   * @method
   * @param {number} x - The current point.
   * @param {number} y - The target point.
   * @param {number} lambda - A higher lambda value will make the movement more sudden,
   * and a lower value will make the movement more gradual.
   * @param {number} dt - Delta time in seconds.
   * @return {number} The interpolated value.
   */
  damp: DM,
  /**
   * Returns a value that alternates between `0` and the given `length` parameter.
   *
   * @static
   * @method
   * @param {number} x - The value to pingpong.
   * @param {number} [length=1] - The positive value the function will pingpong to.
   * @return {number} The alternated value.
   */
  pingpong: LM,
  /**
   * Returns a value in the range `[0,1]` that represents the percentage that `x` has
   * moved between `min` and `max`, but smoothed or slowed down the closer `x` is to
   * the `min` and `max`.
   *
   * See [Smoothstep](http://en.wikipedia.org/wiki/Smoothstep) for more details.
   *
   * @static
   * @method
   * @param {number} x - The value to evaluate based on its position between min and max.
   * @param {number} min - The min value. Any x value below min will be `0`.
   * @param {number} max - The max value. Any x value above max will be `1`.
   * @return {number} The alternated value.
   */
  smoothstep: FM,
  /**
   * A [variation on smoothstep](https://en.wikipedia.org/wiki/Smoothstep#Variations)
   * that has zero 1st and 2nd order derivatives at x=0 and x=1.
   *
   * @static
   * @method
   * @param {number} x - The value to evaluate based on its position between min and max.
   * @param {number} min - The min value. Any x value below min will be `0`.
   * @param {number} max - The max value. Any x value above max will be `1`.
   * @return {number} The alternated value.
   */
  smootherstep: IM,
  /**
   * Returns a random integer from `<low, high>` interval.
   *
   * @static
   * @method
   * @param {number} low - The lower value boundary.
   * @param {number} high - The upper value boundary
   * @return {number} A random integer.
   */
  randInt: UM,
  /**
   * Returns a random float from `<low, high>` interval.
   *
   * @static
   * @method
   * @param {number} low - The lower value boundary.
   * @param {number} high - The upper value boundary
   * @return {number} A random float.
   */
  randFloat: BM,
  /**
   * Returns a random integer from `<-range/2, range/2>` interval.
   *
   * @static
   * @method
   * @param {number} range - Defines the value range.
   * @return {number} A random float.
   */
  randFloatSpread: OM,
  /**
   * Returns a deterministic pseudo-random float in the interval `[0, 1]`.
   *
   * @static
   * @method
   * @param {number} [s] - The integer seed.
   * @return {number} A random float.
   */
  seededRandom: kM,
  /**
   * Converts degrees to radians.
   *
   * @static
   * @method
   * @param {number} degrees - A value in degrees.
   * @return {number} The converted value in radians.
   */
  degToRad: GM,
  /**
   * Converts radians to degrees.
   *
   * @static
   * @method
   * @param {number} radians - A value in radians.
   * @return {number} The converted value in degrees.
   */
  radToDeg: VM,
  /**
   * Returns `true` if the given number is a power of two.
   *
   * @static
   * @method
   * @param {number} value - The value to check.
   * @return {boolean} Whether the given number is a power of two or not.
   */
  isPowerOfTwo: zM,
  /**
   * Returns the smallest power of two that is greater than or equal to the given number.
   *
   * @static
   * @method
   * @param {number} value - The value to find a POT for.
   * @return {number} The smallest power of two that is greater than or equal to the given number.
   */
  ceilPowerOfTwo: HM,
  /**
   * Returns the largest power of two that is less than or equal to the given number.
   *
   * @static
   * @method
   * @param {number} value - The value to find a POT for.
   * @return {number} The largest power of two that is less than or equal to the given number.
   */
  floorPowerOfTwo: $M,
  /**
   * Sets the given quaternion from the [Intrinsic Proper Euler Angles](https://en.wikipedia.org/wiki/Euler_angles)
   * defined by the given angles and order.
   *
   * Rotations are applied to the axes in the order specified by order:
   * rotation by angle `a` is applied first, then by angle `b`, then by angle `c`.
   *
   * @static
   * @method
   * @param {Quaternion} q - The quaternion to set.
   * @param {number} a - The rotation applied to the first axis, in radians.
   * @param {number} b - The rotation applied to the second axis, in radians.
   * @param {number} c - The rotation applied to the third axis, in radians.
   * @param {('XYX'|'XZX'|'YXY'|'YZY'|'ZXZ'|'ZYZ')} order - A string specifying the axes order.
   */
  setQuaternionFromProperEuler: WM,
  /**
   * Normalizes the given value according to the given typed array.
   *
   * @static
   * @method
   * @param {number} value - The float value in the range `[0,1]` to normalize.
   * @param {TypedArray} array - The typed array that defines the data type of the value.
   * @return {number} The normalize value.
   */
  normalize: lt,
  /**
   * Denormalizes the given value according to the given typed array.
   *
   * @static
   * @method
   * @param {number} value - The value to denormalize.
   * @param {TypedArray} array - The typed array that defines the data type of the value.
   * @return {number} The denormalize (float) value in the range `[0,1]`.
   */
  denormalize: ti
};
class de {
  /**
   * Constructs a new 2D vector.
   *
   * @param {number} [x=0] - The x value of this vector.
   * @param {number} [y=0] - The y value of this vector.
   */
  constructor(e = 0, t = 0) {
    de.prototype.isVector2 = !0, this.x = e, this.y = t;
  }
  /**
   * Alias for {@link Vector2#x}.
   *
   * @type {number}
   */
  get width() {
    return this.x;
  }
  set width(e) {
    this.x = e;
  }
  /**
   * Alias for {@link Vector2#y}.
   *
   * @type {number}
   */
  get height() {
    return this.y;
  }
  set height(e) {
    this.y = e;
  }
  /**
   * Sets the vector components.
   *
   * @param {number} x - The value of the x component.
   * @param {number} y - The value of the y component.
   * @return {Vector2} A reference to this vector.
   */
  set(e, t) {
    return this.x = e, this.y = t, this;
  }
  /**
   * Sets the vector components to the same value.
   *
   * @param {number} scalar - The value to set for all vector components.
   * @return {Vector2} A reference to this vector.
   */
  setScalar(e) {
    return this.x = e, this.y = e, this;
  }
  /**
   * Sets the vector's x component to the given value
   *
   * @param {number} x - The value to set.
   * @return {Vector2} A reference to this vector.
   */
  setX(e) {
    return this.x = e, this;
  }
  /**
   * Sets the vector's y component to the given value
   *
   * @param {number} y - The value to set.
   * @return {Vector2} A reference to this vector.
   */
  setY(e) {
    return this.y = e, this;
  }
  /**
   * Allows to set a vector component with an index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y.
   * @param {number} value - The value to set.
   * @return {Vector2} A reference to this vector.
   */
  setComponent(e, t) {
    switch (e) {
      case 0:
        this.x = t;
        break;
      case 1:
        this.y = t;
        break;
      default:
        throw new Error("index is out of range: " + e);
    }
    return this;
  }
  /**
   * Returns the value of the vector component which matches the given index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y.
   * @return {number} A vector component value.
   */
  getComponent(e) {
    switch (e) {
      case 0:
        return this.x;
      case 1:
        return this.y;
      default:
        throw new Error("index is out of range: " + e);
    }
  }
  /**
   * Returns a new vector with copied values from this instance.
   *
   * @return {Vector2} A clone of this instance.
   */
  clone() {
    return new this.constructor(this.x, this.y);
  }
  /**
   * Copies the values of the given vector to this instance.
   *
   * @param {Vector2} v - The vector to copy.
   * @return {Vector2} A reference to this vector.
   */
  copy(e) {
    return this.x = e.x, this.y = e.y, this;
  }
  /**
   * Adds the given vector to this instance.
   *
   * @param {Vector2} v - The vector to add.
   * @return {Vector2} A reference to this vector.
   */
  add(e) {
    return this.x += e.x, this.y += e.y, this;
  }
  /**
   * Adds the given scalar value to all components of this instance.
   *
   * @param {number} s - The scalar to add.
   * @return {Vector2} A reference to this vector.
   */
  addScalar(e) {
    return this.x += e, this.y += e, this;
  }
  /**
   * Adds the given vectors and stores the result in this instance.
   *
   * @param {Vector2} a - The first vector.
   * @param {Vector2} b - The second vector.
   * @return {Vector2} A reference to this vector.
   */
  addVectors(e, t) {
    return this.x = e.x + t.x, this.y = e.y + t.y, this;
  }
  /**
   * Adds the given vector scaled by the given factor to this instance.
   *
   * @param {Vector2} v - The vector.
   * @param {number} s - The factor that scales `v`.
   * @return {Vector2} A reference to this vector.
   */
  addScaledVector(e, t) {
    return this.x += e.x * t, this.y += e.y * t, this;
  }
  /**
   * Subtracts the given vector from this instance.
   *
   * @param {Vector2} v - The vector to subtract.
   * @return {Vector2} A reference to this vector.
   */
  sub(e) {
    return this.x -= e.x, this.y -= e.y, this;
  }
  /**
   * Subtracts the given scalar value from all components of this instance.
   *
   * @param {number} s - The scalar to subtract.
   * @return {Vector2} A reference to this vector.
   */
  subScalar(e) {
    return this.x -= e, this.y -= e, this;
  }
  /**
   * Subtracts the given vectors and stores the result in this instance.
   *
   * @param {Vector2} a - The first vector.
   * @param {Vector2} b - The second vector.
   * @return {Vector2} A reference to this vector.
   */
  subVectors(e, t) {
    return this.x = e.x - t.x, this.y = e.y - t.y, this;
  }
  /**
   * Multiplies the given vector with this instance.
   *
   * @param {Vector2} v - The vector to multiply.
   * @return {Vector2} A reference to this vector.
   */
  multiply(e) {
    return this.x *= e.x, this.y *= e.y, this;
  }
  /**
   * Multiplies the given scalar value with all components of this instance.
   *
   * @param {number} scalar - The scalar to multiply.
   * @return {Vector2} A reference to this vector.
   */
  multiplyScalar(e) {
    return this.x *= e, this.y *= e, this;
  }
  /**
   * Divides this instance by the given vector.
   *
   * @param {Vector2} v - The vector to divide.
   * @return {Vector2} A reference to this vector.
   */
  divide(e) {
    return this.x /= e.x, this.y /= e.y, this;
  }
  /**
   * Divides this vector by the given scalar.
   *
   * @param {number} scalar - The scalar to divide.
   * @return {Vector2} A reference to this vector.
   */
  divideScalar(e) {
    return this.multiplyScalar(1 / e);
  }
  /**
   * Multiplies this vector (with an implicit 1 as the 3rd component) by
   * the given 3x3 matrix.
   *
   * @param {Matrix3} m - The matrix to apply.
   * @return {Vector2} A reference to this vector.
   */
  applyMatrix3(e) {
    const t = this.x, n = this.y, r = e.elements;
    return this.x = r[0] * t + r[3] * n + r[6], this.y = r[1] * t + r[4] * n + r[7], this;
  }
  /**
   * If this vector's x or y value is greater than the given vector's x or y
   * value, replace that value with the corresponding min value.
   *
   * @param {Vector2} v - The vector.
   * @return {Vector2} A reference to this vector.
   */
  min(e) {
    return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this;
  }
  /**
   * If this vector's x or y value is less than the given vector's x or y
   * value, replace that value with the corresponding max value.
   *
   * @param {Vector2} v - The vector.
   * @return {Vector2} A reference to this vector.
   */
  max(e) {
    return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this;
  }
  /**
   * If this vector's x or y value is greater than the max vector's x or y
   * value, it is replaced by the corresponding value.
   * If this vector's x or y value is less than the min vector's x or y value,
   * it is replaced by the corresponding value.
   *
   * @param {Vector2} min - The minimum x and y values.
   * @param {Vector2} max - The maximum x and y values in the desired range.
   * @return {Vector2} A reference to this vector.
   */
  clamp(e, t) {
    return this.x = ct(this.x, e.x, t.x), this.y = ct(this.y, e.y, t.y), this;
  }
  /**
   * If this vector's x or y values are greater than the max value, they are
   * replaced by the max value.
   * If this vector's x or y values are less than the min value, they are
   * replaced by the min value.
   *
   * @param {number} minVal - The minimum value the components will be clamped to.
   * @param {number} maxVal - The maximum value the components will be clamped to.
   * @return {Vector2} A reference to this vector.
   */
  clampScalar(e, t) {
    return this.x = ct(this.x, e, t), this.y = ct(this.y, e, t), this;
  }
  /**
   * If this vector's length is greater than the max value, it is replaced by
   * the max value.
   * If this vector's length is less than the min value, it is replaced by the
   * min value.
   *
   * @param {number} min - The minimum value the vector length will be clamped to.
   * @param {number} max - The maximum value the vector length will be clamped to.
   * @return {Vector2} A reference to this vector.
   */
  clampLength(e, t) {
    const n = this.length();
    return this.divideScalar(n || 1).multiplyScalar(ct(n, e, t));
  }
  /**
   * The components of this vector are rounded down to the nearest integer value.
   *
   * @return {Vector2} A reference to this vector.
   */
  floor() {
    return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this;
  }
  /**
   * The components of this vector are rounded up to the nearest integer value.
   *
   * @return {Vector2} A reference to this vector.
   */
  ceil() {
    return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this;
  }
  /**
   * The components of this vector are rounded to the nearest integer value
   *
   * @return {Vector2} A reference to this vector.
   */
  round() {
    return this.x = Math.round(this.x), this.y = Math.round(this.y), this;
  }
  /**
   * The components of this vector are rounded towards zero (up if negative,
   * down if positive) to an integer value.
   *
   * @return {Vector2} A reference to this vector.
   */
  roundToZero() {
    return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this;
  }
  /**
   * Inverts this vector - i.e. sets x = -x and y = -y.
   *
   * @return {Vector2} A reference to this vector.
   */
  negate() {
    return this.x = -this.x, this.y = -this.y, this;
  }
  /**
   * Calculates the dot product of the given vector with this instance.
   *
   * @param {Vector2} v - The vector to compute the dot product with.
   * @return {number} The result of the dot product.
   */
  dot(e) {
    return this.x * e.x + this.y * e.y;
  }
  /**
   * Calculates the cross product of the given vector with this instance.
   *
   * @param {Vector2} v - The vector to compute the cross product with.
   * @return {number} The result of the cross product.
   */
  cross(e) {
    return this.x * e.y - this.y * e.x;
  }
  /**
   * Computes the square of the Euclidean length (straight-line length) from
   * (0, 0) to (x, y). If you are comparing the lengths of vectors, you should
   * compare the length squared instead as it is slightly more efficient to calculate.
   *
   * @return {number} The square length of this vector.
   */
  lengthSq() {
    return this.x * this.x + this.y * this.y;
  }
  /**
   * Computes the  Euclidean length (straight-line length) from (0, 0) to (x, y).
   *
   * @return {number} The length of this vector.
   */
  length() {
    return Math.sqrt(this.x * this.x + this.y * this.y);
  }
  /**
   * Computes the Manhattan length of this vector.
   *
   * @return {number} The length of this vector.
   */
  manhattanLength() {
    return Math.abs(this.x) + Math.abs(this.y);
  }
  /**
   * Converts this vector to a unit vector - that is, sets it equal to a vector
   * with the same direction as this one, but with a vector length of `1`.
   *
   * @return {Vector2} A reference to this vector.
   */
  normalize() {
    return this.divideScalar(this.length() || 1);
  }
  /**
   * Computes the angle in radians of this vector with respect to the positive x-axis.
   *
   * @return {number} The angle in radians.
   */
  angle() {
    return Math.atan2(-this.y, -this.x) + Math.PI;
  }
  /**
   * Returns the angle between the given vector and this instance in radians.
   *
   * @param {Vector2} v - The vector to compute the angle with.
   * @return {number} The angle in radians.
   */
  angleTo(e) {
    const t = Math.sqrt(this.lengthSq() * e.lengthSq());
    if (t === 0)
      return Math.PI / 2;
    const n = this.dot(e) / t;
    return Math.acos(ct(n, -1, 1));
  }
  /**
   * Computes the distance from the given vector to this instance.
   *
   * @param {Vector2} v - The vector to compute the distance to.
   * @return {number} The distance.
   */
  distanceTo(e) {
    return Math.sqrt(this.distanceToSquared(e));
  }
  /**
   * Computes the squared distance from the given vector to this instance.
   * If you are just comparing the distance with another distance, you should compare
   * the distance squared instead as it is slightly more efficient to calculate.
   *
   * @param {Vector2} v - The vector to compute the squared distance to.
   * @return {number} The squared distance.
   */
  distanceToSquared(e) {
    const t = this.x - e.x, n = this.y - e.y;
    return t * t + n * n;
  }
  /**
   * Computes the Manhattan distance from the given vector to this instance.
   *
   * @param {Vector2} v - The vector to compute the Manhattan distance to.
   * @return {number} The Manhattan distance.
   */
  manhattanDistanceTo(e) {
    return Math.abs(this.x - e.x) + Math.abs(this.y - e.y);
  }
  /**
   * Sets this vector to a vector with the same direction as this one, but
   * with the specified length.
   *
   * @param {number} length - The new length of this vector.
   * @return {Vector2} A reference to this vector.
   */
  setLength(e) {
    return this.normalize().multiplyScalar(e);
  }
  /**
   * Linearly interpolates between the given vector and this instance, where
   * alpha is the percent distance along the line - alpha = 0 will be this
   * vector, and alpha = 1 will be the given one.
   *
   * @param {Vector2} v - The vector to interpolate towards.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector2} A reference to this vector.
   */
  lerp(e, t) {
    return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this;
  }
  /**
   * Linearly interpolates between the given vectors, where alpha is the percent
   * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
   * be the second one. The result is stored in this instance.
   *
   * @param {Vector2} v1 - The first vector.
   * @param {Vector2} v2 - The second vector.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector2} A reference to this vector.
   */
  lerpVectors(e, t, n) {
    return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this;
  }
  /**
   * Returns `true` if this vector is equal with the given one.
   *
   * @param {Vector2} v - The vector to test for equality.
   * @return {boolean} Whether this vector is equal with the given one.
   */
  equals(e) {
    return e.x === this.x && e.y === this.y;
  }
  /**
   * Sets this vector's x value to be `array[ offset ]` and y
   * value to be `array[ offset + 1 ]`.
   *
   * @param {Array<number>} array - An array holding the vector component values.
   * @param {number} [offset=0] - The offset into the array.
   * @return {Vector2} A reference to this vector.
   */
  fromArray(e, t = 0) {
    return this.x = e[t], this.y = e[t + 1], this;
  }
  /**
   * Writes the components of this vector to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the vector components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The vector components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this.x, e[t + 1] = this.y, e;
  }
  /**
   * Sets the components of this vector from the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
   * @param {number} index - The index into the attribute.
   * @return {Vector2} A reference to this vector.
   */
  fromBufferAttribute(e, t) {
    return this.x = e.getX(t), this.y = e.getY(t), this;
  }
  /**
   * Rotates this vector around the given center by the given angle.
   *
   * @param {Vector2} center - The point around which to rotate.
   * @param {number} angle - The angle to rotate, in radians.
   * @return {Vector2} A reference to this vector.
   */
  rotateAround(e, t) {
    const n = Math.cos(t), r = Math.sin(t), s = this.x - e.x, a = this.y - e.y;
    return this.x = s * n - a * r + e.x, this.y = s * r + a * n + e.y, this;
  }
  /**
   * Sets each component of this vector to a pseudo-random value between `0` and
   * `1`, excluding `1`.
   *
   * @return {Vector2} A reference to this vector.
   */
  random() {
    return this.x = Math.random(), this.y = Math.random(), this;
  }
  *[Symbol.iterator]() {
    yield this.x, yield this.y;
  }
}
class Gi {
  /**
   * Constructs a new quaternion.
   *
   * @param {number} [x=0] - The x value of this quaternion.
   * @param {number} [y=0] - The y value of this quaternion.
   * @param {number} [z=0] - The z value of this quaternion.
   * @param {number} [w=1] - The w value of this quaternion.
   */
  constructor(e = 0, t = 0, n = 0, r = 1) {
    this.isQuaternion = !0, this._x = e, this._y = t, this._z = n, this._w = r;
  }
  /**
   * Interpolates between two quaternions via SLERP. This implementation assumes the
   * quaternion data are managed in flat arrays.
   *
   * @param {Array<number>} dst - The destination array.
   * @param {number} dstOffset - An offset into the destination array.
   * @param {Array<number>} src0 - The source array of the first quaternion.
   * @param {number} srcOffset0 - An offset into the first source array.
   * @param {Array<number>} src1 -  The source array of the second quaternion.
   * @param {number} srcOffset1 - An offset into the second source array.
   * @param {number} t - The interpolation factor. A value in the range `[0,1]` will interpolate. A value outside the range `[0,1]` will extrapolate.
   * @see {@link Quaternion#slerp}
   */
  static slerpFlat(e, t, n, r, s, a, o) {
    let l = n[r + 0], c = n[r + 1], u = n[r + 2], h = n[r + 3], d = s[a + 0], f = s[a + 1], p = s[a + 2], _ = s[a + 3];
    if (h !== _ || l !== d || c !== f || u !== p) {
      let g = l * d + c * f + u * p + h * _;
      g < 0 && (d = -d, f = -f, p = -p, _ = -_, g = -g);
      let m = 1 - o;
      if (g < 0.9995) {
        const x = Math.acos(g), y = Math.sin(x);
        m = Math.sin(m * x) / y, o = Math.sin(o * x) / y, l = l * m + d * o, c = c * m + f * o, u = u * m + p * o, h = h * m + _ * o;
      } else {
        l = l * m + d * o, c = c * m + f * o, u = u * m + p * o, h = h * m + _ * o;
        const x = 1 / Math.sqrt(l * l + c * c + u * u + h * h);
        l *= x, c *= x, u *= x, h *= x;
      }
    }
    e[t] = l, e[t + 1] = c, e[t + 2] = u, e[t + 3] = h;
  }
  /**
   * Multiplies two quaternions. This implementation assumes the quaternion data are managed
   * in flat arrays.
   *
   * @param {Array<number>} dst - The destination array.
   * @param {number} dstOffset - An offset into the destination array.
   * @param {Array<number>} src0 - The source array of the first quaternion.
   * @param {number} srcOffset0 - An offset into the first source array.
   * @param {Array<number>} src1 -  The source array of the second quaternion.
   * @param {number} srcOffset1 - An offset into the second source array.
   * @return {Array<number>} The destination array.
   * @see {@link Quaternion#multiplyQuaternions}.
   */
  static multiplyQuaternionsFlat(e, t, n, r, s, a) {
    const o = n[r], l = n[r + 1], c = n[r + 2], u = n[r + 3], h = s[a], d = s[a + 1], f = s[a + 2], p = s[a + 3];
    return e[t] = o * p + u * h + l * f - c * d, e[t + 1] = l * p + u * d + c * h - o * f, e[t + 2] = c * p + u * f + o * d - l * h, e[t + 3] = u * p - o * h - l * d - c * f, e;
  }
  /**
   * The x value of this quaternion.
   *
   * @type {number}
   * @default 0
   */
  get x() {
    return this._x;
  }
  set x(e) {
    this._x = e, this._onChangeCallback();
  }
  /**
   * The y value of this quaternion.
   *
   * @type {number}
   * @default 0
   */
  get y() {
    return this._y;
  }
  set y(e) {
    this._y = e, this._onChangeCallback();
  }
  /**
   * The z value of this quaternion.
   *
   * @type {number}
   * @default 0
   */
  get z() {
    return this._z;
  }
  set z(e) {
    this._z = e, this._onChangeCallback();
  }
  /**
   * The w value of this quaternion.
   *
   * @type {number}
   * @default 1
   */
  get w() {
    return this._w;
  }
  set w(e) {
    this._w = e, this._onChangeCallback();
  }
  /**
   * Sets the quaternion components.
   *
   * @param {number} x - The x value of this quaternion.
   * @param {number} y - The y value of this quaternion.
   * @param {number} z - The z value of this quaternion.
   * @param {number} w - The w value of this quaternion.
   * @return {Quaternion} A reference to this quaternion.
   */
  set(e, t, n, r) {
    return this._x = e, this._y = t, this._z = n, this._w = r, this._onChangeCallback(), this;
  }
  /**
   * Returns a new quaternion with copied values from this instance.
   *
   * @return {Quaternion} A clone of this instance.
   */
  clone() {
    return new this.constructor(this._x, this._y, this._z, this._w);
  }
  /**
   * Copies the values of the given quaternion to this instance.
   *
   * @param {Quaternion} quaternion - The quaternion to copy.
   * @return {Quaternion} A reference to this quaternion.
   */
  copy(e) {
    return this._x = e.x, this._y = e.y, this._z = e.z, this._w = e.w, this._onChangeCallback(), this;
  }
  /**
   * Sets this quaternion from the rotation specified by the given
   * Euler angles.
   *
   * @param {Euler} euler - The Euler angles.
   * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
   * @return {Quaternion} A reference to this quaternion.
   */
  setFromEuler(e, t = !0) {
    const n = e._x, r = e._y, s = e._z, a = e._order, o = Math.cos, l = Math.sin, c = o(n / 2), u = o(r / 2), h = o(s / 2), d = l(n / 2), f = l(r / 2), p = l(s / 2);
    switch (a) {
      case "XYZ":
        this._x = d * u * h + c * f * p, this._y = c * f * h - d * u * p, this._z = c * u * p + d * f * h, this._w = c * u * h - d * f * p;
        break;
      case "YXZ":
        this._x = d * u * h + c * f * p, this._y = c * f * h - d * u * p, this._z = c * u * p - d * f * h, this._w = c * u * h + d * f * p;
        break;
      case "ZXY":
        this._x = d * u * h - c * f * p, this._y = c * f * h + d * u * p, this._z = c * u * p + d * f * h, this._w = c * u * h - d * f * p;
        break;
      case "ZYX":
        this._x = d * u * h - c * f * p, this._y = c * f * h + d * u * p, this._z = c * u * p - d * f * h, this._w = c * u * h + d * f * p;
        break;
      case "YZX":
        this._x = d * u * h + c * f * p, this._y = c * f * h + d * u * p, this._z = c * u * p - d * f * h, this._w = c * u * h - d * f * p;
        break;
      case "XZY":
        this._x = d * u * h - c * f * p, this._y = c * f * h - d * u * p, this._z = c * u * p + d * f * h, this._w = c * u * h + d * f * p;
        break;
      default:
        oe("Quaternion: .setFromEuler() encountered an unknown order: " + a);
    }
    return t === !0 && this._onChangeCallback(), this;
  }
  /**
   * Sets this quaternion from the given axis and angle.
   *
   * @param {Vector3} axis - The normalized axis.
   * @param {number} angle - The angle in radians.
   * @return {Quaternion} A reference to this quaternion.
   */
  setFromAxisAngle(e, t) {
    const n = t / 2, r = Math.sin(n);
    return this._x = e.x * r, this._y = e.y * r, this._z = e.z * r, this._w = Math.cos(n), this._onChangeCallback(), this;
  }
  /**
   * Sets this quaternion from the given rotation matrix.
   *
   * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
   * @return {Quaternion} A reference to this quaternion.
   */
  setFromRotationMatrix(e) {
    const t = e.elements, n = t[0], r = t[4], s = t[8], a = t[1], o = t[5], l = t[9], c = t[2], u = t[6], h = t[10], d = n + o + h;
    if (d > 0) {
      const f = 0.5 / Math.sqrt(d + 1);
      this._w = 0.25 / f, this._x = (u - l) * f, this._y = (s - c) * f, this._z = (a - r) * f;
    } else if (n > o && n > h) {
      const f = 2 * Math.sqrt(1 + n - o - h);
      this._w = (u - l) / f, this._x = 0.25 * f, this._y = (r + a) / f, this._z = (s + c) / f;
    } else if (o > h) {
      const f = 2 * Math.sqrt(1 + o - n - h);
      this._w = (s - c) / f, this._x = (r + a) / f, this._y = 0.25 * f, this._z = (l + u) / f;
    } else {
      const f = 2 * Math.sqrt(1 + h - n - o);
      this._w = (a - r) / f, this._x = (s + c) / f, this._y = (l + u) / f, this._z = 0.25 * f;
    }
    return this._onChangeCallback(), this;
  }
  /**
   * Sets this quaternion to the rotation required to rotate the direction vector
   * `vFrom` to the direction vector `vTo`.
   *
   * @param {Vector3} vFrom - The first (normalized) direction vector.
   * @param {Vector3} vTo - The second (normalized) direction vector.
   * @return {Quaternion} A reference to this quaternion.
   */
  setFromUnitVectors(e, t) {
    let n = e.dot(t) + 1;
    return n < 1e-8 ? (n = 0, Math.abs(e.x) > Math.abs(e.z) ? (this._x = -e.y, this._y = e.x, this._z = 0, this._w = n) : (this._x = 0, this._y = -e.z, this._z = e.y, this._w = n)) : (this._x = e.y * t.z - e.z * t.y, this._y = e.z * t.x - e.x * t.z, this._z = e.x * t.y - e.y * t.x, this._w = n), this.normalize();
  }
  /**
   * Returns the angle between this quaternion and the given one in radians.
   *
   * @param {Quaternion} q - The quaternion to compute the angle with.
   * @return {number} The angle in radians.
   */
  angleTo(e) {
    return 2 * Math.acos(Math.abs(ct(this.dot(e), -1, 1)));
  }
  /**
   * Rotates this quaternion by a given angular step to the given quaternion.
   * The method ensures that the final quaternion will not overshoot `q`.
   *
   * @param {Quaternion} q - The target quaternion.
   * @param {number} step - The angular step in radians.
   * @return {Quaternion} A reference to this quaternion.
   */
  rotateTowards(e, t) {
    const n = this.angleTo(e);
    if (n === 0)
      return this;
    const r = Math.min(1, t / n);
    return this.slerp(e, r), this;
  }
  /**
   * Sets this quaternion to the identity quaternion; that is, to the
   * quaternion that represents "no rotation".
   *
   * @return {Quaternion} A reference to this quaternion.
   */
  identity() {
    return this.set(0, 0, 0, 1);
  }
  /**
   * Inverts this quaternion via {@link Quaternion#conjugate}. The
   * quaternion is assumed to have unit length.
   *
   * @return {Quaternion} A reference to this quaternion.
   */
  invert() {
    return this.conjugate();
  }
  /**
   * Returns the rotational conjugate of this quaternion. The conjugate of a
   * quaternion represents the same rotation in the opposite direction about
   * the rotational axis.
   *
   * @return {Quaternion} A reference to this quaternion.
   */
  conjugate() {
    return this._x *= -1, this._y *= -1, this._z *= -1, this._onChangeCallback(), this;
  }
  /**
   * Calculates the dot product of this quaternion and the given one.
   *
   * @param {Quaternion} v - The quaternion to compute the dot product with.
   * @return {number} The result of the dot product.
   */
  dot(e) {
    return this._x * e._x + this._y * e._y + this._z * e._z + this._w * e._w;
  }
  /**
   * Computes the squared Euclidean length (straight-line length) of this quaternion,
   * considered as a 4 dimensional vector. This can be useful if you are comparing the
   * lengths of two quaternions, as this is a slightly more efficient calculation than
   * {@link Quaternion#length}.
   *
   * @return {number} The squared Euclidean length.
   */
  lengthSq() {
    return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
  }
  /**
   * Computes the Euclidean length (straight-line length) of this quaternion,
   * considered as a 4 dimensional vector.
   *
   * @return {number} The Euclidean length.
   */
  length() {
    return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
  }
  /**
   * Normalizes this quaternion - that is, calculated the quaternion that performs
   * the same rotation as this one, but has a length equal to `1`.
   *
   * @return {Quaternion} A reference to this quaternion.
   */
  normalize() {
    let e = this.length();
    return e === 0 ? (this._x = 0, this._y = 0, this._z = 0, this._w = 1) : (e = 1 / e, this._x = this._x * e, this._y = this._y * e, this._z = this._z * e, this._w = this._w * e), this._onChangeCallback(), this;
  }
  /**
   * Multiplies this quaternion by the given one.
   *
   * @param {Quaternion} q - The quaternion.
   * @return {Quaternion} A reference to this quaternion.
   */
  multiply(e) {
    return this.multiplyQuaternions(this, e);
  }
  /**
   * Pre-multiplies this quaternion by the given one.
   *
   * @param {Quaternion} q - The quaternion.
   * @return {Quaternion} A reference to this quaternion.
   */
  premultiply(e) {
    return this.multiplyQuaternions(e, this);
  }
  /**
   * Multiplies the given quaternions and stores the result in this instance.
   *
   * @param {Quaternion} a - The first quaternion.
   * @param {Quaternion} b - The second quaternion.
   * @return {Quaternion} A reference to this quaternion.
   */
  multiplyQuaternions(e, t) {
    const n = e._x, r = e._y, s = e._z, a = e._w, o = t._x, l = t._y, c = t._z, u = t._w;
    return this._x = n * u + a * o + r * c - s * l, this._y = r * u + a * l + s * o - n * c, this._z = s * u + a * c + n * l - r * o, this._w = a * u - n * o - r * l - s * c, this._onChangeCallback(), this;
  }
  /**
   * Performs a spherical linear interpolation between this quaternion and the target quaternion.
   *
   * @param {Quaternion} qb - The target quaternion.
   * @param {number} t - The interpolation factor. A value in the range `[0,1]` will interpolate. A value outside the range `[0,1]` will extrapolate.
   * @return {Quaternion} A reference to this quaternion.
   */
  slerp(e, t) {
    let n = e._x, r = e._y, s = e._z, a = e._w, o = this.dot(e);
    o < 0 && (n = -n, r = -r, s = -s, a = -a, o = -o);
    let l = 1 - t;
    if (o < 0.9995) {
      const c = Math.acos(o), u = Math.sin(c);
      l = Math.sin(l * c) / u, t = Math.sin(t * c) / u, this._x = this._x * l + n * t, this._y = this._y * l + r * t, this._z = this._z * l + s * t, this._w = this._w * l + a * t, this._onChangeCallback();
    } else
      this._x = this._x * l + n * t, this._y = this._y * l + r * t, this._z = this._z * l + s * t, this._w = this._w * l + a * t, this.normalize();
    return this;
  }
  /**
   * Performs a spherical linear interpolation between the given quaternions
   * and stores the result in this quaternion.
   *
   * @param {Quaternion} qa - The source quaternion.
   * @param {Quaternion} qb - The target quaternion.
   * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
   * @return {Quaternion} A reference to this quaternion.
   */
  slerpQuaternions(e, t, n) {
    return this.copy(e).slerp(t, n);
  }
  /**
   * Sets this quaternion to a uniformly random, normalized quaternion.
   *
   * @return {Quaternion} A reference to this quaternion.
   */
  random() {
    const e = 2 * Math.PI * Math.random(), t = 2 * Math.PI * Math.random(), n = Math.random(), r = Math.sqrt(1 - n), s = Math.sqrt(n);
    return this.set(
      r * Math.sin(e),
      r * Math.cos(e),
      s * Math.sin(t),
      s * Math.cos(t)
    );
  }
  /**
   * Returns `true` if this quaternion is equal with the given one.
   *
   * @param {Quaternion} quaternion - The quaternion to test for equality.
   * @return {boolean} Whether this quaternion is equal with the given one.
   */
  equals(e) {
    return e._x === this._x && e._y === this._y && e._z === this._z && e._w === this._w;
  }
  /**
   * Sets this quaternion's components from the given array.
   *
   * @param {Array<number>} array - An array holding the quaternion component values.
   * @param {number} [offset=0] - The offset into the array.
   * @return {Quaternion} A reference to this quaternion.
   */
  fromArray(e, t = 0) {
    return this._x = e[t], this._y = e[t + 1], this._z = e[t + 2], this._w = e[t + 3], this._onChangeCallback(), this;
  }
  /**
   * Writes the components of this quaternion to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the quaternion components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The quaternion components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this._x, e[t + 1] = this._y, e[t + 2] = this._z, e[t + 3] = this._w, e;
  }
  /**
   * Sets the components of this quaternion from the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute holding quaternion data.
   * @param {number} index - The index into the attribute.
   * @return {Quaternion} A reference to this quaternion.
   */
  fromBufferAttribute(e, t) {
    return this._x = e.getX(t), this._y = e.getY(t), this._z = e.getZ(t), this._w = e.getW(t), this._onChangeCallback(), this;
  }
  /**
   * This methods defines the serialization result of this class. Returns the
   * numerical elements of this quaternion in an array of format `[x, y, z, w]`.
   *
   * @return {Array<number>} The serialized quaternion.
   */
  toJSON() {
    return this.toArray();
  }
  _onChange(e) {
    return this._onChangeCallback = e, this;
  }
  _onChangeCallback() {
  }
  *[Symbol.iterator]() {
    yield this._x, yield this._y, yield this._z, yield this._w;
  }
}
class P {
  /**
   * Constructs a new 3D vector.
   *
   * @param {number} [x=0] - The x value of this vector.
   * @param {number} [y=0] - The y value of this vector.
   * @param {number} [z=0] - The z value of this vector.
   */
  constructor(e = 0, t = 0, n = 0) {
    P.prototype.isVector3 = !0, this.x = e, this.y = t, this.z = n;
  }
  /**
   * Sets the vector components.
   *
   * @param {number} x - The value of the x component.
   * @param {number} y - The value of the y component.
   * @param {number} z - The value of the z component.
   * @return {Vector3} A reference to this vector.
   */
  set(e, t, n) {
    return n === void 0 && (n = this.z), this.x = e, this.y = t, this.z = n, this;
  }
  /**
   * Sets the vector components to the same value.
   *
   * @param {number} scalar - The value to set for all vector components.
   * @return {Vector3} A reference to this vector.
   */
  setScalar(e) {
    return this.x = e, this.y = e, this.z = e, this;
  }
  /**
   * Sets the vector's x component to the given value.
   *
   * @param {number} x - The value to set.
   * @return {Vector3} A reference to this vector.
   */
  setX(e) {
    return this.x = e, this;
  }
  /**
   * Sets the vector's y component to the given value.
   *
   * @param {number} y - The value to set.
   * @return {Vector3} A reference to this vector.
   */
  setY(e) {
    return this.y = e, this;
  }
  /**
   * Sets the vector's z component to the given value.
   *
   * @param {number} z - The value to set.
   * @return {Vector3} A reference to this vector.
   */
  setZ(e) {
    return this.z = e, this;
  }
  /**
   * Allows to set a vector component with an index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
   * @param {number} value - The value to set.
   * @return {Vector3} A reference to this vector.
   */
  setComponent(e, t) {
    switch (e) {
      case 0:
        this.x = t;
        break;
      case 1:
        this.y = t;
        break;
      case 2:
        this.z = t;
        break;
      default:
        throw new Error("index is out of range: " + e);
    }
    return this;
  }
  /**
   * Returns the value of the vector component which matches the given index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
   * @return {number} A vector component value.
   */
  getComponent(e) {
    switch (e) {
      case 0:
        return this.x;
      case 1:
        return this.y;
      case 2:
        return this.z;
      default:
        throw new Error("index is out of range: " + e);
    }
  }
  /**
   * Returns a new vector with copied values from this instance.
   *
   * @return {Vector3} A clone of this instance.
   */
  clone() {
    return new this.constructor(this.x, this.y, this.z);
  }
  /**
   * Copies the values of the given vector to this instance.
   *
   * @param {Vector3} v - The vector to copy.
   * @return {Vector3} A reference to this vector.
   */
  copy(e) {
    return this.x = e.x, this.y = e.y, this.z = e.z, this;
  }
  /**
   * Adds the given vector to this instance.
   *
   * @param {Vector3} v - The vector to add.
   * @return {Vector3} A reference to this vector.
   */
  add(e) {
    return this.x += e.x, this.y += e.y, this.z += e.z, this;
  }
  /**
   * Adds the given scalar value to all components of this instance.
   *
   * @param {number} s - The scalar to add.
   * @return {Vector3} A reference to this vector.
   */
  addScalar(e) {
    return this.x += e, this.y += e, this.z += e, this;
  }
  /**
   * Adds the given vectors and stores the result in this instance.
   *
   * @param {Vector3} a - The first vector.
   * @param {Vector3} b - The second vector.
   * @return {Vector3} A reference to this vector.
   */
  addVectors(e, t) {
    return this.x = e.x + t.x, this.y = e.y + t.y, this.z = e.z + t.z, this;
  }
  /**
   * Adds the given vector scaled by the given factor to this instance.
   *
   * @param {Vector3|Vector4} v - The vector.
   * @param {number} s - The factor that scales `v`.
   * @return {Vector3} A reference to this vector.
   */
  addScaledVector(e, t) {
    return this.x += e.x * t, this.y += e.y * t, this.z += e.z * t, this;
  }
  /**
   * Subtracts the given vector from this instance.
   *
   * @param {Vector3} v - The vector to subtract.
   * @return {Vector3} A reference to this vector.
   */
  sub(e) {
    return this.x -= e.x, this.y -= e.y, this.z -= e.z, this;
  }
  /**
   * Subtracts the given scalar value from all components of this instance.
   *
   * @param {number} s - The scalar to subtract.
   * @return {Vector3} A reference to this vector.
   */
  subScalar(e) {
    return this.x -= e, this.y -= e, this.z -= e, this;
  }
  /**
   * Subtracts the given vectors and stores the result in this instance.
   *
   * @param {Vector3} a - The first vector.
   * @param {Vector3} b - The second vector.
   * @return {Vector3} A reference to this vector.
   */
  subVectors(e, t) {
    return this.x = e.x - t.x, this.y = e.y - t.y, this.z = e.z - t.z, this;
  }
  /**
   * Multiplies the given vector with this instance.
   *
   * @param {Vector3} v - The vector to multiply.
   * @return {Vector3} A reference to this vector.
   */
  multiply(e) {
    return this.x *= e.x, this.y *= e.y, this.z *= e.z, this;
  }
  /**
   * Multiplies the given scalar value with all components of this instance.
   *
   * @param {number} scalar - The scalar to multiply.
   * @return {Vector3} A reference to this vector.
   */
  multiplyScalar(e) {
    return this.x *= e, this.y *= e, this.z *= e, this;
  }
  /**
   * Multiplies the given vectors and stores the result in this instance.
   *
   * @param {Vector3} a - The first vector.
   * @param {Vector3} b - The second vector.
   * @return {Vector3} A reference to this vector.
   */
  multiplyVectors(e, t) {
    return this.x = e.x * t.x, this.y = e.y * t.y, this.z = e.z * t.z, this;
  }
  /**
   * Applies the given Euler rotation to this vector.
   *
   * @param {Euler} euler - The Euler angles.
   * @return {Vector3} A reference to this vector.
   */
  applyEuler(e) {
    return this.applyQuaternion(h_.setFromEuler(e));
  }
  /**
   * Applies a rotation specified by an axis and an angle to this vector.
   *
   * @param {Vector3} axis - A normalized vector representing the rotation axis.
   * @param {number} angle - The angle in radians.
   * @return {Vector3} A reference to this vector.
   */
  applyAxisAngle(e, t) {
    return this.applyQuaternion(h_.setFromAxisAngle(e, t));
  }
  /**
   * Multiplies this vector with the given 3x3 matrix.
   *
   * @param {Matrix3} m - The 3x3 matrix.
   * @return {Vector3} A reference to this vector.
   */
  applyMatrix3(e) {
    const t = this.x, n = this.y, r = this.z, s = e.elements;
    return this.x = s[0] * t + s[3] * n + s[6] * r, this.y = s[1] * t + s[4] * n + s[7] * r, this.z = s[2] * t + s[5] * n + s[8] * r, this;
  }
  /**
   * Multiplies this vector by the given normal matrix and normalizes
   * the result.
   *
   * @param {Matrix3} m - The normal matrix.
   * @return {Vector3} A reference to this vector.
   */
  applyNormalMatrix(e) {
    return this.applyMatrix3(e).normalize();
  }
  /**
   * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and
   * divides by perspective.
   *
   * @param {Matrix4} m - The matrix to apply.
   * @return {Vector3} A reference to this vector.
   */
  applyMatrix4(e) {
    const t = this.x, n = this.y, r = this.z, s = e.elements, a = 1 / (s[3] * t + s[7] * n + s[11] * r + s[15]);
    return this.x = (s[0] * t + s[4] * n + s[8] * r + s[12]) * a, this.y = (s[1] * t + s[5] * n + s[9] * r + s[13]) * a, this.z = (s[2] * t + s[6] * n + s[10] * r + s[14]) * a, this;
  }
  /**
   * Applies the given Quaternion to this vector.
   *
   * @param {Quaternion} q - The Quaternion.
   * @return {Vector3} A reference to this vector.
   */
  applyQuaternion(e) {
    const t = this.x, n = this.y, r = this.z, s = e.x, a = e.y, o = e.z, l = e.w, c = 2 * (a * r - o * n), u = 2 * (o * t - s * r), h = 2 * (s * n - a * t);
    return this.x = t + l * c + a * h - o * u, this.y = n + l * u + o * c - s * h, this.z = r + l * h + s * u - a * c, this;
  }
  /**
   * Projects this vector from world space into the camera's normalized
   * device coordinate (NDC) space.
   *
   * @param {Camera} camera - The camera.
   * @return {Vector3} A reference to this vector.
   */
  project(e) {
    return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix);
  }
  /**
   * Unprojects this vector from the camera's normalized device coordinate (NDC)
   * space into world space.
   *
   * @param {Camera} camera - The camera.
   * @return {Vector3} A reference to this vector.
   */
  unproject(e) {
    return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld);
  }
  /**
   * Transforms the direction of this vector by a matrix (the upper left 3 x 3
   * subset of the given 4x4 matrix and then normalizes the result.
   *
   * @param {Matrix4} m - The matrix.
   * @return {Vector3} A reference to this vector.
   */
  transformDirection(e) {
    const t = this.x, n = this.y, r = this.z, s = e.elements;
    return this.x = s[0] * t + s[4] * n + s[8] * r, this.y = s[1] * t + s[5] * n + s[9] * r, this.z = s[2] * t + s[6] * n + s[10] * r, this.normalize();
  }
  /**
   * Divides this instance by the given vector.
   *
   * @param {Vector3} v - The vector to divide.
   * @return {Vector3} A reference to this vector.
   */
  divide(e) {
    return this.x /= e.x, this.y /= e.y, this.z /= e.z, this;
  }
  /**
   * Divides this vector by the given scalar.
   *
   * @param {number} scalar - The scalar to divide.
   * @return {Vector3} A reference to this vector.
   */
  divideScalar(e) {
    return this.multiplyScalar(1 / e);
  }
  /**
   * If this vector's x, y or z value is greater than the given vector's x, y or z
   * value, replace that value with the corresponding min value.
   *
   * @param {Vector3} v - The vector.
   * @return {Vector3} A reference to this vector.
   */
  min(e) {
    return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this.z = Math.min(this.z, e.z), this;
  }
  /**
   * If this vector's x, y or z value is less than the given vector's x, y or z
   * value, replace that value with the corresponding max value.
   *
   * @param {Vector3} v - The vector.
   * @return {Vector3} A reference to this vector.
   */
  max(e) {
    return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this;
  }
  /**
   * If this vector's x, y or z value is greater than the max vector's x, y or z
   * value, it is replaced by the corresponding value.
   * If this vector's x, y or z value is less than the min vector's x, y or z value,
   * it is replaced by the corresponding value.
   *
   * @param {Vector3} min - The minimum x, y and z values.
   * @param {Vector3} max - The maximum x, y and z values in the desired range.
   * @return {Vector3} A reference to this vector.
   */
  clamp(e, t) {
    return this.x = ct(this.x, e.x, t.x), this.y = ct(this.y, e.y, t.y), this.z = ct(this.z, e.z, t.z), this;
  }
  /**
   * If this vector's x, y or z values are greater than the max value, they are
   * replaced by the max value.
   * If this vector's x, y or z values are less than the min value, they are
   * replaced by the min value.
   *
   * @param {number} minVal - The minimum value the components will be clamped to.
   * @param {number} maxVal - The maximum value the components will be clamped to.
   * @return {Vector3} A reference to this vector.
   */
  clampScalar(e, t) {
    return this.x = ct(this.x, e, t), this.y = ct(this.y, e, t), this.z = ct(this.z, e, t), this;
  }
  /**
   * If this vector's length is greater than the max value, it is replaced by
   * the max value.
   * If this vector's length is less than the min value, it is replaced by the
   * min value.
   *
   * @param {number} min - The minimum value the vector length will be clamped to.
   * @param {number} max - The maximum value the vector length will be clamped to.
   * @return {Vector3} A reference to this vector.
   */
  clampLength(e, t) {
    const n = this.length();
    return this.divideScalar(n || 1).multiplyScalar(ct(n, e, t));
  }
  /**
   * The components of this vector are rounded down to the nearest integer value.
   *
   * @return {Vector3} A reference to this vector.
   */
  floor() {
    return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this;
  }
  /**
   * The components of this vector are rounded up to the nearest integer value.
   *
   * @return {Vector3} A reference to this vector.
   */
  ceil() {
    return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this.z = Math.ceil(this.z), this;
  }
  /**
   * The components of this vector are rounded to the nearest integer value
   *
   * @return {Vector3} A reference to this vector.
   */
  round() {
    return this.x = Math.round(this.x), this.y = Math.round(this.y), this.z = Math.round(this.z), this;
  }
  /**
   * The components of this vector are rounded towards zero (up if negative,
   * down if positive) to an integer value.
   *
   * @return {Vector3} A reference to this vector.
   */
  roundToZero() {
    return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this.z = Math.trunc(this.z), this;
  }
  /**
   * Inverts this vector - i.e. sets x = -x, y = -y and z = -z.
   *
   * @return {Vector3} A reference to this vector.
   */
  negate() {
    return this.x = -this.x, this.y = -this.y, this.z = -this.z, this;
  }
  /**
   * Calculates the dot product of the given vector with this instance.
   *
   * @param {Vector3} v - The vector to compute the dot product with.
   * @return {number} The result of the dot product.
   */
  dot(e) {
    return this.x * e.x + this.y * e.y + this.z * e.z;
  }
  /**
   * Computes the square of the Euclidean length (straight-line length) from
   * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should
   * compare the length squared instead as it is slightly more efficient to calculate.
   *
   * @return {number} The square length of this vector.
   */
  lengthSq() {
    return this.x * this.x + this.y * this.y + this.z * this.z;
  }
  /**
   * Computes the  Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).
   *
   * @return {number} The length of this vector.
   */
  length() {
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  }
  /**
   * Computes the Manhattan length of this vector.
   *
   * @return {number} The length of this vector.
   */
  manhattanLength() {
    return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
  }
  /**
   * Converts this vector to a unit vector - that is, sets it equal to a vector
   * with the same direction as this one, but with a vector length of `1`.
   *
   * @return {Vector3} A reference to this vector.
   */
  normalize() {
    return this.divideScalar(this.length() || 1);
  }
  /**
   * Sets this vector to a vector with the same direction as this one, but
   * with the specified length.
   *
   * @param {number} length - The new length of this vector.
   * @return {Vector3} A reference to this vector.
   */
  setLength(e) {
    return this.normalize().multiplyScalar(e);
  }
  /**
   * Linearly interpolates between the given vector and this instance, where
   * alpha is the percent distance along the line - alpha = 0 will be this
   * vector, and alpha = 1 will be the given one.
   *
   * @param {Vector3} v - The vector to interpolate towards.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector3} A reference to this vector.
   */
  lerp(e, t) {
    return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this.z += (e.z - this.z) * t, this;
  }
  /**
   * Linearly interpolates between the given vectors, where alpha is the percent
   * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
   * be the second one. The result is stored in this instance.
   *
   * @param {Vector3} v1 - The first vector.
   * @param {Vector3} v2 - The second vector.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector3} A reference to this vector.
   */
  lerpVectors(e, t, n) {
    return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this.z = e.z + (t.z - e.z) * n, this;
  }
  /**
   * Calculates the cross product of the given vector with this instance.
   *
   * @param {Vector3} v - The vector to compute the cross product with.
   * @return {Vector3} The result of the cross product.
   */
  cross(e) {
    return this.crossVectors(this, e);
  }
  /**
   * Calculates the cross product of the given vectors and stores the result
   * in this instance.
   *
   * @param {Vector3} a - The first vector.
   * @param {Vector3} b - The second vector.
   * @return {Vector3} A reference to this vector.
   */
  crossVectors(e, t) {
    const n = e.x, r = e.y, s = e.z, a = t.x, o = t.y, l = t.z;
    return this.x = r * l - s * o, this.y = s * a - n * l, this.z = n * o - r * a, this;
  }
  /**
   * Projects this vector onto the given one.
   *
   * @param {Vector3} v - The vector to project to.
   * @return {Vector3} A reference to this vector.
   */
  projectOnVector(e) {
    const t = e.lengthSq();
    if (t === 0)
      return this.set(0, 0, 0);
    const n = e.dot(this) / t;
    return this.copy(e).multiplyScalar(n);
  }
  /**
   * Projects this vector onto a plane by subtracting this
   * vector projected onto the plane's normal from this vector.
   *
   * @param {Vector3} planeNormal - The plane normal.
   * @return {Vector3} A reference to this vector.
   */
  projectOnPlane(e) {
    return kd.copy(this).projectOnVector(e), this.sub(kd);
  }
  /**
   * Reflects this vector off a plane orthogonal to the given normal vector.
   *
   * @param {Vector3} normal - The (normalized) normal vector.
   * @return {Vector3} A reference to this vector.
   */
  reflect(e) {
    return this.sub(kd.copy(e).multiplyScalar(2 * this.dot(e)));
  }
  /**
   * Returns the angle between the given vector and this instance in radians.
   *
   * @param {Vector3} v - The vector to compute the angle with.
   * @return {number} The angle in radians.
   */
  angleTo(e) {
    const t = Math.sqrt(this.lengthSq() * e.lengthSq());
    if (t === 0)
      return Math.PI / 2;
    const n = this.dot(e) / t;
    return Math.acos(ct(n, -1, 1));
  }
  /**
   * Computes the distance from the given vector to this instance.
   *
   * @param {Vector3} v - The vector to compute the distance to.
   * @return {number} The distance.
   */
  distanceTo(e) {
    return Math.sqrt(this.distanceToSquared(e));
  }
  /**
   * Computes the squared distance from the given vector to this instance.
   * If you are just comparing the distance with another distance, you should compare
   * the distance squared instead as it is slightly more efficient to calculate.
   *
   * @param {Vector3} v - The vector to compute the squared distance to.
   * @return {number} The squared distance.
   */
  distanceToSquared(e) {
    const t = this.x - e.x, n = this.y - e.y, r = this.z - e.z;
    return t * t + n * n + r * r;
  }
  /**
   * Computes the Manhattan distance from the given vector to this instance.
   *
   * @param {Vector3} v - The vector to compute the Manhattan distance to.
   * @return {number} The Manhattan distance.
   */
  manhattanDistanceTo(e) {
    return Math.abs(this.x - e.x) + Math.abs(this.y - e.y) + Math.abs(this.z - e.z);
  }
  /**
   * Sets the vector components from the given spherical coordinates.
   *
   * @param {Spherical} s - The spherical coordinates.
   * @return {Vector3} A reference to this vector.
   */
  setFromSpherical(e) {
    return this.setFromSphericalCoords(e.radius, e.phi, e.theta);
  }
  /**
   * Sets the vector components from the given spherical coordinates.
   *
   * @param {number} radius - The radius.
   * @param {number} phi - The phi angle in radians.
   * @param {number} theta - The theta angle in radians.
   * @return {Vector3} A reference to this vector.
   */
  setFromSphericalCoords(e, t, n) {
    const r = Math.sin(t) * e;
    return this.x = r * Math.sin(n), this.y = Math.cos(t) * e, this.z = r * Math.cos(n), this;
  }
  /**
   * Sets the vector components from the given cylindrical coordinates.
   *
   * @param {Cylindrical} c - The cylindrical coordinates.
   * @return {Vector3} A reference to this vector.
   */
  setFromCylindrical(e) {
    return this.setFromCylindricalCoords(e.radius, e.theta, e.y);
  }
  /**
   * Sets the vector components from the given cylindrical coordinates.
   *
   * @param {number} radius - The radius.
   * @param {number} theta - The theta angle in radians.
   * @param {number} y - The y value.
   * @return {Vector3} A reference to this vector.
   */
  setFromCylindricalCoords(e, t, n) {
    return this.x = e * Math.sin(t), this.y = n, this.z = e * Math.cos(t), this;
  }
  /**
   * Sets the vector components to the position elements of the
   * given transformation matrix.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @return {Vector3} A reference to this vector.
   */
  setFromMatrixPosition(e) {
    const t = e.elements;
    return this.x = t[12], this.y = t[13], this.z = t[14], this;
  }
  /**
   * Sets the vector components to the scale elements of the
   * given transformation matrix.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @return {Vector3} A reference to this vector.
   */
  setFromMatrixScale(e) {
    const t = this.setFromMatrixColumn(e, 0).length(), n = this.setFromMatrixColumn(e, 1).length(), r = this.setFromMatrixColumn(e, 2).length();
    return this.x = t, this.y = n, this.z = r, this;
  }
  /**
   * Sets the vector components from the specified matrix column.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @param {number} index - The column index.
   * @return {Vector3} A reference to this vector.
   */
  setFromMatrixColumn(e, t) {
    return this.fromArray(e.elements, t * 4);
  }
  /**
   * Sets the vector components from the specified matrix column.
   *
   * @param {Matrix3} m - The 3x3 matrix.
   * @param {number} index - The column index.
   * @return {Vector3} A reference to this vector.
   */
  setFromMatrix3Column(e, t) {
    return this.fromArray(e.elements, t * 3);
  }
  /**
   * Sets the vector components from the given Euler angles.
   *
   * @param {Euler} e - The Euler angles to set.
   * @return {Vector3} A reference to this vector.
   */
  setFromEuler(e) {
    return this.x = e._x, this.y = e._y, this.z = e._z, this;
  }
  /**
   * Sets the vector components from the RGB components of the
   * given color.
   *
   * @param {Color} c - The color to set.
   * @return {Vector3} A reference to this vector.
   */
  setFromColor(e) {
    return this.x = e.r, this.y = e.g, this.z = e.b, this;
  }
  /**
   * Returns `true` if this vector is equal with the given one.
   *
   * @param {Vector3} v - The vector to test for equality.
   * @return {boolean} Whether this vector is equal with the given one.
   */
  equals(e) {
    return e.x === this.x && e.y === this.y && e.z === this.z;
  }
  /**
   * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`
   * and z value to be `array[ offset + 2 ]`.
   *
   * @param {Array<number>} array - An array holding the vector component values.
   * @param {number} [offset=0] - The offset into the array.
   * @return {Vector3} A reference to this vector.
   */
  fromArray(e, t = 0) {
    return this.x = e[t], this.y = e[t + 1], this.z = e[t + 2], this;
  }
  /**
   * Writes the components of this vector to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the vector components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The vector components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this.x, e[t + 1] = this.y, e[t + 2] = this.z, e;
  }
  /**
   * Sets the components of this vector from the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
   * @param {number} index - The index into the attribute.
   * @return {Vector3} A reference to this vector.
   */
  fromBufferAttribute(e, t) {
    return this.x = e.getX(t), this.y = e.getY(t), this.z = e.getZ(t), this;
  }
  /**
   * Sets each component of this vector to a pseudo-random value between `0` and
   * `1`, excluding `1`.
   *
   * @return {Vector3} A reference to this vector.
   */
  random() {
    return this.x = Math.random(), this.y = Math.random(), this.z = Math.random(), this;
  }
  /**
   * Sets this vector to a uniformly random point on a unit sphere.
   *
   * @return {Vector3} A reference to this vector.
   */
  randomDirection() {
    const e = Math.random() * Math.PI * 2, t = Math.random() * 2 - 1, n = Math.sqrt(1 - t * t);
    return this.x = n * Math.cos(e), this.y = t, this.z = n * Math.sin(e), this;
  }
  *[Symbol.iterator]() {
    yield this.x, yield this.y, yield this.z;
  }
}
const kd = /* @__PURE__ */ new P(), h_ = /* @__PURE__ */ new Gi();
class nt {
  /**
   * Constructs a new 3x3 matrix. The arguments are supposed to be
   * in row-major order. If no arguments are provided, the constructor
   * initializes the matrix as an identity matrix.
   *
   * @param {number} [n11] - 1-1 matrix element.
   * @param {number} [n12] - 1-2 matrix element.
   * @param {number} [n13] - 1-3 matrix element.
   * @param {number} [n21] - 2-1 matrix element.
   * @param {number} [n22] - 2-2 matrix element.
   * @param {number} [n23] - 2-3 matrix element.
   * @param {number} [n31] - 3-1 matrix element.
   * @param {number} [n32] - 3-2 matrix element.
   * @param {number} [n33] - 3-3 matrix element.
   */
  constructor(e, t, n, r, s, a, o, l, c) {
    nt.prototype.isMatrix3 = !0, this.elements = [
      1,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      1
    ], e !== void 0 && this.set(e, t, n, r, s, a, o, l, c);
  }
  /**
   * Sets the elements of the matrix.The arguments are supposed to be
   * in row-major order.
   *
   * @param {number} [n11] - 1-1 matrix element.
   * @param {number} [n12] - 1-2 matrix element.
   * @param {number} [n13] - 1-3 matrix element.
   * @param {number} [n21] - 2-1 matrix element.
   * @param {number} [n22] - 2-2 matrix element.
   * @param {number} [n23] - 2-3 matrix element.
   * @param {number} [n31] - 3-1 matrix element.
   * @param {number} [n32] - 3-2 matrix element.
   * @param {number} [n33] - 3-3 matrix element.
   * @return {Matrix3} A reference to this matrix.
   */
  set(e, t, n, r, s, a, o, l, c) {
    const u = this.elements;
    return u[0] = e, u[1] = r, u[2] = o, u[3] = t, u[4] = s, u[5] = l, u[6] = n, u[7] = a, u[8] = c, this;
  }
  /**
   * Sets this matrix to the 3x3 identity matrix.
   *
   * @return {Matrix3} A reference to this matrix.
   */
  identity() {
    return this.set(
      1,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Copies the values of the given matrix to this instance.
   *
   * @param {Matrix3} m - The matrix to copy.
   * @return {Matrix3} A reference to this matrix.
   */
  copy(e) {
    const t = this.elements, n = e.elements;
    return t[0] = n[0], t[1] = n[1], t[2] = n[2], t[3] = n[3], t[4] = n[4], t[5] = n[5], t[6] = n[6], t[7] = n[7], t[8] = n[8], this;
  }
  /**
   * Extracts the basis of this matrix into the three axis vectors provided.
   *
   * @param {Vector3} xAxis - The basis's x axis.
   * @param {Vector3} yAxis - The basis's y axis.
   * @param {Vector3} zAxis - The basis's z axis.
   * @return {Matrix3} A reference to this matrix.
   */
  extractBasis(e, t, n) {
    return e.setFromMatrix3Column(this, 0), t.setFromMatrix3Column(this, 1), n.setFromMatrix3Column(this, 2), this;
  }
  /**
   * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @return {Matrix3} A reference to this matrix.
   */
  setFromMatrix4(e) {
    const t = e.elements;
    return this.set(
      t[0],
      t[4],
      t[8],
      t[1],
      t[5],
      t[9],
      t[2],
      t[6],
      t[10]
    ), this;
  }
  /**
   * Post-multiplies this matrix by the given 3x3 matrix.
   *
   * @param {Matrix3} m - The matrix to multiply with.
   * @return {Matrix3} A reference to this matrix.
   */
  multiply(e) {
    return this.multiplyMatrices(this, e);
  }
  /**
   * Pre-multiplies this matrix by the given 3x3 matrix.
   *
   * @param {Matrix3} m - The matrix to multiply with.
   * @return {Matrix3} A reference to this matrix.
   */
  premultiply(e) {
    return this.multiplyMatrices(e, this);
  }
  /**
   * Multiples the given 3x3 matrices and stores the result
   * in this matrix.
   *
   * @param {Matrix3} a - The first matrix.
   * @param {Matrix3} b - The second matrix.
   * @return {Matrix3} A reference to this matrix.
   */
  multiplyMatrices(e, t) {
    const n = e.elements, r = t.elements, s = this.elements, a = n[0], o = n[3], l = n[6], c = n[1], u = n[4], h = n[7], d = n[2], f = n[5], p = n[8], _ = r[0], g = r[3], m = r[6], x = r[1], y = r[4], b = r[7], T = r[2], S = r[5], E = r[8];
    return s[0] = a * _ + o * x + l * T, s[3] = a * g + o * y + l * S, s[6] = a * m + o * b + l * E, s[1] = c * _ + u * x + h * T, s[4] = c * g + u * y + h * S, s[7] = c * m + u * b + h * E, s[2] = d * _ + f * x + p * T, s[5] = d * g + f * y + p * S, s[8] = d * m + f * b + p * E, this;
  }
  /**
   * Multiplies every component of the matrix by the given scalar.
   *
   * @param {number} s - The scalar.
   * @return {Matrix3} A reference to this matrix.
   */
  multiplyScalar(e) {
    const t = this.elements;
    return t[0] *= e, t[3] *= e, t[6] *= e, t[1] *= e, t[4] *= e, t[7] *= e, t[2] *= e, t[5] *= e, t[8] *= e, this;
  }
  /**
   * Computes and returns the determinant of this matrix.
   *
   * @return {number} The determinant.
   */
  determinant() {
    const e = this.elements, t = e[0], n = e[1], r = e[2], s = e[3], a = e[4], o = e[5], l = e[6], c = e[7], u = e[8];
    return t * a * u - t * o * c - n * s * u + n * o * l + r * s * c - r * a * l;
  }
  /**
   * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution).
   * You can not invert with a determinant of zero. If you attempt this, the method produces
   * a zero matrix instead.
   *
   * @return {Matrix3} A reference to this matrix.
   */
  invert() {
    const e = this.elements, t = e[0], n = e[1], r = e[2], s = e[3], a = e[4], o = e[5], l = e[6], c = e[7], u = e[8], h = u * a - o * c, d = o * l - u * s, f = c * s - a * l, p = t * h + n * d + r * f;
    if (p === 0)
      return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
    const _ = 1 / p;
    return e[0] = h * _, e[1] = (r * c - u * n) * _, e[2] = (o * n - r * a) * _, e[3] = d * _, e[4] = (u * t - r * l) * _, e[5] = (r * s - o * t) * _, e[6] = f * _, e[7] = (n * l - c * t) * _, e[8] = (a * t - n * s) * _, this;
  }
  /**
   * Transposes this matrix in place.
   *
   * @return {Matrix3} A reference to this matrix.
   */
  transpose() {
    let e;
    const t = this.elements;
    return e = t[1], t[1] = t[3], t[3] = e, e = t[2], t[2] = t[6], t[6] = e, e = t[5], t[5] = t[7], t[7] = e, this;
  }
  /**
   * Computes the normal matrix which is the inverse transpose of the upper
   * left 3x3 portion of the given 4x4 matrix.
   *
   * @param {Matrix4} matrix4 - The 4x4 matrix.
   * @return {Matrix3} A reference to this matrix.
   */
  getNormalMatrix(e) {
    return this.setFromMatrix4(e).invert().transpose();
  }
  /**
   * Transposes this matrix into the supplied array, and returns itself unchanged.
   *
   * @param {Array<number>} r - An array to store the transposed matrix elements.
   * @return {Matrix3} A reference to this matrix.
   */
  transposeIntoArray(e) {
    const t = this.elements;
    return e[0] = t[0], e[1] = t[3], e[2] = t[6], e[3] = t[1], e[4] = t[4], e[5] = t[7], e[6] = t[2], e[7] = t[5], e[8] = t[8], this;
  }
  /**
   * Sets the UV transform matrix from offset, repeat, rotation, and center.
   *
   * @param {number} tx - Offset x.
   * @param {number} ty - Offset y.
   * @param {number} sx - Repeat x.
   * @param {number} sy - Repeat y.
   * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.
   * @param {number} cx - Center x of rotation.
   * @param {number} cy - Center y of rotation
   * @return {Matrix3} A reference to this matrix.
   */
  setUvTransform(e, t, n, r, s, a, o) {
    const l = Math.cos(s), c = Math.sin(s);
    return this.set(
      n * l,
      n * c,
      -n * (l * a + c * o) + a + e,
      -r * c,
      r * l,
      -r * (-c * a + l * o) + o + t,
      0,
      0,
      1
    ), this;
  }
  /**
   * Scales this matrix with the given scalar values.
   *
   * @param {number} sx - The amount to scale in the X axis.
   * @param {number} sy - The amount to scale in the Y axis.
   * @return {Matrix3} A reference to this matrix.
   */
  scale(e, t) {
    return this.premultiply(Gd.makeScale(e, t)), this;
  }
  /**
   * Rotates this matrix by the given angle.
   *
   * @param {number} theta - The rotation in radians.
   * @return {Matrix3} A reference to this matrix.
   */
  rotate(e) {
    return this.premultiply(Gd.makeRotation(-e)), this;
  }
  /**
   * Translates this matrix by the given scalar values.
   *
   * @param {number} tx - The amount to translate in the X axis.
   * @param {number} ty - The amount to translate in the Y axis.
   * @return {Matrix3} A reference to this matrix.
   */
  translate(e, t) {
    return this.premultiply(Gd.makeTranslation(e, t)), this;
  }
  // for 2D Transforms
  /**
   * Sets this matrix as a 2D translation transform.
   *
   * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.
   * @param {number} y - The amount to translate in the Y axis.
   * @return {Matrix3} A reference to this matrix.
   */
  makeTranslation(e, t) {
    return e.isVector2 ? this.set(
      1,
      0,
      e.x,
      0,
      1,
      e.y,
      0,
      0,
      1
    ) : this.set(
      1,
      0,
      e,
      0,
      1,
      t,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a 2D rotational transformation.
   *
   * @param {number} theta - The rotation in radians.
   * @return {Matrix3} A reference to this matrix.
   */
  makeRotation(e) {
    const t = Math.cos(e), n = Math.sin(e);
    return this.set(
      t,
      -n,
      0,
      n,
      t,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a 2D scale transform.
   *
   * @param {number} x - The amount to scale in the X axis.
   * @param {number} y - The amount to scale in the Y axis.
   * @return {Matrix3} A reference to this matrix.
   */
  makeScale(e, t) {
    return this.set(
      e,
      0,
      0,
      0,
      t,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Returns `true` if this matrix is equal with the given one.
   *
   * @param {Matrix3} matrix - The matrix to test for equality.
   * @return {boolean} Whether this matrix is equal with the given one.
   */
  equals(e) {
    const t = this.elements, n = e.elements;
    for (let r = 0; r < 9; r++)
      if (t[r] !== n[r])
        return !1;
    return !0;
  }
  /**
   * Sets the elements of the matrix from the given array.
   *
   * @param {Array<number>} array - The matrix elements in column-major order.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Matrix3} A reference to this matrix.
   */
  fromArray(e, t = 0) {
    for (let n = 0; n < 9; n++)
      this.elements[n] = e[n + t];
    return this;
  }
  /**
   * Writes the elements of this matrix to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The matrix elements in column-major order.
   */
  toArray(e = [], t = 0) {
    const n = this.elements;
    return e[t] = n[0], e[t + 1] = n[1], e[t + 2] = n[2], e[t + 3] = n[3], e[t + 4] = n[4], e[t + 5] = n[5], e[t + 6] = n[6], e[t + 7] = n[7], e[t + 8] = n[8], e;
  }
  /**
   * Returns a matrix with copied values from this instance.
   *
   * @return {Matrix3} A clone of this instance.
   */
  clone() {
    return new this.constructor().fromArray(this.elements);
  }
}
const Gd = /* @__PURE__ */ new nt(), d_ = /* @__PURE__ */ new nt().set(
  0.4123908,
  0.3575843,
  0.1804808,
  0.212639,
  0.7151687,
  0.0721923,
  0.0193308,
  0.1191948,
  0.9505322
), f_ = /* @__PURE__ */ new nt().set(
  3.2409699,
  -1.5373832,
  -0.4986108,
  -0.9692436,
  1.8759675,
  0.0415551,
  0.0556301,
  -0.203977,
  1.0569715
);
function qM() {
  const i = {
    enabled: !0,
    workingColorSpace: La,
    /**
     * Implementations of supported color spaces.
     *
     * Required:
     *	- primaries: chromaticity coordinates [ rx ry gx gy bx by ]
     *	- whitePoint: reference white [ x y ]
     *	- transfer: transfer function (pre-defined)
     *	- toXYZ: Matrix3 RGB to XYZ transform
     *	- fromXYZ: Matrix3 XYZ to RGB transform
     *	- luminanceCoefficients: RGB luminance coefficients
     *
     * Optional:
     *  - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace, toneMappingMode: 'extended' | 'standard' }
     *  - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
     *
     * Reference:
     * - https://www.russellcottrell.com/photo/matrixCalculator.htm
     */
    spaces: {},
    convert: function(r, s, a) {
      return this.enabled === !1 || s === a || !s || !a || (this.spaces[s].transfer === Te && (r.r = as(r.r), r.g = as(r.g), r.b = as(r.b)), this.spaces[s].primaries !== this.spaces[a].primaries && (r.applyMatrix3(this.spaces[s].toXYZ), r.applyMatrix3(this.spaces[a].fromXYZ)), this.spaces[a].transfer === Te && (r.r = Do(r.r), r.g = Do(r.g), r.b = Do(r.b))), r;
    },
    workingToColorSpace: function(r, s) {
      return this.convert(r, this.workingColorSpace, s);
    },
    colorSpaceToWorking: function(r, s) {
      return this.convert(r, s, this.workingColorSpace);
    },
    getPrimaries: function(r) {
      return this.spaces[r].primaries;
    },
    getTransfer: function(r) {
      return r === hi ? ll : this.spaces[r].transfer;
    },
    getToneMappingMode: function(r) {
      return this.spaces[r].outputColorSpaceConfig.toneMappingMode || "standard";
    },
    getLuminanceCoefficients: function(r, s = this.workingColorSpace) {
      return r.fromArray(this.spaces[s].luminanceCoefficients);
    },
    define: function(r) {
      Object.assign(this.spaces, r);
    },
    // Internal APIs
    _getMatrix: function(r, s, a) {
      return r.copy(this.spaces[s].toXYZ).multiply(this.spaces[a].fromXYZ);
    },
    _getDrawingBufferColorSpace: function(r) {
      return this.spaces[r].outputColorSpaceConfig.drawingBufferColorSpace;
    },
    _getUnpackColorSpace: function(r = this.workingColorSpace) {
      return this.spaces[r].workingColorSpaceConfig.unpackColorSpace;
    },
    // Deprecated
    fromWorkingColorSpace: function(r, s) {
      return Pt("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."), i.workingToColorSpace(r, s);
    },
    toWorkingColorSpace: function(r, s) {
      return Pt("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."), i.colorSpaceToWorking(r, s);
    }
  }, e = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06], t = [0.2126, 0.7152, 0.0722], n = [0.3127, 0.329];
  return i.define({
    [La]: {
      primaries: e,
      whitePoint: n,
      transfer: ll,
      toXYZ: d_,
      fromXYZ: f_,
      luminanceCoefficients: t,
      workingColorSpaceConfig: { unpackColorSpace: Jn },
      outputColorSpaceConfig: { drawingBufferColorSpace: Jn }
    },
    [Jn]: {
      primaries: e,
      whitePoint: n,
      transfer: Te,
      toXYZ: d_,
      fromXYZ: f_,
      luminanceCoefficients: t,
      outputColorSpaceConfig: { drawingBufferColorSpace: Jn }
    }
  }), i;
}
const Ke = /* @__PURE__ */ qM();
function as(i) {
  return i < 0.04045 ? i * 0.0773993808 : Math.pow(i * 0.9478672986 + 0.0521327014, 2.4);
}
function Do(i) {
  return i < 31308e-7 ? i * 12.92 : 1.055 * Math.pow(i, 0.41666) - 0.055;
}
let Za;
class XM {
  /**
   * Returns a data URI containing a representation of the given image.
   *
   * @param {(HTMLImageElement|HTMLCanvasElement)} image - The image object.
   * @param {string} [type='image/png'] - Indicates the image format.
   * @return {string} The data URI.
   */
  static getDataURL(e, t = "image/png") {
    if (/^data:/i.test(e.src) || typeof HTMLCanvasElement > "u")
      return e.src;
    let n;
    if (e instanceof HTMLCanvasElement)
      n = e;
    else {
      Za === void 0 && (Za = zc("canvas")), Za.width = e.width, Za.height = e.height;
      const r = Za.getContext("2d");
      e instanceof ImageData ? r.putImageData(e, 0, 0) : r.drawImage(e, 0, 0, e.width, e.height), n = Za;
    }
    return n.toDataURL(t);
  }
  /**
   * Converts the given sRGB image data to linear color space.
   *
   * @param {(HTMLImageElement|HTMLCanvasElement|ImageBitmap|Object)} image - The image object.
   * @return {HTMLCanvasElement|Object} The converted image.
   */
  static sRGBToLinear(e) {
    if (typeof HTMLImageElement < "u" && e instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && e instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && e instanceof ImageBitmap) {
      const t = zc("canvas");
      t.width = e.width, t.height = e.height;
      const n = t.getContext("2d");
      n.drawImage(e, 0, 0, e.width, e.height);
      const r = n.getImageData(0, 0, e.width, e.height), s = r.data;
      for (let a = 0; a < s.length; a++)
        s[a] = as(s[a] / 255) * 255;
      return n.putImageData(r, 0, 0), t;
    } else if (e.data) {
      const t = e.data.slice(0);
      for (let n = 0; n < t.length; n++)
        t instanceof Uint8Array || t instanceof Uint8ClampedArray ? t[n] = Math.floor(as(t[n] / 255) * 255) : t[n] = as(t[n]);
      return {
        data: t,
        width: e.width,
        height: e.height
      };
    } else
      return oe("ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."), e;
  }
}
let jM = 0;
class $m {
  /**
   * Constructs a new video texture.
   *
   * @param {any} [data=null] - The data definition of a texture.
   */
  constructor(e = null) {
    this.isSource = !0, Object.defineProperty(this, "id", { value: jM++ }), this.uuid = ss(), this.data = e, this.dataReady = !0, this.version = 0;
  }
  /**
   * Returns the dimensions of the source into the given target vector.
   *
   * @param {(Vector2|Vector3)} target - The target object the result is written into.
   * @return {(Vector2|Vector3)} The dimensions of the source.
   */
  getSize(e) {
    const t = this.data;
    return typeof HTMLVideoElement < "u" && t instanceof HTMLVideoElement ? e.set(t.videoWidth, t.videoHeight, 0) : typeof VideoFrame < "u" && t instanceof VideoFrame ? e.set(t.displayHeight, t.displayWidth, 0) : t !== null ? e.set(t.width, t.height, t.depth || 0) : e.set(0, 0, 0), e;
  }
  /**
   * When the property is set to `true`, the engine allocates the memory
   * for the texture (if necessary) and triggers the actual texture upload
   * to the GPU next time the source is used.
   *
   * @type {boolean}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && this.version++;
  }
  /**
   * Serializes the source into JSON.
   *
   * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized source.
   * @see {@link ObjectLoader#parse}
   */
  toJSON(e) {
    const t = e === void 0 || typeof e == "string";
    if (!t && e.images[this.uuid] !== void 0)
      return e.images[this.uuid];
    const n = {
      uuid: this.uuid,
      url: ""
    }, r = this.data;
    if (r !== null) {
      let s;
      if (Array.isArray(r)) {
        s = [];
        for (let a = 0, o = r.length; a < o; a++)
          r[a].isDataTexture ? s.push(Vd(r[a].image)) : s.push(Vd(r[a]));
      } else
        s = Vd(r);
      n.url = s;
    }
    return t || (e.images[this.uuid] = n), n;
  }
}
function Vd(i) {
  return typeof HTMLImageElement < "u" && i instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && i instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && i instanceof ImageBitmap ? XM.getDataURL(i) : i.data ? {
    data: Array.from(i.data),
    width: i.width,
    height: i.height,
    type: i.data.constructor.name
  } : (oe("Texture: Unable to serialize Texture."), {});
}
let YM = 0;
const zd = /* @__PURE__ */ new P();
class mn extends Fr {
  /**
   * Constructs a new texture.
   *
   * @param {?Object} [image=Texture.DEFAULT_IMAGE] - The image holding the texture data.
   * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
   * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
   * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
   * @param {number} [magFilter=LinearFilter] - The mag filter value.
   * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value.
   * @param {number} [format=RGBAFormat] - The texture format.
   * @param {number} [type=UnsignedByteType] - The texture type.
   * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
   * @param {string} [colorSpace=NoColorSpace] - The color space.
   */
  constructor(e = mn.DEFAULT_IMAGE, t = mn.DEFAULT_MAPPING, n = fi, r = fi, s = Ot, a = pi, o = cn, l = Zt, c = mn.DEFAULT_ANISOTROPY, u = hi) {
    super(), this.isTexture = !0, Object.defineProperty(this, "id", { value: YM++ }), this.uuid = ss(), this.name = "", this.source = new $m(e), this.mipmaps = [], this.mapping = t, this.channel = 0, this.wrapS = n, this.wrapT = r, this.magFilter = s, this.minFilter = a, this.anisotropy = c, this.format = o, this.internalFormat = null, this.type = l, this.offset = new de(0, 0), this.repeat = new de(1, 1), this.center = new de(0, 0), this.rotation = 0, this.matrixAutoUpdate = !0, this.matrix = new nt(), this.generateMipmaps = !0, this.premultiplyAlpha = !1, this.flipY = !0, this.unpackAlignment = 4, this.colorSpace = u, this.userData = {}, this.updateRanges = [], this.version = 0, this.onUpdate = null, this.renderTarget = null, this.isRenderTargetTexture = !1, this.isArrayTexture = !!(e && e.depth && e.depth > 1), this.pmremVersion = 0;
  }
  /**
   * The width of the texture in pixels.
   */
  get width() {
    return this.source.getSize(zd).x;
  }
  /**
   * The height of the texture in pixels.
   */
  get height() {
    return this.source.getSize(zd).y;
  }
  /**
   * The depth of the texture in pixels.
   */
  get depth() {
    return this.source.getSize(zd).z;
  }
  /**
   * The image object holding the texture data.
   *
   * @type {?Object}
   */
  get image() {
    return this.source.data;
  }
  set image(e = null) {
    this.source.data = e;
  }
  /**
   * Updates the texture transformation matrix from the from the properties {@link Texture#offset},
   * {@link Texture#repeat}, {@link Texture#rotation}, and {@link Texture#center}.
   */
  updateMatrix() {
    this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
  }
  /**
   * Adds a range of data in the data texture to be updated on the GPU.
   *
   * @param {number} start - Position at which to start update.
   * @param {number} count - The number of components to update.
   */
  addUpdateRange(e, t) {
    this.updateRanges.push({ start: e, count: t });
  }
  /**
   * Clears the update ranges.
   */
  clearUpdateRanges() {
    this.updateRanges.length = 0;
  }
  /**
   * Returns a new texture with copied values from this instance.
   *
   * @return {Texture} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given texture to this instance.
   *
   * @param {Texture} source - The texture to copy.
   * @return {Texture} A reference to this instance.
   */
  copy(e) {
    return this.name = e.name, this.source = e.source, this.mipmaps = e.mipmaps.slice(0), this.mapping = e.mapping, this.channel = e.channel, this.wrapS = e.wrapS, this.wrapT = e.wrapT, this.magFilter = e.magFilter, this.minFilter = e.minFilter, this.anisotropy = e.anisotropy, this.format = e.format, this.internalFormat = e.internalFormat, this.type = e.type, this.offset.copy(e.offset), this.repeat.copy(e.repeat), this.center.copy(e.center), this.rotation = e.rotation, this.matrixAutoUpdate = e.matrixAutoUpdate, this.matrix.copy(e.matrix), this.generateMipmaps = e.generateMipmaps, this.premultiplyAlpha = e.premultiplyAlpha, this.flipY = e.flipY, this.unpackAlignment = e.unpackAlignment, this.colorSpace = e.colorSpace, this.renderTarget = e.renderTarget, this.isRenderTargetTexture = e.isRenderTargetTexture, this.isArrayTexture = e.isArrayTexture, this.userData = JSON.parse(JSON.stringify(e.userData)), this.needsUpdate = !0, this;
  }
  /**
   * Sets this texture's properties based on `values`.
   * @param {Object} values - A container with texture parameters.
   */
  setValues(e) {
    for (const t in e) {
      const n = e[t];
      if (n === void 0) {
        oe(`Texture.setValues(): parameter '${t}' has value of undefined.`);
        continue;
      }
      const r = this[t];
      if (r === void 0) {
        oe(`Texture.setValues(): property '${t}' does not exist.`);
        continue;
      }
      r && n && r.isVector2 && n.isVector2 || r && n && r.isVector3 && n.isVector3 || r && n && r.isMatrix3 && n.isMatrix3 ? r.copy(n) : this[t] = n;
    }
  }
  /**
   * Serializes the texture into JSON.
   *
   * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized texture.
   * @see {@link ObjectLoader#parse}
   */
  toJSON(e) {
    const t = e === void 0 || typeof e == "string";
    if (!t && e.textures[this.uuid] !== void 0)
      return e.textures[this.uuid];
    const n = {
      metadata: {
        version: 4.7,
        type: "Texture",
        generator: "Texture.toJSON"
      },
      uuid: this.uuid,
      name: this.name,
      image: this.source.toJSON(e).uuid,
      mapping: this.mapping,
      channel: this.channel,
      repeat: [this.repeat.x, this.repeat.y],
      offset: [this.offset.x, this.offset.y],
      center: [this.center.x, this.center.y],
      rotation: this.rotation,
      wrap: [this.wrapS, this.wrapT],
      format: this.format,
      internalFormat: this.internalFormat,
      type: this.type,
      colorSpace: this.colorSpace,
      minFilter: this.minFilter,
      magFilter: this.magFilter,
      anisotropy: this.anisotropy,
      flipY: this.flipY,
      generateMipmaps: this.generateMipmaps,
      premultiplyAlpha: this.premultiplyAlpha,
      unpackAlignment: this.unpackAlignment
    };
    return Object.keys(this.userData).length > 0 && (n.userData = this.userData), t || (e.textures[this.uuid] = n), n;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   *
   * @fires Texture#dispose
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
  /**
   * Transforms the given uv vector with the textures uv transformation matrix.
   *
   * @param {Vector2} uv - The uv vector.
   * @return {Vector2} The transformed uv vector.
   */
  transformUv(e) {
    if (this.mapping !== Im)
      return e;
    if (e.applyMatrix3(this.matrix), e.x < 0 || e.x > 1)
      switch (this.wrapS) {
        case Ca:
          e.x = e.x - Math.floor(e.x);
          break;
        case fi:
          e.x = e.x < 0 ? 0 : 1;
          break;
        case Na:
          Math.abs(Math.floor(e.x) % 2) === 1 ? e.x = Math.ceil(e.x) - e.x : e.x = e.x - Math.floor(e.x);
          break;
      }
    if (e.y < 0 || e.y > 1)
      switch (this.wrapT) {
        case Ca:
          e.y = e.y - Math.floor(e.y);
          break;
        case fi:
          e.y = e.y < 0 ? 0 : 1;
          break;
        case Na:
          Math.abs(Math.floor(e.y) % 2) === 1 ? e.y = Math.ceil(e.y) - e.y : e.y = e.y - Math.floor(e.y);
          break;
      }
    return this.flipY && (e.y = 1 - e.y), e;
  }
  /**
   * Setting this property to `true` indicates the engine the texture
   * must be updated in the next render. This triggers a texture upload
   * to the GPU and ensures correct texture parameter configuration.
   *
   * @type {boolean}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && (this.version++, this.source.needsUpdate = !0);
  }
  /**
   * Setting this property to `true` indicates the engine the PMREM
   * must be regenerated.
   *
   * @type {boolean}
   * @default false
   * @param {boolean} value
   */
  set needsPMREMUpdate(e) {
    e === !0 && this.pmremVersion++;
  }
}
mn.DEFAULT_IMAGE = null;
mn.DEFAULT_MAPPING = Im;
mn.DEFAULT_ANISOTROPY = 1;
class rt {
  /**
   * Constructs a new 4D vector.
   *
   * @param {number} [x=0] - The x value of this vector.
   * @param {number} [y=0] - The y value of this vector.
   * @param {number} [z=0] - The z value of this vector.
   * @param {number} [w=1] - The w value of this vector.
   */
  constructor(e = 0, t = 0, n = 0, r = 1) {
    rt.prototype.isVector4 = !0, this.x = e, this.y = t, this.z = n, this.w = r;
  }
  /**
   * Alias for {@link Vector4#z}.
   *
   * @type {number}
   */
  get width() {
    return this.z;
  }
  set width(e) {
    this.z = e;
  }
  /**
   * Alias for {@link Vector4#w}.
   *
   * @type {number}
   */
  get height() {
    return this.w;
  }
  set height(e) {
    this.w = e;
  }
  /**
   * Sets the vector components.
   *
   * @param {number} x - The value of the x component.
   * @param {number} y - The value of the y component.
   * @param {number} z - The value of the z component.
   * @param {number} w - The value of the w component.
   * @return {Vector4} A reference to this vector.
   */
  set(e, t, n, r) {
    return this.x = e, this.y = t, this.z = n, this.w = r, this;
  }
  /**
   * Sets the vector components to the same value.
   *
   * @param {number} scalar - The value to set for all vector components.
   * @return {Vector4} A reference to this vector.
   */
  setScalar(e) {
    return this.x = e, this.y = e, this.z = e, this.w = e, this;
  }
  /**
   * Sets the vector's x component to the given value
   *
   * @param {number} x - The value to set.
   * @return {Vector4} A reference to this vector.
   */
  setX(e) {
    return this.x = e, this;
  }
  /**
   * Sets the vector's y component to the given value
   *
   * @param {number} y - The value to set.
   * @return {Vector4} A reference to this vector.
   */
  setY(e) {
    return this.y = e, this;
  }
  /**
   * Sets the vector's z component to the given value
   *
   * @param {number} z - The value to set.
   * @return {Vector4} A reference to this vector.
   */
  setZ(e) {
    return this.z = e, this;
  }
  /**
   * Sets the vector's w component to the given value
   *
   * @param {number} w - The value to set.
   * @return {Vector4} A reference to this vector.
   */
  setW(e) {
    return this.w = e, this;
  }
  /**
   * Allows to set a vector component with an index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y,
   * `2` equals to z, `3` equals to w.
   * @param {number} value - The value to set.
   * @return {Vector4} A reference to this vector.
   */
  setComponent(e, t) {
    switch (e) {
      case 0:
        this.x = t;
        break;
      case 1:
        this.y = t;
        break;
      case 2:
        this.z = t;
        break;
      case 3:
        this.w = t;
        break;
      default:
        throw new Error("index is out of range: " + e);
    }
    return this;
  }
  /**
   * Returns the value of the vector component which matches the given index.
   *
   * @param {number} index - The component index. `0` equals to x, `1` equals to y,
   * `2` equals to z, `3` equals to w.
   * @return {number} A vector component value.
   */
  getComponent(e) {
    switch (e) {
      case 0:
        return this.x;
      case 1:
        return this.y;
      case 2:
        return this.z;
      case 3:
        return this.w;
      default:
        throw new Error("index is out of range: " + e);
    }
  }
  /**
   * Returns a new vector with copied values from this instance.
   *
   * @return {Vector4} A clone of this instance.
   */
  clone() {
    return new this.constructor(this.x, this.y, this.z, this.w);
  }
  /**
   * Copies the values of the given vector to this instance.
   *
   * @param {Vector3|Vector4} v - The vector to copy.
   * @return {Vector4} A reference to this vector.
   */
  copy(e) {
    return this.x = e.x, this.y = e.y, this.z = e.z, this.w = e.w !== void 0 ? e.w : 1, this;
  }
  /**
   * Adds the given vector to this instance.
   *
   * @param {Vector4} v - The vector to add.
   * @return {Vector4} A reference to this vector.
   */
  add(e) {
    return this.x += e.x, this.y += e.y, this.z += e.z, this.w += e.w, this;
  }
  /**
   * Adds the given scalar value to all components of this instance.
   *
   * @param {number} s - The scalar to add.
   * @return {Vector4} A reference to this vector.
   */
  addScalar(e) {
    return this.x += e, this.y += e, this.z += e, this.w += e, this;
  }
  /**
   * Adds the given vectors and stores the result in this instance.
   *
   * @param {Vector4} a - The first vector.
   * @param {Vector4} b - The second vector.
   * @return {Vector4} A reference to this vector.
   */
  addVectors(e, t) {
    return this.x = e.x + t.x, this.y = e.y + t.y, this.z = e.z + t.z, this.w = e.w + t.w, this;
  }
  /**
   * Adds the given vector scaled by the given factor to this instance.
   *
   * @param {Vector4} v - The vector.
   * @param {number} s - The factor that scales `v`.
   * @return {Vector4} A reference to this vector.
   */
  addScaledVector(e, t) {
    return this.x += e.x * t, this.y += e.y * t, this.z += e.z * t, this.w += e.w * t, this;
  }
  /**
   * Subtracts the given vector from this instance.
   *
   * @param {Vector4} v - The vector to subtract.
   * @return {Vector4} A reference to this vector.
   */
  sub(e) {
    return this.x -= e.x, this.y -= e.y, this.z -= e.z, this.w -= e.w, this;
  }
  /**
   * Subtracts the given scalar value from all components of this instance.
   *
   * @param {number} s - The scalar to subtract.
   * @return {Vector4} A reference to this vector.
   */
  subScalar(e) {
    return this.x -= e, this.y -= e, this.z -= e, this.w -= e, this;
  }
  /**
   * Subtracts the given vectors and stores the result in this instance.
   *
   * @param {Vector4} a - The first vector.
   * @param {Vector4} b - The second vector.
   * @return {Vector4} A reference to this vector.
   */
  subVectors(e, t) {
    return this.x = e.x - t.x, this.y = e.y - t.y, this.z = e.z - t.z, this.w = e.w - t.w, this;
  }
  /**
   * Multiplies the given vector with this instance.
   *
   * @param {Vector4} v - The vector to multiply.
   * @return {Vector4} A reference to this vector.
   */
  multiply(e) {
    return this.x *= e.x, this.y *= e.y, this.z *= e.z, this.w *= e.w, this;
  }
  /**
   * Multiplies the given scalar value with all components of this instance.
   *
   * @param {number} scalar - The scalar to multiply.
   * @return {Vector4} A reference to this vector.
   */
  multiplyScalar(e) {
    return this.x *= e, this.y *= e, this.z *= e, this.w *= e, this;
  }
  /**
   * Multiplies this vector with the given 4x4 matrix.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @return {Vector4} A reference to this vector.
   */
  applyMatrix4(e) {
    const t = this.x, n = this.y, r = this.z, s = this.w, a = e.elements;
    return this.x = a[0] * t + a[4] * n + a[8] * r + a[12] * s, this.y = a[1] * t + a[5] * n + a[9] * r + a[13] * s, this.z = a[2] * t + a[6] * n + a[10] * r + a[14] * s, this.w = a[3] * t + a[7] * n + a[11] * r + a[15] * s, this;
  }
  /**
   * Divides this instance by the given vector.
   *
   * @param {Vector4} v - The vector to divide.
   * @return {Vector4} A reference to this vector.
   */
  divide(e) {
    return this.x /= e.x, this.y /= e.y, this.z /= e.z, this.w /= e.w, this;
  }
  /**
   * Divides this vector by the given scalar.
   *
   * @param {number} scalar - The scalar to divide.
   * @return {Vector4} A reference to this vector.
   */
  divideScalar(e) {
    return this.multiplyScalar(1 / e);
  }
  /**
   * Sets the x, y and z components of this
   * vector to the quaternion's axis and w to the angle.
   *
   * @param {Quaternion} q - The Quaternion to set.
   * @return {Vector4} A reference to this vector.
   */
  setAxisAngleFromQuaternion(e) {
    this.w = 2 * Math.acos(e.w);
    const t = Math.sqrt(1 - e.w * e.w);
    return t < 1e-4 ? (this.x = 1, this.y = 0, this.z = 0) : (this.x = e.x / t, this.y = e.y / t, this.z = e.z / t), this;
  }
  /**
   * Sets the x, y and z components of this
   * vector to the axis of rotation and w to the angle.
   *
   * @param {Matrix4} m - A 4x4 matrix of which the upper left 3x3 matrix is a pure rotation matrix.
   * @return {Vector4} A reference to this vector.
   */
  setAxisAngleFromRotationMatrix(e) {
    let t, n, r, s;
    const l = e.elements, c = l[0], u = l[4], h = l[8], d = l[1], f = l[5], p = l[9], _ = l[2], g = l[6], m = l[10];
    if (Math.abs(u - d) < 0.01 && Math.abs(h - _) < 0.01 && Math.abs(p - g) < 0.01) {
      if (Math.abs(u + d) < 0.1 && Math.abs(h + _) < 0.1 && Math.abs(p + g) < 0.1 && Math.abs(c + f + m - 3) < 0.1)
        return this.set(1, 0, 0, 0), this;
      t = Math.PI;
      const y = (c + 1) / 2, b = (f + 1) / 2, T = (m + 1) / 2, S = (u + d) / 4, E = (h + _) / 4, v = (p + g) / 4;
      return y > b && y > T ? y < 0.01 ? (n = 0, r = 0.707106781, s = 0.707106781) : (n = Math.sqrt(y), r = S / n, s = E / n) : b > T ? b < 0.01 ? (n = 0.707106781, r = 0, s = 0.707106781) : (r = Math.sqrt(b), n = S / r, s = v / r) : T < 0.01 ? (n = 0.707106781, r = 0.707106781, s = 0) : (s = Math.sqrt(T), n = E / s, r = v / s), this.set(n, r, s, t), this;
    }
    let x = Math.sqrt((g - p) * (g - p) + (h - _) * (h - _) + (d - u) * (d - u));
    return Math.abs(x) < 1e-3 && (x = 1), this.x = (g - p) / x, this.y = (h - _) / x, this.z = (d - u) / x, this.w = Math.acos((c + f + m - 1) / 2), this;
  }
  /**
   * Sets the vector components to the position elements of the
   * given transformation matrix.
   *
   * @param {Matrix4} m - The 4x4 matrix.
   * @return {Vector4} A reference to this vector.
   */
  setFromMatrixPosition(e) {
    const t = e.elements;
    return this.x = t[12], this.y = t[13], this.z = t[14], this.w = t[15], this;
  }
  /**
   * If this vector's x, y, z or w value is greater than the given vector's x, y, z or w
   * value, replace that value with the corresponding min value.
   *
   * @param {Vector4} v - The vector.
   * @return {Vector4} A reference to this vector.
   */
  min(e) {
    return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this.z = Math.min(this.z, e.z), this.w = Math.min(this.w, e.w), this;
  }
  /**
   * If this vector's x, y, z or w value is less than the given vector's x, y, z or w
   * value, replace that value with the corresponding max value.
   *
   * @param {Vector4} v - The vector.
   * @return {Vector4} A reference to this vector.
   */
  max(e) {
    return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this.w = Math.max(this.w, e.w), this;
  }
  /**
   * If this vector's x, y, z or w value is greater than the max vector's x, y, z or w
   * value, it is replaced by the corresponding value.
   * If this vector's x, y, z or w value is less than the min vector's x, y, z or w value,
   * it is replaced by the corresponding value.
   *
   * @param {Vector4} min - The minimum x, y and z values.
   * @param {Vector4} max - The maximum x, y and z values in the desired range.
   * @return {Vector4} A reference to this vector.
   */
  clamp(e, t) {
    return this.x = ct(this.x, e.x, t.x), this.y = ct(this.y, e.y, t.y), this.z = ct(this.z, e.z, t.z), this.w = ct(this.w, e.w, t.w), this;
  }
  /**
   * If this vector's x, y, z or w values are greater than the max value, they are
   * replaced by the max value.
   * If this vector's x, y, z or w values are less than the min value, they are
   * replaced by the min value.
   *
   * @param {number} minVal - The minimum value the components will be clamped to.
   * @param {number} maxVal - The maximum value the components will be clamped to.
   * @return {Vector4} A reference to this vector.
   */
  clampScalar(e, t) {
    return this.x = ct(this.x, e, t), this.y = ct(this.y, e, t), this.z = ct(this.z, e, t), this.w = ct(this.w, e, t), this;
  }
  /**
   * If this vector's length is greater than the max value, it is replaced by
   * the max value.
   * If this vector's length is less than the min value, it is replaced by the
   * min value.
   *
   * @param {number} min - The minimum value the vector length will be clamped to.
   * @param {number} max - The maximum value the vector length will be clamped to.
   * @return {Vector4} A reference to this vector.
   */
  clampLength(e, t) {
    const n = this.length();
    return this.divideScalar(n || 1).multiplyScalar(ct(n, e, t));
  }
  /**
   * The components of this vector are rounded down to the nearest integer value.
   *
   * @return {Vector4} A reference to this vector.
   */
  floor() {
    return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this.w = Math.floor(this.w), this;
  }
  /**
   * The components of this vector are rounded up to the nearest integer value.
   *
   * @return {Vector4} A reference to this vector.
   */
  ceil() {
    return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this.z = Math.ceil(this.z), this.w = Math.ceil(this.w), this;
  }
  /**
   * The components of this vector are rounded to the nearest integer value
   *
   * @return {Vector4} A reference to this vector.
   */
  round() {
    return this.x = Math.round(this.x), this.y = Math.round(this.y), this.z = Math.round(this.z), this.w = Math.round(this.w), this;
  }
  /**
   * The components of this vector are rounded towards zero (up if negative,
   * down if positive) to an integer value.
   *
   * @return {Vector4} A reference to this vector.
   */
  roundToZero() {
    return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this.z = Math.trunc(this.z), this.w = Math.trunc(this.w), this;
  }
  /**
   * Inverts this vector - i.e. sets x = -x, y = -y, z = -z, w = -w.
   *
   * @return {Vector4} A reference to this vector.
   */
  negate() {
    return this.x = -this.x, this.y = -this.y, this.z = -this.z, this.w = -this.w, this;
  }
  /**
   * Calculates the dot product of the given vector with this instance.
   *
   * @param {Vector4} v - The vector to compute the dot product with.
   * @return {number} The result of the dot product.
   */
  dot(e) {
    return this.x * e.x + this.y * e.y + this.z * e.z + this.w * e.w;
  }
  /**
   * Computes the square of the Euclidean length (straight-line length) from
   * (0, 0, 0, 0) to (x, y, z, w). If you are comparing the lengths of vectors, you should
   * compare the length squared instead as it is slightly more efficient to calculate.
   *
   * @return {number} The square length of this vector.
   */
  lengthSq() {
    return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
  }
  /**
   * Computes the  Euclidean length (straight-line length) from (0, 0, 0, 0) to (x, y, z, w).
   *
   * @return {number} The length of this vector.
   */
  length() {
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
  }
  /**
   * Computes the Manhattan length of this vector.
   *
   * @return {number} The length of this vector.
   */
  manhattanLength() {
    return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
  }
  /**
   * Converts this vector to a unit vector - that is, sets it equal to a vector
   * with the same direction as this one, but with a vector length of `1`.
   *
   * @return {Vector4} A reference to this vector.
   */
  normalize() {
    return this.divideScalar(this.length() || 1);
  }
  /**
   * Sets this vector to a vector with the same direction as this one, but
   * with the specified length.
   *
   * @param {number} length - The new length of this vector.
   * @return {Vector4} A reference to this vector.
   */
  setLength(e) {
    return this.normalize().multiplyScalar(e);
  }
  /**
   * Linearly interpolates between the given vector and this instance, where
   * alpha is the percent distance along the line - alpha = 0 will be this
   * vector, and alpha = 1 will be the given one.
   *
   * @param {Vector4} v - The vector to interpolate towards.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector4} A reference to this vector.
   */
  lerp(e, t) {
    return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this.z += (e.z - this.z) * t, this.w += (e.w - this.w) * t, this;
  }
  /**
   * Linearly interpolates between the given vectors, where alpha is the percent
   * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
   * be the second one. The result is stored in this instance.
   *
   * @param {Vector4} v1 - The first vector.
   * @param {Vector4} v2 - The second vector.
   * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
   * @return {Vector4} A reference to this vector.
   */
  lerpVectors(e, t, n) {
    return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this.z = e.z + (t.z - e.z) * n, this.w = e.w + (t.w - e.w) * n, this;
  }
  /**
   * Returns `true` if this vector is equal with the given one.
   *
   * @param {Vector4} v - The vector to test for equality.
   * @return {boolean} Whether this vector is equal with the given one.
   */
  equals(e) {
    return e.x === this.x && e.y === this.y && e.z === this.z && e.w === this.w;
  }
  /**
   * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`,
   * z value to be `array[ offset + 2 ]`, w value to be `array[ offset + 3 ]`.
   *
   * @param {Array<number>} array - An array holding the vector component values.
   * @param {number} [offset=0] - The offset into the array.
   * @return {Vector4} A reference to this vector.
   */
  fromArray(e, t = 0) {
    return this.x = e[t], this.y = e[t + 1], this.z = e[t + 2], this.w = e[t + 3], this;
  }
  /**
   * Writes the components of this vector to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the vector components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The vector components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this.x, e[t + 1] = this.y, e[t + 2] = this.z, e[t + 3] = this.w, e;
  }
  /**
   * Sets the components of this vector from the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
   * @param {number} index - The index into the attribute.
   * @return {Vector4} A reference to this vector.
   */
  fromBufferAttribute(e, t) {
    return this.x = e.getX(t), this.y = e.getY(t), this.z = e.getZ(t), this.w = e.getW(t), this;
  }
  /**
   * Sets each component of this vector to a pseudo-random value between `0` and
   * `1`, excluding `1`.
   *
   * @return {Vector4} A reference to this vector.
   */
  random() {
    return this.x = Math.random(), this.y = Math.random(), this.z = Math.random(), this.w = Math.random(), this;
  }
  *[Symbol.iterator]() {
    yield this.x, yield this.y, yield this.z, yield this.w;
  }
}
class js extends Fr {
  /**
   * Render target options.
   *
   * @typedef {Object} RenderTarget~Options
   * @property {boolean} [generateMipmaps=false] - Whether to generate mipmaps or not.
   * @property {number} [magFilter=LinearFilter] - The mag filter.
   * @property {number} [minFilter=LinearFilter] - The min filter.
   * @property {number} [format=RGBAFormat] - The texture format.
   * @property {number} [type=UnsignedByteType] - The texture type.
   * @property {?string} [internalFormat=null] - The texture's internal format.
   * @property {number} [wrapS=ClampToEdgeWrapping] - The texture's uv wrapping mode.
   * @property {number} [wrapT=ClampToEdgeWrapping] - The texture's uv wrapping mode.
   * @property {number} [anisotropy=1] - The texture's anisotropy value.
   * @property {string} [colorSpace=NoColorSpace] - The texture's color space.
   * @property {boolean} [depthBuffer=true] - Whether to allocate a depth buffer or not.
   * @property {boolean} [stencilBuffer=false] - Whether to allocate a stencil buffer or not.
   * @property {boolean} [resolveDepthBuffer=true] - Whether to resolve the depth buffer or not.
   * @property {boolean} [resolveStencilBuffer=true] - Whether  to resolve the stencil buffer or not.
   * @property {?Texture} [depthTexture=null] - Reference to a depth texture.
   * @property {number} [samples=0] - The MSAA samples count.
   * @property {number} [count=1] - Defines the number of color attachments . Must be at least `1`.
   * @property {number} [depth=1] - The texture depth.
   * @property {boolean} [multiview=false] - Whether this target is used for multiview rendering.
   */
  /**
   * Constructs a new render target.
   *
   * @param {number} [width=1] - The width of the render target.
   * @param {number} [height=1] - The height of the render target.
   * @param {RenderTarget~Options} [options] - The configuration object.
   */
  constructor(e = 1, t = 1, n = {}) {
    super(), n = Object.assign({
      generateMipmaps: !1,
      internalFormat: null,
      minFilter: Ot,
      depthBuffer: !0,
      stencilBuffer: !1,
      resolveDepthBuffer: !0,
      resolveStencilBuffer: !0,
      depthTexture: null,
      samples: 0,
      count: 1,
      depth: 1,
      multiview: !1
    }, n), this.isRenderTarget = !0, this.width = e, this.height = t, this.depth = n.depth, this.scissor = new rt(0, 0, e, t), this.scissorTest = !1, this.viewport = new rt(0, 0, e, t), this.textures = [];
    const r = { width: e, height: t, depth: n.depth }, s = new mn(r), a = n.count;
    for (let o = 0; o < a; o++)
      this.textures[o] = s.clone(), this.textures[o].isRenderTargetTexture = !0, this.textures[o].renderTarget = this;
    this._setTextureOptions(n), this.depthBuffer = n.depthBuffer, this.stencilBuffer = n.stencilBuffer, this.resolveDepthBuffer = n.resolveDepthBuffer, this.resolveStencilBuffer = n.resolveStencilBuffer, this._depthTexture = null, this.depthTexture = n.depthTexture, this.samples = n.samples, this.multiview = n.multiview;
  }
  _setTextureOptions(e = {}) {
    const t = {
      minFilter: Ot,
      generateMipmaps: !1,
      flipY: !1,
      internalFormat: null
    };
    e.mapping !== void 0 && (t.mapping = e.mapping), e.wrapS !== void 0 && (t.wrapS = e.wrapS), e.wrapT !== void 0 && (t.wrapT = e.wrapT), e.wrapR !== void 0 && (t.wrapR = e.wrapR), e.magFilter !== void 0 && (t.magFilter = e.magFilter), e.minFilter !== void 0 && (t.minFilter = e.minFilter), e.format !== void 0 && (t.format = e.format), e.type !== void 0 && (t.type = e.type), e.anisotropy !== void 0 && (t.anisotropy = e.anisotropy), e.colorSpace !== void 0 && (t.colorSpace = e.colorSpace), e.flipY !== void 0 && (t.flipY = e.flipY), e.generateMipmaps !== void 0 && (t.generateMipmaps = e.generateMipmaps), e.internalFormat !== void 0 && (t.internalFormat = e.internalFormat);
    for (let n = 0; n < this.textures.length; n++)
      this.textures[n].setValues(t);
  }
  /**
   * The texture representing the default color attachment.
   *
   * @type {Texture}
   */
  get texture() {
    return this.textures[0];
  }
  set texture(e) {
    this.textures[0] = e;
  }
  set depthTexture(e) {
    this._depthTexture !== null && (this._depthTexture.renderTarget = null), e !== null && (e.renderTarget = this), this._depthTexture = e;
  }
  /**
   * Instead of saving the depth in a renderbuffer, a texture
   * can be used instead which is useful for further processing
   * e.g. in context of post-processing.
   *
   * @type {?DepthTexture}
   * @default null
   */
  get depthTexture() {
    return this._depthTexture;
  }
  /**
   * Sets the size of this render target.
   *
   * @param {number} width - The width.
   * @param {number} height - The height.
   * @param {number} [depth=1] - The depth.
   */
  setSize(e, t, n = 1) {
    if (this.width !== e || this.height !== t || this.depth !== n) {
      this.width = e, this.height = t, this.depth = n;
      for (let r = 0, s = this.textures.length; r < s; r++)
        this.textures[r].image.width = e, this.textures[r].image.height = t, this.textures[r].image.depth = n, this.textures[r].isData3DTexture !== !0 && (this.textures[r].isArrayTexture = this.textures[r].image.depth > 1);
      this.dispose();
    }
    this.viewport.set(0, 0, e, t), this.scissor.set(0, 0, e, t);
  }
  /**
   * Returns a new render target with copied values from this instance.
   *
   * @return {RenderTarget} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the settings of the given render target. This is a structural copy so
   * no resources are shared between render targets after the copy. That includes
   * all MRT textures and the depth texture.
   *
   * @param {RenderTarget} source - The render target to copy.
   * @return {RenderTarget} A reference to this instance.
   */
  copy(e) {
    this.width = e.width, this.height = e.height, this.depth = e.depth, this.scissor.copy(e.scissor), this.scissorTest = e.scissorTest, this.viewport.copy(e.viewport), this.textures.length = 0;
    for (let t = 0, n = e.textures.length; t < n; t++) {
      this.textures[t] = e.textures[t].clone(), this.textures[t].isRenderTargetTexture = !0, this.textures[t].renderTarget = this;
      const r = Object.assign({}, e.textures[t].image);
      this.textures[t].source = new $m(r);
    }
    return this.depthBuffer = e.depthBuffer, this.stencilBuffer = e.stencilBuffer, this.resolveDepthBuffer = e.resolveDepthBuffer, this.resolveStencilBuffer = e.resolveStencilBuffer, e.depthTexture !== null && (this.depthTexture = e.depthTexture.clone()), this.samples = e.samples, this;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   *
   * @fires RenderTarget#dispose
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
}
class tr extends js {
  /**
   * Constructs a new 3D render target.
   *
   * @param {number} [width=1] - The width of the render target.
   * @param {number} [height=1] - The height of the render target.
   * @param {RenderTarget~Options} [options] - The configuration object.
   */
  constructor(e = 1, t = 1, n = {}) {
    super(e, t, n), this.isWebGLRenderTarget = !0;
  }
}
class Wm extends mn {
  /**
   * Constructs a new data array texture.
   *
   * @param {?TypedArray} [data=null] - The buffer data.
   * @param {number} [width=1] - The width of the texture.
   * @param {number} [height=1] - The height of the texture.
   * @param {number} [depth=1] - The depth of the texture.
   */
  constructor(e = null, t = 1, n = 1, r = 1) {
    super(null), this.isDataArrayTexture = !0, this.image = { data: e, width: t, height: n, depth: r }, this.magFilter = Tt, this.minFilter = Tt, this.wrapR = fi, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1, this.layerUpdates = /* @__PURE__ */ new Set();
  }
  /**
   * Describes that a specific layer of the texture needs to be updated.
   * Normally when {@link Texture#needsUpdate} is set to `true`, the
   * entire data texture array is sent to the GPU. Marking specific
   * layers will only transmit subsets of all mipmaps associated with a
   * specific depth in the array which is often much more performant.
   *
   * @param {number} layerIndex - The layer index that should be updated.
   */
  addLayerUpdate(e) {
    this.layerUpdates.add(e);
  }
  /**
   * Resets the layer updates registry.
   */
  clearLayerUpdates() {
    this.layerUpdates.clear();
  }
}
class KM extends mn {
  /**
   * Constructs a new data array texture.
   *
   * @param {?TypedArray} [data=null] - The buffer data.
   * @param {number} [width=1] - The width of the texture.
   * @param {number} [height=1] - The height of the texture.
   * @param {number} [depth=1] - The depth of the texture.
   */
  constructor(e = null, t = 1, n = 1, r = 1) {
    super(null), this.isData3DTexture = !0, this.image = { data: e, width: t, height: n, depth: r }, this.magFilter = Tt, this.minFilter = Tt, this.wrapR = fi, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1;
  }
}
class pt {
  /**
   * Constructs a new 4x4 matrix. The arguments are supposed to be
   * in row-major order. If no arguments are provided, the constructor
   * initializes the matrix as an identity matrix.
   *
   * @param {number} [n11] - 1-1 matrix element.
   * @param {number} [n12] - 1-2 matrix element.
   * @param {number} [n13] - 1-3 matrix element.
   * @param {number} [n14] - 1-4 matrix element.
   * @param {number} [n21] - 2-1 matrix element.
   * @param {number} [n22] - 2-2 matrix element.
   * @param {number} [n23] - 2-3 matrix element.
   * @param {number} [n24] - 2-4 matrix element.
   * @param {number} [n31] - 3-1 matrix element.
   * @param {number} [n32] - 3-2 matrix element.
   * @param {number} [n33] - 3-3 matrix element.
   * @param {number} [n34] - 3-4 matrix element.
   * @param {number} [n41] - 4-1 matrix element.
   * @param {number} [n42] - 4-2 matrix element.
   * @param {number} [n43] - 4-3 matrix element.
   * @param {number} [n44] - 4-4 matrix element.
   */
  constructor(e, t, n, r, s, a, o, l, c, u, h, d, f, p, _, g) {
    pt.prototype.isMatrix4 = !0, this.elements = [
      1,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      1
    ], e !== void 0 && this.set(e, t, n, r, s, a, o, l, c, u, h, d, f, p, _, g);
  }
  /**
   * Sets the elements of the matrix.The arguments are supposed to be
   * in row-major order.
   *
   * @param {number} [n11] - 1-1 matrix element.
   * @param {number} [n12] - 1-2 matrix element.
   * @param {number} [n13] - 1-3 matrix element.
   * @param {number} [n14] - 1-4 matrix element.
   * @param {number} [n21] - 2-1 matrix element.
   * @param {number} [n22] - 2-2 matrix element.
   * @param {number} [n23] - 2-3 matrix element.
   * @param {number} [n24] - 2-4 matrix element.
   * @param {number} [n31] - 3-1 matrix element.
   * @param {number} [n32] - 3-2 matrix element.
   * @param {number} [n33] - 3-3 matrix element.
   * @param {number} [n34] - 3-4 matrix element.
   * @param {number} [n41] - 4-1 matrix element.
   * @param {number} [n42] - 4-2 matrix element.
   * @param {number} [n43] - 4-3 matrix element.
   * @param {number} [n44] - 4-4 matrix element.
   * @return {Matrix4} A reference to this matrix.
   */
  set(e, t, n, r, s, a, o, l, c, u, h, d, f, p, _, g) {
    const m = this.elements;
    return m[0] = e, m[4] = t, m[8] = n, m[12] = r, m[1] = s, m[5] = a, m[9] = o, m[13] = l, m[2] = c, m[6] = u, m[10] = h, m[14] = d, m[3] = f, m[7] = p, m[11] = _, m[15] = g, this;
  }
  /**
   * Sets this matrix to the 4x4 identity matrix.
   *
   * @return {Matrix4} A reference to this matrix.
   */
  identity() {
    return this.set(
      1,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Returns a matrix with copied values from this instance.
   *
   * @return {Matrix4} A clone of this instance.
   */
  clone() {
    return new pt().fromArray(this.elements);
  }
  /**
   * Copies the values of the given matrix to this instance.
   *
   * @param {Matrix4} m - The matrix to copy.
   * @return {Matrix4} A reference to this matrix.
   */
  copy(e) {
    const t = this.elements, n = e.elements;
    return t[0] = n[0], t[1] = n[1], t[2] = n[2], t[3] = n[3], t[4] = n[4], t[5] = n[5], t[6] = n[6], t[7] = n[7], t[8] = n[8], t[9] = n[9], t[10] = n[10], t[11] = n[11], t[12] = n[12], t[13] = n[13], t[14] = n[14], t[15] = n[15], this;
  }
  /**
   * Copies the translation component of the given matrix
   * into this matrix's translation component.
   *
   * @param {Matrix4} m - The matrix to copy the translation component.
   * @return {Matrix4} A reference to this matrix.
   */
  copyPosition(e) {
    const t = this.elements, n = e.elements;
    return t[12] = n[12], t[13] = n[13], t[14] = n[14], this;
  }
  /**
   * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix.
   *
   * @param {Matrix3} m - The 3x3 matrix.
   * @return {Matrix4} A reference to this matrix.
   */
  setFromMatrix3(e) {
    const t = e.elements;
    return this.set(
      t[0],
      t[3],
      t[6],
      0,
      t[1],
      t[4],
      t[7],
      0,
      t[2],
      t[5],
      t[8],
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Extracts the basis of this matrix into the three axis vectors provided.
   *
   * @param {Vector3} xAxis - The basis's x axis.
   * @param {Vector3} yAxis - The basis's y axis.
   * @param {Vector3} zAxis - The basis's z axis.
   * @return {Matrix4} A reference to this matrix.
   */
  extractBasis(e, t, n) {
    return this.determinant() === 0 ? (e.set(1, 0, 0), t.set(0, 1, 0), n.set(0, 0, 1), this) : (e.setFromMatrixColumn(this, 0), t.setFromMatrixColumn(this, 1), n.setFromMatrixColumn(this, 2), this);
  }
  /**
   * Sets the given basis vectors to this matrix.
   *
   * @param {Vector3} xAxis - The basis's x axis.
   * @param {Vector3} yAxis - The basis's y axis.
   * @param {Vector3} zAxis - The basis's z axis.
   * @return {Matrix4} A reference to this matrix.
   */
  makeBasis(e, t, n) {
    return this.set(
      e.x,
      t.x,
      n.x,
      0,
      e.y,
      t.y,
      n.y,
      0,
      e.z,
      t.z,
      n.z,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Extracts the rotation component of the given matrix
   * into this matrix's rotation component.
   *
   * Note: This method does not support reflection matrices.
   *
   * @param {Matrix4} m - The matrix.
   * @return {Matrix4} A reference to this matrix.
   */
  extractRotation(e) {
    if (e.determinant() === 0)
      return this.identity();
    const t = this.elements, n = e.elements, r = 1 / Qa.setFromMatrixColumn(e, 0).length(), s = 1 / Qa.setFromMatrixColumn(e, 1).length(), a = 1 / Qa.setFromMatrixColumn(e, 2).length();
    return t[0] = n[0] * r, t[1] = n[1] * r, t[2] = n[2] * r, t[3] = 0, t[4] = n[4] * s, t[5] = n[5] * s, t[6] = n[6] * s, t[7] = 0, t[8] = n[8] * a, t[9] = n[9] * a, t[10] = n[10] * a, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this;
  }
  /**
   * Sets the rotation component (the upper left 3x3 matrix) of this matrix to
   * the rotation specified by the given Euler angles. The rest of
   * the matrix is set to the identity. Depending on the {@link Euler#order},
   * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix)
   * for a complete list.
   *
   * @param {Euler} euler - The Euler angles.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationFromEuler(e) {
    const t = this.elements, n = e.x, r = e.y, s = e.z, a = Math.cos(n), o = Math.sin(n), l = Math.cos(r), c = Math.sin(r), u = Math.cos(s), h = Math.sin(s);
    if (e.order === "XYZ") {
      const d = a * u, f = a * h, p = o * u, _ = o * h;
      t[0] = l * u, t[4] = -l * h, t[8] = c, t[1] = f + p * c, t[5] = d - _ * c, t[9] = -o * l, t[2] = _ - d * c, t[6] = p + f * c, t[10] = a * l;
    } else if (e.order === "YXZ") {
      const d = l * u, f = l * h, p = c * u, _ = c * h;
      t[0] = d + _ * o, t[4] = p * o - f, t[8] = a * c, t[1] = a * h, t[5] = a * u, t[9] = -o, t[2] = f * o - p, t[6] = _ + d * o, t[10] = a * l;
    } else if (e.order === "ZXY") {
      const d = l * u, f = l * h, p = c * u, _ = c * h;
      t[0] = d - _ * o, t[4] = -a * h, t[8] = p + f * o, t[1] = f + p * o, t[5] = a * u, t[9] = _ - d * o, t[2] = -a * c, t[6] = o, t[10] = a * l;
    } else if (e.order === "ZYX") {
      const d = a * u, f = a * h, p = o * u, _ = o * h;
      t[0] = l * u, t[4] = p * c - f, t[8] = d * c + _, t[1] = l * h, t[5] = _ * c + d, t[9] = f * c - p, t[2] = -c, t[6] = o * l, t[10] = a * l;
    } else if (e.order === "YZX") {
      const d = a * l, f = a * c, p = o * l, _ = o * c;
      t[0] = l * u, t[4] = _ - d * h, t[8] = p * h + f, t[1] = h, t[5] = a * u, t[9] = -o * u, t[2] = -c * u, t[6] = f * h + p, t[10] = d - _ * h;
    } else if (e.order === "XZY") {
      const d = a * l, f = a * c, p = o * l, _ = o * c;
      t[0] = l * u, t[4] = -h, t[8] = c * u, t[1] = d * h + _, t[5] = a * u, t[9] = f * h - p, t[2] = p * h - f, t[6] = o * u, t[10] = _ * h + d;
    }
    return t[3] = 0, t[7] = 0, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this;
  }
  /**
   * Sets the rotation component of this matrix to the rotation specified by
   * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion)
   * The rest of the matrix is set to the identity.
   *
   * @param {Quaternion} q - The Quaternion.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationFromQuaternion(e) {
    return this.compose(ZM, e, QM);
  }
  /**
   * Sets the rotation component of the transformation matrix, looking from `eye` towards
   * `target`, and oriented by the up-direction.
   *
   * @param {Vector3} eye - The eye vector.
   * @param {Vector3} target - The target vector.
   * @param {Vector3} up - The up vector.
   * @return {Matrix4} A reference to this matrix.
   */
  lookAt(e, t, n) {
    const r = this.elements;
    return bi.subVectors(e, t), bi.lengthSq() === 0 && (bi.z = 1), bi.normalize(), gs.crossVectors(n, bi), gs.lengthSq() === 0 && (Math.abs(n.z) === 1 ? bi.x += 1e-4 : bi.z += 1e-4, bi.normalize(), gs.crossVectors(n, bi)), gs.normalize(), mu.crossVectors(bi, gs), r[0] = gs.x, r[4] = mu.x, r[8] = bi.x, r[1] = gs.y, r[5] = mu.y, r[9] = bi.y, r[2] = gs.z, r[6] = mu.z, r[10] = bi.z, this;
  }
  /**
   * Post-multiplies this matrix by the given 4x4 matrix.
   *
   * @param {Matrix4} m - The matrix to multiply with.
   * @return {Matrix4} A reference to this matrix.
   */
  multiply(e) {
    return this.multiplyMatrices(this, e);
  }
  /**
   * Pre-multiplies this matrix by the given 4x4 matrix.
   *
   * @param {Matrix4} m - The matrix to multiply with.
   * @return {Matrix4} A reference to this matrix.
   */
  premultiply(e) {
    return this.multiplyMatrices(e, this);
  }
  /**
   * Multiples the given 4x4 matrices and stores the result
   * in this matrix.
   *
   * @param {Matrix4} a - The first matrix.
   * @param {Matrix4} b - The second matrix.
   * @return {Matrix4} A reference to this matrix.
   */
  multiplyMatrices(e, t) {
    const n = e.elements, r = t.elements, s = this.elements, a = n[0], o = n[4], l = n[8], c = n[12], u = n[1], h = n[5], d = n[9], f = n[13], p = n[2], _ = n[6], g = n[10], m = n[14], x = n[3], y = n[7], b = n[11], T = n[15], S = r[0], E = r[4], v = r[8], M = r[12], F = r[1], R = r[5], I = r[9], B = r[13], N = r[2], C = r[6], L = r[10], k = r[14], re = r[3], se = r[7], ve = r[11], X = r[15];
    return s[0] = a * S + o * F + l * N + c * re, s[4] = a * E + o * R + l * C + c * se, s[8] = a * v + o * I + l * L + c * ve, s[12] = a * M + o * B + l * k + c * X, s[1] = u * S + h * F + d * N + f * re, s[5] = u * E + h * R + d * C + f * se, s[9] = u * v + h * I + d * L + f * ve, s[13] = u * M + h * B + d * k + f * X, s[2] = p * S + _ * F + g * N + m * re, s[6] = p * E + _ * R + g * C + m * se, s[10] = p * v + _ * I + g * L + m * ve, s[14] = p * M + _ * B + g * k + m * X, s[3] = x * S + y * F + b * N + T * re, s[7] = x * E + y * R + b * C + T * se, s[11] = x * v + y * I + b * L + T * ve, s[15] = x * M + y * B + b * k + T * X, this;
  }
  /**
   * Multiplies every component of the matrix by the given scalar.
   *
   * @param {number} s - The scalar.
   * @return {Matrix4} A reference to this matrix.
   */
  multiplyScalar(e) {
    const t = this.elements;
    return t[0] *= e, t[4] *= e, t[8] *= e, t[12] *= e, t[1] *= e, t[5] *= e, t[9] *= e, t[13] *= e, t[2] *= e, t[6] *= e, t[10] *= e, t[14] *= e, t[3] *= e, t[7] *= e, t[11] *= e, t[15] *= e, this;
  }
  /**
   * Computes and returns the determinant of this matrix.
   *
   * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html).
   *
   * @return {number} The determinant.
   */
  determinant() {
    const e = this.elements, t = e[0], n = e[4], r = e[8], s = e[12], a = e[1], o = e[5], l = e[9], c = e[13], u = e[2], h = e[6], d = e[10], f = e[14], p = e[3], _ = e[7], g = e[11], m = e[15], x = l * f - c * d, y = o * f - c * h, b = o * d - l * h, T = a * f - c * u, S = a * d - l * u, E = a * h - o * u;
    return t * (_ * x - g * y + m * b) - n * (p * x - g * T + m * S) + r * (p * y - _ * T + m * E) - s * (p * b - _ * S + g * E);
  }
  /**
   * Transposes this matrix in place.
   *
   * @return {Matrix4} A reference to this matrix.
   */
  transpose() {
    const e = this.elements;
    let t;
    return t = e[1], e[1] = e[4], e[4] = t, t = e[2], e[2] = e[8], e[8] = t, t = e[6], e[6] = e[9], e[9] = t, t = e[3], e[3] = e[12], e[12] = t, t = e[7], e[7] = e[13], e[13] = t, t = e[11], e[11] = e[14], e[14] = t, this;
  }
  /**
   * Sets the position component for this matrix from the given vector,
   * without affecting the rest of the matrix.
   *
   * @param {number|Vector3} x - The x component of the vector or alternatively the vector object.
   * @param {number} y - The y component of the vector.
   * @param {number} z - The z component of the vector.
   * @return {Matrix4} A reference to this matrix.
   */
  setPosition(e, t, n) {
    const r = this.elements;
    return e.isVector3 ? (r[12] = e.x, r[13] = e.y, r[14] = e.z) : (r[12] = e, r[13] = t, r[14] = n), this;
  }
  /**
   * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution).
   * You can not invert with a determinant of zero. If you attempt this, the method produces
   * a zero matrix instead.
   *
   * @return {Matrix4} A reference to this matrix.
   */
  invert() {
    const e = this.elements, t = e[0], n = e[1], r = e[2], s = e[3], a = e[4], o = e[5], l = e[6], c = e[7], u = e[8], h = e[9], d = e[10], f = e[11], p = e[12], _ = e[13], g = e[14], m = e[15], x = t * o - n * a, y = t * l - r * a, b = t * c - s * a, T = n * l - r * o, S = n * c - s * o, E = r * c - s * l, v = u * _ - h * p, M = u * g - d * p, F = u * m - f * p, R = h * g - d * _, I = h * m - f * _, B = d * m - f * g, N = x * B - y * I + b * R + T * F - S * M + E * v;
    if (N === 0)
      return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    const C = 1 / N;
    return e[0] = (o * B - l * I + c * R) * C, e[1] = (r * I - n * B - s * R) * C, e[2] = (_ * E - g * S + m * T) * C, e[3] = (d * S - h * E - f * T) * C, e[4] = (l * F - a * B - c * M) * C, e[5] = (t * B - r * F + s * M) * C, e[6] = (g * b - p * E - m * y) * C, e[7] = (u * E - d * b + f * y) * C, e[8] = (a * I - o * F + c * v) * C, e[9] = (n * F - t * I - s * v) * C, e[10] = (p * S - _ * b + m * x) * C, e[11] = (h * b - u * S - f * x) * C, e[12] = (o * M - a * R - l * v) * C, e[13] = (t * R - n * M + r * v) * C, e[14] = (_ * y - p * T - g * x) * C, e[15] = (u * T - h * y + d * x) * C, this;
  }
  /**
   * Multiplies the columns of this matrix by the given vector.
   *
   * @param {Vector3} v - The scale vector.
   * @return {Matrix4} A reference to this matrix.
   */
  scale(e) {
    const t = this.elements, n = e.x, r = e.y, s = e.z;
    return t[0] *= n, t[4] *= r, t[8] *= s, t[1] *= n, t[5] *= r, t[9] *= s, t[2] *= n, t[6] *= r, t[10] *= s, t[3] *= n, t[7] *= r, t[11] *= s, this;
  }
  /**
   * Gets the maximum scale value of the three axes.
   *
   * @return {number} The maximum scale.
   */
  getMaxScaleOnAxis() {
    const e = this.elements, t = e[0] * e[0] + e[1] * e[1] + e[2] * e[2], n = e[4] * e[4] + e[5] * e[5] + e[6] * e[6], r = e[8] * e[8] + e[9] * e[9] + e[10] * e[10];
    return Math.sqrt(Math.max(t, n, r));
  }
  /**
   * Sets this matrix as a translation transform from the given vector.
   *
   * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector.
   * @param {number} y - The amount to translate in the Y axis.
   * @param {number} z - The amount to translate in the z axis.
   * @return {Matrix4} A reference to this matrix.
   */
  makeTranslation(e, t, n) {
    return e.isVector3 ? this.set(
      1,
      0,
      0,
      e.x,
      0,
      1,
      0,
      e.y,
      0,
      0,
      1,
      e.z,
      0,
      0,
      0,
      1
    ) : this.set(
      1,
      0,
      0,
      e,
      0,
      1,
      0,
      t,
      0,
      0,
      1,
      n,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a rotational transformation around the X axis by
   * the given angle.
   *
   * @param {number} theta - The rotation in radians.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationX(e) {
    const t = Math.cos(e), n = Math.sin(e);
    return this.set(
      1,
      0,
      0,
      0,
      0,
      t,
      -n,
      0,
      0,
      n,
      t,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a rotational transformation around the Y axis by
   * the given angle.
   *
   * @param {number} theta - The rotation in radians.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationY(e) {
    const t = Math.cos(e), n = Math.sin(e);
    return this.set(
      t,
      0,
      n,
      0,
      0,
      1,
      0,
      0,
      -n,
      0,
      t,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a rotational transformation around the Z axis by
   * the given angle.
   *
   * @param {number} theta - The rotation in radians.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationZ(e) {
    const t = Math.cos(e), n = Math.sin(e);
    return this.set(
      t,
      -n,
      0,
      0,
      n,
      t,
      0,
      0,
      0,
      0,
      1,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a rotational transformation around the given axis by
   * the given angle.
   *
   * This is a somewhat controversial but mathematically sound alternative to
   * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199).
   *
   * @param {Vector3} axis - The normalized rotation axis.
   * @param {number} angle - The rotation in radians.
   * @return {Matrix4} A reference to this matrix.
   */
  makeRotationAxis(e, t) {
    const n = Math.cos(t), r = Math.sin(t), s = 1 - n, a = e.x, o = e.y, l = e.z, c = s * a, u = s * o;
    return this.set(
      c * a + n,
      c * o - r * l,
      c * l + r * o,
      0,
      c * o + r * l,
      u * o + n,
      u * l - r * a,
      0,
      c * l - r * o,
      u * l + r * a,
      s * l * l + n,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a scale transformation.
   *
   * @param {number} x - The amount to scale in the X axis.
   * @param {number} y - The amount to scale in the Y axis.
   * @param {number} z - The amount to scale in the Z axis.
   * @return {Matrix4} A reference to this matrix.
   */
  makeScale(e, t, n) {
    return this.set(
      e,
      0,
      0,
      0,
      0,
      t,
      0,
      0,
      0,
      0,
      n,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix as a shear transformation.
   *
   * @param {number} xy - The amount to shear X by Y.
   * @param {number} xz - The amount to shear X by Z.
   * @param {number} yx - The amount to shear Y by X.
   * @param {number} yz - The amount to shear Y by Z.
   * @param {number} zx - The amount to shear Z by X.
   * @param {number} zy - The amount to shear Z by Y.
   * @return {Matrix4} A reference to this matrix.
   */
  makeShear(e, t, n, r, s, a) {
    return this.set(
      1,
      n,
      s,
      0,
      e,
      1,
      a,
      0,
      t,
      r,
      1,
      0,
      0,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets this matrix to the transformation composed of the given position,
   * rotation (Quaternion) and scale.
   *
   * @param {Vector3} position - The position vector.
   * @param {Quaternion} quaternion - The rotation as a Quaternion.
   * @param {Vector3} scale - The scale vector.
   * @return {Matrix4} A reference to this matrix.
   */
  compose(e, t, n) {
    const r = this.elements, s = t._x, a = t._y, o = t._z, l = t._w, c = s + s, u = a + a, h = o + o, d = s * c, f = s * u, p = s * h, _ = a * u, g = a * h, m = o * h, x = l * c, y = l * u, b = l * h, T = n.x, S = n.y, E = n.z;
    return r[0] = (1 - (_ + m)) * T, r[1] = (f + b) * T, r[2] = (p - y) * T, r[3] = 0, r[4] = (f - b) * S, r[5] = (1 - (d + m)) * S, r[6] = (g + x) * S, r[7] = 0, r[8] = (p + y) * E, r[9] = (g - x) * E, r[10] = (1 - (d + _)) * E, r[11] = 0, r[12] = e.x, r[13] = e.y, r[14] = e.z, r[15] = 1, this;
  }
  /**
   * Decomposes this matrix into its position, rotation and scale components
   * and provides the result in the given objects.
   *
   * Note: Not all matrices are decomposable in this way. For example, if an
   * object has a non-uniformly scaled parent, then the object's world matrix
   * may not be decomposable, and this method may not be appropriate.
   *
   * @param {Vector3} position - The position vector.
   * @param {Quaternion} quaternion - The rotation as a Quaternion.
   * @param {Vector3} scale - The scale vector.
   * @return {Matrix4} A reference to this matrix.
   */
  decompose(e, t, n) {
    const r = this.elements;
    e.x = r[12], e.y = r[13], e.z = r[14];
    const s = this.determinant();
    if (s === 0)
      return n.set(1, 1, 1), t.identity(), this;
    let a = Qa.set(r[0], r[1], r[2]).length();
    const o = Qa.set(r[4], r[5], r[6]).length(), l = Qa.set(r[8], r[9], r[10]).length();
    s < 0 && (a = -a), Wi.copy(this);
    const c = 1 / a, u = 1 / o, h = 1 / l;
    return Wi.elements[0] *= c, Wi.elements[1] *= c, Wi.elements[2] *= c, Wi.elements[4] *= u, Wi.elements[5] *= u, Wi.elements[6] *= u, Wi.elements[8] *= h, Wi.elements[9] *= h, Wi.elements[10] *= h, t.setFromRotationMatrix(Wi), n.x = a, n.y = o, n.z = l, this;
  }
  /**
  	 * Creates a perspective projection matrix. This is used internally by
  	 * {@link PerspectiveCamera#updateProjectionMatrix}.
  
  	 * @param {number} left - Left boundary of the viewing frustum at the near plane.
  	 * @param {number} right - Right boundary of the viewing frustum at the near plane.
  	 * @param {number} top - Top boundary of the viewing frustum at the near plane.
  	 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
  	 * @param {number} near - The distance from the camera to the near plane.
  	 * @param {number} far - The distance from the camera to the far plane.
  	 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
  	 * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth.
  	 * @return {Matrix4} A reference to this matrix.
  	 */
  makePerspective(e, t, n, r, s, a, o = si, l = !1) {
    const c = this.elements, u = 2 * s / (t - e), h = 2 * s / (n - r), d = (t + e) / (t - e), f = (n + r) / (n - r);
    let p, _;
    if (l)
      p = s / (a - s), _ = a * s / (a - s);
    else if (o === si)
      p = -(a + s) / (a - s), _ = -2 * a * s / (a - s);
    else if (o === Cr)
      p = -a / (a - s), _ = -a * s / (a - s);
    else
      throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + o);
    return c[0] = u, c[4] = 0, c[8] = d, c[12] = 0, c[1] = 0, c[5] = h, c[9] = f, c[13] = 0, c[2] = 0, c[6] = 0, c[10] = p, c[14] = _, c[3] = 0, c[7] = 0, c[11] = -1, c[15] = 0, this;
  }
  /**
  	 * Creates a orthographic projection matrix. This is used internally by
  	 * {@link OrthographicCamera#updateProjectionMatrix}.
  
  	 * @param {number} left - Left boundary of the viewing frustum at the near plane.
  	 * @param {number} right - Right boundary of the viewing frustum at the near plane.
  	 * @param {number} top - Top boundary of the viewing frustum at the near plane.
  	 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
  	 * @param {number} near - The distance from the camera to the near plane.
  	 * @param {number} far - The distance from the camera to the far plane.
  	 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
  	 * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth.
  	 * @return {Matrix4} A reference to this matrix.
  	 */
  makeOrthographic(e, t, n, r, s, a, o = si, l = !1) {
    const c = this.elements, u = 2 / (t - e), h = 2 / (n - r), d = -(t + e) / (t - e), f = -(n + r) / (n - r);
    let p, _;
    if (l)
      p = 1 / (a - s), _ = a / (a - s);
    else if (o === si)
      p = -2 / (a - s), _ = -(a + s) / (a - s);
    else if (o === Cr)
      p = -1 / (a - s), _ = -s / (a - s);
    else
      throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + o);
    return c[0] = u, c[4] = 0, c[8] = 0, c[12] = d, c[1] = 0, c[5] = h, c[9] = 0, c[13] = f, c[2] = 0, c[6] = 0, c[10] = p, c[14] = _, c[3] = 0, c[7] = 0, c[11] = 0, c[15] = 1, this;
  }
  /**
   * Returns `true` if this matrix is equal with the given one.
   *
   * @param {Matrix4} matrix - The matrix to test for equality.
   * @return {boolean} Whether this matrix is equal with the given one.
   */
  equals(e) {
    const t = this.elements, n = e.elements;
    for (let r = 0; r < 16; r++)
      if (t[r] !== n[r])
        return !1;
    return !0;
  }
  /**
   * Sets the elements of the matrix from the given array.
   *
   * @param {Array<number>} array - The matrix elements in column-major order.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Matrix4} A reference to this matrix.
   */
  fromArray(e, t = 0) {
    for (let n = 0; n < 16; n++)
      this.elements[n] = e[n + t];
    return this;
  }
  /**
   * Writes the elements of this matrix to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The matrix elements in column-major order.
   */
  toArray(e = [], t = 0) {
    const n = this.elements;
    return e[t] = n[0], e[t + 1] = n[1], e[t + 2] = n[2], e[t + 3] = n[3], e[t + 4] = n[4], e[t + 5] = n[5], e[t + 6] = n[6], e[t + 7] = n[7], e[t + 8] = n[8], e[t + 9] = n[9], e[t + 10] = n[10], e[t + 11] = n[11], e[t + 12] = n[12], e[t + 13] = n[13], e[t + 14] = n[14], e[t + 15] = n[15], e;
  }
}
const Qa = /* @__PURE__ */ new P(), Wi = /* @__PURE__ */ new pt(), ZM = /* @__PURE__ */ new P(0, 0, 0), QM = /* @__PURE__ */ new P(1, 1, 1), gs = /* @__PURE__ */ new P(), mu = /* @__PURE__ */ new P(), bi = /* @__PURE__ */ new P(), p_ = /* @__PURE__ */ new pt(), m_ = /* @__PURE__ */ new Gi();
class gi {
  /**
   * Constructs a new euler instance.
   *
   * @param {number} [x=0] - The angle of the x axis in radians.
   * @param {number} [y=0] - The angle of the y axis in radians.
   * @param {number} [z=0] - The angle of the z axis in radians.
   * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied.
   */
  constructor(e = 0, t = 0, n = 0, r = gi.DEFAULT_ORDER) {
    this.isEuler = !0, this._x = e, this._y = t, this._z = n, this._order = r;
  }
  /**
   * The angle of the x axis in radians.
   *
   * @type {number}
   * @default 0
   */
  get x() {
    return this._x;
  }
  set x(e) {
    this._x = e, this._onChangeCallback();
  }
  /**
   * The angle of the y axis in radians.
   *
   * @type {number}
   * @default 0
   */
  get y() {
    return this._y;
  }
  set y(e) {
    this._y = e, this._onChangeCallback();
  }
  /**
   * The angle of the z axis in radians.
   *
   * @type {number}
   * @default 0
   */
  get z() {
    return this._z;
  }
  set z(e) {
    this._z = e, this._onChangeCallback();
  }
  /**
   * A string representing the order that the rotations are applied.
   *
   * @type {string}
   * @default 'XYZ'
   */
  get order() {
    return this._order;
  }
  set order(e) {
    this._order = e, this._onChangeCallback();
  }
  /**
   * Sets the Euler components.
   *
   * @param {number} x - The angle of the x axis in radians.
   * @param {number} y - The angle of the y axis in radians.
   * @param {number} z - The angle of the z axis in radians.
   * @param {string} [order] - A string representing the order that the rotations are applied.
   * @return {Euler} A reference to this Euler instance.
   */
  set(e, t, n, r = this._order) {
    return this._x = e, this._y = t, this._z = n, this._order = r, this._onChangeCallback(), this;
  }
  /**
   * Returns a new Euler instance with copied values from this instance.
   *
   * @return {Euler} A clone of this instance.
   */
  clone() {
    return new this.constructor(this._x, this._y, this._z, this._order);
  }
  /**
   * Copies the values of the given Euler instance to this instance.
   *
   * @param {Euler} euler - The Euler instance to copy.
   * @return {Euler} A reference to this Euler instance.
   */
  copy(e) {
    return this._x = e._x, this._y = e._y, this._z = e._z, this._order = e._order, this._onChangeCallback(), this;
  }
  /**
   * Sets the angles of this Euler instance from a pure rotation matrix.
   *
   * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
   * @param {string} [order] - A string representing the order that the rotations are applied.
   * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
   * @return {Euler} A reference to this Euler instance.
   */
  setFromRotationMatrix(e, t = this._order, n = !0) {
    const r = e.elements, s = r[0], a = r[4], o = r[8], l = r[1], c = r[5], u = r[9], h = r[2], d = r[6], f = r[10];
    switch (t) {
      case "XYZ":
        this._y = Math.asin(ct(o, -1, 1)), Math.abs(o) < 0.9999999 ? (this._x = Math.atan2(-u, f), this._z = Math.atan2(-a, s)) : (this._x = Math.atan2(d, c), this._z = 0);
        break;
      case "YXZ":
        this._x = Math.asin(-ct(u, -1, 1)), Math.abs(u) < 0.9999999 ? (this._y = Math.atan2(o, f), this._z = Math.atan2(l, c)) : (this._y = Math.atan2(-h, s), this._z = 0);
        break;
      case "ZXY":
        this._x = Math.asin(ct(d, -1, 1)), Math.abs(d) < 0.9999999 ? (this._y = Math.atan2(-h, f), this._z = Math.atan2(-a, c)) : (this._y = 0, this._z = Math.atan2(l, s));
        break;
      case "ZYX":
        this._y = Math.asin(-ct(h, -1, 1)), Math.abs(h) < 0.9999999 ? (this._x = Math.atan2(d, f), this._z = Math.atan2(l, s)) : (this._x = 0, this._z = Math.atan2(-a, c));
        break;
      case "YZX":
        this._z = Math.asin(ct(l, -1, 1)), Math.abs(l) < 0.9999999 ? (this._x = Math.atan2(-u, c), this._y = Math.atan2(-h, s)) : (this._x = 0, this._y = Math.atan2(o, f));
        break;
      case "XZY":
        this._z = Math.asin(-ct(a, -1, 1)), Math.abs(a) < 0.9999999 ? (this._x = Math.atan2(d, c), this._y = Math.atan2(o, s)) : (this._x = Math.atan2(-u, f), this._y = 0);
        break;
      default:
        oe("Euler: .setFromRotationMatrix() encountered an unknown order: " + t);
    }
    return this._order = t, n === !0 && this._onChangeCallback(), this;
  }
  /**
   * Sets the angles of this Euler instance from a normalized quaternion.
   *
   * @param {Quaternion} q - A normalized Quaternion.
   * @param {string} [order] - A string representing the order that the rotations are applied.
   * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
   * @return {Euler} A reference to this Euler instance.
   */
  setFromQuaternion(e, t, n) {
    return p_.makeRotationFromQuaternion(e), this.setFromRotationMatrix(p_, t, n);
  }
  /**
   * Sets the angles of this Euler instance from the given vector.
   *
   * @param {Vector3} v - The vector.
   * @param {string} [order] - A string representing the order that the rotations are applied.
   * @return {Euler} A reference to this Euler instance.
   */
  setFromVector3(e, t = this._order) {
    return this.set(e.x, e.y, e.z, t);
  }
  /**
   * Resets the euler angle with a new order by creating a quaternion from this
   * euler angle and then setting this euler angle with the quaternion and the
   * new order.
   *
   * Warning: This discards revolution information.
   *
   * @param {string} [newOrder] - A string representing the new order that the rotations are applied.
   * @return {Euler} A reference to this Euler instance.
   */
  reorder(e) {
    return m_.setFromEuler(this), this.setFromQuaternion(m_, e);
  }
  /**
   * Returns `true` if this Euler instance is equal with the given one.
   *
   * @param {Euler} euler - The Euler instance to test for equality.
   * @return {boolean} Whether this Euler instance is equal with the given one.
   */
  equals(e) {
    return e._x === this._x && e._y === this._y && e._z === this._z && e._order === this._order;
  }
  /**
   * Sets this Euler instance's components to values from the given array. The first three
   * entries of the array are assign to the x,y and z components. An optional fourth entry
   * defines the Euler order.
   *
   * @param {Array<number,number,number,?string>} array - An array holding the Euler component values.
   * @return {Euler} A reference to this Euler instance.
   */
  fromArray(e) {
    return this._x = e[0], this._y = e[1], this._z = e[2], e[3] !== void 0 && (this._order = e[3]), this._onChangeCallback(), this;
  }
  /**
   * Writes the components of this Euler instance to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number,number,number,string>} [array=[]] - The target array holding the Euler components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number,number,number,string>} The Euler components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this._x, e[t + 1] = this._y, e[t + 2] = this._z, e[t + 3] = this._order, e;
  }
  _onChange(e) {
    return this._onChangeCallback = e, this;
  }
  _onChangeCallback() {
  }
  *[Symbol.iterator]() {
    yield this._x, yield this._y, yield this._z, yield this._order;
  }
}
gi.DEFAULT_ORDER = "XYZ";
class qm {
  /**
   * Constructs a new layers instance, with membership
   * initially set to layer `0`.
   */
  constructor() {
    this.mask = 1;
  }
  /**
   * Sets membership to the given layer, and remove membership all other layers.
   *
   * @param {number} layer - The layer to set.
   */
  set(e) {
    this.mask = (1 << e | 0) >>> 0;
  }
  /**
   * Adds membership of the given layer.
   *
   * @param {number} layer - The layer to enable.
   */
  enable(e) {
    this.mask |= 1 << e | 0;
  }
  /**
   * Adds membership to all layers.
   */
  enableAll() {
    this.mask = -1;
  }
  /**
   * Toggles the membership of the given layer.
   *
   * @param {number} layer - The layer to toggle.
   */
  toggle(e) {
    this.mask ^= 1 << e | 0;
  }
  /**
   * Removes membership of the given layer.
   *
   * @param {number} layer - The layer to enable.
   */
  disable(e) {
    this.mask &= ~(1 << e | 0);
  }
  /**
   * Removes the membership from all layers.
   */
  disableAll() {
    this.mask = 0;
  }
  /**
   * Returns `true` if this and the given layers object have at least one
   * layer in common.
   *
   * @param {Layers} layers - The layers to test.
   * @return {boolean } Whether this and the given layers object have at least one layer in common or not.
   */
  test(e) {
    return (this.mask & e.mask) !== 0;
  }
  /**
   * Returns `true` if the given layer is enabled.
   *
   * @param {number} layer - The layer to test.
   * @return {boolean } Whether the given layer is enabled or not.
   */
  isEnabled(e) {
    return (this.mask & (1 << e | 0)) !== 0;
  }
}
let JM = 0;
const g_ = /* @__PURE__ */ new P(), Ja = /* @__PURE__ */ new Gi(), kr = /* @__PURE__ */ new pt(), gu = /* @__PURE__ */ new P(), Fl = /* @__PURE__ */ new P(), eE = /* @__PURE__ */ new P(), tE = /* @__PURE__ */ new Gi(), __ = /* @__PURE__ */ new P(1, 0, 0), x_ = /* @__PURE__ */ new P(0, 1, 0), v_ = /* @__PURE__ */ new P(0, 0, 1), y_ = { type: "added" }, nE = { type: "removed" }, eo = { type: "childadded", child: null }, Hd = { type: "childremoved", child: null };
class gn extends Fr {
  /**
   * Constructs a new 3D object.
   */
  constructor() {
    super(), this.isObject3D = !0, Object.defineProperty(this, "id", { value: JM++ }), this.uuid = ss(), this.name = "", this.type = "Object3D", this.parent = null, this.children = [], this.up = gn.DEFAULT_UP.clone();
    const e = new P(), t = new gi(), n = new Gi(), r = new P(1, 1, 1);
    function s() {
      n.setFromEuler(t, !1);
    }
    function a() {
      t.setFromQuaternion(n, void 0, !1);
    }
    t._onChange(s), n._onChange(a), Object.defineProperties(this, {
      /**
       * Represents the object's local position.
       *
       * @name Object3D#position
       * @type {Vector3}
       * @default (0,0,0)
       */
      position: {
        configurable: !0,
        enumerable: !0,
        value: e
      },
      /**
       * Represents the object's local rotation as Euler angles, in radians.
       *
       * @name Object3D#rotation
       * @type {Euler}
       * @default (0,0,0)
       */
      rotation: {
        configurable: !0,
        enumerable: !0,
        value: t
      },
      /**
       * Represents the object's local rotation as Quaternions.
       *
       * @name Object3D#quaternion
       * @type {Quaternion}
       */
      quaternion: {
        configurable: !0,
        enumerable: !0,
        value: n
      },
      /**
       * Represents the object's local scale.
       *
       * @name Object3D#scale
       * @type {Vector3}
       * @default (1,1,1)
       */
      scale: {
        configurable: !0,
        enumerable: !0,
        value: r
      },
      /**
       * Represents the object's model-view matrix.
       *
       * @name Object3D#modelViewMatrix
       * @type {Matrix4}
       */
      modelViewMatrix: {
        value: new pt()
      },
      /**
       * Represents the object's normal matrix.
       *
       * @name Object3D#normalMatrix
       * @type {Matrix3}
       */
      normalMatrix: {
        value: new nt()
      }
    }), this.matrix = new pt(), this.matrixWorld = new pt(), this.matrixAutoUpdate = gn.DEFAULT_MATRIX_AUTO_UPDATE, this.matrixWorldAutoUpdate = gn.DEFAULT_MATRIX_WORLD_AUTO_UPDATE, this.matrixWorldNeedsUpdate = !1, this.layers = new qm(), this.visible = !0, this.castShadow = !1, this.receiveShadow = !1, this.frustumCulled = !0, this.renderOrder = 0, this.animations = [], this.customDepthMaterial = void 0, this.customDistanceMaterial = void 0, this.static = !1, this.userData = {}, this.pivot = null;
  }
  /**
   * A callback that is executed immediately before a 3D object is rendered to a shadow map.
   *
   * @param {Renderer|WebGLRenderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {Camera} shadowCamera - The shadow camera.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} depthMaterial - The depth material.
   * @param {Object} group - The geometry group data.
   */
  onBeforeShadow() {
  }
  /**
   * A callback that is executed immediately after a 3D object is rendered to a shadow map.
   *
   * @param {Renderer|WebGLRenderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {Camera} shadowCamera - The shadow camera.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} depthMaterial - The depth material.
   * @param {Object} group - The geometry group data.
   */
  onAfterShadow() {
  }
  /**
   * A callback that is executed immediately before a 3D object is rendered.
   *
   * @param {Renderer|WebGLRenderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} material - The 3D object's material.
   * @param {Object} group - The geometry group data.
   */
  onBeforeRender() {
  }
  /**
   * A callback that is executed immediately after a 3D object is rendered.
   *
   * @param {Renderer|WebGLRenderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} material - The 3D object's material.
   * @param {Object} group - The geometry group data.
   */
  onAfterRender() {
  }
  /**
   * Applies the given transformation matrix to the object and updates the object's position,
   * rotation and scale.
   *
   * @param {Matrix4} matrix - The transformation matrix.
   */
  applyMatrix4(e) {
    this.matrixAutoUpdate && this.updateMatrix(), this.matrix.premultiply(e), this.matrix.decompose(this.position, this.quaternion, this.scale);
  }
  /**
   * Applies a rotation represented by given the quaternion to the 3D object.
   *
   * @param {Quaternion} q - The quaternion.
   * @return {Object3D} A reference to this instance.
   */
  applyQuaternion(e) {
    return this.quaternion.premultiply(e), this;
  }
  /**
   * Sets the given rotation represented as an axis/angle couple to the 3D object.
   *
   * @param {Vector3} axis - The (normalized) axis vector.
   * @param {number} angle - The angle in radians.
   */
  setRotationFromAxisAngle(e, t) {
    this.quaternion.setFromAxisAngle(e, t);
  }
  /**
   * Sets the given rotation represented as Euler angles to the 3D object.
   *
   * @param {Euler} euler - The Euler angles.
   */
  setRotationFromEuler(e) {
    this.quaternion.setFromEuler(e, !0);
  }
  /**
   * Sets the given rotation represented as rotation matrix to the 3D object.
   *
   * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be
   * a pure rotation matrix (i.e, unscaled).
   */
  setRotationFromMatrix(e) {
    this.quaternion.setFromRotationMatrix(e);
  }
  /**
   * Sets the given rotation represented as a Quaternion to the 3D object.
   *
   * @param {Quaternion} q - The Quaternion
   */
  setRotationFromQuaternion(e) {
    this.quaternion.copy(e);
  }
  /**
   * Rotates the 3D object along an axis in local space.
   *
   * @param {Vector3} axis - The (normalized) axis vector.
   * @param {number} angle - The angle in radians.
   * @return {Object3D} A reference to this instance.
   */
  rotateOnAxis(e, t) {
    return Ja.setFromAxisAngle(e, t), this.quaternion.multiply(Ja), this;
  }
  /**
   * Rotates the 3D object along an axis in world space.
   *
   * @param {Vector3} axis - The (normalized) axis vector.
   * @param {number} angle - The angle in radians.
   * @return {Object3D} A reference to this instance.
   */
  rotateOnWorldAxis(e, t) {
    return Ja.setFromAxisAngle(e, t), this.quaternion.premultiply(Ja), this;
  }
  /**
   * Rotates the 3D object around its X axis in local space.
   *
   * @param {number} angle - The angle in radians.
   * @return {Object3D} A reference to this instance.
   */
  rotateX(e) {
    return this.rotateOnAxis(__, e);
  }
  /**
   * Rotates the 3D object around its Y axis in local space.
   *
   * @param {number} angle - The angle in radians.
   * @return {Object3D} A reference to this instance.
   */
  rotateY(e) {
    return this.rotateOnAxis(x_, e);
  }
  /**
   * Rotates the 3D object around its Z axis in local space.
   *
   * @param {number} angle - The angle in radians.
   * @return {Object3D} A reference to this instance.
   */
  rotateZ(e) {
    return this.rotateOnAxis(v_, e);
  }
  /**
   * Translate the 3D object by a distance along the given axis in local space.
   *
   * @param {Vector3} axis - The (normalized) axis vector.
   * @param {number} distance - The distance in world units.
   * @return {Object3D} A reference to this instance.
   */
  translateOnAxis(e, t) {
    return g_.copy(e).applyQuaternion(this.quaternion), this.position.add(g_.multiplyScalar(t)), this;
  }
  /**
   * Translate the 3D object by a distance along its X-axis in local space.
   *
   * @param {number} distance - The distance in world units.
   * @return {Object3D} A reference to this instance.
   */
  translateX(e) {
    return this.translateOnAxis(__, e);
  }
  /**
   * Translate the 3D object by a distance along its Y-axis in local space.
   *
   * @param {number} distance - The distance in world units.
   * @return {Object3D} A reference to this instance.
   */
  translateY(e) {
    return this.translateOnAxis(x_, e);
  }
  /**
   * Translate the 3D object by a distance along its Z-axis in local space.
   *
   * @param {number} distance - The distance in world units.
   * @return {Object3D} A reference to this instance.
   */
  translateZ(e) {
    return this.translateOnAxis(v_, e);
  }
  /**
   * Converts the given vector from this 3D object's local space to world space.
   *
   * @param {Vector3} vector - The vector to convert.
   * @return {Vector3} The converted vector.
   */
  localToWorld(e) {
    return this.updateWorldMatrix(!0, !1), e.applyMatrix4(this.matrixWorld);
  }
  /**
   * Converts the given vector from this 3D object's world space to local space.
   *
   * @param {Vector3} vector - The vector to convert.
   * @return {Vector3} The converted vector.
   */
  worldToLocal(e) {
    return this.updateWorldMatrix(!0, !1), e.applyMatrix4(kr.copy(this.matrixWorld).invert());
  }
  /**
   * Rotates the object to face a point in world space.
   *
   * This method does not support objects having non-uniformly-scaled parent(s).
   *
   * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space
   * @param {number} [y] - The y coordinate in world space.
   * @param {number} [z] - The z coordinate in world space.
   */
  lookAt(e, t, n) {
    e.isVector3 ? gu.copy(e) : gu.set(e, t, n);
    const r = this.parent;
    this.updateWorldMatrix(!0, !1), Fl.setFromMatrixPosition(this.matrixWorld), this.isCamera || this.isLight ? kr.lookAt(Fl, gu, this.up) : kr.lookAt(gu, Fl, this.up), this.quaternion.setFromRotationMatrix(kr), r && (kr.extractRotation(r.matrixWorld), Ja.setFromRotationMatrix(kr), this.quaternion.premultiply(Ja.invert()));
  }
  /**
   * Adds the given 3D object as a child to this 3D object. An arbitrary number of
   * objects may be added. Any current parent on an object passed in here will be
   * removed, since an object can have at most one parent.
   *
   * @fires Object3D#added
   * @fires Object3D#childadded
   * @param {Object3D} object - The 3D object to add.
   * @return {Object3D} A reference to this instance.
   */
  add(e) {
    if (arguments.length > 1) {
      for (let t = 0; t < arguments.length; t++)
        this.add(arguments[t]);
      return this;
    }
    return e === this ? (le("Object3D.add: object can't be added as a child of itself.", e), this) : (e && e.isObject3D ? (e.removeFromParent(), e.parent = this, this.children.push(e), e.dispatchEvent(y_), eo.child = e, this.dispatchEvent(eo), eo.child = null) : le("Object3D.add: object not an instance of THREE.Object3D.", e), this);
  }
  /**
   * Removes the given 3D object as child from this 3D object.
   * An arbitrary number of objects may be removed.
   *
   * @fires Object3D#removed
   * @fires Object3D#childremoved
   * @param {Object3D} object - The 3D object to remove.
   * @return {Object3D} A reference to this instance.
   */
  remove(e) {
    if (arguments.length > 1) {
      for (let n = 0; n < arguments.length; n++)
        this.remove(arguments[n]);
      return this;
    }
    const t = this.children.indexOf(e);
    return t !== -1 && (e.parent = null, this.children.splice(t, 1), e.dispatchEvent(nE), Hd.child = e, this.dispatchEvent(Hd), Hd.child = null), this;
  }
  /**
   * Removes this 3D object from its current parent.
   *
   * @fires Object3D#removed
   * @fires Object3D#childremoved
   * @return {Object3D} A reference to this instance.
   */
  removeFromParent() {
    const e = this.parent;
    return e !== null && e.remove(this), this;
  }
  /**
   * Removes all child objects.
   *
   * @fires Object3D#removed
   * @fires Object3D#childremoved
   * @return {Object3D} A reference to this instance.
   */
  clear() {
    return this.remove(...this.children);
  }
  /**
   * Adds the given 3D object as a child of this 3D object, while maintaining the object's world
   * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s).
   *
   * @fires Object3D#added
   * @fires Object3D#childadded
   * @param {Object3D} object - The 3D object to attach.
   * @return {Object3D} A reference to this instance.
   */
  attach(e) {
    return this.updateWorldMatrix(!0, !1), kr.copy(this.matrixWorld).invert(), e.parent !== null && (e.parent.updateWorldMatrix(!0, !1), kr.multiply(e.parent.matrixWorld)), e.applyMatrix4(kr), e.removeFromParent(), e.parent = this, this.children.push(e), e.updateWorldMatrix(!1, !0), e.dispatchEvent(y_), eo.child = e, this.dispatchEvent(eo), eo.child = null, this;
  }
  /**
   * Searches through the 3D object and its children, starting with the 3D object
   * itself, and returns the first with a matching ID.
   *
   * @param {number} id - The id.
   * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
   */
  getObjectById(e) {
    return this.getObjectByProperty("id", e);
  }
  /**
   * Searches through the 3D object and its children, starting with the 3D object
   * itself, and returns the first with a matching name.
   *
   * @param {string} name - The name.
   * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
   */
  getObjectByName(e) {
    return this.getObjectByProperty("name", e);
  }
  /**
   * Searches through the 3D object and its children, starting with the 3D object
   * itself, and returns the first with a matching property value.
   *
   * @param {string} name - The name of the property.
   * @param {any} value - The value.
   * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
   */
  getObjectByProperty(e, t) {
    if (this[e] === t)
      return this;
    for (let n = 0, r = this.children.length; n < r; n++) {
      const a = this.children[n].getObjectByProperty(e, t);
      if (a !== void 0)
        return a;
    }
  }
  /**
   * Searches through the 3D object and its children, starting with the 3D object
   * itself, and returns all 3D objects with a matching property value.
   *
   * @param {string} name - The name of the property.
   * @param {any} value - The value.
   * @param {Array<Object3D>} result - The method stores the result in this array.
   * @return {Array<Object3D>} The found 3D objects.
   */
  getObjectsByProperty(e, t, n = []) {
    this[e] === t && n.push(this);
    const r = this.children;
    for (let s = 0, a = r.length; s < a; s++)
      r[s].getObjectsByProperty(e, t, n);
    return n;
  }
  /**
   * Returns a vector representing the position of the 3D object in world space.
   *
   * @param {Vector3} target - The target vector the result is stored to.
   * @return {Vector3} The 3D object's position in world space.
   */
  getWorldPosition(e) {
    return this.updateWorldMatrix(!0, !1), e.setFromMatrixPosition(this.matrixWorld);
  }
  /**
   * Returns a Quaternion representing the position of the 3D object in world space.
   *
   * @param {Quaternion} target - The target Quaternion the result is stored to.
   * @return {Quaternion} The 3D object's rotation in world space.
   */
  getWorldQuaternion(e) {
    return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(Fl, e, eE), e;
  }
  /**
   * Returns a vector representing the scale of the 3D object in world space.
   *
   * @param {Vector3} target - The target vector the result is stored to.
   * @return {Vector3} The 3D object's scale in world space.
   */
  getWorldScale(e) {
    return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(Fl, tE, e), e;
  }
  /**
   * Returns a vector representing the ("look") direction of the 3D object in world space.
   *
   * @param {Vector3} target - The target vector the result is stored to.
   * @return {Vector3} The 3D object's direction in world space.
   */
  getWorldDirection(e) {
    this.updateWorldMatrix(!0, !1);
    const t = this.matrixWorld.elements;
    return e.set(t[8], t[9], t[10]).normalize();
  }
  /**
   * Abstract method to get intersections between a casted ray and this
   * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points}
   * implement this method in order to use raycasting.
   *
   * @abstract
   * @param {Raycaster} raycaster - The raycaster.
   * @param {Array<Object>} intersects - An array holding the result of the method.
   */
  raycast() {
  }
  /**
   * Executes the callback on this 3D object and all descendants.
   *
   * Note: Modifying the scene graph inside the callback is discouraged.
   *
   * @param {Function} callback - A callback function that allows to process the current 3D object.
   */
  traverse(e) {
    e(this);
    const t = this.children;
    for (let n = 0, r = t.length; n < r; n++)
      t[n].traverse(e);
  }
  /**
   * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects.
   * Descendants of invisible 3D objects are not traversed.
   *
   * Note: Modifying the scene graph inside the callback is discouraged.
   *
   * @param {Function} callback - A callback function that allows to process the current 3D object.
   */
  traverseVisible(e) {
    if (this.visible === !1)
      return;
    e(this);
    const t = this.children;
    for (let n = 0, r = t.length; n < r; n++)
      t[n].traverseVisible(e);
  }
  /**
   * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors.
   *
   * Note: Modifying the scene graph inside the callback is discouraged.
   *
   * @param {Function} callback - A callback function that allows to process the current 3D object.
   */
  traverseAncestors(e) {
    const t = this.parent;
    t !== null && (e(t), t.traverseAncestors(e));
  }
  /**
   * Updates the transformation matrix in local space by computing it from the current
   * position, rotation and scale values.
   */
  updateMatrix() {
    this.matrix.compose(this.position, this.quaternion, this.scale);
    const e = this.pivot;
    if (e !== null) {
      const t = e.x, n = e.y, r = e.z, s = this.matrix.elements;
      s[12] += t - s[0] * t - s[4] * n - s[8] * r, s[13] += n - s[1] * t - s[5] * n - s[9] * r, s[14] += r - s[2] * t - s[6] * n - s[10] * r;
    }
    this.matrixWorldNeedsUpdate = !0;
  }
  /**
   * Updates the transformation matrix in world space of this 3D objects and its descendants.
   *
   * To ensure correct results, this method also recomputes the 3D object's transformation matrix in
   * local space. The computation of the local and world matrix can be controlled with the
   * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both
   * `true` by default.  Set these flags to `false` if you need more control over the update matrix process.
   *
   * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even
   * when {@link Object3D#matrixWorldNeedsUpdate} is `false`.
   */
  updateMatrixWorld(e) {
    this.matrixAutoUpdate && this.updateMatrix(), (this.matrixWorldNeedsUpdate || e) && (this.matrixWorldAutoUpdate === !0 && (this.parent === null ? this.matrixWorld.copy(this.matrix) : this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)), this.matrixWorldNeedsUpdate = !1, e = !0);
    const t = this.children;
    for (let n = 0, r = t.length; n < r; n++)
      t[n].updateMatrixWorld(e);
  }
  /**
   * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the
   * update of ancestor and descendant nodes.
   *
   * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not.
   * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not.
   */
  updateWorldMatrix(e, t) {
    const n = this.parent;
    if (e === !0 && n !== null && n.updateWorldMatrix(!0, !1), this.matrixAutoUpdate && this.updateMatrix(), this.matrixWorldAutoUpdate === !0 && (this.parent === null ? this.matrixWorld.copy(this.matrix) : this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)), t === !0) {
      const r = this.children;
      for (let s = 0, a = r.length; s < a; s++)
        r[s].updateWorldMatrix(!1, !0);
    }
  }
  /**
   * Serializes the 3D object into JSON.
   *
   * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized 3D object.
   * @see {@link ObjectLoader#parse}
   */
  toJSON(e) {
    const t = e === void 0 || typeof e == "string", n = {};
    t && (e = {
      geometries: {},
      materials: {},
      textures: {},
      images: {},
      shapes: {},
      skeletons: {},
      animations: {},
      nodes: {}
    }, n.metadata = {
      version: 4.7,
      type: "Object",
      generator: "Object3D.toJSON"
    });
    const r = {};
    r.uuid = this.uuid, r.type = this.type, this.name !== "" && (r.name = this.name), this.castShadow === !0 && (r.castShadow = !0), this.receiveShadow === !0 && (r.receiveShadow = !0), this.visible === !1 && (r.visible = !1), this.frustumCulled === !1 && (r.frustumCulled = !1), this.renderOrder !== 0 && (r.renderOrder = this.renderOrder), this.static !== !1 && (r.static = this.static), Object.keys(this.userData).length > 0 && (r.userData = this.userData), r.layers = this.layers.mask, r.matrix = this.matrix.toArray(), r.up = this.up.toArray(), this.pivot !== null && (r.pivot = this.pivot.toArray()), this.matrixAutoUpdate === !1 && (r.matrixAutoUpdate = !1), this.morphTargetDictionary !== void 0 && (r.morphTargetDictionary = Object.assign({}, this.morphTargetDictionary)), this.morphTargetInfluences !== void 0 && (r.morphTargetInfluences = this.morphTargetInfluences.slice()), this.isInstancedMesh && (r.type = "InstancedMesh", r.count = this.count, r.instanceMatrix = this.instanceMatrix.toJSON(), this.instanceColor !== null && (r.instanceColor = this.instanceColor.toJSON())), this.isBatchedMesh && (r.type = "BatchedMesh", r.perObjectFrustumCulled = this.perObjectFrustumCulled, r.sortObjects = this.sortObjects, r.drawRanges = this._drawRanges, r.reservedRanges = this._reservedRanges, r.geometryInfo = this._geometryInfo.map((o) => ({
      ...o,
      boundingBox: o.boundingBox ? o.boundingBox.toJSON() : void 0,
      boundingSphere: o.boundingSphere ? o.boundingSphere.toJSON() : void 0
    })), r.instanceInfo = this._instanceInfo.map((o) => ({ ...o })), r.availableInstanceIds = this._availableInstanceIds.slice(), r.availableGeometryIds = this._availableGeometryIds.slice(), r.nextIndexStart = this._nextIndexStart, r.nextVertexStart = this._nextVertexStart, r.geometryCount = this._geometryCount, r.maxInstanceCount = this._maxInstanceCount, r.maxVertexCount = this._maxVertexCount, r.maxIndexCount = this._maxIndexCount, r.geometryInitialized = this._geometryInitialized, r.matricesTexture = this._matricesTexture.toJSON(e), r.indirectTexture = this._indirectTexture.toJSON(e), this._colorsTexture !== null && (r.colorsTexture = this._colorsTexture.toJSON(e)), this.boundingSphere !== null && (r.boundingSphere = this.boundingSphere.toJSON()), this.boundingBox !== null && (r.boundingBox = this.boundingBox.toJSON()));
    function s(o, l) {
      return o[l.uuid] === void 0 && (o[l.uuid] = l.toJSON(e)), l.uuid;
    }
    if (this.isScene)
      this.background && (this.background.isColor ? r.background = this.background.toJSON() : this.background.isTexture && (r.background = this.background.toJSON(e).uuid)), this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== !0 && (r.environment = this.environment.toJSON(e).uuid);
    else if (this.isMesh || this.isLine || this.isPoints) {
      r.geometry = s(e.geometries, this.geometry);
      const o = this.geometry.parameters;
      if (o !== void 0 && o.shapes !== void 0) {
        const l = o.shapes;
        if (Array.isArray(l))
          for (let c = 0, u = l.length; c < u; c++) {
            const h = l[c];
            s(e.shapes, h);
          }
        else
          s(e.shapes, l);
      }
    }
    if (this.isSkinnedMesh && (r.bindMode = this.bindMode, r.bindMatrix = this.bindMatrix.toArray(), this.skeleton !== void 0 && (s(e.skeletons, this.skeleton), r.skeleton = this.skeleton.uuid)), this.material !== void 0)
      if (Array.isArray(this.material)) {
        const o = [];
        for (let l = 0, c = this.material.length; l < c; l++)
          o.push(s(e.materials, this.material[l]));
        r.material = o;
      } else
        r.material = s(e.materials, this.material);
    if (this.children.length > 0) {
      r.children = [];
      for (let o = 0; o < this.children.length; o++)
        r.children.push(this.children[o].toJSON(e).object);
    }
    if (this.animations.length > 0) {
      r.animations = [];
      for (let o = 0; o < this.animations.length; o++) {
        const l = this.animations[o];
        r.animations.push(s(e.animations, l));
      }
    }
    if (t) {
      const o = a(e.geometries), l = a(e.materials), c = a(e.textures), u = a(e.images), h = a(e.shapes), d = a(e.skeletons), f = a(e.animations), p = a(e.nodes);
      o.length > 0 && (n.geometries = o), l.length > 0 && (n.materials = l), c.length > 0 && (n.textures = c), u.length > 0 && (n.images = u), h.length > 0 && (n.shapes = h), d.length > 0 && (n.skeletons = d), f.length > 0 && (n.animations = f), p.length > 0 && (n.nodes = p);
    }
    return n.object = r, n;
    function a(o) {
      const l = [];
      for (const c in o) {
        const u = o[c];
        delete u.metadata, l.push(u);
      }
      return l;
    }
  }
  /**
   * Returns a new 3D object with copied values from this instance.
   *
   * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned.
   * @return {Object3D} A clone of this instance.
   */
  clone(e) {
    return new this.constructor().copy(this, e);
  }
  /**
   * Copies the values of the given 3D object to this instance.
   *
   * @param {Object3D} source - The 3D object to copy.
   * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned.
   * @return {Object3D} A reference to this instance.
   */
  copy(e, t = !0) {
    if (this.name = e.name, this.up.copy(e.up), this.position.copy(e.position), this.rotation.order = e.rotation.order, this.quaternion.copy(e.quaternion), this.scale.copy(e.scale), e.pivot !== null && (this.pivot = e.pivot.clone()), this.matrix.copy(e.matrix), this.matrixWorld.copy(e.matrixWorld), this.matrixAutoUpdate = e.matrixAutoUpdate, this.matrixWorldAutoUpdate = e.matrixWorldAutoUpdate, this.matrixWorldNeedsUpdate = e.matrixWorldNeedsUpdate, this.layers.mask = e.layers.mask, this.visible = e.visible, this.castShadow = e.castShadow, this.receiveShadow = e.receiveShadow, this.frustumCulled = e.frustumCulled, this.renderOrder = e.renderOrder, this.static = e.static, this.animations = e.animations.slice(), this.userData = JSON.parse(JSON.stringify(e.userData)), t === !0)
      for (let n = 0; n < e.children.length; n++) {
        const r = e.children[n];
        this.add(r.clone());
      }
    return this;
  }
}
gn.DEFAULT_UP = /* @__PURE__ */ new P(0, 1, 0);
gn.DEFAULT_MATRIX_AUTO_UPDATE = !0;
gn.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = !0;
let Mo = class extends gn {
  constructor() {
    super(), this.isGroup = !0, this.type = "Group";
  }
};
const iE = { type: "move" };
class bh {
  /**
   * Constructs a new XR controller.
   */
  constructor() {
    this._targetRay = null, this._grip = null, this._hand = null;
  }
  /**
   * Returns a group representing the hand space of the XR controller.
   *
   * @return {Group} A group representing the hand space of the XR controller.
   */
  getHandSpace() {
    return this._hand === null && (this._hand = new Mo(), this._hand.matrixAutoUpdate = !1, this._hand.visible = !1, this._hand.joints = {}, this._hand.inputState = { pinching: !1 }), this._hand;
  }
  /**
   * Returns a group representing the target ray space of the XR controller.
   *
   * @return {Group} A group representing the target ray space of the XR controller.
   */
  getTargetRaySpace() {
    return this._targetRay === null && (this._targetRay = new Mo(), this._targetRay.matrixAutoUpdate = !1, this._targetRay.visible = !1, this._targetRay.hasLinearVelocity = !1, this._targetRay.linearVelocity = new P(), this._targetRay.hasAngularVelocity = !1, this._targetRay.angularVelocity = new P()), this._targetRay;
  }
  /**
   * Returns a group representing the grip space of the XR controller.
   *
   * @return {Group} A group representing the grip space of the XR controller.
   */
  getGripSpace() {
    return this._grip === null && (this._grip = new Mo(), this._grip.matrixAutoUpdate = !1, this._grip.visible = !1, this._grip.hasLinearVelocity = !1, this._grip.linearVelocity = new P(), this._grip.hasAngularVelocity = !1, this._grip.angularVelocity = new P()), this._grip;
  }
  /**
   * Dispatches the given event to the groups representing
   * the different coordinate spaces of the XR controller.
   *
   * @param {Object} event - The event to dispatch.
   * @return {WebXRController} A reference to this instance.
   */
  dispatchEvent(e) {
    return this._targetRay !== null && this._targetRay.dispatchEvent(e), this._grip !== null && this._grip.dispatchEvent(e), this._hand !== null && this._hand.dispatchEvent(e), this;
  }
  /**
   * Connects the controller with the given XR input source.
   *
   * @param {XRInputSource} inputSource - The input source.
   * @return {WebXRController} A reference to this instance.
   */
  connect(e) {
    if (e && e.hand) {
      const t = this._hand;
      if (t)
        for (const n of e.hand.values())
          this._getHandJoint(t, n);
    }
    return this.dispatchEvent({ type: "connected", data: e }), this;
  }
  /**
   * Disconnects the controller from the given XR input source.
   *
   * @param {XRInputSource} inputSource - The input source.
   * @return {WebXRController} A reference to this instance.
   */
  disconnect(e) {
    return this.dispatchEvent({ type: "disconnected", data: e }), this._targetRay !== null && (this._targetRay.visible = !1), this._grip !== null && (this._grip.visible = !1), this._hand !== null && (this._hand.visible = !1), this;
  }
  /**
   * Updates the controller with the given input source, XR frame and reference space.
   * This updates the transformations of the groups that represent the different
   * coordinate systems of the controller.
   *
   * @param {XRInputSource} inputSource - The input source.
   * @param {XRFrame} frame - The XR frame.
   * @param {XRReferenceSpace} referenceSpace - The reference space.
   * @return {WebXRController} A reference to this instance.
   */
  update(e, t, n) {
    let r = null, s = null, a = null;
    const o = this._targetRay, l = this._grip, c = this._hand;
    if (e && t.session.visibilityState !== "visible-blurred") {
      if (c && e.hand) {
        a = !0;
        for (const _ of e.hand.values()) {
          const g = t.getJointPose(_, n), m = this._getHandJoint(c, _);
          g !== null && (m.matrix.fromArray(g.transform.matrix), m.matrix.decompose(m.position, m.rotation, m.scale), m.matrixWorldNeedsUpdate = !0, m.jointRadius = g.radius), m.visible = g !== null;
        }
        const u = c.joints["index-finger-tip"], h = c.joints["thumb-tip"], d = u.position.distanceTo(h.position), f = 0.02, p = 5e-3;
        c.inputState.pinching && d > f + p ? (c.inputState.pinching = !1, this.dispatchEvent({
          type: "pinchend",
          handedness: e.handedness,
          target: this
        })) : !c.inputState.pinching && d <= f - p && (c.inputState.pinching = !0, this.dispatchEvent({
          type: "pinchstart",
          handedness: e.handedness,
          target: this
        }));
      } else
        l !== null && e.gripSpace && (s = t.getPose(e.gripSpace, n), s !== null && (l.matrix.fromArray(s.transform.matrix), l.matrix.decompose(l.position, l.rotation, l.scale), l.matrixWorldNeedsUpdate = !0, s.linearVelocity ? (l.hasLinearVelocity = !0, l.linearVelocity.copy(s.linearVelocity)) : l.hasLinearVelocity = !1, s.angularVelocity ? (l.hasAngularVelocity = !0, l.angularVelocity.copy(s.angularVelocity)) : l.hasAngularVelocity = !1));
      o !== null && (r = t.getPose(e.targetRaySpace, n), r === null && s !== null && (r = s), r !== null && (o.matrix.fromArray(r.transform.matrix), o.matrix.decompose(o.position, o.rotation, o.scale), o.matrixWorldNeedsUpdate = !0, r.linearVelocity ? (o.hasLinearVelocity = !0, o.linearVelocity.copy(r.linearVelocity)) : o.hasLinearVelocity = !1, r.angularVelocity ? (o.hasAngularVelocity = !0, o.angularVelocity.copy(r.angularVelocity)) : o.hasAngularVelocity = !1, this.dispatchEvent(iE)));
    }
    return o !== null && (o.visible = r !== null), l !== null && (l.visible = s !== null), c !== null && (c.visible = a !== null), this;
  }
  /**
   * Returns a group representing the hand joint for the given input joint.
   *
   * @private
   * @param {Group} hand - The group representing the hand space.
   * @param {XRJointSpace} inputjoint - The hand joint data.
   * @return {Group} A group representing the hand joint for the given input joint.
   */
  _getHandJoint(e, t) {
    if (e.joints[t.jointName] === void 0) {
      const n = new Mo();
      n.matrixAutoUpdate = !1, n.visible = !1, e.joints[t.jointName] = n, e.add(n);
    }
    return e.joints[t.jointName];
  }
}
const Jv = {
  aliceblue: 15792383,
  antiquewhite: 16444375,
  aqua: 65535,
  aquamarine: 8388564,
  azure: 15794175,
  beige: 16119260,
  bisque: 16770244,
  black: 0,
  blanchedalmond: 16772045,
  blue: 255,
  blueviolet: 9055202,
  brown: 10824234,
  burlywood: 14596231,
  cadetblue: 6266528,
  chartreuse: 8388352,
  chocolate: 13789470,
  coral: 16744272,
  cornflowerblue: 6591981,
  cornsilk: 16775388,
  crimson: 14423100,
  cyan: 65535,
  darkblue: 139,
  darkcyan: 35723,
  darkgoldenrod: 12092939,
  darkgray: 11119017,
  darkgreen: 25600,
  darkgrey: 11119017,
  darkkhaki: 12433259,
  darkmagenta: 9109643,
  darkolivegreen: 5597999,
  darkorange: 16747520,
  darkorchid: 10040012,
  darkred: 9109504,
  darksalmon: 15308410,
  darkseagreen: 9419919,
  darkslateblue: 4734347,
  darkslategray: 3100495,
  darkslategrey: 3100495,
  darkturquoise: 52945,
  darkviolet: 9699539,
  deeppink: 16716947,
  deepskyblue: 49151,
  dimgray: 6908265,
  dimgrey: 6908265,
  dodgerblue: 2003199,
  firebrick: 11674146,
  floralwhite: 16775920,
  forestgreen: 2263842,
  fuchsia: 16711935,
  gainsboro: 14474460,
  ghostwhite: 16316671,
  gold: 16766720,
  goldenrod: 14329120,
  gray: 8421504,
  green: 32768,
  greenyellow: 11403055,
  grey: 8421504,
  honeydew: 15794160,
  hotpink: 16738740,
  indianred: 13458524,
  indigo: 4915330,
  ivory: 16777200,
  khaki: 15787660,
  lavender: 15132410,
  lavenderblush: 16773365,
  lawngreen: 8190976,
  lemonchiffon: 16775885,
  lightblue: 11393254,
  lightcoral: 15761536,
  lightcyan: 14745599,
  lightgoldenrodyellow: 16448210,
  lightgray: 13882323,
  lightgreen: 9498256,
  lightgrey: 13882323,
  lightpink: 16758465,
  lightsalmon: 16752762,
  lightseagreen: 2142890,
  lightskyblue: 8900346,
  lightslategray: 7833753,
  lightslategrey: 7833753,
  lightsteelblue: 11584734,
  lightyellow: 16777184,
  lime: 65280,
  limegreen: 3329330,
  linen: 16445670,
  magenta: 16711935,
  maroon: 8388608,
  mediumaquamarine: 6737322,
  mediumblue: 205,
  mediumorchid: 12211667,
  mediumpurple: 9662683,
  mediumseagreen: 3978097,
  mediumslateblue: 8087790,
  mediumspringgreen: 64154,
  mediumturquoise: 4772300,
  mediumvioletred: 13047173,
  midnightblue: 1644912,
  mintcream: 16121850,
  mistyrose: 16770273,
  moccasin: 16770229,
  navajowhite: 16768685,
  navy: 128,
  oldlace: 16643558,
  olive: 8421376,
  olivedrab: 7048739,
  orange: 16753920,
  orangered: 16729344,
  orchid: 14315734,
  palegoldenrod: 15657130,
  palegreen: 10025880,
  paleturquoise: 11529966,
  palevioletred: 14381203,
  papayawhip: 16773077,
  peachpuff: 16767673,
  peru: 13468991,
  pink: 16761035,
  plum: 14524637,
  powderblue: 11591910,
  purple: 8388736,
  rebeccapurple: 6697881,
  red: 16711680,
  rosybrown: 12357519,
  royalblue: 4286945,
  saddlebrown: 9127187,
  salmon: 16416882,
  sandybrown: 16032864,
  seagreen: 3050327,
  seashell: 16774638,
  sienna: 10506797,
  silver: 12632256,
  skyblue: 8900331,
  slateblue: 6970061,
  slategray: 7372944,
  slategrey: 7372944,
  snow: 16775930,
  springgreen: 65407,
  steelblue: 4620980,
  tan: 13808780,
  teal: 32896,
  thistle: 14204888,
  tomato: 16737095,
  turquoise: 4251856,
  violet: 15631086,
  wheat: 16113331,
  white: 16777215,
  whitesmoke: 16119285,
  yellow: 16776960,
  yellowgreen: 10145074
}, _s = { h: 0, s: 0, l: 0 }, _u = { h: 0, s: 0, l: 0 };
function $d(i, e, t) {
  return t < 0 && (t += 1), t > 1 && (t -= 1), t < 1 / 6 ? i + (e - i) * 6 * t : t < 1 / 2 ? e : t < 2 / 3 ? i + (e - i) * 6 * (2 / 3 - t) : i;
}
class He {
  /**
   * Constructs a new color.
   *
   * Note that standard method of specifying color in three.js is with a hexadecimal triplet,
   * and that method is used throughout the rest of the documentation.
   *
   * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are
   * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.
   * @param {number} [g] - The green component.
   * @param {number} [b] - The blue component.
   */
  constructor(e, t, n) {
    return this.isColor = !0, this.r = 1, this.g = 1, this.b = 1, this.set(e, t, n);
  }
  /**
   * Sets the colors's components from the given values.
   *
   * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are
   * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.
   * @param {number} [g] - The green component.
   * @param {number} [b] - The blue component.
   * @return {Color} A reference to this color.
   */
  set(e, t, n) {
    if (t === void 0 && n === void 0) {
      const r = e;
      r && r.isColor ? this.copy(r) : typeof r == "number" ? this.setHex(r) : typeof r == "string" && this.setStyle(r);
    } else
      this.setRGB(e, t, n);
    return this;
  }
  /**
   * Sets the colors's components to the given scalar value.
   *
   * @param {number} scalar - The scalar value.
   * @return {Color} A reference to this color.
   */
  setScalar(e) {
    return this.r = e, this.g = e, this.b = e, this;
  }
  /**
   * Sets this color from a hexadecimal value.
   *
   * @param {number} hex - The hexadecimal value.
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {Color} A reference to this color.
   */
  setHex(e, t = Jn) {
    return e = Math.floor(e), this.r = (e >> 16 & 255) / 255, this.g = (e >> 8 & 255) / 255, this.b = (e & 255) / 255, Ke.colorSpaceToWorking(this, t), this;
  }
  /**
   * Sets this color from RGB values.
   *
   * @param {number} r - Red channel value between `0.0` and `1.0`.
   * @param {number} g - Green channel value between `0.0` and `1.0`.
   * @param {number} b - Blue channel value between `0.0` and `1.0`.
   * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
   * @return {Color} A reference to this color.
   */
  setRGB(e, t, n, r = Ke.workingColorSpace) {
    return this.r = e, this.g = t, this.b = n, Ke.colorSpaceToWorking(this, r), this;
  }
  /**
   * Sets this color from RGB values.
   *
   * @param {number} h - Hue value between `0.0` and `1.0`.
   * @param {number} s - Saturation value between `0.0` and `1.0`.
   * @param {number} l - Lightness value between `0.0` and `1.0`.
   * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
   * @return {Color} A reference to this color.
   */
  setHSL(e, t, n, r = Ke.workingColorSpace) {
    if (e = Hm(e, 1), t = ct(t, 0, 1), n = ct(n, 0, 1), t === 0)
      this.r = this.g = this.b = n;
    else {
      const s = n <= 0.5 ? n * (1 + t) : n + t - n * t, a = 2 * n - s;
      this.r = $d(a, s, e + 1 / 3), this.g = $d(a, s, e), this.b = $d(a, s, e - 1 / 3);
    }
    return Ke.colorSpaceToWorking(this, r), this;
  }
  /**
   * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`,
   * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or
   * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) -
   * all 140 color names are supported).
   *
   * @param {string} style - Color as a CSS-style string.
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {Color} A reference to this color.
   */
  setStyle(e, t = Jn) {
    function n(s) {
      s !== void 0 && parseFloat(s) < 1 && oe("Color: Alpha component of " + e + " will be ignored.");
    }
    let r;
    if (r = /^(\w+)\(([^\)]*)\)/.exec(e)) {
      let s;
      const a = r[1], o = r[2];
      switch (a) {
        case "rgb":
        case "rgba":
          if (s = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))
            return n(s[4]), this.setRGB(
              Math.min(255, parseInt(s[1], 10)) / 255,
              Math.min(255, parseInt(s[2], 10)) / 255,
              Math.min(255, parseInt(s[3], 10)) / 255,
              t
            );
          if (s = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))
            return n(s[4]), this.setRGB(
              Math.min(100, parseInt(s[1], 10)) / 100,
              Math.min(100, parseInt(s[2], 10)) / 100,
              Math.min(100, parseInt(s[3], 10)) / 100,
              t
            );
          break;
        case "hsl":
        case "hsla":
          if (s = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))
            return n(s[4]), this.setHSL(
              parseFloat(s[1]) / 360,
              parseFloat(s[2]) / 100,
              parseFloat(s[3]) / 100,
              t
            );
          break;
        default:
          oe("Color: Unknown color model " + e);
      }
    } else if (r = /^\#([A-Fa-f\d]+)$/.exec(e)) {
      const s = r[1], a = s.length;
      if (a === 3)
        return this.setRGB(
          parseInt(s.charAt(0), 16) / 15,
          parseInt(s.charAt(1), 16) / 15,
          parseInt(s.charAt(2), 16) / 15,
          t
        );
      if (a === 6)
        return this.setHex(parseInt(s, 16), t);
      oe("Color: Invalid hex color " + e);
    } else if (e && e.length > 0)
      return this.setColorName(e, t);
    return this;
  }
  /**
   * Sets this color from a color name. Faster than {@link Color#setStyle} if
   * you don't need the other CSS-style formats.
   *
   * For convenience, the list of names is exposed in `Color.NAMES` as a hash.
   * ```js
   * Color.NAMES.aliceblue // returns 0xF0F8FF
   * ```
   *
   * @param {string} style - The color name.
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {Color} A reference to this color.
   */
  setColorName(e, t = Jn) {
    const n = Jv[e.toLowerCase()];
    return n !== void 0 ? this.setHex(n, t) : oe("Color: Unknown color " + e), this;
  }
  /**
   * Returns a new color with copied values from this instance.
   *
   * @return {Color} A clone of this instance.
   */
  clone() {
    return new this.constructor(this.r, this.g, this.b);
  }
  /**
   * Copies the values of the given color to this instance.
   *
   * @param {Color} color - The color to copy.
   * @return {Color} A reference to this color.
   */
  copy(e) {
    return this.r = e.r, this.g = e.g, this.b = e.b, this;
  }
  /**
   * Copies the given color into this color, and then converts this color from
   * `SRGBColorSpace` to `LinearSRGBColorSpace`.
   *
   * @param {Color} color - The color to copy/convert.
   * @return {Color} A reference to this color.
   */
  copySRGBToLinear(e) {
    return this.r = as(e.r), this.g = as(e.g), this.b = as(e.b), this;
  }
  /**
   * Copies the given color into this color, and then converts this color from
   * `LinearSRGBColorSpace` to `SRGBColorSpace`.
   *
   * @param {Color} color - The color to copy/convert.
   * @return {Color} A reference to this color.
   */
  copyLinearToSRGB(e) {
    return this.r = Do(e.r), this.g = Do(e.g), this.b = Do(e.b), this;
  }
  /**
   * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`.
   *
   * @return {Color} A reference to this color.
   */
  convertSRGBToLinear() {
    return this.copySRGBToLinear(this), this;
  }
  /**
   * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`.
   *
   * @return {Color} A reference to this color.
   */
  convertLinearToSRGB() {
    return this.copyLinearToSRGB(this), this;
  }
  /**
   * Returns the hexadecimal value of this color.
   *
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {number} The hexadecimal value.
   */
  getHex(e = Jn) {
    return Ke.workingToColorSpace(Hn.copy(this), e), Math.round(ct(Hn.r * 255, 0, 255)) * 65536 + Math.round(ct(Hn.g * 255, 0, 255)) * 256 + Math.round(ct(Hn.b * 255, 0, 255));
  }
  /**
   * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').
   *
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {string} The hexadecimal value as a string.
   */
  getHexString(e = Jn) {
    return ("000000" + this.getHex(e).toString(16)).slice(-6);
  }
  /**
   * Converts the colors RGB values into the HSL format and stores them into the
   * given target object.
   *
   * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result.
   * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
   * @return {{h:number,s:number,l:number}} The HSL representation of this color.
   */
  getHSL(e, t = Ke.workingColorSpace) {
    Ke.workingToColorSpace(Hn.copy(this), t);
    const n = Hn.r, r = Hn.g, s = Hn.b, a = Math.max(n, r, s), o = Math.min(n, r, s);
    let l, c;
    const u = (o + a) / 2;
    if (o === a)
      l = 0, c = 0;
    else {
      const h = a - o;
      switch (c = u <= 0.5 ? h / (a + o) : h / (2 - a - o), a) {
        case n:
          l = (r - s) / h + (r < s ? 6 : 0);
          break;
        case r:
          l = (s - n) / h + 2;
          break;
        case s:
          l = (n - r) / h + 4;
          break;
      }
      l /= 6;
    }
    return e.h = l, e.s = c, e.l = u, e;
  }
  /**
   * Returns the RGB values of this color and stores them into the given target object.
   *
   * @param {Color} target - The target color that is used to store the method's result.
   * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
   * @return {Color} The RGB representation of this color.
   */
  getRGB(e, t = Ke.workingColorSpace) {
    return Ke.workingToColorSpace(Hn.copy(this), t), e.r = Hn.r, e.g = Hn.g, e.b = Hn.b, e;
  }
  /**
   * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`.
   *
   * @param {string} [colorSpace=SRGBColorSpace] - The color space.
   * @return {string} The CSS representation of this color.
   */
  getStyle(e = Jn) {
    Ke.workingToColorSpace(Hn.copy(this), e);
    const t = Hn.r, n = Hn.g, r = Hn.b;
    return e !== Jn ? `color(${e} ${t.toFixed(3)} ${n.toFixed(3)} ${r.toFixed(3)})` : `rgb(${Math.round(t * 255)},${Math.round(n * 255)},${Math.round(r * 255)})`;
  }
  /**
   * Adds the given HSL values to this color's values.
   * Internally, this converts the color's RGB values to HSL, adds HSL
   * and then converts the color back to RGB.
   *
   * @param {number} h - Hue value between `0.0` and `1.0`.
   * @param {number} s - Saturation value between `0.0` and `1.0`.
   * @param {number} l - Lightness value between `0.0` and `1.0`.
   * @return {Color} A reference to this color.
   */
  offsetHSL(e, t, n) {
    return this.getHSL(_s), this.setHSL(_s.h + e, _s.s + t, _s.l + n);
  }
  /**
   * Adds the RGB values of the given color to the RGB values of this color.
   *
   * @param {Color} color - The color to add.
   * @return {Color} A reference to this color.
   */
  add(e) {
    return this.r += e.r, this.g += e.g, this.b += e.b, this;
  }
  /**
   * Adds the RGB values of the given colors and stores the result in this instance.
   *
   * @param {Color} color1 - The first color.
   * @param {Color} color2 - The second color.
   * @return {Color} A reference to this color.
   */
  addColors(e, t) {
    return this.r = e.r + t.r, this.g = e.g + t.g, this.b = e.b + t.b, this;
  }
  /**
   * Adds the given scalar value to the RGB values of this color.
   *
   * @param {number} s - The scalar to add.
   * @return {Color} A reference to this color.
   */
  addScalar(e) {
    return this.r += e, this.g += e, this.b += e, this;
  }
  /**
   * Subtracts the RGB values of the given color from the RGB values of this color.
   *
   * @param {Color} color - The color to subtract.
   * @return {Color} A reference to this color.
   */
  sub(e) {
    return this.r = Math.max(0, this.r - e.r), this.g = Math.max(0, this.g - e.g), this.b = Math.max(0, this.b - e.b), this;
  }
  /**
   * Multiplies the RGB values of the given color with the RGB values of this color.
   *
   * @param {Color} color - The color to multiply.
   * @return {Color} A reference to this color.
   */
  multiply(e) {
    return this.r *= e.r, this.g *= e.g, this.b *= e.b, this;
  }
  /**
   * Multiplies the given scalar value with the RGB values of this color.
   *
   * @param {number} s - The scalar to multiply.
   * @return {Color} A reference to this color.
   */
  multiplyScalar(e) {
    return this.r *= e, this.g *= e, this.b *= e, this;
  }
  /**
   * Linearly interpolates this color's RGB values toward the RGB values of the
   * given color. The alpha argument can be thought of as the ratio between
   * the two colors, where `0.0` is this color and `1.0` is the first argument.
   *
   * @param {Color} color - The color to converge on.
   * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
   * @return {Color} A reference to this color.
   */
  lerp(e, t) {
    return this.r += (e.r - this.r) * t, this.g += (e.g - this.g) * t, this.b += (e.b - this.b) * t, this;
  }
  /**
   * Linearly interpolates between the given colors and stores the result in this instance.
   * The alpha argument can be thought of as the ratio between the two colors, where `0.0`
   * is the first and `1.0` is the second color.
   *
   * @param {Color} color1 - The first color.
   * @param {Color} color2 - The second color.
   * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
   * @return {Color} A reference to this color.
   */
  lerpColors(e, t, n) {
    return this.r = e.r + (t.r - e.r) * n, this.g = e.g + (t.g - e.g) * n, this.b = e.b + (t.b - e.b) * n, this;
  }
  /**
   * Linearly interpolates this color's HSL values toward the HSL values of the
   * given color. It differs from {@link Color#lerp} by not interpolating straight
   * from one color to the other, but instead going through all the hues in between
   * those two colors. The alpha argument can be thought of as the ratio between
   * the two colors, where 0.0 is this color and 1.0 is the first argument.
   *
   * @param {Color} color - The color to converge on.
   * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
   * @return {Color} A reference to this color.
   */
  lerpHSL(e, t) {
    this.getHSL(_s), e.getHSL(_u);
    const n = pc(_s.h, _u.h, t), r = pc(_s.s, _u.s, t), s = pc(_s.l, _u.l, t);
    return this.setHSL(n, r, s), this;
  }
  /**
   * Sets the color's RGB components from the given 3D vector.
   *
   * @param {Vector3} v - The vector to set.
   * @return {Color} A reference to this color.
   */
  setFromVector3(e) {
    return this.r = e.x, this.g = e.y, this.b = e.z, this;
  }
  /**
   * Transforms this color with the given 3x3 matrix.
   *
   * @param {Matrix3} m - The matrix.
   * @return {Color} A reference to this color.
   */
  applyMatrix3(e) {
    const t = this.r, n = this.g, r = this.b, s = e.elements;
    return this.r = s[0] * t + s[3] * n + s[6] * r, this.g = s[1] * t + s[4] * n + s[7] * r, this.b = s[2] * t + s[5] * n + s[8] * r, this;
  }
  /**
   * Returns `true` if this color is equal with the given one.
   *
   * @param {Color} c - The color to test for equality.
   * @return {boolean} Whether this bounding color is equal with the given one.
   */
  equals(e) {
    return e.r === this.r && e.g === this.g && e.b === this.b;
  }
  /**
   * Sets this color's RGB components from the given array.
   *
   * @param {Array<number>} array - An array holding the RGB values.
   * @param {number} [offset=0] - The offset into the array.
   * @return {Color} A reference to this color.
   */
  fromArray(e, t = 0) {
    return this.r = e[t], this.g = e[t + 1], this.b = e[t + 2], this;
  }
  /**
   * Writes the RGB components of this color to the given array. If no array is provided,
   * the method returns a new instance.
   *
   * @param {Array<number>} [array=[]] - The target array holding the color components.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Array<number>} The color components.
   */
  toArray(e = [], t = 0) {
    return e[t] = this.r, e[t + 1] = this.g, e[t + 2] = this.b, e;
  }
  /**
   * Sets the components of this color from the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute holding color data.
   * @param {number} index - The index into the attribute.
   * @return {Color} A reference to this color.
   */
  fromBufferAttribute(e, t) {
    return this.r = e.getX(t), this.g = e.getY(t), this.b = e.getZ(t), this;
  }
  /**
   * This methods defines the serialization result of this class. Returns the color
   * as a hexadecimal value.
   *
   * @return {number} The hexadecimal value.
   */
  toJSON() {
    return this.getHex();
  }
  *[Symbol.iterator]() {
    yield this.r, yield this.g, yield this.b;
  }
}
const Hn = /* @__PURE__ */ new He();
He.NAMES = Jv;
class Xm extends gn {
  /**
   * Constructs a new scene.
   */
  constructor() {
    super(), this.isScene = !0, this.type = "Scene", this.background = null, this.environment = null, this.fog = null, this.backgroundBlurriness = 0, this.backgroundIntensity = 1, this.backgroundRotation = new gi(), this.environmentIntensity = 1, this.environmentRotation = new gi(), this.overrideMaterial = null, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this }));
  }
  copy(e, t) {
    return super.copy(e, t), e.background !== null && (this.background = e.background.clone()), e.environment !== null && (this.environment = e.environment.clone()), e.fog !== null && (this.fog = e.fog.clone()), this.backgroundBlurriness = e.backgroundBlurriness, this.backgroundIntensity = e.backgroundIntensity, this.backgroundRotation.copy(e.backgroundRotation), this.environmentIntensity = e.environmentIntensity, this.environmentRotation.copy(e.environmentRotation), e.overrideMaterial !== null && (this.overrideMaterial = e.overrideMaterial.clone()), this.matrixAutoUpdate = e.matrixAutoUpdate, this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return this.fog !== null && (t.object.fog = this.fog.toJSON()), this.backgroundBlurriness > 0 && (t.object.backgroundBlurriness = this.backgroundBlurriness), this.backgroundIntensity !== 1 && (t.object.backgroundIntensity = this.backgroundIntensity), t.object.backgroundRotation = this.backgroundRotation.toArray(), this.environmentIntensity !== 1 && (t.object.environmentIntensity = this.environmentIntensity), t.object.environmentRotation = this.environmentRotation.toArray(), t;
  }
}
const qi = /* @__PURE__ */ new P(), Gr = /* @__PURE__ */ new P(), Wd = /* @__PURE__ */ new P(), Vr = /* @__PURE__ */ new P(), to = /* @__PURE__ */ new P(), no = /* @__PURE__ */ new P(), b_ = /* @__PURE__ */ new P(), qd = /* @__PURE__ */ new P(), Xd = /* @__PURE__ */ new P(), jd = /* @__PURE__ */ new P(), Yd = /* @__PURE__ */ new rt(), Kd = /* @__PURE__ */ new rt(), Zd = /* @__PURE__ */ new rt();
class Qi {
  /**
   * Constructs a new triangle.
   *
   * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle.
   * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle.
   * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle.
   */
  constructor(e = new P(), t = new P(), n = new P()) {
    this.a = e, this.b = t, this.c = n;
  }
  /**
   * Computes the normal vector of a triangle.
   *
   * @param {Vector3} a - The first corner of the triangle.
   * @param {Vector3} b - The second corner of the triangle.
   * @param {Vector3} c - The third corner of the triangle.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The triangle's normal.
   */
  static getNormal(e, t, n, r) {
    r.subVectors(n, t), qi.subVectors(e, t), r.cross(qi);
    const s = r.lengthSq();
    return s > 0 ? r.multiplyScalar(1 / Math.sqrt(s)) : r.set(0, 0, 0);
  }
  /**
   * Computes a barycentric coordinates from the given vector.
   * Returns `null` if the triangle is degenerate.
   *
   * @param {Vector3} point - A point in 3D space.
   * @param {Vector3} a - The first corner of the triangle.
   * @param {Vector3} b - The second corner of the triangle.
   * @param {Vector3} c - The third corner of the triangle.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The barycentric coordinates for the given point
   */
  static getBarycoord(e, t, n, r, s) {
    qi.subVectors(r, t), Gr.subVectors(n, t), Wd.subVectors(e, t);
    const a = qi.dot(qi), o = qi.dot(Gr), l = qi.dot(Wd), c = Gr.dot(Gr), u = Gr.dot(Wd), h = a * c - o * o;
    if (h === 0)
      return s.set(0, 0, 0), null;
    const d = 1 / h, f = (c * l - o * u) * d, p = (a * u - o * l) * d;
    return s.set(1 - f - p, p, f);
  }
  /**
   * Returns `true` if the given point, when projected onto the plane of the
   * triangle, lies within the triangle.
   *
   * @param {Vector3} point - The point in 3D space to test.
   * @param {Vector3} a - The first corner of the triangle.
   * @param {Vector3} b - The second corner of the triangle.
   * @param {Vector3} c - The third corner of the triangle.
   * @return {boolean} Whether the given point, when projected onto the plane of the
   * triangle, lies within the triangle or not.
   */
  static containsPoint(e, t, n, r) {
    return this.getBarycoord(e, t, n, r, Vr) === null ? !1 : Vr.x >= 0 && Vr.y >= 0 && Vr.x + Vr.y <= 1;
  }
  /**
   * Computes the value barycentrically interpolated for the given point on the
   * triangle. Returns `null` if the triangle is degenerate.
   *
   * @param {Vector3} point - Position of interpolated point.
   * @param {Vector3} p1 - The first corner of the triangle.
   * @param {Vector3} p2 - The second corner of the triangle.
   * @param {Vector3} p3 - The third corner of the triangle.
   * @param {Vector3} v1 - Value to interpolate of first vertex.
   * @param {Vector3} v2 - Value to interpolate of second vertex.
   * @param {Vector3} v3 - Value to interpolate of third vertex.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The interpolated value.
   */
  static getInterpolation(e, t, n, r, s, a, o, l) {
    return this.getBarycoord(e, t, n, r, Vr) === null ? (l.x = 0, l.y = 0, "z" in l && (l.z = 0), "w" in l && (l.w = 0), null) : (l.setScalar(0), l.addScaledVector(s, Vr.x), l.addScaledVector(a, Vr.y), l.addScaledVector(o, Vr.z), l);
  }
  /**
   * Computes the value barycentrically interpolated for the given attribute and indices.
   *
   * @param {BufferAttribute} attr - The attribute to interpolate.
   * @param {number} i1 - Index of first vertex.
   * @param {number} i2 - Index of second vertex.
   * @param {number} i3 - Index of third vertex.
   * @param {Vector3} barycoord - The barycoordinate value to use to interpolate.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The interpolated attribute value.
   */
  static getInterpolatedAttribute(e, t, n, r, s, a) {
    return Yd.setScalar(0), Kd.setScalar(0), Zd.setScalar(0), Yd.fromBufferAttribute(e, t), Kd.fromBufferAttribute(e, n), Zd.fromBufferAttribute(e, r), a.setScalar(0), a.addScaledVector(Yd, s.x), a.addScaledVector(Kd, s.y), a.addScaledVector(Zd, s.z), a;
  }
  /**
   * Returns `true` if the triangle is oriented towards the given direction.
   *
   * @param {Vector3} a - The first corner of the triangle.
   * @param {Vector3} b - The second corner of the triangle.
   * @param {Vector3} c - The third corner of the triangle.
   * @param {Vector3} direction - The (normalized) direction vector.
   * @return {boolean} Whether the triangle is oriented towards the given direction or not.
   */
  static isFrontFacing(e, t, n, r) {
    return qi.subVectors(n, t), Gr.subVectors(e, t), qi.cross(Gr).dot(r) < 0;
  }
  /**
   * Sets the triangle's vertices by copying the given values.
   *
   * @param {Vector3} a - The first corner of the triangle.
   * @param {Vector3} b - The second corner of the triangle.
   * @param {Vector3} c - The third corner of the triangle.
   * @return {Triangle} A reference to this triangle.
   */
  set(e, t, n) {
    return this.a.copy(e), this.b.copy(t), this.c.copy(n), this;
  }
  /**
   * Sets the triangle's vertices by copying the given array values.
   *
   * @param {Array<Vector3>} points - An array with 3D points.
   * @param {number} i0 - The array index representing the first corner of the triangle.
   * @param {number} i1 - The array index representing the second corner of the triangle.
   * @param {number} i2 - The array index representing the third corner of the triangle.
   * @return {Triangle} A reference to this triangle.
   */
  setFromPointsAndIndices(e, t, n, r) {
    return this.a.copy(e[t]), this.b.copy(e[n]), this.c.copy(e[r]), this;
  }
  /**
   * Sets the triangle's vertices by copying the given attribute values.
   *
   * @param {BufferAttribute} attribute - A buffer attribute with 3D points data.
   * @param {number} i0 - The attribute index representing the first corner of the triangle.
   * @param {number} i1 - The attribute index representing the second corner of the triangle.
   * @param {number} i2 - The attribute index representing the third corner of the triangle.
   * @return {Triangle} A reference to this triangle.
   */
  setFromAttributeAndIndices(e, t, n, r) {
    return this.a.fromBufferAttribute(e, t), this.b.fromBufferAttribute(e, n), this.c.fromBufferAttribute(e, r), this;
  }
  /**
   * Returns a new triangle with copied values from this instance.
   *
   * @return {Triangle} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given triangle to this instance.
   *
   * @param {Triangle} triangle - The triangle to copy.
   * @return {Triangle} A reference to this triangle.
   */
  copy(e) {
    return this.a.copy(e.a), this.b.copy(e.b), this.c.copy(e.c), this;
  }
  /**
   * Computes the area of the triangle.
   *
   * @return {number} The triangle's area.
   */
  getArea() {
    return qi.subVectors(this.c, this.b), Gr.subVectors(this.a, this.b), qi.cross(Gr).length() * 0.5;
  }
  /**
   * Computes the midpoint of the triangle.
   *
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The triangle's midpoint.
   */
  getMidpoint(e) {
    return e.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3);
  }
  /**
   * Computes the normal of the triangle.
   *
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The triangle's normal.
   */
  getNormal(e) {
    return Qi.getNormal(this.a, this.b, this.c, e);
  }
  /**
   * Computes a plane the triangle lies within.
   *
   * @param {Plane} target - The target vector that is used to store the method's result.
   * @return {Plane} The plane the triangle lies within.
   */
  getPlane(e) {
    return e.setFromCoplanarPoints(this.a, this.b, this.c);
  }
  /**
   * Computes a barycentric coordinates from the given vector.
   * Returns `null` if the triangle is degenerate.
   *
   * @param {Vector3} point - A point in 3D space.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The barycentric coordinates for the given point
   */
  getBarycoord(e, t) {
    return Qi.getBarycoord(e, this.a, this.b, this.c, t);
  }
  /**
   * Computes the value barycentrically interpolated for the given point on the
   * triangle. Returns `null` if the triangle is degenerate.
   *
   * @param {Vector3} point - Position of interpolated point.
   * @param {Vector3} v1 - Value to interpolate of first vertex.
   * @param {Vector3} v2 - Value to interpolate of second vertex.
   * @param {Vector3} v3 - Value to interpolate of third vertex.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The interpolated value.
   */
  getInterpolation(e, t, n, r, s) {
    return Qi.getInterpolation(e, this.a, this.b, this.c, t, n, r, s);
  }
  /**
   * Returns `true` if the given point, when projected onto the plane of the
   * triangle, lies within the triangle.
   *
   * @param {Vector3} point - The point in 3D space to test.
   * @return {boolean} Whether the given point, when projected onto the plane of the
   * triangle, lies within the triangle or not.
   */
  containsPoint(e) {
    return Qi.containsPoint(e, this.a, this.b, this.c);
  }
  /**
   * Returns `true` if the triangle is oriented towards the given direction.
   *
   * @param {Vector3} direction - The (normalized) direction vector.
   * @return {boolean} Whether the triangle is oriented towards the given direction or not.
   */
  isFrontFacing(e) {
    return Qi.isFrontFacing(this.a, this.b, this.c, e);
  }
  /**
   * Returns `true` if this triangle intersects with the given box.
   *
   * @param {Box3} box - The box to intersect.
   * @return {boolean} Whether this triangle intersects with the given box or not.
   */
  intersectsBox(e) {
    return e.intersectsTriangle(this);
  }
  /**
   * Returns the closest point on the triangle to the given point.
   *
   * @param {Vector3} p - The point to compute the closest point for.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The closest point on the triangle.
   */
  closestPointToPoint(e, t) {
    const n = this.a, r = this.b, s = this.c;
    let a, o;
    to.subVectors(r, n), no.subVectors(s, n), qd.subVectors(e, n);
    const l = to.dot(qd), c = no.dot(qd);
    if (l <= 0 && c <= 0)
      return t.copy(n);
    Xd.subVectors(e, r);
    const u = to.dot(Xd), h = no.dot(Xd);
    if (u >= 0 && h <= u)
      return t.copy(r);
    const d = l * h - u * c;
    if (d <= 0 && l >= 0 && u <= 0)
      return a = l / (l - u), t.copy(n).addScaledVector(to, a);
    jd.subVectors(e, s);
    const f = to.dot(jd), p = no.dot(jd);
    if (p >= 0 && f <= p)
      return t.copy(s);
    const _ = f * c - l * p;
    if (_ <= 0 && c >= 0 && p <= 0)
      return o = c / (c - p), t.copy(n).addScaledVector(no, o);
    const g = u * p - f * h;
    if (g <= 0 && h - u >= 0 && f - p >= 0)
      return b_.subVectors(s, r), o = (h - u) / (h - u + (f - p)), t.copy(r).addScaledVector(b_, o);
    const m = 1 / (g + _ + d);
    return a = _ * m, o = d * m, t.copy(n).addScaledVector(to, a).addScaledVector(no, o);
  }
  /**
   * Returns `true` if this triangle is equal with the given one.
   *
   * @param {Triangle} triangle - The triangle to test for equality.
   * @return {boolean} Whether this triangle is equal with the given one.
   */
  equals(e) {
    return e.a.equals(this.a) && e.b.equals(this.b) && e.c.equals(this.c);
  }
}
class Ha {
  /**
   * Constructs a new bounding box.
   *
   * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box.
   * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box.
   */
  constructor(e = new P(1 / 0, 1 / 0, 1 / 0), t = new P(-1 / 0, -1 / 0, -1 / 0)) {
    this.isBox3 = !0, this.min = e, this.max = t;
  }
  /**
   * Sets the lower and upper boundaries of this box.
   * Please note that this method only copies the values from the given objects.
   *
   * @param {Vector3} min - The lower boundary of the box.
   * @param {Vector3} max - The upper boundary of the box.
   * @return {Box3} A reference to this bounding box.
   */
  set(e, t) {
    return this.min.copy(e), this.max.copy(t), this;
  }
  /**
   * Sets the upper and lower bounds of this box so it encloses the position data
   * in the given array.
   *
   * @param {Array<number>} array - An array holding 3D position data.
   * @return {Box3} A reference to this bounding box.
   */
  setFromArray(e) {
    this.makeEmpty();
    for (let t = 0, n = e.length; t < n; t += 3)
      this.expandByPoint(Xi.fromArray(e, t));
    return this;
  }
  /**
   * Sets the upper and lower bounds of this box so it encloses the position data
   * in the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data.
   * @return {Box3} A reference to this bounding box.
   */
  setFromBufferAttribute(e) {
    this.makeEmpty();
    for (let t = 0, n = e.count; t < n; t++)
      this.expandByPoint(Xi.fromBufferAttribute(e, t));
    return this;
  }
  /**
   * Sets the upper and lower bounds of this box so it encloses the position data
   * in the given array.
   *
   * @param {Array<Vector3>} points - An array holding 3D position data as instances of {@link Vector3}.
   * @return {Box3} A reference to this bounding box.
   */
  setFromPoints(e) {
    this.makeEmpty();
    for (let t = 0, n = e.length; t < n; t++)
      this.expandByPoint(e[t]);
    return this;
  }
  /**
   * Centers this box on the given center vector and sets this box's width, height and
   * depth to the given size values.
   *
   * @param {Vector3} center - The center of the box.
   * @param {Vector3} size - The x, y and z dimensions of the box.
   * @return {Box3} A reference to this bounding box.
   */
  setFromCenterAndSize(e, t) {
    const n = Xi.copy(t).multiplyScalar(0.5);
    return this.min.copy(e).sub(n), this.max.copy(e).add(n), this;
  }
  /**
   * Computes the world-axis-aligned bounding box for the given 3D object
   * (including its children), accounting for the object's, and children's,
   * world transforms. The function may result in a larger box than strictly necessary.
   *
   * @param {Object3D} object - The 3D object to compute the bounding box for.
   * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest
   * world-axis-aligned bounding box at the expense of more computation.
   * @return {Box3} A reference to this bounding box.
   */
  setFromObject(e, t = !1) {
    return this.makeEmpty(), this.expandByObject(e, t);
  }
  /**
   * Returns a new box with copied values from this instance.
   *
   * @return {Box3} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given box to this instance.
   *
   * @param {Box3} box - The box to copy.
   * @return {Box3} A reference to this bounding box.
   */
  copy(e) {
    return this.min.copy(e.min), this.max.copy(e.max), this;
  }
  /**
   * Makes this box empty which means in encloses a zero space in 3D.
   *
   * @return {Box3} A reference to this bounding box.
   */
  makeEmpty() {
    return this.min.x = this.min.y = this.min.z = 1 / 0, this.max.x = this.max.y = this.max.z = -1 / 0, this;
  }
  /**
   * Returns true if this box includes zero points within its bounds.
   * Note that a box with equal lower and upper bounds still includes one
   * point, the one both bounds share.
   *
   * @return {boolean} Whether this box is empty or not.
   */
  isEmpty() {
    return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
  }
  /**
   * Returns the center point of this box.
   *
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The center point.
   */
  getCenter(e) {
    return this.isEmpty() ? e.set(0, 0, 0) : e.addVectors(this.min, this.max).multiplyScalar(0.5);
  }
  /**
   * Returns the dimensions of this box.
   *
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The size.
   */
  getSize(e) {
    return this.isEmpty() ? e.set(0, 0, 0) : e.subVectors(this.max, this.min);
  }
  /**
   * Expands the boundaries of this box to include the given point.
   *
   * @param {Vector3} point - The point that should be included by the bounding box.
   * @return {Box3} A reference to this bounding box.
   */
  expandByPoint(e) {
    return this.min.min(e), this.max.max(e), this;
  }
  /**
   * Expands this box equilaterally by the given vector. The width of this
   * box will be expanded by the x component of the vector in both
   * directions. The height of this box will be expanded by the y component of
   * the vector in both directions. The depth of this box will be
   * expanded by the z component of the vector in both directions.
   *
   * @param {Vector3} vector - The vector that should expand the bounding box.
   * @return {Box3} A reference to this bounding box.
   */
  expandByVector(e) {
    return this.min.sub(e), this.max.add(e), this;
  }
  /**
   * Expands each dimension of the box by the given scalar. If negative, the
   * dimensions of the box will be contracted.
   *
   * @param {number} scalar - The scalar value that should expand the bounding box.
   * @return {Box3} A reference to this bounding box.
   */
  expandByScalar(e) {
    return this.min.addScalar(-e), this.max.addScalar(e), this;
  }
  /**
   * Expands the boundaries of this box to include the given 3D object and
   * its children, accounting for the object's, and children's, world
   * transforms. The function may result in a larger box than strictly
   * necessary (unless the precise parameter is set to true).
   *
   * @param {Object3D} object - The 3D object that should expand the bounding box.
   * @param {boolean} precise - If set to `true`, the method expands the bounding box
   * as little as necessary at the expense of more computation.
   * @return {Box3} A reference to this bounding box.
   */
  expandByObject(e, t = !1) {
    e.updateWorldMatrix(!1, !1);
    const n = e.geometry;
    if (n !== void 0) {
      const s = n.getAttribute("position");
      if (t === !0 && s !== void 0 && e.isInstancedMesh !== !0)
        for (let a = 0, o = s.count; a < o; a++)
          e.isMesh === !0 ? e.getVertexPosition(a, Xi) : Xi.fromBufferAttribute(s, a), Xi.applyMatrix4(e.matrixWorld), this.expandByPoint(Xi);
      else
        e.boundingBox !== void 0 ? (e.boundingBox === null && e.computeBoundingBox(), xu.copy(e.boundingBox)) : (n.boundingBox === null && n.computeBoundingBox(), xu.copy(n.boundingBox)), xu.applyMatrix4(e.matrixWorld), this.union(xu);
    }
    const r = e.children;
    for (let s = 0, a = r.length; s < a; s++)
      this.expandByObject(r[s], t);
    return this;
  }
  /**
   * Returns `true` if the given point lies within or on the boundaries of this box.
   *
   * @param {Vector3} point - The point to test.
   * @return {boolean} Whether the bounding box contains the given point or not.
   */
  containsPoint(e) {
    return e.x >= this.min.x && e.x <= this.max.x && e.y >= this.min.y && e.y <= this.max.y && e.z >= this.min.z && e.z <= this.max.z;
  }
  /**
   * Returns `true` if this bounding box includes the entirety of the given bounding box.
   * If this box and the given one are identical, this function also returns `true`.
   *
   * @param {Box3} box - The bounding box to test.
   * @return {boolean} Whether the bounding box contains the given bounding box or not.
   */
  containsBox(e) {
    return this.min.x <= e.min.x && e.max.x <= this.max.x && this.min.y <= e.min.y && e.max.y <= this.max.y && this.min.z <= e.min.z && e.max.z <= this.max.z;
  }
  /**
   * Returns a point as a proportion of this box's width, height and depth.
   *
   * @param {Vector3} point - A point in 3D space.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} A point as a proportion of this box's width, height and depth.
   */
  getParameter(e, t) {
    return t.set(
      (e.x - this.min.x) / (this.max.x - this.min.x),
      (e.y - this.min.y) / (this.max.y - this.min.y),
      (e.z - this.min.z) / (this.max.z - this.min.z)
    );
  }
  /**
   * Returns `true` if the given bounding box intersects with this bounding box.
   *
   * @param {Box3} box - The bounding box to test.
   * @return {boolean} Whether the given bounding box intersects with this bounding box.
   */
  intersectsBox(e) {
    return e.max.x >= this.min.x && e.min.x <= this.max.x && e.max.y >= this.min.y && e.min.y <= this.max.y && e.max.z >= this.min.z && e.min.z <= this.max.z;
  }
  /**
   * Returns `true` if the given bounding sphere intersects with this bounding box.
   *
   * @param {Sphere} sphere - The bounding sphere to test.
   * @return {boolean} Whether the given bounding sphere intersects with this bounding box.
   */
  intersectsSphere(e) {
    return this.clampPoint(e.center, Xi), Xi.distanceToSquared(e.center) <= e.radius * e.radius;
  }
  /**
   * Returns `true` if the given plane intersects with this bounding box.
   *
   * @param {Plane} plane - The plane to test.
   * @return {boolean} Whether the given plane intersects with this bounding box.
   */
  intersectsPlane(e) {
    let t, n;
    return e.normal.x > 0 ? (t = e.normal.x * this.min.x, n = e.normal.x * this.max.x) : (t = e.normal.x * this.max.x, n = e.normal.x * this.min.x), e.normal.y > 0 ? (t += e.normal.y * this.min.y, n += e.normal.y * this.max.y) : (t += e.normal.y * this.max.y, n += e.normal.y * this.min.y), e.normal.z > 0 ? (t += e.normal.z * this.min.z, n += e.normal.z * this.max.z) : (t += e.normal.z * this.max.z, n += e.normal.z * this.min.z), t <= -e.constant && n >= -e.constant;
  }
  /**
   * Returns `true` if the given triangle intersects with this bounding box.
   *
   * @param {Triangle} triangle - The triangle to test.
   * @return {boolean} Whether the given triangle intersects with this bounding box.
   */
  intersectsTriangle(e) {
    if (this.isEmpty())
      return !1;
    this.getCenter(Il), vu.subVectors(this.max, Il), io.subVectors(e.a, Il), ro.subVectors(e.b, Il), so.subVectors(e.c, Il), xs.subVectors(ro, io), vs.subVectors(so, ro), na.subVectors(io, so);
    let t = [
      0,
      -xs.z,
      xs.y,
      0,
      -vs.z,
      vs.y,
      0,
      -na.z,
      na.y,
      xs.z,
      0,
      -xs.x,
      vs.z,
      0,
      -vs.x,
      na.z,
      0,
      -na.x,
      -xs.y,
      xs.x,
      0,
      -vs.y,
      vs.x,
      0,
      -na.y,
      na.x,
      0
    ];
    return !Qd(t, io, ro, so, vu) || (t = [1, 0, 0, 0, 1, 0, 0, 0, 1], !Qd(t, io, ro, so, vu)) ? !1 : (yu.crossVectors(xs, vs), t = [yu.x, yu.y, yu.z], Qd(t, io, ro, so, vu));
  }
  /**
   * Clamps the given point within the bounds of this box.
   *
   * @param {Vector3} point - The point to clamp.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The clamped point.
   */
  clampPoint(e, t) {
    return t.copy(e).clamp(this.min, this.max);
  }
  /**
   * Returns the euclidean distance from any edge of this box to the specified point. If
   * the given point lies inside of this box, the distance will be `0`.
   *
   * @param {Vector3} point - The point to compute the distance to.
   * @return {number} The euclidean distance.
   */
  distanceToPoint(e) {
    return this.clampPoint(e, Xi).distanceTo(e);
  }
  /**
   * Returns a bounding sphere that encloses this bounding box.
   *
   * @param {Sphere} target - The target sphere that is used to store the method's result.
   * @return {Sphere} The bounding sphere that encloses this bounding box.
   */
  getBoundingSphere(e) {
    return this.isEmpty() ? e.makeEmpty() : (this.getCenter(e.center), e.radius = this.getSize(Xi).length() * 0.5), e;
  }
  /**
   * Computes the intersection of this bounding box and the given one, setting the upper
   * bound of this box to the lesser of the two boxes' upper bounds and the
   * lower bound of this box to the greater of the two boxes' lower bounds. If
   * there's no overlap, makes this box empty.
   *
   * @param {Box3} box - The bounding box to intersect with.
   * @return {Box3} A reference to this bounding box.
   */
  intersect(e) {
    return this.min.max(e.min), this.max.min(e.max), this.isEmpty() && this.makeEmpty(), this;
  }
  /**
   * Computes the union of this box and another and the given one, setting the upper
   * bound of this box to the greater of the two boxes' upper bounds and the
   * lower bound of this box to the lesser of the two boxes' lower bounds.
   *
   * @param {Box3} box - The bounding box that will be unioned with this instance.
   * @return {Box3} A reference to this bounding box.
   */
  union(e) {
    return this.min.min(e.min), this.max.max(e.max), this;
  }
  /**
   * Transforms this bounding box by the given 4x4 transformation matrix.
   *
   * @param {Matrix4} matrix - The transformation matrix.
   * @return {Box3} A reference to this bounding box.
   */
  applyMatrix4(e) {
    return this.isEmpty() ? this : (zr[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(e), zr[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(e), zr[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(e), zr[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(e), zr[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(e), zr[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(e), zr[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(e), zr[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(e), this.setFromPoints(zr), this);
  }
  /**
   * Adds the given offset to both the upper and lower bounds of this bounding box,
   * effectively moving it in 3D space.
   *
   * @param {Vector3} offset - The offset that should be used to translate the bounding box.
   * @return {Box3} A reference to this bounding box.
   */
  translate(e) {
    return this.min.add(e), this.max.add(e), this;
  }
  /**
   * Returns `true` if this bounding box is equal with the given one.
   *
   * @param {Box3} box - The box to test for equality.
   * @return {boolean} Whether this bounding box is equal with the given one.
   */
  equals(e) {
    return e.min.equals(this.min) && e.max.equals(this.max);
  }
  /**
   * Returns a serialized structure of the bounding box.
   *
   * @return {Object} Serialized structure with fields representing the object state.
   */
  toJSON() {
    return {
      min: this.min.toArray(),
      max: this.max.toArray()
    };
  }
  /**
   * Returns a serialized structure of the bounding box.
   *
   * @param {Object} json - The serialized json to set the box from.
   * @return {Box3} A reference to this bounding box.
   */
  fromJSON(e) {
    return this.min.fromArray(e.min), this.max.fromArray(e.max), this;
  }
}
const zr = [
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P(),
  /* @__PURE__ */ new P()
], Xi = /* @__PURE__ */ new P(), xu = /* @__PURE__ */ new Ha(), io = /* @__PURE__ */ new P(), ro = /* @__PURE__ */ new P(), so = /* @__PURE__ */ new P(), xs = /* @__PURE__ */ new P(), vs = /* @__PURE__ */ new P(), na = /* @__PURE__ */ new P(), Il = /* @__PURE__ */ new P(), vu = /* @__PURE__ */ new P(), yu = /* @__PURE__ */ new P(), ia = /* @__PURE__ */ new P();
function Qd(i, e, t, n, r) {
  for (let s = 0, a = i.length - 3; s <= a; s += 3) {
    ia.fromArray(i, s);
    const o = r.x * Math.abs(ia.x) + r.y * Math.abs(ia.y) + r.z * Math.abs(ia.z), l = e.dot(ia), c = t.dot(ia), u = n.dot(ia);
    if (Math.max(-Math.max(l, c, u), Math.min(l, c, u)) > o)
      return !1;
  }
  return !0;
}
const Kr = /* @__PURE__ */ rE();
function rE() {
  const i = new ArrayBuffer(4), e = new Float32Array(i), t = new Uint32Array(i), n = new Uint32Array(512), r = new Uint32Array(512);
  for (let l = 0; l < 256; ++l) {
    const c = l - 127;
    c < -27 ? (n[l] = 0, n[l | 256] = 32768, r[l] = 24, r[l | 256] = 24) : c < -14 ? (n[l] = 1024 >> -c - 14, n[l | 256] = 1024 >> -c - 14 | 32768, r[l] = -c - 1, r[l | 256] = -c - 1) : c <= 15 ? (n[l] = c + 15 << 10, n[l | 256] = c + 15 << 10 | 32768, r[l] = 13, r[l | 256] = 13) : c < 128 ? (n[l] = 31744, n[l | 256] = 64512, r[l] = 24, r[l | 256] = 24) : (n[l] = 31744, n[l | 256] = 64512, r[l] = 13, r[l | 256] = 13);
  }
  const s = new Uint32Array(2048), a = new Uint32Array(64), o = new Uint32Array(64);
  for (let l = 1; l < 1024; ++l) {
    let c = l << 13, u = 0;
    for (; !(c & 8388608); )
      c <<= 1, u -= 8388608;
    c &= -8388609, u += 947912704, s[l] = c | u;
  }
  for (let l = 1024; l < 2048; ++l)
    s[l] = 939524096 + (l - 1024 << 13);
  for (let l = 1; l < 31; ++l)
    a[l] = l << 23;
  a[31] = 1199570944, a[32] = 2147483648;
  for (let l = 33; l < 63; ++l)
    a[l] = 2147483648 + (l - 32 << 23);
  a[63] = 3347054592;
  for (let l = 1; l < 64; ++l)
    l !== 32 && (o[l] = 1024);
  return {
    floatView: e,
    uint32View: t,
    baseTable: n,
    shiftTable: r,
    mantissaTable: s,
    exponentTable: a,
    offsetTable: o
  };
}
function Si(i) {
  Math.abs(i) > 65504 && oe("DataUtils.toHalfFloat(): Value out of range."), i = ct(i, -65504, 65504), Kr.floatView[0] = i;
  const e = Kr.uint32View[0], t = e >> 23 & 511;
  return Kr.baseTable[t] + ((e & 8388607) >> Kr.shiftTable[t]);
}
function bu(i) {
  const e = i >> 10;
  return Kr.uint32View[0] = Kr.mantissaTable[Kr.offsetTable[e] + (i & 1023)] + Kr.exponentTable[e], Kr.floatView[0];
}
const pn = /* @__PURE__ */ new P(), Su = /* @__PURE__ */ new de();
let sE = 0;
class Bn {
  /**
   * Constructs a new buffer attribute.
   *
   * @param {TypedArray} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n = !1) {
    if (Array.isArray(e))
      throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");
    this.isBufferAttribute = !0, Object.defineProperty(this, "id", { value: sE++ }), this.name = "", this.array = e, this.itemSize = t, this.count = e !== void 0 ? e.length / t : 0, this.normalized = n, this.usage = cl, this.updateRanges = [], this.gpuType = ln, this.version = 0;
  }
  /**
   * A callback function that is executed after the renderer has transferred the attribute
   * array data to the GPU.
   */
  onUploadCallback() {
  }
  /**
   * Flag to indicate that this attribute has changed and should be re-sent to
   * the GPU. Set this to `true` when you modify the value of the array.
   *
   * @type {number}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && this.version++;
  }
  /**
   * Sets the usage of this buffer attribute.
   *
   * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set.
   * @return {BufferAttribute} A reference to this buffer attribute.
   */
  setUsage(e) {
    return this.usage = e, this;
  }
  /**
   * Adds a range of data in the data array to be updated on the GPU.
   *
   * @param {number} start - Position at which to start update.
   * @param {number} count - The number of components to update.
   */
  addUpdateRange(e, t) {
    this.updateRanges.push({ start: e, count: t });
  }
  /**
   * Clears the update ranges.
   */
  clearUpdateRanges() {
    this.updateRanges.length = 0;
  }
  /**
   * Copies the values of the given buffer attribute to this instance.
   *
   * @param {BufferAttribute} source - The buffer attribute to copy.
   * @return {BufferAttribute} A reference to this instance.
   */
  copy(e) {
    return this.name = e.name, this.array = new e.array.constructor(e.array), this.itemSize = e.itemSize, this.count = e.count, this.normalized = e.normalized, this.usage = e.usage, this.gpuType = e.gpuType, this;
  }
  /**
   * Copies a vector from the given buffer attribute to this one. The start
   * and destination position in the attribute buffers are represented by the
   * given indices.
   *
   * @param {number} index1 - The destination index into this buffer attribute.
   * @param {BufferAttribute} attribute - The buffer attribute to copy from.
   * @param {number} index2 - The source index into the given buffer attribute.
   * @return {BufferAttribute} A reference to this instance.
   */
  copyAt(e, t, n) {
    e *= this.itemSize, n *= t.itemSize;
    for (let r = 0, s = this.itemSize; r < s; r++)
      this.array[e + r] = t.array[n + r];
    return this;
  }
  /**
   * Copies the given array data into this buffer attribute.
   *
   * @param {(TypedArray|Array)} array - The array to copy.
   * @return {BufferAttribute} A reference to this instance.
   */
  copyArray(e) {
    return this.array.set(e), this;
  }
  /**
   * Applies the given 3x3 matrix to the given attribute. Works with
   * item size `2` and `3`.
   *
   * @param {Matrix3} m - The matrix to apply.
   * @return {BufferAttribute} A reference to this instance.
   */
  applyMatrix3(e) {
    if (this.itemSize === 2)
      for (let t = 0, n = this.count; t < n; t++)
        Su.fromBufferAttribute(this, t), Su.applyMatrix3(e), this.setXY(t, Su.x, Su.y);
    else if (this.itemSize === 3)
      for (let t = 0, n = this.count; t < n; t++)
        pn.fromBufferAttribute(this, t), pn.applyMatrix3(e), this.setXYZ(t, pn.x, pn.y, pn.z);
    return this;
  }
  /**
   * Applies the given 4x4 matrix to the given attribute. Only works with
   * item size `3`.
   *
   * @param {Matrix4} m - The matrix to apply.
   * @return {BufferAttribute} A reference to this instance.
   */
  applyMatrix4(e) {
    for (let t = 0, n = this.count; t < n; t++)
      pn.fromBufferAttribute(this, t), pn.applyMatrix4(e), this.setXYZ(t, pn.x, pn.y, pn.z);
    return this;
  }
  /**
   * Applies the given 3x3 normal matrix to the given attribute. Only works with
   * item size `3`.
   *
   * @param {Matrix3} m - The normal matrix to apply.
   * @return {BufferAttribute} A reference to this instance.
   */
  applyNormalMatrix(e) {
    for (let t = 0, n = this.count; t < n; t++)
      pn.fromBufferAttribute(this, t), pn.applyNormalMatrix(e), this.setXYZ(t, pn.x, pn.y, pn.z);
    return this;
  }
  /**
   * Applies the given 4x4 matrix to the given attribute. Only works with
   * item size `3` and with direction vectors.
   *
   * @param {Matrix4} m - The matrix to apply.
   * @return {BufferAttribute} A reference to this instance.
   */
  transformDirection(e) {
    for (let t = 0, n = this.count; t < n; t++)
      pn.fromBufferAttribute(this, t), pn.transformDirection(e), this.setXYZ(t, pn.x, pn.y, pn.z);
    return this;
  }
  /**
   * Sets the given array data in the buffer attribute.
   *
   * @param {(TypedArray|Array)} value - The array data to set.
   * @param {number} [offset=0] - The offset in this buffer attribute's array.
   * @return {BufferAttribute} A reference to this instance.
   */
  set(e, t = 0) {
    return this.array.set(e, t), this;
  }
  /**
   * Returns the given component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} component - The component index.
   * @return {number} The returned value.
   */
  getComponent(e, t) {
    let n = this.array[e * this.itemSize + t];
    return this.normalized && (n = ti(n, this.array)), n;
  }
  /**
   * Sets the given value to the given component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} component - The component index.
   * @param {number} value - The value to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setComponent(e, t, n) {
    return this.normalized && (n = lt(n, this.array)), this.array[e * this.itemSize + t] = n, this;
  }
  /**
   * Returns the x component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The x component.
   */
  getX(e) {
    let t = this.array[e * this.itemSize];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Sets the x component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setX(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize] = t, this;
  }
  /**
   * Returns the y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The y component.
   */
  getY(e) {
    let t = this.array[e * this.itemSize + 1];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Sets the y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} y - The value to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setY(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 1] = t, this;
  }
  /**
   * Returns the z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The z component.
   */
  getZ(e) {
    let t = this.array[e * this.itemSize + 2];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Sets the z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} z - The value to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setZ(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 2] = t, this;
  }
  /**
   * Returns the w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The w component.
   */
  getW(e) {
    let t = this.array[e * this.itemSize + 3];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Sets the w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} w - The value to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setW(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 3] = t, this;
  }
  /**
   * Sets the x and y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setXY(e, t, n) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this;
  }
  /**
   * Sets the x, y and z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @param {number} z - The value for the z component to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setXYZ(e, t, n, r) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this.array[e + 2] = r, this;
  }
  /**
   * Sets the x, y, z and w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @param {number} z - The value for the z component to set.
   * @param {number} w - The value for the w component to set.
   * @return {BufferAttribute} A reference to this instance.
   */
  setXYZW(e, t, n, r, s) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array), s = lt(s, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this.array[e + 2] = r, this.array[e + 3] = s, this;
  }
  /**
   * Sets the given callback function that is executed after the Renderer has transferred
   * the attribute array data to the GPU. Can be used to perform clean-up operations after
   * the upload when attribute data are not needed anymore on the CPU side.
   *
   * @param {Function} callback - The `onUpload()` callback.
   * @return {BufferAttribute} A reference to this instance.
   */
  onUpload(e) {
    return this.onUploadCallback = e, this;
  }
  /**
   * Returns a new buffer attribute with copied values from this instance.
   *
   * @return {BufferAttribute} A clone of this instance.
   */
  clone() {
    return new this.constructor(this.array, this.itemSize).copy(this);
  }
  /**
   * Serializes the buffer attribute into JSON.
   *
   * @return {Object} A JSON object representing the serialized buffer attribute.
   */
  toJSON() {
    const e = {
      itemSize: this.itemSize,
      type: this.array.constructor.name,
      array: Array.from(this.array),
      normalized: this.normalized
    };
    return this.name !== "" && (e.name = this.name), this.usage !== cl && (e.usage = this.usage), e;
  }
}
class jm extends Bn {
  /**
   * Constructs a new buffer attribute.
   *
   * @param {(Array<number>|Uint16Array)} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n) {
    super(new Uint16Array(e), t, n);
  }
}
class Ym extends Bn {
  /**
   * Constructs a new buffer attribute.
   *
   * @param {(Array<number>|Uint32Array)} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n) {
    super(new Uint32Array(e), t, n);
  }
}
class ey extends Bn {
  /**
   * Constructs a new buffer attribute.
   *
   * @param {(Array<number>|Uint16Array)} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n) {
    super(new Uint16Array(e), t, n), this.isFloat16BufferAttribute = !0;
  }
  getX(e) {
    let t = bu(this.array[e * this.itemSize]);
    return this.normalized && (t = ti(t, this.array)), t;
  }
  setX(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize] = Si(t), this;
  }
  getY(e) {
    let t = bu(this.array[e * this.itemSize + 1]);
    return this.normalized && (t = ti(t, this.array)), t;
  }
  setY(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 1] = Si(t), this;
  }
  getZ(e) {
    let t = bu(this.array[e * this.itemSize + 2]);
    return this.normalized && (t = ti(t, this.array)), t;
  }
  setZ(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 2] = Si(t), this;
  }
  getW(e) {
    let t = bu(this.array[e * this.itemSize + 3]);
    return this.normalized && (t = ti(t, this.array)), t;
  }
  setW(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.array[e * this.itemSize + 3] = Si(t), this;
  }
  setXY(e, t, n) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array)), this.array[e + 0] = Si(t), this.array[e + 1] = Si(n), this;
  }
  setXYZ(e, t, n, r) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array)), this.array[e + 0] = Si(t), this.array[e + 1] = Si(n), this.array[e + 2] = Si(r), this;
  }
  setXYZW(e, t, n, r, s) {
    return e *= this.itemSize, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array), s = lt(s, this.array)), this.array[e + 0] = Si(t), this.array[e + 1] = Si(n), this.array[e + 2] = Si(r), this.array[e + 3] = Si(s), this;
  }
}
class an extends Bn {
  /**
   * Constructs a new buffer attribute.
   *
   * @param {(Array<number>|Float32Array)} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n) {
    super(new Float32Array(e), t, n);
  }
}
const aE = /* @__PURE__ */ new Ha(), Ul = /* @__PURE__ */ new P(), Jd = /* @__PURE__ */ new P();
class tu {
  /**
   * Constructs a new sphere.
   *
   * @param {Vector3} [center=(0,0,0)] - The center of the sphere
   * @param {number} [radius=-1] - The radius of the sphere.
   */
  constructor(e = new P(), t = -1) {
    this.isSphere = !0, this.center = e, this.radius = t;
  }
  /**
   * Sets the sphere's components by copying the given values.
   *
   * @param {Vector3} center - The center.
   * @param {number} radius - The radius.
   * @return {Sphere} A reference to this sphere.
   */
  set(e, t) {
    return this.center.copy(e), this.radius = t, this;
  }
  /**
   * Computes the minimum bounding sphere for list of points.
   * If the optional center point is given, it is used as the sphere's
   * center. Otherwise, the center of the axis-aligned bounding box
   * encompassing the points is calculated.
   *
   * @param {Array<Vector3>} points - A list of points in 3D space.
   * @param {Vector3} [optionalCenter] - The center of the sphere.
   * @return {Sphere} A reference to this sphere.
   */
  setFromPoints(e, t) {
    const n = this.center;
    t !== void 0 ? n.copy(t) : aE.setFromPoints(e).getCenter(n);
    let r = 0;
    for (let s = 0, a = e.length; s < a; s++)
      r = Math.max(r, n.distanceToSquared(e[s]));
    return this.radius = Math.sqrt(r), this;
  }
  /**
   * Copies the values of the given sphere to this instance.
   *
   * @param {Sphere} sphere - The sphere to copy.
   * @return {Sphere} A reference to this sphere.
   */
  copy(e) {
    return this.center.copy(e.center), this.radius = e.radius, this;
  }
  /**
   * Returns `true` if the sphere is empty (the radius set to a negative number).
   *
   * Spheres with a radius of `0` contain only their center point and are not
   * considered to be empty.
   *
   * @return {boolean} Whether this sphere is empty or not.
   */
  isEmpty() {
    return this.radius < 0;
  }
  /**
   * Makes this sphere empty which means in encloses a zero space in 3D.
   *
   * @return {Sphere} A reference to this sphere.
   */
  makeEmpty() {
    return this.center.set(0, 0, 0), this.radius = -1, this;
  }
  /**
   * Returns `true` if this sphere contains the given point inclusive of
   * the surface of the sphere.
   *
   * @param {Vector3} point - The point to check.
   * @return {boolean} Whether this sphere contains the given point or not.
   */
  containsPoint(e) {
    return e.distanceToSquared(this.center) <= this.radius * this.radius;
  }
  /**
   * Returns the closest distance from the boundary of the sphere to the
   * given point. If the sphere contains the point, the distance will
   * be negative.
   *
   * @param {Vector3} point - The point to compute the distance to.
   * @return {number} The distance to the point.
   */
  distanceToPoint(e) {
    return e.distanceTo(this.center) - this.radius;
  }
  /**
   * Returns `true` if this sphere intersects with the given one.
   *
   * @param {Sphere} sphere - The sphere to test.
   * @return {boolean} Whether this sphere intersects with the given one or not.
   */
  intersectsSphere(e) {
    const t = this.radius + e.radius;
    return e.center.distanceToSquared(this.center) <= t * t;
  }
  /**
   * Returns `true` if this sphere intersects with the given box.
   *
   * @param {Box3} box - The box to test.
   * @return {boolean} Whether this sphere intersects with the given box or not.
   */
  intersectsBox(e) {
    return e.intersectsSphere(this);
  }
  /**
   * Returns `true` if this sphere intersects with the given plane.
   *
   * @param {Plane} plane - The plane to test.
   * @return {boolean} Whether this sphere intersects with the given plane or not.
   */
  intersectsPlane(e) {
    return Math.abs(e.distanceToPoint(this.center)) <= this.radius;
  }
  /**
   * Clamps a point within the sphere. If the point is outside the sphere, it
   * will clamp it to the closest point on the edge of the sphere. Points
   * already inside the sphere will not be affected.
   *
   * @param {Vector3} point - The plane to clamp.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The clamped point.
   */
  clampPoint(e, t) {
    const n = this.center.distanceToSquared(e);
    return t.copy(e), n > this.radius * this.radius && (t.sub(this.center).normalize(), t.multiplyScalar(this.radius).add(this.center)), t;
  }
  /**
   * Returns a bounding box that encloses this sphere.
   *
   * @param {Box3} target - The target box that is used to store the method's result.
   * @return {Box3} The bounding box that encloses this sphere.
   */
  getBoundingBox(e) {
    return this.isEmpty() ? (e.makeEmpty(), e) : (e.set(this.center, this.center), e.expandByScalar(this.radius), e);
  }
  /**
   * Transforms this sphere with the given 4x4 transformation matrix.
   *
   * @param {Matrix4} matrix - The transformation matrix.
   * @return {Sphere} A reference to this sphere.
   */
  applyMatrix4(e) {
    return this.center.applyMatrix4(e), this.radius = this.radius * e.getMaxScaleOnAxis(), this;
  }
  /**
   * Translates the sphere's center by the given offset.
   *
   * @param {Vector3} offset - The offset.
   * @return {Sphere} A reference to this sphere.
   */
  translate(e) {
    return this.center.add(e), this;
  }
  /**
   * Expands the boundaries of this sphere to include the given point.
   *
   * @param {Vector3} point - The point to include.
   * @return {Sphere} A reference to this sphere.
   */
  expandByPoint(e) {
    if (this.isEmpty())
      return this.center.copy(e), this.radius = 0, this;
    Ul.subVectors(e, this.center);
    const t = Ul.lengthSq();
    if (t > this.radius * this.radius) {
      const n = Math.sqrt(t), r = (n - this.radius) * 0.5;
      this.center.addScaledVector(Ul, r / n), this.radius += r;
    }
    return this;
  }
  /**
   * Expands this sphere to enclose both the original sphere and the given sphere.
   *
   * @param {Sphere} sphere - The sphere to include.
   * @return {Sphere} A reference to this sphere.
   */
  union(e) {
    return e.isEmpty() ? this : this.isEmpty() ? (this.copy(e), this) : (this.center.equals(e.center) === !0 ? this.radius = Math.max(this.radius, e.radius) : (Jd.subVectors(e.center, this.center).setLength(e.radius), this.expandByPoint(Ul.copy(e.center).add(Jd)), this.expandByPoint(Ul.copy(e.center).sub(Jd))), this);
  }
  /**
   * Returns `true` if this sphere is equal with the given one.
   *
   * @param {Sphere} sphere - The sphere to test for equality.
   * @return {boolean} Whether this bounding sphere is equal with the given one.
   */
  equals(e) {
    return e.center.equals(this.center) && e.radius === this.radius;
  }
  /**
   * Returns a new sphere with copied values from this instance.
   *
   * @return {Sphere} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Returns a serialized structure of the bounding sphere.
   *
   * @return {Object} Serialized structure with fields representing the object state.
   */
  toJSON() {
    return {
      radius: this.radius,
      center: this.center.toArray()
    };
  }
  /**
   * Returns a serialized structure of the bounding sphere.
   *
   * @param {Object} json - The serialized json to set the sphere from.
   * @return {Sphere} A reference to this bounding sphere.
   */
  fromJSON(e) {
    return this.radius = e.radius, this.center.fromArray(e.center), this;
  }
}
let oE = 0;
const Pi = /* @__PURE__ */ new pt(), ef = /* @__PURE__ */ new gn(), ao = /* @__PURE__ */ new P(), Ti = /* @__PURE__ */ new Ha(), Bl = /* @__PURE__ */ new Ha(), Mn = /* @__PURE__ */ new P();
class Pn extends Fr {
  /**
   * Constructs a new geometry.
   */
  constructor() {
    super(), this.isBufferGeometry = !0, Object.defineProperty(this, "id", { value: oE++ }), this.uuid = ss(), this.name = "", this.type = "BufferGeometry", this.index = null, this.indirect = null, this.indirectOffset = 0, this.attributes = {}, this.morphAttributes = {}, this.morphTargetsRelative = !1, this.groups = [], this.boundingBox = null, this.boundingSphere = null, this.drawRange = { start: 0, count: 1 / 0 }, this.userData = {};
  }
  /**
   * Returns the index of this geometry.
   *
   * @return {?BufferAttribute} The index. Returns `null` if no index is defined.
   */
  getIndex() {
    return this.index;
  }
  /**
   * Sets the given index to this geometry.
   *
   * @param {Array<number>|BufferAttribute} index - The index to set.
   * @return {BufferGeometry} A reference to this instance.
   */
  setIndex(e) {
    return Array.isArray(e) ? this.index = new (RM(e) ? Ym : jm)(e, 1) : this.index = e, this;
  }
  /**
   * Sets the given indirect attribute to this geometry.
   *
   * @param {BufferAttribute} indirect - The attribute holding indirect draw calls.
   * @param {number|Array<number>} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset.
   * @return {BufferGeometry} A reference to this instance.
   */
  setIndirect(e, t = 0) {
    return this.indirect = e, this.indirectOffset = t, this;
  }
  /**
   * Returns the indirect attribute of this geometry.
   *
   * @return {?BufferAttribute} The indirect attribute. Returns `null` if no indirect attribute is defined.
   */
  getIndirect() {
    return this.indirect;
  }
  /**
   * Returns the buffer attribute for the given name.
   *
   * @param {string} name - The attribute name.
   * @return {BufferAttribute|InterleavedBufferAttribute|undefined} The buffer attribute.
   * Returns `undefined` if not attribute has been found.
   */
  getAttribute(e) {
    return this.attributes[e];
  }
  /**
   * Sets the given attribute for the given name.
   *
   * @param {string} name - The attribute name.
   * @param {BufferAttribute|InterleavedBufferAttribute} attribute - The attribute to set.
   * @return {BufferGeometry} A reference to this instance.
   */
  setAttribute(e, t) {
    return this.attributes[e] = t, this;
  }
  /**
   * Deletes the attribute for the given name.
   *
   * @param {string} name - The attribute name to delete.
   * @return {BufferGeometry} A reference to this instance.
   */
  deleteAttribute(e) {
    return delete this.attributes[e], this;
  }
  /**
   * Returns `true` if this geometry has an attribute for the given name.
   *
   * @param {string} name - The attribute name.
   * @return {boolean} Whether this geometry has an attribute for the given name or not.
   */
  hasAttribute(e) {
    return this.attributes[e] !== void 0;
  }
  /**
   * Adds a group to this geometry.
   *
   * @param {number} start - The first element in this draw call. That is the first
   * vertex for non-indexed geometry, otherwise the first triangle index.
   * @param {number} count - Specifies how many vertices (or indices) are part of this group.
   * @param {number} [materialIndex=0] - The material array index to use.
   */
  addGroup(e, t, n = 0) {
    this.groups.push({
      start: e,
      count: t,
      materialIndex: n
    });
  }
  /**
   * Clears all groups.
   */
  clearGroups() {
    this.groups = [];
  }
  /**
   * Sets the draw range for this geometry.
   *
   * @param {number} start - The first vertex for non-indexed geometry, otherwise the first triangle index.
   * @param {number} count - For non-indexed BufferGeometry, `count` is the number of vertices to render.
   * For indexed BufferGeometry, `count` is the number of indices to render.
   */
  setDrawRange(e, t) {
    this.drawRange.start = e, this.drawRange.count = t;
  }
  /**
   * Applies the given 4x4 transformation matrix to the geometry.
   *
   * @param {Matrix4} matrix - The matrix to apply.
   * @return {BufferGeometry} A reference to this instance.
   */
  applyMatrix4(e) {
    const t = this.attributes.position;
    t !== void 0 && (t.applyMatrix4(e), t.needsUpdate = !0);
    const n = this.attributes.normal;
    if (n !== void 0) {
      const s = new nt().getNormalMatrix(e);
      n.applyNormalMatrix(s), n.needsUpdate = !0;
    }
    const r = this.attributes.tangent;
    return r !== void 0 && (r.transformDirection(e), r.needsUpdate = !0), this.boundingBox !== null && this.computeBoundingBox(), this.boundingSphere !== null && this.computeBoundingSphere(), this;
  }
  /**
   * Applies the rotation represented by the Quaternion to the geometry.
   *
   * @param {Quaternion} q - The Quaternion to apply.
   * @return {BufferGeometry} A reference to this instance.
   */
  applyQuaternion(e) {
    return Pi.makeRotationFromQuaternion(e), this.applyMatrix4(Pi), this;
  }
  /**
   * Rotates the geometry about the X axis. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#rotation} for typical
   * real-time mesh rotation.
   *
   * @param {number} angle - The angle in radians.
   * @return {BufferGeometry} A reference to this instance.
   */
  rotateX(e) {
    return Pi.makeRotationX(e), this.applyMatrix4(Pi), this;
  }
  /**
   * Rotates the geometry about the Y axis. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#rotation} for typical
   * real-time mesh rotation.
   *
   * @param {number} angle - The angle in radians.
   * @return {BufferGeometry} A reference to this instance.
   */
  rotateY(e) {
    return Pi.makeRotationY(e), this.applyMatrix4(Pi), this;
  }
  /**
   * Rotates the geometry about the Z axis. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#rotation} for typical
   * real-time mesh rotation.
   *
   * @param {number} angle - The angle in radians.
   * @return {BufferGeometry} A reference to this instance.
   */
  rotateZ(e) {
    return Pi.makeRotationZ(e), this.applyMatrix4(Pi), this;
  }
  /**
   * Translates the geometry. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#position} for typical
   * real-time mesh rotation.
   *
   * @param {number} x - The x offset.
   * @param {number} y - The y offset.
   * @param {number} z - The z offset.
   * @return {BufferGeometry} A reference to this instance.
   */
  translate(e, t, n) {
    return Pi.makeTranslation(e, t, n), this.applyMatrix4(Pi), this;
  }
  /**
   * Scales the geometry. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#scale} for typical
   * real-time mesh rotation.
   *
   * @param {number} x - The x scale.
   * @param {number} y - The y scale.
   * @param {number} z - The z scale.
   * @return {BufferGeometry} A reference to this instance.
   */
  scale(e, t, n) {
    return Pi.makeScale(e, t, n), this.applyMatrix4(Pi), this;
  }
  /**
   * Rotates the geometry to face a point in 3D space. This is typically done as a one time
   * operation, and not during a loop. Use {@link Object3D#lookAt} for typical
   * real-time mesh rotation.
   *
   * @param {Vector3} vector - The target point.
   * @return {BufferGeometry} A reference to this instance.
   */
  lookAt(e) {
    return ef.lookAt(e), ef.updateMatrix(), this.applyMatrix4(ef.matrix), this;
  }
  /**
   * Center the geometry based on its bounding box.
   *
   * @return {BufferGeometry} A reference to this instance.
   */
  center() {
    return this.computeBoundingBox(), this.boundingBox.getCenter(ao).negate(), this.translate(ao.x, ao.y, ao.z), this;
  }
  /**
   * Defines a geometry by creating a `position` attribute based on the given array of points. The array
   * can hold 2D or 3D vectors. When using two-dimensional data, the `z` coordinate for all vertices is
   * set to `0`.
   *
   * If the method is used with an existing `position` attribute, the vertex data are overwritten with the
   * data from the array. The length of the array must match the vertex count.
   *
   * @param {Array<Vector2>|Array<Vector3>} points - The points.
   * @return {BufferGeometry} A reference to this instance.
   */
  setFromPoints(e) {
    const t = this.getAttribute("position");
    if (t === void 0) {
      const n = [];
      for (let r = 0, s = e.length; r < s; r++) {
        const a = e[r];
        n.push(a.x, a.y, a.z || 0);
      }
      this.setAttribute("position", new an(n, 3));
    } else {
      const n = Math.min(e.length, t.count);
      for (let r = 0; r < n; r++) {
        const s = e[r];
        t.setXYZ(r, s.x, s.y, s.z || 0);
      }
      e.length > t.count && oe("BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."), t.needsUpdate = !0;
    }
    return this;
  }
  /**
   * Computes the bounding box of the geometry, and updates the `boundingBox` member.
   * The bounding box is not computed by the engine; it must be computed by your app.
   * You may need to recompute the bounding box if the geometry vertices are modified.
   */
  computeBoundingBox() {
    this.boundingBox === null && (this.boundingBox = new Ha());
    const e = this.attributes.position, t = this.morphAttributes.position;
    if (e && e.isGLBufferAttribute) {
      le("BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.", this), this.boundingBox.set(
        new P(-1 / 0, -1 / 0, -1 / 0),
        new P(1 / 0, 1 / 0, 1 / 0)
      );
      return;
    }
    if (e !== void 0) {
      if (this.boundingBox.setFromBufferAttribute(e), t)
        for (let n = 0, r = t.length; n < r; n++) {
          const s = t[n];
          Ti.setFromBufferAttribute(s), this.morphTargetsRelative ? (Mn.addVectors(this.boundingBox.min, Ti.min), this.boundingBox.expandByPoint(Mn), Mn.addVectors(this.boundingBox.max, Ti.max), this.boundingBox.expandByPoint(Mn)) : (this.boundingBox.expandByPoint(Ti.min), this.boundingBox.expandByPoint(Ti.max));
        }
    } else
      this.boundingBox.makeEmpty();
    (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) && le('BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this);
  }
  /**
   * Computes the bounding sphere of the geometry, and updates the `boundingSphere` member.
   * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling.
   * You may need to recompute the bounding sphere if the geometry vertices are modified.
   */
  computeBoundingSphere() {
    this.boundingSphere === null && (this.boundingSphere = new tu());
    const e = this.attributes.position, t = this.morphAttributes.position;
    if (e && e.isGLBufferAttribute) {
      le("BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.", this), this.boundingSphere.set(new P(), 1 / 0);
      return;
    }
    if (e) {
      const n = this.boundingSphere.center;
      if (Ti.setFromBufferAttribute(e), t)
        for (let s = 0, a = t.length; s < a; s++) {
          const o = t[s];
          Bl.setFromBufferAttribute(o), this.morphTargetsRelative ? (Mn.addVectors(Ti.min, Bl.min), Ti.expandByPoint(Mn), Mn.addVectors(Ti.max, Bl.max), Ti.expandByPoint(Mn)) : (Ti.expandByPoint(Bl.min), Ti.expandByPoint(Bl.max));
        }
      Ti.getCenter(n);
      let r = 0;
      for (let s = 0, a = e.count; s < a; s++)
        Mn.fromBufferAttribute(e, s), r = Math.max(r, n.distanceToSquared(Mn));
      if (t)
        for (let s = 0, a = t.length; s < a; s++) {
          const o = t[s], l = this.morphTargetsRelative;
          for (let c = 0, u = o.count; c < u; c++)
            Mn.fromBufferAttribute(o, c), l && (ao.fromBufferAttribute(e, c), Mn.add(ao)), r = Math.max(r, n.distanceToSquared(Mn));
        }
      this.boundingSphere.radius = Math.sqrt(r), isNaN(this.boundingSphere.radius) && le('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this);
    }
  }
  /**
   * Calculates and adds a tangent attribute to this geometry.
   *
   * The computation is only supported for indexed geometries and if position, normal, and uv attributes
   * are defined. When using a tangent space normal map, prefer the MikkTSpace algorithm provided by
   * {@link BufferGeometryUtils#computeMikkTSpaceTangents} instead.
   */
  computeTangents() {
    const e = this.index, t = this.attributes;
    if (e === null || t.position === void 0 || t.normal === void 0 || t.uv === void 0) {
      le("BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)");
      return;
    }
    const n = t.position, r = t.normal, s = t.uv;
    this.hasAttribute("tangent") === !1 && this.setAttribute("tangent", new Bn(new Float32Array(4 * n.count), 4));
    const a = this.getAttribute("tangent"), o = [], l = [];
    for (let v = 0; v < n.count; v++)
      o[v] = new P(), l[v] = new P();
    const c = new P(), u = new P(), h = new P(), d = new de(), f = new de(), p = new de(), _ = new P(), g = new P();
    function m(v, M, F) {
      c.fromBufferAttribute(n, v), u.fromBufferAttribute(n, M), h.fromBufferAttribute(n, F), d.fromBufferAttribute(s, v), f.fromBufferAttribute(s, M), p.fromBufferAttribute(s, F), u.sub(c), h.sub(c), f.sub(d), p.sub(d);
      const R = 1 / (f.x * p.y - p.x * f.y);
      isFinite(R) && (_.copy(u).multiplyScalar(p.y).addScaledVector(h, -f.y).multiplyScalar(R), g.copy(h).multiplyScalar(f.x).addScaledVector(u, -p.x).multiplyScalar(R), o[v].add(_), o[M].add(_), o[F].add(_), l[v].add(g), l[M].add(g), l[F].add(g));
    }
    let x = this.groups;
    x.length === 0 && (x = [{
      start: 0,
      count: e.count
    }]);
    for (let v = 0, M = x.length; v < M; ++v) {
      const F = x[v], R = F.start, I = F.count;
      for (let B = R, N = R + I; B < N; B += 3)
        m(
          e.getX(B + 0),
          e.getX(B + 1),
          e.getX(B + 2)
        );
    }
    const y = new P(), b = new P(), T = new P(), S = new P();
    function E(v) {
      T.fromBufferAttribute(r, v), S.copy(T);
      const M = o[v];
      y.copy(M), y.sub(T.multiplyScalar(T.dot(M))).normalize(), b.crossVectors(S, M);
      const R = b.dot(l[v]) < 0 ? -1 : 1;
      a.setXYZW(v, y.x, y.y, y.z, R);
    }
    for (let v = 0, M = x.length; v < M; ++v) {
      const F = x[v], R = F.start, I = F.count;
      for (let B = R, N = R + I; B < N; B += 3)
        E(e.getX(B + 0)), E(e.getX(B + 1)), E(e.getX(B + 2));
    }
  }
  /**
   * Computes vertex normals for the given vertex data. For indexed geometries, the method sets
   * each vertex normal to be the average of the face normals of the faces that share that vertex.
   * For non-indexed geometries, vertices are not shared, and the method sets each vertex normal
   * to be the same as the face normal.
   */
  computeVertexNormals() {
    const e = this.index, t = this.getAttribute("position");
    if (t !== void 0) {
      let n = this.getAttribute("normal");
      if (n === void 0)
        n = new Bn(new Float32Array(t.count * 3), 3), this.setAttribute("normal", n);
      else
        for (let d = 0, f = n.count; d < f; d++)
          n.setXYZ(d, 0, 0, 0);
      const r = new P(), s = new P(), a = new P(), o = new P(), l = new P(), c = new P(), u = new P(), h = new P();
      if (e)
        for (let d = 0, f = e.count; d < f; d += 3) {
          const p = e.getX(d + 0), _ = e.getX(d + 1), g = e.getX(d + 2);
          r.fromBufferAttribute(t, p), s.fromBufferAttribute(t, _), a.fromBufferAttribute(t, g), u.subVectors(a, s), h.subVectors(r, s), u.cross(h), o.fromBufferAttribute(n, p), l.fromBufferAttribute(n, _), c.fromBufferAttribute(n, g), o.add(u), l.add(u), c.add(u), n.setXYZ(p, o.x, o.y, o.z), n.setXYZ(_, l.x, l.y, l.z), n.setXYZ(g, c.x, c.y, c.z);
        }
      else
        for (let d = 0, f = t.count; d < f; d += 3)
          r.fromBufferAttribute(t, d + 0), s.fromBufferAttribute(t, d + 1), a.fromBufferAttribute(t, d + 2), u.subVectors(a, s), h.subVectors(r, s), u.cross(h), n.setXYZ(d + 0, u.x, u.y, u.z), n.setXYZ(d + 1, u.x, u.y, u.z), n.setXYZ(d + 2, u.x, u.y, u.z);
      this.normalizeNormals(), n.needsUpdate = !0;
    }
  }
  /**
   * Ensures every normal vector in a geometry will have a magnitude of `1`. This will
   * correct lighting on the geometry surfaces.
   */
  normalizeNormals() {
    const e = this.attributes.normal;
    for (let t = 0, n = e.count; t < n; t++)
      Mn.fromBufferAttribute(e, t), Mn.normalize(), e.setXYZ(t, Mn.x, Mn.y, Mn.z);
  }
  /**
   * Return a new non-index version of this indexed geometry. If the geometry
   * is already non-indexed, the method is a NOOP.
   *
   * @return {BufferGeometry} The non-indexed version of this indexed geometry.
   */
  toNonIndexed() {
    function e(o, l) {
      const c = o.array, u = o.itemSize, h = o.normalized, d = new c.constructor(l.length * u);
      let f = 0, p = 0;
      for (let _ = 0, g = l.length; _ < g; _++) {
        o.isInterleavedBufferAttribute ? f = l[_] * o.data.stride + o.offset : f = l[_] * u;
        for (let m = 0; m < u; m++)
          d[p++] = c[f++];
      }
      return new Bn(d, u, h);
    }
    if (this.index === null)
      return oe("BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed."), this;
    const t = new Pn(), n = this.index.array, r = this.attributes;
    for (const o in r) {
      const l = r[o], c = e(l, n);
      t.setAttribute(o, c);
    }
    const s = this.morphAttributes;
    for (const o in s) {
      const l = [], c = s[o];
      for (let u = 0, h = c.length; u < h; u++) {
        const d = c[u], f = e(d, n);
        l.push(f);
      }
      t.morphAttributes[o] = l;
    }
    t.morphTargetsRelative = this.morphTargetsRelative;
    const a = this.groups;
    for (let o = 0, l = a.length; o < l; o++) {
      const c = a[o];
      t.addGroup(c.start, c.count, c.materialIndex);
    }
    return t;
  }
  /**
   * Serializes the geometry into JSON.
   *
   * @return {Object} A JSON object representing the serialized geometry.
   */
  toJSON() {
    const e = {
      metadata: {
        version: 4.7,
        type: "BufferGeometry",
        generator: "BufferGeometry.toJSON"
      }
    };
    if (e.uuid = this.uuid, e.type = this.type, this.name !== "" && (e.name = this.name), Object.keys(this.userData).length > 0 && (e.userData = this.userData), this.parameters !== void 0) {
      const l = this.parameters;
      for (const c in l)
        l[c] !== void 0 && (e[c] = l[c]);
      return e;
    }
    e.data = { attributes: {} };
    const t = this.index;
    t !== null && (e.data.index = {
      type: t.array.constructor.name,
      array: Array.prototype.slice.call(t.array)
    });
    const n = this.attributes;
    for (const l in n) {
      const c = n[l];
      e.data.attributes[l] = c.toJSON(e.data);
    }
    const r = {};
    let s = !1;
    for (const l in this.morphAttributes) {
      const c = this.morphAttributes[l], u = [];
      for (let h = 0, d = c.length; h < d; h++) {
        const f = c[h];
        u.push(f.toJSON(e.data));
      }
      u.length > 0 && (r[l] = u, s = !0);
    }
    s && (e.data.morphAttributes = r, e.data.morphTargetsRelative = this.morphTargetsRelative);
    const a = this.groups;
    a.length > 0 && (e.data.groups = JSON.parse(JSON.stringify(a)));
    const o = this.boundingSphere;
    return o !== null && (e.data.boundingSphere = o.toJSON()), e;
  }
  /**
   * Returns a new geometry with copied values from this instance.
   *
   * @return {BufferGeometry} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given geometry to this instance.
   *
   * @param {BufferGeometry} source - The geometry to copy.
   * @return {BufferGeometry} A reference to this instance.
   */
  copy(e) {
    this.index = null, this.attributes = {}, this.morphAttributes = {}, this.groups = [], this.boundingBox = null, this.boundingSphere = null;
    const t = {};
    this.name = e.name;
    const n = e.index;
    n !== null && this.setIndex(n.clone());
    const r = e.attributes;
    for (const c in r) {
      const u = r[c];
      this.setAttribute(c, u.clone(t));
    }
    const s = e.morphAttributes;
    for (const c in s) {
      const u = [], h = s[c];
      for (let d = 0, f = h.length; d < f; d++)
        u.push(h[d].clone(t));
      this.morphAttributes[c] = u;
    }
    this.morphTargetsRelative = e.morphTargetsRelative;
    const a = e.groups;
    for (let c = 0, u = a.length; c < u; c++) {
      const h = a[c];
      this.addGroup(h.start, h.count, h.materialIndex);
    }
    const o = e.boundingBox;
    o !== null && (this.boundingBox = o.clone());
    const l = e.boundingSphere;
    return l !== null && (this.boundingSphere = l.clone()), this.drawRange.start = e.drawRange.start, this.drawRange.count = e.drawRange.count, this.userData = e.userData, this;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   *
   * @fires BufferGeometry#dispose
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
}
class ty {
  /**
   * Constructs a new interleaved buffer.
   *
   * @param {TypedArray} array - A typed array with a shared buffer storing attribute data.
   * @param {number} stride - The number of typed-array elements per vertex.
   */
  constructor(e, t) {
    this.isInterleavedBuffer = !0, this.array = e, this.stride = t, this.count = e !== void 0 ? e.length / t : 0, this.usage = cl, this.updateRanges = [], this.version = 0, this.uuid = ss();
  }
  /**
   * A callback function that is executed after the renderer has transferred the attribute array
   * data to the GPU.
   */
  onUploadCallback() {
  }
  /**
   * Flag to indicate that this attribute has changed and should be re-sent to
   * the GPU. Set this to `true` when you modify the value of the array.
   *
   * @type {number}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && this.version++;
  }
  /**
   * Sets the usage of this interleaved buffer.
   *
   * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set.
   * @return {InterleavedBuffer} A reference to this interleaved buffer.
   */
  setUsage(e) {
    return this.usage = e, this;
  }
  /**
   * Adds a range of data in the data array to be updated on the GPU.
   *
   * @param {number} start - Position at which to start update.
   * @param {number} count - The number of components to update.
   */
  addUpdateRange(e, t) {
    this.updateRanges.push({ start: e, count: t });
  }
  /**
   * Clears the update ranges.
   */
  clearUpdateRanges() {
    this.updateRanges.length = 0;
  }
  /**
   * Copies the values of the given interleaved buffer to this instance.
   *
   * @param {InterleavedBuffer} source - The interleaved buffer to copy.
   * @return {InterleavedBuffer} A reference to this instance.
   */
  copy(e) {
    return this.array = new e.array.constructor(e.array), this.count = e.count, this.stride = e.stride, this.usage = e.usage, this;
  }
  /**
   * Copies a vector from the given interleaved buffer to this one. The start
   * and destination position in the attribute buffers are represented by the
   * given indices.
   *
   * @param {number} index1 - The destination index into this interleaved buffer.
   * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from.
   * @param {number} index2 - The source index into the given interleaved buffer.
   * @return {InterleavedBuffer} A reference to this instance.
   */
  copyAt(e, t, n) {
    e *= this.stride, n *= t.stride;
    for (let r = 0, s = this.stride; r < s; r++)
      this.array[e + r] = t.array[n + r];
    return this;
  }
  /**
   * Sets the given array data in the interleaved buffer.
   *
   * @param {(TypedArray|Array)} value - The array data to set.
   * @param {number} [offset=0] - The offset in this interleaved buffer's array.
   * @return {InterleavedBuffer} A reference to this instance.
   */
  set(e, t = 0) {
    return this.array.set(e, t), this;
  }
  /**
   * Returns a new interleaved buffer with copied values from this instance.
   *
   * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures.
   * @return {InterleavedBuffer} A clone of this instance.
   */
  clone(e) {
    e.arrayBuffers === void 0 && (e.arrayBuffers = {}), this.array.buffer._uuid === void 0 && (this.array.buffer._uuid = ss()), e.arrayBuffers[this.array.buffer._uuid] === void 0 && (e.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer);
    const t = new this.array.constructor(e.arrayBuffers[this.array.buffer._uuid]), n = new this.constructor(t, this.stride);
    return n.setUsage(this.usage), n;
  }
  /**
   * Sets the given callback function that is executed after the Renderer has transferred
   * the array data to the GPU. Can be used to perform clean-up operations after
   * the upload when data are not needed anymore on the CPU side.
   *
   * @param {Function} callback - The `onUpload()` callback.
   * @return {InterleavedBuffer} A reference to this instance.
   */
  onUpload(e) {
    return this.onUploadCallback = e, this;
  }
  /**
   * Serializes the interleaved buffer into JSON.
   *
   * @param {Object} [data] - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized interleaved buffer.
   */
  toJSON(e) {
    return e.arrayBuffers === void 0 && (e.arrayBuffers = {}), this.array.buffer._uuid === void 0 && (this.array.buffer._uuid = ss()), e.arrayBuffers[this.array.buffer._uuid] === void 0 && (e.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer))), {
      uuid: this.uuid,
      buffer: this.array.buffer._uuid,
      type: this.array.constructor.name,
      stride: this.stride
    };
  }
}
const Kn = /* @__PURE__ */ new P();
class Km {
  /**
   * Constructs a new interleaved buffer attribute.
   *
   * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data.
   * @param {number} itemSize - The item size.
   * @param {number} offset - The attribute offset into the buffer.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   */
  constructor(e, t, n, r = !1) {
    this.isInterleavedBufferAttribute = !0, this.name = "", this.data = e, this.itemSize = t, this.offset = n, this.normalized = r;
  }
  /**
   * The item count of this buffer attribute.
   *
   * @type {number}
   * @readonly
   */
  get count() {
    return this.data.count;
  }
  /**
   * The array holding the interleaved buffer attribute data.
   *
   * @type {TypedArray}
   */
  get array() {
    return this.data.array;
  }
  /**
   * Flag to indicate that this attribute has changed and should be re-sent to
   * the GPU. Set this to `true` when you modify the value of the array.
   *
   * @type {number}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    this.data.needsUpdate = e;
  }
  /**
   * Applies the given 4x4 matrix to the given attribute. Only works with
   * item size `3`.
   *
   * @param {Matrix4} m - The matrix to apply.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  applyMatrix4(e) {
    for (let t = 0, n = this.data.count; t < n; t++)
      Kn.fromBufferAttribute(this, t), Kn.applyMatrix4(e), this.setXYZ(t, Kn.x, Kn.y, Kn.z);
    return this;
  }
  /**
   * Applies the given 3x3 normal matrix to the given attribute. Only works with
   * item size `3`.
   *
   * @param {Matrix3} m - The normal matrix to apply.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  applyNormalMatrix(e) {
    for (let t = 0, n = this.count; t < n; t++)
      Kn.fromBufferAttribute(this, t), Kn.applyNormalMatrix(e), this.setXYZ(t, Kn.x, Kn.y, Kn.z);
    return this;
  }
  /**
   * Applies the given 4x4 matrix to the given attribute. Only works with
   * item size `3` and with direction vectors.
   *
   * @param {Matrix4} m - The matrix to apply.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  transformDirection(e) {
    for (let t = 0, n = this.count; t < n; t++)
      Kn.fromBufferAttribute(this, t), Kn.transformDirection(e), this.setXYZ(t, Kn.x, Kn.y, Kn.z);
    return this;
  }
  /**
   * Returns the given component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} component - The component index.
   * @return {number} The returned value.
   */
  getComponent(e, t) {
    let n = this.array[e * this.data.stride + this.offset + t];
    return this.normalized && (n = ti(n, this.array)), n;
  }
  /**
   * Sets the given value to the given component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} component - The component index.
   * @param {number} value - The value to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setComponent(e, t, n) {
    return this.normalized && (n = lt(n, this.array)), this.data.array[e * this.data.stride + this.offset + t] = n, this;
  }
  /**
   * Sets the x component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setX(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.data.array[e * this.data.stride + this.offset] = t, this;
  }
  /**
   * Sets the y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} y - The value to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setY(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.data.array[e * this.data.stride + this.offset + 1] = t, this;
  }
  /**
   * Sets the z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} z - The value to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setZ(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.data.array[e * this.data.stride + this.offset + 2] = t, this;
  }
  /**
   * Sets the w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} w - The value to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setW(e, t) {
    return this.normalized && (t = lt(t, this.array)), this.data.array[e * this.data.stride + this.offset + 3] = t, this;
  }
  /**
   * Returns the x component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The x component.
   */
  getX(e) {
    let t = this.data.array[e * this.data.stride + this.offset];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Returns the y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The y component.
   */
  getY(e) {
    let t = this.data.array[e * this.data.stride + this.offset + 1];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Returns the z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The z component.
   */
  getZ(e) {
    let t = this.data.array[e * this.data.stride + this.offset + 2];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Returns the w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @return {number} The w component.
   */
  getW(e) {
    let t = this.data.array[e * this.data.stride + this.offset + 3];
    return this.normalized && (t = ti(t, this.array)), t;
  }
  /**
   * Sets the x and y component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setXY(e, t, n) {
    return e = e * this.data.stride + this.offset, this.normalized && (t = lt(t, this.array), n = lt(n, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this;
  }
  /**
   * Sets the x, y and z component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @param {number} z - The value for the z component to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setXYZ(e, t, n, r) {
    return e = e * this.data.stride + this.offset, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this.data.array[e + 2] = r, this;
  }
  /**
   * Sets the x, y, z and w component of the vector at the given index.
   *
   * @param {number} index - The index into the buffer attribute.
   * @param {number} x - The value for the x component to set.
   * @param {number} y - The value for the y component to set.
   * @param {number} z - The value for the z component to set.
   * @param {number} w - The value for the w component to set.
   * @return {InterleavedBufferAttribute} A reference to this instance.
   */
  setXYZW(e, t, n, r, s) {
    return e = e * this.data.stride + this.offset, this.normalized && (t = lt(t, this.array), n = lt(n, this.array), r = lt(r, this.array), s = lt(s, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this.data.array[e + 2] = r, this.data.array[e + 3] = s, this;
  }
  /**
   * Returns a new buffer attribute with copied values from this instance.
   *
   * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data.
   *
   * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property.
   * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance.
   */
  clone(e) {
    if (e === void 0) {
      Hc("InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.");
      const t = [];
      for (let n = 0; n < this.count; n++) {
        const r = n * this.data.stride + this.offset;
        for (let s = 0; s < this.itemSize; s++)
          t.push(this.data.array[r + s]);
      }
      return new Bn(new this.array.constructor(t), this.itemSize, this.normalized);
    } else
      return e.interleavedBuffers === void 0 && (e.interleavedBuffers = {}), e.interleavedBuffers[this.data.uuid] === void 0 && (e.interleavedBuffers[this.data.uuid] = this.data.clone(e)), new Km(e.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized);
  }
  /**
   * Serializes the buffer attribute into JSON.
   *
   * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data.
   *
   * @param {Object} [data] - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized buffer attribute.
   */
  toJSON(e) {
    if (e === void 0) {
      Hc("InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.");
      const t = [];
      for (let n = 0; n < this.count; n++) {
        const r = n * this.data.stride + this.offset;
        for (let s = 0; s < this.itemSize; s++)
          t.push(this.data.array[r + s]);
      }
      return {
        itemSize: this.itemSize,
        type: this.array.constructor.name,
        array: t,
        normalized: this.normalized
      };
    } else
      return e.interleavedBuffers === void 0 && (e.interleavedBuffers = {}), e.interleavedBuffers[this.data.uuid] === void 0 && (e.interleavedBuffers[this.data.uuid] = this.data.toJSON(e)), {
        isInterleavedBufferAttribute: !0,
        itemSize: this.itemSize,
        data: this.data.uuid,
        offset: this.offset,
        normalized: this.normalized
      };
  }
}
let lE = 0;
class jn extends Fr {
  /**
   * Constructs a new material.
   */
  constructor() {
    super(), this.isMaterial = !0, Object.defineProperty(this, "id", { value: lE++ }), this.uuid = ss(), this.name = "", this.type = "Material", this.blending = ei, this.side = ai, this.vertexColors = !1, this.opacity = 1, this.transparent = !1, this.alphaHash = !1, this.blendSrc = Rc, this.blendDst = Cc, this.blendEquation = Xn, this.blendSrcAlpha = null, this.blendDstAlpha = null, this.blendEquationAlpha = null, this.blendColor = new He(0, 0, 0), this.blendAlpha = 0, this.depthFunc = Hs, this.depthTest = !0, this.depthWrite = !0, this.stencilWriteMask = 255, this.stencilFunc = Ap, this.stencilRef = 0, this.stencilFuncMask = 255, this.stencilFail = ha, this.stencilZFail = ha, this.stencilZPass = ha, this.stencilWrite = !1, this.clippingPlanes = null, this.clipIntersection = !1, this.clipShadows = !1, this.shadowSide = null, this.colorWrite = !0, this.precision = null, this.polygonOffset = !1, this.polygonOffsetFactor = 0, this.polygonOffsetUnits = 0, this.dithering = !1, this.alphaToCoverage = !1, this.premultipliedAlpha = !1, this.forceSinglePass = !1, this.allowOverride = !0, this.visible = !0, this.toneMapped = !0, this.userData = {}, this.version = 0, this._alphaTest = 0;
  }
  /**
   * Sets the alpha value to be used when running an alpha test. The material
   * will not be rendered if the opacity is lower than this value.
   *
   * @type {number}
   * @readonly
   * @default 0
   */
  get alphaTest() {
    return this._alphaTest;
  }
  set alphaTest(e) {
    this._alphaTest > 0 != e > 0 && this.version++, this._alphaTest = e;
  }
  /**
   * An optional callback that is executed immediately before the material is used to render a 3D object.
   *
   * This method can only be used when rendering with {@link WebGLRenderer}.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {Scene} scene - The scene.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Object3D} object - The 3D object.
   * @param {Object} group - The geometry group data.
   */
  onBeforeRender() {
  }
  /**
   * An optional callback that is executed immediately before the shader
   * program is compiled. This function is called with the shader source code
   * as a parameter. Useful for the modification of built-in materials.
   *
   * This method can only be used when rendering with {@link WebGLRenderer}. The
   * recommended approach when customizing materials is to use `WebGPURenderer` with the new
   * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language).
   *
   * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source.
   * @param {WebGLRenderer} renderer - A reference to the renderer.
   */
  onBeforeCompile() {
  }
  /**
   * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify
   * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached
   * shader or recompile the shader for this material as needed.
   *
   * This method can only be used when rendering with {@link WebGLRenderer}.
   *
   * @return {string} The custom program cache key.
   */
  customProgramCacheKey() {
    return this.onBeforeCompile.toString();
  }
  /**
   * This method can be used to set default values from parameter objects.
   * It is a generic implementation so it can be used with different types
   * of materials.
   *
   * @param {Object} [values] - The material values to set.
   */
  setValues(e) {
    if (e !== void 0)
      for (const t in e) {
        const n = e[t];
        if (n === void 0) {
          oe(`Material: parameter '${t}' has value of undefined.`);
          continue;
        }
        const r = this[t];
        if (r === void 0) {
          oe(`Material: '${t}' is not a property of THREE.${this.type}.`);
          continue;
        }
        r && r.isColor ? r.set(n) : r && r.isVector3 && n && n.isVector3 ? r.copy(n) : this[t] = n;
      }
  }
  /**
   * Serializes the material into JSON.
   *
   * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
   * @return {Object} A JSON object representing the serialized material.
   * @see {@link ObjectLoader#parse}
   */
  toJSON(e) {
    const t = e === void 0 || typeof e == "string";
    t && (e = {
      textures: {},
      images: {}
    });
    const n = {
      metadata: {
        version: 4.7,
        type: "Material",
        generator: "Material.toJSON"
      }
    };
    n.uuid = this.uuid, n.type = this.type, this.name !== "" && (n.name = this.name), this.color && this.color.isColor && (n.color = this.color.getHex()), this.roughness !== void 0 && (n.roughness = this.roughness), this.metalness !== void 0 && (n.metalness = this.metalness), this.sheen !== void 0 && (n.sheen = this.sheen), this.sheenColor && this.sheenColor.isColor && (n.sheenColor = this.sheenColor.getHex()), this.sheenRoughness !== void 0 && (n.sheenRoughness = this.sheenRoughness), this.emissive && this.emissive.isColor && (n.emissive = this.emissive.getHex()), this.emissiveIntensity !== void 0 && this.emissiveIntensity !== 1 && (n.emissiveIntensity = this.emissiveIntensity), this.specular && this.specular.isColor && (n.specular = this.specular.getHex()), this.specularIntensity !== void 0 && (n.specularIntensity = this.specularIntensity), this.specularColor && this.specularColor.isColor && (n.specularColor = this.specularColor.getHex()), this.shininess !== void 0 && (n.shininess = this.shininess), this.clearcoat !== void 0 && (n.clearcoat = this.clearcoat), this.clearcoatRoughness !== void 0 && (n.clearcoatRoughness = this.clearcoatRoughness), this.clearcoatMap && this.clearcoatMap.isTexture && (n.clearcoatMap = this.clearcoatMap.toJSON(e).uuid), this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture && (n.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(e).uuid), this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture && (n.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(e).uuid, n.clearcoatNormalScale = this.clearcoatNormalScale.toArray()), this.sheenColorMap && this.sheenColorMap.isTexture && (n.sheenColorMap = this.sheenColorMap.toJSON(e).uuid), this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture && (n.sheenRoughnessMap = this.sheenRoughnessMap.toJSON(e).uuid), this.dispersion !== void 0 && (n.dispersion = this.dispersion), this.iridescence !== void 0 && (n.iridescence = this.iridescence), this.iridescenceIOR !== void 0 && (n.iridescenceIOR = this.iridescenceIOR), this.iridescenceThicknessRange !== void 0 && (n.iridescenceThicknessRange = this.iridescenceThicknessRange), this.iridescenceMap && this.iridescenceMap.isTexture && (n.iridescenceMap = this.iridescenceMap.toJSON(e).uuid), this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture && (n.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(e).uuid), this.anisotropy !== void 0 && (n.anisotropy = this.anisotropy), this.anisotropyRotation !== void 0 && (n.anisotropyRotation = this.anisotropyRotation), this.anisotropyMap && this.anisotropyMap.isTexture && (n.anisotropyMap = this.anisotropyMap.toJSON(e).uuid), this.map && this.map.isTexture && (n.map = this.map.toJSON(e).uuid), this.matcap && this.matcap.isTexture && (n.matcap = this.matcap.toJSON(e).uuid), this.alphaMap && this.alphaMap.isTexture && (n.alphaMap = this.alphaMap.toJSON(e).uuid), this.lightMap && this.lightMap.isTexture && (n.lightMap = this.lightMap.toJSON(e).uuid, n.lightMapIntensity = this.lightMapIntensity), this.aoMap && this.aoMap.isTexture && (n.aoMap = this.aoMap.toJSON(e).uuid, n.aoMapIntensity = this.aoMapIntensity), this.bumpMap && this.bumpMap.isTexture && (n.bumpMap = this.bumpMap.toJSON(e).uuid, n.bumpScale = this.bumpScale), this.normalMap && this.normalMap.isTexture && (n.normalMap = this.normalMap.toJSON(e).uuid, n.normalMapType = this.normalMapType, n.normalScale = this.normalScale.toArray()), this.displacementMap && this.displacementMap.isTexture && (n.displacementMap = this.displacementMap.toJSON(e).uuid, n.displacementScale = this.displacementScale, n.displacementBias = this.displacementBias), this.roughnessMap && this.roughnessMap.isTexture && (n.roughnessMap = this.roughnessMap.toJSON(e).uuid), this.metalnessMap && this.metalnessMap.isTexture && (n.metalnessMap = this.metalnessMap.toJSON(e).uuid), this.emissiveMap && this.emissiveMap.isTexture && (n.emissiveMap = this.emissiveMap.toJSON(e).uuid), this.specularMap && this.specularMap.isTexture && (n.specularMap = this.specularMap.toJSON(e).uuid), this.specularIntensityMap && this.specularIntensityMap.isTexture && (n.specularIntensityMap = this.specularIntensityMap.toJSON(e).uuid), this.specularColorMap && this.specularColorMap.isTexture && (n.specularColorMap = this.specularColorMap.toJSON(e).uuid), this.envMap && this.envMap.isTexture && (n.envMap = this.envMap.toJSON(e).uuid, this.combine !== void 0 && (n.combine = this.combine)), this.envMapRotation !== void 0 && (n.envMapRotation = this.envMapRotation.toArray()), this.envMapIntensity !== void 0 && (n.envMapIntensity = this.envMapIntensity), this.reflectivity !== void 0 && (n.reflectivity = this.reflectivity), this.refractionRatio !== void 0 && (n.refractionRatio = this.refractionRatio), this.gradientMap && this.gradientMap.isTexture && (n.gradientMap = this.gradientMap.toJSON(e).uuid), this.transmission !== void 0 && (n.transmission = this.transmission), this.transmissionMap && this.transmissionMap.isTexture && (n.transmissionMap = this.transmissionMap.toJSON(e).uuid), this.thickness !== void 0 && (n.thickness = this.thickness), this.thicknessMap && this.thicknessMap.isTexture && (n.thicknessMap = this.thicknessMap.toJSON(e).uuid), this.attenuationDistance !== void 0 && this.attenuationDistance !== 1 / 0 && (n.attenuationDistance = this.attenuationDistance), this.attenuationColor !== void 0 && (n.attenuationColor = this.attenuationColor.getHex()), this.size !== void 0 && (n.size = this.size), this.shadowSide !== null && (n.shadowSide = this.shadowSide), this.sizeAttenuation !== void 0 && (n.sizeAttenuation = this.sizeAttenuation), this.blending !== ei && (n.blending = this.blending), this.side !== ai && (n.side = this.side), this.vertexColors === !0 && (n.vertexColors = !0), this.opacity < 1 && (n.opacity = this.opacity), this.transparent === !0 && (n.transparent = !0), this.blendSrc !== Rc && (n.blendSrc = this.blendSrc), this.blendDst !== Cc && (n.blendDst = this.blendDst), this.blendEquation !== Xn && (n.blendEquation = this.blendEquation), this.blendSrcAlpha !== null && (n.blendSrcAlpha = this.blendSrcAlpha), this.blendDstAlpha !== null && (n.blendDstAlpha = this.blendDstAlpha), this.blendEquationAlpha !== null && (n.blendEquationAlpha = this.blendEquationAlpha), this.blendColor && this.blendColor.isColor && (n.blendColor = this.blendColor.getHex()), this.blendAlpha !== 0 && (n.blendAlpha = this.blendAlpha), this.depthFunc !== Hs && (n.depthFunc = this.depthFunc), this.depthTest === !1 && (n.depthTest = this.depthTest), this.depthWrite === !1 && (n.depthWrite = this.depthWrite), this.colorWrite === !1 && (n.colorWrite = this.colorWrite), this.stencilWriteMask !== 255 && (n.stencilWriteMask = this.stencilWriteMask), this.stencilFunc !== Ap && (n.stencilFunc = this.stencilFunc), this.stencilRef !== 0 && (n.stencilRef = this.stencilRef), this.stencilFuncMask !== 255 && (n.stencilFuncMask = this.stencilFuncMask), this.stencilFail !== ha && (n.stencilFail = this.stencilFail), this.stencilZFail !== ha && (n.stencilZFail = this.stencilZFail), this.stencilZPass !== ha && (n.stencilZPass = this.stencilZPass), this.stencilWrite === !0 && (n.stencilWrite = this.stencilWrite), this.rotation !== void 0 && this.rotation !== 0 && (n.rotation = this.rotation), this.polygonOffset === !0 && (n.polygonOffset = !0), this.polygonOffsetFactor !== 0 && (n.polygonOffsetFactor = this.polygonOffsetFactor), this.polygonOffsetUnits !== 0 && (n.polygonOffsetUnits = this.polygonOffsetUnits), this.linewidth !== void 0 && this.linewidth !== 1 && (n.linewidth = this.linewidth), this.dashSize !== void 0 && (n.dashSize = this.dashSize), this.gapSize !== void 0 && (n.gapSize = this.gapSize), this.scale !== void 0 && (n.scale = this.scale), this.dithering === !0 && (n.dithering = !0), this.alphaTest > 0 && (n.alphaTest = this.alphaTest), this.alphaHash === !0 && (n.alphaHash = !0), this.alphaToCoverage === !0 && (n.alphaToCoverage = !0), this.premultipliedAlpha === !0 && (n.premultipliedAlpha = !0), this.forceSinglePass === !0 && (n.forceSinglePass = !0), this.allowOverride === !1 && (n.allowOverride = !1), this.wireframe === !0 && (n.wireframe = !0), this.wireframeLinewidth > 1 && (n.wireframeLinewidth = this.wireframeLinewidth), this.wireframeLinecap !== "round" && (n.wireframeLinecap = this.wireframeLinecap), this.wireframeLinejoin !== "round" && (n.wireframeLinejoin = this.wireframeLinejoin), this.flatShading === !0 && (n.flatShading = !0), this.visible === !1 && (n.visible = !1), this.toneMapped === !1 && (n.toneMapped = !1), this.fog === !1 && (n.fog = !1), Object.keys(this.userData).length > 0 && (n.userData = this.userData);
    function r(s) {
      const a = [];
      for (const o in s) {
        const l = s[o];
        delete l.metadata, a.push(l);
      }
      return a;
    }
    if (t) {
      const s = r(e.textures), a = r(e.images);
      s.length > 0 && (n.textures = s), a.length > 0 && (n.images = a);
    }
    return n;
  }
  /**
   * Returns a new material with copied values from this instance.
   *
   * @return {Material} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given material to this instance.
   *
   * @param {Material} source - The material to copy.
   * @return {Material} A reference to this instance.
   */
  copy(e) {
    this.name = e.name, this.blending = e.blending, this.side = e.side, this.vertexColors = e.vertexColors, this.opacity = e.opacity, this.transparent = e.transparent, this.blendSrc = e.blendSrc, this.blendDst = e.blendDst, this.blendEquation = e.blendEquation, this.blendSrcAlpha = e.blendSrcAlpha, this.blendDstAlpha = e.blendDstAlpha, this.blendEquationAlpha = e.blendEquationAlpha, this.blendColor.copy(e.blendColor), this.blendAlpha = e.blendAlpha, this.depthFunc = e.depthFunc, this.depthTest = e.depthTest, this.depthWrite = e.depthWrite, this.stencilWriteMask = e.stencilWriteMask, this.stencilFunc = e.stencilFunc, this.stencilRef = e.stencilRef, this.stencilFuncMask = e.stencilFuncMask, this.stencilFail = e.stencilFail, this.stencilZFail = e.stencilZFail, this.stencilZPass = e.stencilZPass, this.stencilWrite = e.stencilWrite;
    const t = e.clippingPlanes;
    let n = null;
    if (t !== null) {
      const r = t.length;
      n = new Array(r);
      for (let s = 0; s !== r; ++s)
        n[s] = t[s].clone();
    }
    return this.clippingPlanes = n, this.clipIntersection = e.clipIntersection, this.clipShadows = e.clipShadows, this.shadowSide = e.shadowSide, this.colorWrite = e.colorWrite, this.precision = e.precision, this.polygonOffset = e.polygonOffset, this.polygonOffsetFactor = e.polygonOffsetFactor, this.polygonOffsetUnits = e.polygonOffsetUnits, this.dithering = e.dithering, this.alphaTest = e.alphaTest, this.alphaHash = e.alphaHash, this.alphaToCoverage = e.alphaToCoverage, this.premultipliedAlpha = e.premultipliedAlpha, this.forceSinglePass = e.forceSinglePass, this.allowOverride = e.allowOverride, this.visible = e.visible, this.toneMapped = e.toneMapped, this.userData = JSON.parse(JSON.stringify(e.userData)), this;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   *
   * @fires Material#dispose
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
  /**
   * Setting this property to `true` indicates the engine the material
   * needs to be recompiled.
   *
   * @type {boolean}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && this.version++;
  }
}
class cE extends jn {
  /**
   * Constructs a new sprite material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isSpriteMaterial = !0, this.type = "SpriteMaterial", this.color = new He(16777215), this.map = null, this.alphaMap = null, this.rotation = 0, this.sizeAttenuation = !0, this.transparent = !0, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.alphaMap = e.alphaMap, this.rotation = e.rotation, this.sizeAttenuation = e.sizeAttenuation, this.fog = e.fog, this;
  }
}
const Hr = /* @__PURE__ */ new P(), tf = /* @__PURE__ */ new P(), Tu = /* @__PURE__ */ new P(), ys = /* @__PURE__ */ new P(), nf = /* @__PURE__ */ new P(), Mu = /* @__PURE__ */ new P(), rf = /* @__PURE__ */ new P();
class cd {
  /**
   * Constructs a new ray.
   *
   * @param {Vector3} [origin=(0,0,0)] - The origin of the ray.
   * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray.
   */
  constructor(e = new P(), t = new P(0, 0, -1)) {
    this.origin = e, this.direction = t;
  }
  /**
   * Sets the ray's components by copying the given values.
   *
   * @param {Vector3} origin - The origin.
   * @param {Vector3} direction - The direction.
   * @return {Ray} A reference to this ray.
   */
  set(e, t) {
    return this.origin.copy(e), this.direction.copy(t), this;
  }
  /**
   * Copies the values of the given ray to this instance.
   *
   * @param {Ray} ray - The ray to copy.
   * @return {Ray} A reference to this ray.
   */
  copy(e) {
    return this.origin.copy(e.origin), this.direction.copy(e.direction), this;
  }
  /**
   * Returns a vector that is located at a given distance along this ray.
   *
   * @param {number} t - The distance along the ray to retrieve a position for.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} A position on the ray.
   */
  at(e, t) {
    return t.copy(this.origin).addScaledVector(this.direction, e);
  }
  /**
   * Adjusts the direction of the ray to point at the given vector in world space.
   *
   * @param {Vector3} v - The target position.
   * @return {Ray} A reference to this ray.
   */
  lookAt(e) {
    return this.direction.copy(e).sub(this.origin).normalize(), this;
  }
  /**
   * Shift the origin of this ray along its direction by the given distance.
   *
   * @param {number} t - The distance along the ray to interpolate.
   * @return {Ray} A reference to this ray.
   */
  recast(e) {
    return this.origin.copy(this.at(e, Hr)), this;
  }
  /**
   * Returns the point along this ray that is closest to the given point.
   *
   * @param {Vector3} point - A point in 3D space to get the closet location on the ray for.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The closest point on this ray.
   */
  closestPointToPoint(e, t) {
    t.subVectors(e, this.origin);
    const n = t.dot(this.direction);
    return n < 0 ? t.copy(this.origin) : t.copy(this.origin).addScaledVector(this.direction, n);
  }
  /**
   * Returns the distance of the closest approach between this ray and the given point.
   *
   * @param {Vector3} point - A point in 3D space to compute the distance to.
   * @return {number} The distance.
   */
  distanceToPoint(e) {
    return Math.sqrt(this.distanceSqToPoint(e));
  }
  /**
   * Returns the squared distance of the closest approach between this ray and the given point.
   *
   * @param {Vector3} point - A point in 3D space to compute the distance to.
   * @return {number} The squared distance.
   */
  distanceSqToPoint(e) {
    const t = Hr.subVectors(e, this.origin).dot(this.direction);
    return t < 0 ? this.origin.distanceToSquared(e) : (Hr.copy(this.origin).addScaledVector(this.direction, t), Hr.distanceToSquared(e));
  }
  /**
   * Returns the squared distance between this ray and the given line segment.
   *
   * @param {Vector3} v0 - The start point of the line segment.
   * @param {Vector3} v1 - The end point of the line segment.
   * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment.
   * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray.
   * @return {number} The squared distance.
   */
  distanceSqToSegment(e, t, n, r) {
    tf.copy(e).add(t).multiplyScalar(0.5), Tu.copy(t).sub(e).normalize(), ys.copy(this.origin).sub(tf);
    const s = e.distanceTo(t) * 0.5, a = -this.direction.dot(Tu), o = ys.dot(this.direction), l = -ys.dot(Tu), c = ys.lengthSq(), u = Math.abs(1 - a * a);
    let h, d, f, p;
    if (u > 0)
      if (h = a * l - o, d = a * o - l, p = s * u, h >= 0)
        if (d >= -p)
          if (d <= p) {
            const _ = 1 / u;
            h *= _, d *= _, f = h * (h + a * d + 2 * o) + d * (a * h + d + 2 * l) + c;
          } else
            d = s, h = Math.max(0, -(a * d + o)), f = -h * h + d * (d + 2 * l) + c;
        else
          d = -s, h = Math.max(0, -(a * d + o)), f = -h * h + d * (d + 2 * l) + c;
      else
        d <= -p ? (h = Math.max(0, -(-a * s + o)), d = h > 0 ? -s : Math.min(Math.max(-s, -l), s), f = -h * h + d * (d + 2 * l) + c) : d <= p ? (h = 0, d = Math.min(Math.max(-s, -l), s), f = d * (d + 2 * l) + c) : (h = Math.max(0, -(a * s + o)), d = h > 0 ? s : Math.min(Math.max(-s, -l), s), f = -h * h + d * (d + 2 * l) + c);
    else
      d = a > 0 ? -s : s, h = Math.max(0, -(a * d + o)), f = -h * h + d * (d + 2 * l) + c;
    return n && n.copy(this.origin).addScaledVector(this.direction, h), r && r.copy(tf).addScaledVector(Tu, d), f;
  }
  /**
   * Intersects this ray with the given sphere, returning the intersection
   * point or `null` if there is no intersection.
   *
   * @param {Sphere} sphere - The sphere to intersect.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The intersection point.
   */
  intersectSphere(e, t) {
    Hr.subVectors(e.center, this.origin);
    const n = Hr.dot(this.direction), r = Hr.dot(Hr) - n * n, s = e.radius * e.radius;
    if (r > s)
      return null;
    const a = Math.sqrt(s - r), o = n - a, l = n + a;
    return l < 0 ? null : o < 0 ? this.at(l, t) : this.at(o, t);
  }
  /**
   * Returns `true` if this ray intersects with the given sphere.
   *
   * @param {Sphere} sphere - The sphere to intersect.
   * @return {boolean} Whether this ray intersects with the given sphere or not.
   */
  intersectsSphere(e) {
    return e.radius < 0 ? !1 : this.distanceSqToPoint(e.center) <= e.radius * e.radius;
  }
  /**
   * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray
   * does not intersect with the plane.
   *
   * @param {Plane} plane - The plane to compute the distance to.
   * @return {?number} Whether this ray intersects with the given sphere or not.
   */
  distanceToPlane(e) {
    const t = e.normal.dot(this.direction);
    if (t === 0)
      return e.distanceToPoint(this.origin) === 0 ? 0 : null;
    const n = -(this.origin.dot(e.normal) + e.constant) / t;
    return n >= 0 ? n : null;
  }
  /**
   * Intersects this ray with the given plane, returning the intersection
   * point or `null` if there is no intersection.
   *
   * @param {Plane} plane - The plane to intersect.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The intersection point.
   */
  intersectPlane(e, t) {
    const n = this.distanceToPlane(e);
    return n === null ? null : this.at(n, t);
  }
  /**
   * Returns `true` if this ray intersects with the given plane.
   *
   * @param {Plane} plane - The plane to intersect.
   * @return {boolean} Whether this ray intersects with the given plane or not.
   */
  intersectsPlane(e) {
    const t = e.distanceToPoint(this.origin);
    return t === 0 || e.normal.dot(this.direction) * t < 0;
  }
  /**
   * Intersects this ray with the given bounding box, returning the intersection
   * point or `null` if there is no intersection.
   *
   * @param {Box3} box - The box to intersect.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The intersection point.
   */
  intersectBox(e, t) {
    let n, r, s, a, o, l;
    const c = 1 / this.direction.x, u = 1 / this.direction.y, h = 1 / this.direction.z, d = this.origin;
    return c >= 0 ? (n = (e.min.x - d.x) * c, r = (e.max.x - d.x) * c) : (n = (e.max.x - d.x) * c, r = (e.min.x - d.x) * c), u >= 0 ? (s = (e.min.y - d.y) * u, a = (e.max.y - d.y) * u) : (s = (e.max.y - d.y) * u, a = (e.min.y - d.y) * u), n > a || s > r || ((s > n || isNaN(n)) && (n = s), (a < r || isNaN(r)) && (r = a), h >= 0 ? (o = (e.min.z - d.z) * h, l = (e.max.z - d.z) * h) : (o = (e.max.z - d.z) * h, l = (e.min.z - d.z) * h), n > l || o > r) || ((o > n || n !== n) && (n = o), (l < r || r !== r) && (r = l), r < 0) ? null : this.at(n >= 0 ? n : r, t);
  }
  /**
   * Returns `true` if this ray intersects with the given box.
   *
   * @param {Box3} box - The box to intersect.
   * @return {boolean} Whether this ray intersects with the given box or not.
   */
  intersectsBox(e) {
    return this.intersectBox(e, Hr) !== null;
  }
  /**
   * Intersects this ray with the given triangle, returning the intersection
   * point or `null` if there is no intersection.
   *
   * @param {Vector3} a - The first vertex of the triangle.
   * @param {Vector3} b - The second vertex of the triangle.
   * @param {Vector3} c - The third vertex of the triangle.
   * @param {boolean} backfaceCulling - Whether to use backface culling or not.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The intersection point.
   */
  intersectTriangle(e, t, n, r, s) {
    nf.subVectors(t, e), Mu.subVectors(n, e), rf.crossVectors(nf, Mu);
    let a = this.direction.dot(rf), o;
    if (a > 0) {
      if (r)
        return null;
      o = 1;
    } else if (a < 0)
      o = -1, a = -a;
    else
      return null;
    ys.subVectors(this.origin, e);
    const l = o * this.direction.dot(Mu.crossVectors(ys, Mu));
    if (l < 0)
      return null;
    const c = o * this.direction.dot(nf.cross(ys));
    if (c < 0 || l + c > a)
      return null;
    const u = -o * ys.dot(rf);
    return u < 0 ? null : this.at(u / a, s);
  }
  /**
   * Transforms this ray with the given 4x4 transformation matrix.
   *
   * @param {Matrix4} matrix4 - The transformation matrix.
   * @return {Ray} A reference to this ray.
   */
  applyMatrix4(e) {
    return this.origin.applyMatrix4(e), this.direction.transformDirection(e), this;
  }
  /**
   * Returns `true` if this ray is equal with the given one.
   *
   * @param {Ray} ray - The ray to test for equality.
   * @return {boolean} Whether this ray is equal with the given one.
   */
  equals(e) {
    return e.origin.equals(this.origin) && e.direction.equals(this.direction);
  }
  /**
   * Returns a new ray with copied values from this instance.
   *
   * @return {Ray} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
}
class xr extends jn {
  /**
   * Constructs a new mesh basic material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshBasicMaterial = !0, this.type = "MeshBasicMaterial", this.color = new He(16777215), this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.specularMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new gi(), this.combine = Qc, this.reflectivity = 1, this.refractionRatio = 0.98, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.specularMap = e.specularMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.combine = e.combine, this.reflectivity = e.reflectivity, this.refractionRatio = e.refractionRatio, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.fog = e.fog, this;
  }
}
const S_ = /* @__PURE__ */ new pt(), ra = /* @__PURE__ */ new cd(), Eu = /* @__PURE__ */ new tu(), T_ = /* @__PURE__ */ new P(), wu = /* @__PURE__ */ new P(), Au = /* @__PURE__ */ new P(), Ru = /* @__PURE__ */ new P(), sf = /* @__PURE__ */ new P(), Cu = /* @__PURE__ */ new P(), M_ = /* @__PURE__ */ new P(), Nu = /* @__PURE__ */ new P();
class _n extends gn {
  /**
   * Constructs a new mesh.
   *
   * @param {BufferGeometry} [geometry] - The mesh geometry.
   * @param {Material|Array<Material>} [material] - The mesh material.
   */
  constructor(e = new Pn(), t = new xr()) {
    super(), this.isMesh = !0, this.type = "Mesh", this.geometry = e, this.material = t, this.morphTargetDictionary = void 0, this.morphTargetInfluences = void 0, this.count = 1, this.updateMorphTargets();
  }
  copy(e, t) {
    return super.copy(e, t), e.morphTargetInfluences !== void 0 && (this.morphTargetInfluences = e.morphTargetInfluences.slice()), e.morphTargetDictionary !== void 0 && (this.morphTargetDictionary = Object.assign({}, e.morphTargetDictionary)), this.material = Array.isArray(e.material) ? e.material.slice() : e.material, this.geometry = e.geometry, this;
  }
  /**
   * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences}
   * to make sure existing morph targets can influence this 3D object.
   */
  updateMorphTargets() {
    const t = this.geometry.morphAttributes, n = Object.keys(t);
    if (n.length > 0) {
      const r = t[n[0]];
      if (r !== void 0) {
        this.morphTargetInfluences = [], this.morphTargetDictionary = {};
        for (let s = 0, a = r.length; s < a; s++) {
          const o = r[s].name || String(s);
          this.morphTargetInfluences.push(0), this.morphTargetDictionary[o] = s;
        }
      }
    }
  }
  /**
   * Returns the local-space position of the vertex at the given index, taking into
   * account the current animation state of both morph targets and skinning.
   *
   * @param {number} index - The vertex index.
   * @param {Vector3} target - The target object that is used to store the method's result.
   * @return {Vector3} The vertex position in local space.
   */
  getVertexPosition(e, t) {
    const n = this.geometry, r = n.attributes.position, s = n.morphAttributes.position, a = n.morphTargetsRelative;
    t.fromBufferAttribute(r, e);
    const o = this.morphTargetInfluences;
    if (s && o) {
      Cu.set(0, 0, 0);
      for (let l = 0, c = s.length; l < c; l++) {
        const u = o[l], h = s[l];
        u !== 0 && (sf.fromBufferAttribute(h, e), a ? Cu.addScaledVector(sf, u) : Cu.addScaledVector(sf.sub(t), u));
      }
      t.add(Cu);
    }
    return t;
  }
  /**
   * Computes intersection points between a casted ray and this line.
   *
   * @param {Raycaster} raycaster - The raycaster.
   * @param {Array<Object>} intersects - The target array that holds the intersection points.
   */
  raycast(e, t) {
    const n = this.geometry, r = this.material, s = this.matrixWorld;
    r !== void 0 && (n.boundingSphere === null && n.computeBoundingSphere(), Eu.copy(n.boundingSphere), Eu.applyMatrix4(s), ra.copy(e.ray).recast(e.near), !(Eu.containsPoint(ra.origin) === !1 && (ra.intersectSphere(Eu, T_) === null || ra.origin.distanceToSquared(T_) > (e.far - e.near) ** 2)) && (S_.copy(s).invert(), ra.copy(e.ray).applyMatrix4(S_), !(n.boundingBox !== null && ra.intersectsBox(n.boundingBox) === !1) && this._computeIntersections(e, t, ra)));
  }
  _computeIntersections(e, t, n) {
    let r;
    const s = this.geometry, a = this.material, o = s.index, l = s.attributes.position, c = s.attributes.uv, u = s.attributes.uv1, h = s.attributes.normal, d = s.groups, f = s.drawRange;
    if (o !== null)
      if (Array.isArray(a))
        for (let p = 0, _ = d.length; p < _; p++) {
          const g = d[p], m = a[g.materialIndex], x = Math.max(g.start, f.start), y = Math.min(o.count, Math.min(g.start + g.count, f.start + f.count));
          for (let b = x, T = y; b < T; b += 3) {
            const S = o.getX(b), E = o.getX(b + 1), v = o.getX(b + 2);
            r = Pu(this, m, e, n, c, u, h, S, E, v), r && (r.faceIndex = Math.floor(b / 3), r.face.materialIndex = g.materialIndex, t.push(r));
          }
        }
      else {
        const p = Math.max(0, f.start), _ = Math.min(o.count, f.start + f.count);
        for (let g = p, m = _; g < m; g += 3) {
          const x = o.getX(g), y = o.getX(g + 1), b = o.getX(g + 2);
          r = Pu(this, a, e, n, c, u, h, x, y, b), r && (r.faceIndex = Math.floor(g / 3), t.push(r));
        }
      }
    else if (l !== void 0)
      if (Array.isArray(a))
        for (let p = 0, _ = d.length; p < _; p++) {
          const g = d[p], m = a[g.materialIndex], x = Math.max(g.start, f.start), y = Math.min(l.count, Math.min(g.start + g.count, f.start + f.count));
          for (let b = x, T = y; b < T; b += 3) {
            const S = b, E = b + 1, v = b + 2;
            r = Pu(this, m, e, n, c, u, h, S, E, v), r && (r.faceIndex = Math.floor(b / 3), r.face.materialIndex = g.materialIndex, t.push(r));
          }
        }
      else {
        const p = Math.max(0, f.start), _ = Math.min(l.count, f.start + f.count);
        for (let g = p, m = _; g < m; g += 3) {
          const x = g, y = g + 1, b = g + 2;
          r = Pu(this, a, e, n, c, u, h, x, y, b), r && (r.faceIndex = Math.floor(g / 3), t.push(r));
        }
      }
  }
}
function uE(i, e, t, n, r, s, a, o) {
  let l;
  if (e.side === Ft ? l = n.intersectTriangle(a, s, r, !0, o) : l = n.intersectTriangle(r, s, a, e.side === ai, o), l === null)
    return null;
  Nu.copy(o), Nu.applyMatrix4(i.matrixWorld);
  const c = t.ray.origin.distanceTo(Nu);
  return c < t.near || c > t.far ? null : {
    distance: c,
    point: Nu.clone(),
    object: i
  };
}
function Pu(i, e, t, n, r, s, a, o, l, c) {
  i.getVertexPosition(o, wu), i.getVertexPosition(l, Au), i.getVertexPosition(c, Ru);
  const u = uE(i, e, t, n, wu, Au, Ru, M_);
  if (u) {
    const h = new P();
    Qi.getBarycoord(M_, wu, Au, Ru, h), r && (u.uv = Qi.getInterpolatedAttribute(r, o, l, c, h, new de())), s && (u.uv1 = Qi.getInterpolatedAttribute(s, o, l, c, h, new de())), a && (u.normal = Qi.getInterpolatedAttribute(a, o, l, c, h, new P()), u.normal.dot(n.direction) > 0 && u.normal.multiplyScalar(-1));
    const d = {
      a: o,
      b: l,
      c,
      normal: new P(),
      materialIndex: 0
    };
    Qi.getNormal(wu, Au, Ru, d.normal), u.face = d, u.barycoord = h;
  }
  return u;
}
class Zm extends mn {
  /**
   * Constructs a new data texture.
   *
   * @param {?TypedArray} [data=null] - The buffer data.
   * @param {number} [width=1] - The width of the texture.
   * @param {number} [height=1] - The height of the texture.
   * @param {number} [format=RGBAFormat] - The texture format.
   * @param {number} [type=UnsignedByteType] - The texture type.
   * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
   * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
   * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
   * @param {number} [magFilter=NearestFilter] - The mag filter value.
   * @param {number} [minFilter=NearestFilter] - The min filter value.
   * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
   * @param {string} [colorSpace=NoColorSpace] - The color space.
   */
  constructor(e = null, t = 1, n = 1, r, s, a, o, l, c = Tt, u = Tt, h, d) {
    super(null, a, o, l, c, u, r, s, h, d), this.isDataTexture = !0, this.image = { data: e, width: t, height: n }, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1;
  }
}
class hE extends Bn {
  /**
   * Constructs a new instanced buffer attribute.
   *
   * @param {TypedArray} array - The array holding the attribute data.
   * @param {number} itemSize - The item size.
   * @param {boolean} [normalized=false] - Whether the data are normalized or not.
   * @param {number} [meshPerAttribute=1] - How often a value of this buffer attribute should be repeated.
   */
  constructor(e, t, n, r = 1) {
    super(e, t, n), this.isInstancedBufferAttribute = !0, this.meshPerAttribute = r;
  }
  copy(e) {
    return super.copy(e), this.meshPerAttribute = e.meshPerAttribute, this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.meshPerAttribute = this.meshPerAttribute, e.isInstancedBufferAttribute = !0, e;
  }
}
const af = /* @__PURE__ */ new P(), dE = /* @__PURE__ */ new P(), fE = /* @__PURE__ */ new nt();
class Zi {
  /**
   * Constructs a new plane.
   *
   * @param {Vector3} [normal=(1,0,0)] - A unit length vector defining the normal of the plane.
   * @param {number} [constant=0] - The signed distance from the origin to the plane.
   */
  constructor(e = new P(1, 0, 0), t = 0) {
    this.isPlane = !0, this.normal = e, this.constant = t;
  }
  /**
   * Sets the plane components by copying the given values.
   *
   * @param {Vector3} normal - The normal.
   * @param {number} constant - The constant.
   * @return {Plane} A reference to this plane.
   */
  set(e, t) {
    return this.normal.copy(e), this.constant = t, this;
  }
  /**
   * Sets the plane components by defining `x`, `y`, `z` as the
   * plane normal and `w` as the constant.
   *
   * @param {number} x - The value for the normal's x component.
   * @param {number} y - The value for the normal's y component.
   * @param {number} z - The value for the normal's z component.
   * @param {number} w - The constant value.
   * @return {Plane} A reference to this plane.
   */
  setComponents(e, t, n, r) {
    return this.normal.set(e, t, n), this.constant = r, this;
  }
  /**
   * Sets the plane from the given normal and coplanar point (that is a point
   * that lies onto the plane).
   *
   * @param {Vector3} normal - The normal.
   * @param {Vector3} point - A coplanar point.
   * @return {Plane} A reference to this plane.
   */
  setFromNormalAndCoplanarPoint(e, t) {
    return this.normal.copy(e), this.constant = -t.dot(this.normal), this;
  }
  /**
   * Sets the plane from three coplanar points. The winding order is
   * assumed to be counter-clockwise, and determines the direction of
   * the plane normal.
   *
   * @param {Vector3} a - The first coplanar point.
   * @param {Vector3} b - The second coplanar point.
   * @param {Vector3} c - The third coplanar point.
   * @return {Plane} A reference to this plane.
   */
  setFromCoplanarPoints(e, t, n) {
    const r = af.subVectors(n, t).cross(dE.subVectors(e, t)).normalize();
    return this.setFromNormalAndCoplanarPoint(r, e), this;
  }
  /**
   * Copies the values of the given plane to this instance.
   *
   * @param {Plane} plane - The plane to copy.
   * @return {Plane} A reference to this plane.
   */
  copy(e) {
    return this.normal.copy(e.normal), this.constant = e.constant, this;
  }
  /**
   * Normalizes the plane normal and adjusts the constant accordingly.
   *
   * @return {Plane} A reference to this plane.
   */
  normalize() {
    const e = 1 / this.normal.length();
    return this.normal.multiplyScalar(e), this.constant *= e, this;
  }
  /**
   * Negates both the plane normal and the constant.
   *
   * @return {Plane} A reference to this plane.
   */
  negate() {
    return this.constant *= -1, this.normal.negate(), this;
  }
  /**
   * Returns the signed distance from the given point to this plane.
   *
   * @param {Vector3} point - The point to compute the distance for.
   * @return {number} The signed distance.
   */
  distanceToPoint(e) {
    return this.normal.dot(e) + this.constant;
  }
  /**
   * Returns the signed distance from the given sphere to this plane.
   *
   * @param {Sphere} sphere - The sphere to compute the distance for.
   * @return {number} The signed distance.
   */
  distanceToSphere(e) {
    return this.distanceToPoint(e.center) - e.radius;
  }
  /**
   * Projects a the given point onto the plane.
   *
   * @param {Vector3} point - The point to project.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The projected point on the plane.
   */
  projectPoint(e, t) {
    return t.copy(e).addScaledVector(this.normal, -this.distanceToPoint(e));
  }
  /**
   * Returns the intersection point of the passed line and the plane. Returns
   * `null` if the line does not intersect. Returns the line's starting point if
   * the line is coplanar with the plane.
   *
   * @param {Line3} line - The line to compute the intersection for.
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {?Vector3} The intersection point.
   */
  intersectLine(e, t) {
    const n = e.delta(af), r = this.normal.dot(n);
    if (r === 0)
      return this.distanceToPoint(e.start) === 0 ? t.copy(e.start) : null;
    const s = -(e.start.dot(this.normal) + this.constant) / r;
    return s < 0 || s > 1 ? null : t.copy(e.start).addScaledVector(n, s);
  }
  /**
   * Returns `true` if the given line segment intersects with (passes through) the plane.
   *
   * @param {Line3} line - The line to test.
   * @return {boolean} Whether the given line segment intersects with the plane or not.
   */
  intersectsLine(e) {
    const t = this.distanceToPoint(e.start), n = this.distanceToPoint(e.end);
    return t < 0 && n > 0 || n < 0 && t > 0;
  }
  /**
   * Returns `true` if the given bounding box intersects with the plane.
   *
   * @param {Box3} box - The bounding box to test.
   * @return {boolean} Whether the given bounding box intersects with the plane or not.
   */
  intersectsBox(e) {
    return e.intersectsPlane(this);
  }
  /**
   * Returns `true` if the given bounding sphere intersects with the plane.
   *
   * @param {Sphere} sphere - The bounding sphere to test.
   * @return {boolean} Whether the given bounding sphere intersects with the plane or not.
   */
  intersectsSphere(e) {
    return e.intersectsPlane(this);
  }
  /**
   * Returns a coplanar vector to the plane, by calculating the
   * projection of the normal at the origin onto the plane.
   *
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The coplanar point.
   */
  coplanarPoint(e) {
    return e.copy(this.normal).multiplyScalar(-this.constant);
  }
  /**
   * Apply a 4x4 matrix to the plane. The matrix must be an affine, homogeneous transform.
   *
   * The optional normal matrix can be pre-computed like so:
   * ```js
   * const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
   * ```
   *
   * @param {Matrix4} matrix - The transformation matrix.
   * @param {Matrix4} [optionalNormalMatrix] - A pre-computed normal matrix.
   * @return {Plane} A reference to this plane.
   */
  applyMatrix4(e, t) {
    const n = t || fE.getNormalMatrix(e), r = this.coplanarPoint(af).applyMatrix4(e), s = this.normal.applyMatrix3(n).normalize();
    return this.constant = -r.dot(s), this;
  }
  /**
   * Translates the plane by the distance defined by the given offset vector.
   * Note that this only affects the plane constant and will not affect the normal vector.
   *
   * @param {Vector3} offset - The offset vector.
   * @return {Plane} A reference to this plane.
   */
  translate(e) {
    return this.constant -= e.dot(this.normal), this;
  }
  /**
   * Returns `true` if this plane is equal with the given one.
   *
   * @param {Plane} plane - The plane to test for equality.
   * @return {boolean} Whether this plane is equal with the given one.
   */
  equals(e) {
    return e.normal.equals(this.normal) && e.constant === this.constant;
  }
  /**
   * Returns a new plane with copied values from this instance.
   *
   * @return {Plane} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
}
const sa = /* @__PURE__ */ new tu(), pE = /* @__PURE__ */ new de(0.5, 0.5), Du = /* @__PURE__ */ new P();
class nu {
  /**
   * Constructs a new frustum.
   *
   * @param {Plane} [p0] - The first plane that encloses the frustum.
   * @param {Plane} [p1] - The second plane that encloses the frustum.
   * @param {Plane} [p2] - The third plane that encloses the frustum.
   * @param {Plane} [p3] - The fourth plane that encloses the frustum.
   * @param {Plane} [p4] - The fifth plane that encloses the frustum.
   * @param {Plane} [p5] - The sixth plane that encloses the frustum.
   */
  constructor(e = new Zi(), t = new Zi(), n = new Zi(), r = new Zi(), s = new Zi(), a = new Zi()) {
    this.planes = [e, t, n, r, s, a];
  }
  /**
   * Sets the frustum planes by copying the given planes.
   *
   * @param {Plane} [p0] - The first plane that encloses the frustum.
   * @param {Plane} [p1] - The second plane that encloses the frustum.
   * @param {Plane} [p2] - The third plane that encloses the frustum.
   * @param {Plane} [p3] - The fourth plane that encloses the frustum.
   * @param {Plane} [p4] - The fifth plane that encloses the frustum.
   * @param {Plane} [p5] - The sixth plane that encloses the frustum.
   * @return {Frustum} A reference to this frustum.
   */
  set(e, t, n, r, s, a) {
    const o = this.planes;
    return o[0].copy(e), o[1].copy(t), o[2].copy(n), o[3].copy(r), o[4].copy(s), o[5].copy(a), this;
  }
  /**
   * Copies the values of the given frustum to this instance.
   *
   * @param {Frustum} frustum - The frustum to copy.
   * @return {Frustum} A reference to this frustum.
   */
  copy(e) {
    const t = this.planes;
    for (let n = 0; n < 6; n++)
      t[n].copy(e.planes[n]);
    return this;
  }
  /**
   * Sets the frustum planes from the given projection matrix.
   *
   * @param {Matrix4} m - The projection matrix.
   * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} coordinateSystem - The coordinate system.
   * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth.
   * @return {Frustum} A reference to this frustum.
   */
  setFromProjectionMatrix(e, t = si, n = !1) {
    const r = this.planes, s = e.elements, a = s[0], o = s[1], l = s[2], c = s[3], u = s[4], h = s[5], d = s[6], f = s[7], p = s[8], _ = s[9], g = s[10], m = s[11], x = s[12], y = s[13], b = s[14], T = s[15];
    if (r[0].setComponents(c - a, f - u, m - p, T - x).normalize(), r[1].setComponents(c + a, f + u, m + p, T + x).normalize(), r[2].setComponents(c + o, f + h, m + _, T + y).normalize(), r[3].setComponents(c - o, f - h, m - _, T - y).normalize(), n)
      r[4].setComponents(l, d, g, b).normalize(), r[5].setComponents(c - l, f - d, m - g, T - b).normalize();
    else if (r[4].setComponents(c - l, f - d, m - g, T - b).normalize(), t === si)
      r[5].setComponents(c + l, f + d, m + g, T + b).normalize();
    else if (t === Cr)
      r[5].setComponents(l, d, g, b).normalize();
    else
      throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: " + t);
    return this;
  }
  /**
   * Returns `true` if the 3D object's bounding sphere is intersecting this frustum.
   *
   * Note that the 3D object must have a geometry so that the bounding sphere can be calculated.
   *
   * @param {Object3D} object - The 3D object to test.
   * @return {boolean} Whether the 3D object's bounding sphere is intersecting this frustum or not.
   */
  intersectsObject(e) {
    if (e.boundingSphere !== void 0)
      e.boundingSphere === null && e.computeBoundingSphere(), sa.copy(e.boundingSphere).applyMatrix4(e.matrixWorld);
    else {
      const t = e.geometry;
      t.boundingSphere === null && t.computeBoundingSphere(), sa.copy(t.boundingSphere).applyMatrix4(e.matrixWorld);
    }
    return this.intersectsSphere(sa);
  }
  /**
   * Returns `true` if the given sprite is intersecting this frustum.
   *
   * @param {Sprite} sprite - The sprite to test.
   * @return {boolean} Whether the sprite is intersecting this frustum or not.
   */
  intersectsSprite(e) {
    sa.center.set(0, 0, 0);
    const t = pE.distanceTo(e.center);
    return sa.radius = 0.7071067811865476 + t, sa.applyMatrix4(e.matrixWorld), this.intersectsSphere(sa);
  }
  /**
   * Returns `true` if the given bounding sphere is intersecting this frustum.
   *
   * @param {Sphere} sphere - The bounding sphere to test.
   * @return {boolean} Whether the bounding sphere is intersecting this frustum or not.
   */
  intersectsSphere(e) {
    const t = this.planes, n = e.center, r = -e.radius;
    for (let s = 0; s < 6; s++)
      if (t[s].distanceToPoint(n) < r)
        return !1;
    return !0;
  }
  /**
   * Returns `true` if the given bounding box is intersecting this frustum.
   *
   * @param {Box3} box - The bounding box to test.
   * @return {boolean} Whether the bounding box is intersecting this frustum or not.
   */
  intersectsBox(e) {
    const t = this.planes;
    for (let n = 0; n < 6; n++) {
      const r = t[n];
      if (Du.x = r.normal.x > 0 ? e.max.x : e.min.x, Du.y = r.normal.y > 0 ? e.max.y : e.min.y, Du.z = r.normal.z > 0 ? e.max.z : e.min.z, r.distanceToPoint(Du) < 0)
        return !1;
    }
    return !0;
  }
  /**
   * Returns `true` if the given point lies within the frustum.
   *
   * @param {Vector3} point - The point to test.
   * @return {boolean} Whether the point lies within this frustum or not.
   */
  containsPoint(e) {
    const t = this.planes;
    for (let n = 0; n < 6; n++)
      if (t[n].distanceToPoint(e) < 0)
        return !1;
    return !0;
  }
  /**
   * Returns a new frustum with copied values from this instance.
   *
   * @return {Frustum} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
}
const rr = /* @__PURE__ */ new pt(), sr = /* @__PURE__ */ new nu();
class Qm {
  /**
   * Constructs a new frustum array.
   *
   */
  constructor() {
    this.coordinateSystem = si;
  }
  /**
   * Returns `true` if the 3D object's bounding sphere is intersecting any frustum
   * from the camera array.
   *
   * @param {Object3D} object - The 3D object to test.
   * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
   * @return {boolean} Whether the 3D object is visible in any camera.
   */
  intersectsObject(e, t) {
    if (!t.isArrayCamera || t.cameras.length === 0)
      return !1;
    for (let n = 0; n < t.cameras.length; n++) {
      const r = t.cameras[n];
      if (rr.multiplyMatrices(
        r.projectionMatrix,
        r.matrixWorldInverse
      ), sr.setFromProjectionMatrix(
        rr,
        r.coordinateSystem,
        r.reversedDepth
      ), sr.intersectsObject(e))
        return !0;
    }
    return !1;
  }
  /**
   * Returns `true` if the given sprite is intersecting any frustum
   * from the camera array.
   *
   * @param {Sprite} sprite - The sprite to test.
   * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
   * @return {boolean} Whether the sprite is visible in any camera.
   */
  intersectsSprite(e, t) {
    if (!t || !t.cameras || t.cameras.length === 0)
      return !1;
    for (let n = 0; n < t.cameras.length; n++) {
      const r = t.cameras[n];
      if (rr.multiplyMatrices(
        r.projectionMatrix,
        r.matrixWorldInverse
      ), sr.setFromProjectionMatrix(
        rr,
        r.coordinateSystem,
        r.reversedDepth
      ), sr.intersectsSprite(e))
        return !0;
    }
    return !1;
  }
  /**
   * Returns `true` if the given bounding sphere is intersecting any frustum
   * from the camera array.
   *
   * @param {Sphere} sphere - The bounding sphere to test.
   * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
   * @return {boolean} Whether the sphere is visible in any camera.
   */
  intersectsSphere(e, t) {
    if (!t || !t.cameras || t.cameras.length === 0)
      return !1;
    for (let n = 0; n < t.cameras.length; n++) {
      const r = t.cameras[n];
      if (rr.multiplyMatrices(
        r.projectionMatrix,
        r.matrixWorldInverse
      ), sr.setFromProjectionMatrix(
        rr,
        r.coordinateSystem,
        r.reversedDepth
      ), sr.intersectsSphere(e))
        return !0;
    }
    return !1;
  }
  /**
   * Returns `true` if the given bounding box is intersecting any frustum
   * from the camera array.
   *
   * @param {Box3} box - The bounding box to test.
   * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
   * @return {boolean} Whether the box is visible in any camera.
   */
  intersectsBox(e, t) {
    if (!t || !t.cameras || t.cameras.length === 0)
      return !1;
    for (let n = 0; n < t.cameras.length; n++) {
      const r = t.cameras[n];
      if (rr.multiplyMatrices(
        r.projectionMatrix,
        r.matrixWorldInverse
      ), sr.setFromProjectionMatrix(
        rr,
        r.coordinateSystem,
        r.reversedDepth
      ), sr.intersectsBox(e))
        return !0;
    }
    return !1;
  }
  /**
   * Returns `true` if the given point lies within any frustum
   * from the camera array.
   *
   * @param {Vector3} point - The point to test.
   * @param {Object} cameraArray - An object with a cameras property containing an array of cameras.
   * @return {boolean} Whether the point is visible in any camera.
   */
  containsPoint(e, t) {
    if (!t || !t.cameras || t.cameras.length === 0)
      return !1;
    for (let n = 0; n < t.cameras.length; n++) {
      const r = t.cameras[n];
      if (rr.multiplyMatrices(
        r.projectionMatrix,
        r.matrixWorldInverse
      ), sr.setFromProjectionMatrix(
        rr,
        r.coordinateSystem,
        r.reversedDepth
      ), sr.containsPoint(e))
        return !0;
    }
    return !1;
  }
  /**
   * Returns a new frustum array with copied values from this instance.
   *
   * @return {FrustumArray} A clone of this instance.
   */
  clone() {
    return new Qm();
  }
}
class ud extends jn {
  /**
   * Constructs a new line basic material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isLineBasicMaterial = !0, this.type = "LineBasicMaterial", this.color = new He(16777215), this.map = null, this.linewidth = 1, this.linecap = "round", this.linejoin = "round", this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.linewidth = e.linewidth, this.linecap = e.linecap, this.linejoin = e.linejoin, this.fog = e.fog, this;
  }
}
const Ih = /* @__PURE__ */ new P(), Uh = /* @__PURE__ */ new P(), E_ = /* @__PURE__ */ new pt(), Ol = /* @__PURE__ */ new cd(), Lu = /* @__PURE__ */ new tu(), of = /* @__PURE__ */ new P(), w_ = /* @__PURE__ */ new P();
class mE extends gn {
  /**
   * Constructs a new line.
   *
   * @param {BufferGeometry} [geometry] - The line geometry.
   * @param {Material|Array<Material>} [material] - The line material.
   */
  constructor(e = new Pn(), t = new ud()) {
    super(), this.isLine = !0, this.type = "Line", this.geometry = e, this.material = t, this.morphTargetDictionary = void 0, this.morphTargetInfluences = void 0, this.updateMorphTargets();
  }
  copy(e, t) {
    return super.copy(e, t), this.material = Array.isArray(e.material) ? e.material.slice() : e.material, this.geometry = e.geometry, this;
  }
  /**
   * Computes an array of distance values which are necessary for rendering dashed lines.
   * For each vertex in the geometry, the method calculates the cumulative length from the
   * current point to the very beginning of the line.
   *
   * @return {Line} A reference to this line.
   */
  computeLineDistances() {
    const e = this.geometry;
    if (e.index === null) {
      const t = e.attributes.position, n = [0];
      for (let r = 1, s = t.count; r < s; r++)
        Ih.fromBufferAttribute(t, r - 1), Uh.fromBufferAttribute(t, r), n[r] = n[r - 1], n[r] += Ih.distanceTo(Uh);
      e.setAttribute("lineDistance", new an(n, 1));
    } else
      oe("Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");
    return this;
  }
  /**
   * Computes intersection points between a casted ray and this line.
   *
   * @param {Raycaster} raycaster - The raycaster.
   * @param {Array<Object>} intersects - The target array that holds the intersection points.
   */
  raycast(e, t) {
    const n = this.geometry, r = this.matrixWorld, s = e.params.Line.threshold, a = n.drawRange;
    if (n.boundingSphere === null && n.computeBoundingSphere(), Lu.copy(n.boundingSphere), Lu.applyMatrix4(r), Lu.radius += s, e.ray.intersectsSphere(Lu) === !1)
      return;
    E_.copy(r).invert(), Ol.copy(e.ray).applyMatrix4(E_);
    const o = s / ((this.scale.x + this.scale.y + this.scale.z) / 3), l = o * o, c = this.isLineSegments ? 2 : 1, u = n.index, d = n.attributes.position;
    if (u !== null) {
      const f = Math.max(0, a.start), p = Math.min(u.count, a.start + a.count);
      for (let _ = f, g = p - 1; _ < g; _ += c) {
        const m = u.getX(_), x = u.getX(_ + 1), y = Fu(this, e, Ol, l, m, x, _);
        y && t.push(y);
      }
      if (this.isLineLoop) {
        const _ = u.getX(p - 1), g = u.getX(f), m = Fu(this, e, Ol, l, _, g, p - 1);
        m && t.push(m);
      }
    } else {
      const f = Math.max(0, a.start), p = Math.min(d.count, a.start + a.count);
      for (let _ = f, g = p - 1; _ < g; _ += c) {
        const m = Fu(this, e, Ol, l, _, _ + 1, _);
        m && t.push(m);
      }
      if (this.isLineLoop) {
        const _ = Fu(this, e, Ol, l, p - 1, f, p - 1);
        _ && t.push(_);
      }
    }
  }
  /**
   * Sets the values of {@link Line#morphTargetDictionary} and {@link Line#morphTargetInfluences}
   * to make sure existing morph targets can influence this 3D object.
   */
  updateMorphTargets() {
    const t = this.geometry.morphAttributes, n = Object.keys(t);
    if (n.length > 0) {
      const r = t[n[0]];
      if (r !== void 0) {
        this.morphTargetInfluences = [], this.morphTargetDictionary = {};
        for (let s = 0, a = r.length; s < a; s++) {
          const o = r[s].name || String(s);
          this.morphTargetInfluences.push(0), this.morphTargetDictionary[o] = s;
        }
      }
    }
  }
}
function Fu(i, e, t, n, r, s, a) {
  const o = i.geometry.attributes.position;
  if (Ih.fromBufferAttribute(o, r), Uh.fromBufferAttribute(o, s), t.distanceSqToSegment(Ih, Uh, of, w_) > n)
    return;
  of.applyMatrix4(i.matrixWorld);
  const c = e.ray.origin.distanceTo(of);
  if (!(c < e.near || c > e.far))
    return {
      distance: c,
      // What do we want? intersection point on the ray or on the segment??
      // point: raycaster.ray.at( distance ),
      point: w_.clone().applyMatrix4(i.matrixWorld),
      index: a,
      face: null,
      faceIndex: null,
      barycoord: null,
      object: i
    };
}
class gE extends jn {
  /**
   * Constructs a new points material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isPointsMaterial = !0, this.type = "PointsMaterial", this.color = new He(16777215), this.map = null, this.alphaMap = null, this.size = 1, this.sizeAttenuation = !0, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.alphaMap = e.alphaMap, this.size = e.size, this.sizeAttenuation = e.sizeAttenuation, this.fog = e.fog, this;
  }
}
class ny extends mn {
  /**
   * Constructs a new framebuffer texture.
   *
   * @param {number} [width] - The width of the texture.
   * @param {number} [height] - The height of the texture.
   */
  constructor(e, t) {
    super({ width: e, height: t }), this.isFramebufferTexture = !0, this.magFilter = Tt, this.minFilter = Tt, this.generateMipmaps = !1, this.needsUpdate = !0;
  }
}
class yl extends mn {
  /**
   * Constructs a new cube texture.
   *
   * @param {Array<Image>} [images=[]] - An array holding a image for each side of a cube.
   * @param {number} [mapping=CubeReflectionMapping] - The texture mapping.
   * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
   * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
   * @param {number} [magFilter=LinearFilter] - The mag filter value.
   * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value.
   * @param {number} [format=RGBAFormat] - The texture format.
   * @param {number} [type=UnsignedByteType] - The texture type.
   * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
   * @param {string} [colorSpace=NoColorSpace] - The color space value.
   */
  constructor(e = [], t = nr, n, r, s, a, o, l, c, u) {
    super(e, t, n, r, s, a, o, l, c, u), this.isCubeTexture = !0, this.flipY = !1;
  }
  /**
   * Alias for {@link CubeTexture#image}.
   *
   * @type {Array<Image>}
   */
  get images() {
    return this.image;
  }
  set images(e) {
    this.image = e;
  }
}
class oi extends mn {
  /**
   * Constructs a new depth texture.
   *
   * @param {number} width - The width of the texture.
   * @param {number} height - The height of the texture.
   * @param {number} [type=UnsignedIntType] - The texture type.
   * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
   * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
   * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
   * @param {number} [magFilter=LinearFilter] - The mag filter value.
   * @param {number} [minFilter=LinearFilter] - The min filter value.
   * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
   * @param {number} [format=DepthFormat] - The texture format.
   * @param {number} [depth=1] - The depth of the texture.
   */
  constructor(e, t, n = Dt, r, s, a, o = Tt, l = Tt, c, u = Un, h = 1) {
    if (u !== Un && u !== ii)
      throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");
    const d = { width: e, height: t, depth: h };
    super(d, r, s, a, o, l, u, n, c), this.isDepthTexture = !0, this.flipY = !1, this.generateMipmaps = !1, this.compareFunction = null;
  }
  copy(e) {
    return super.copy(e), this.source = new $m(Object.assign({}, e.image)), this.compareFunction = e.compareFunction, this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return this.compareFunction !== null && (t.compareFunction = this.compareFunction), t;
  }
}
class iy extends oi {
  /**
   * Constructs a new cube depth texture.
   *
   * @param {number} size - The size (width and height) of each cube face.
   * @param {number} [type=UnsignedIntType] - The texture type.
   * @param {number} [mapping=CubeReflectionMapping] - The texture mapping.
   * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
   * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
   * @param {number} [magFilter=NearestFilter] - The mag filter value.
   * @param {number} [minFilter=NearestFilter] - The min filter value.
   * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value.
   * @param {number} [format=DepthFormat] - The texture format.
   */
  constructor(e, t = Dt, n = nr, r, s, a = Tt, o = Tt, l, c = Un) {
    const u = { width: e, height: e, depth: 1 }, h = [u, u, u, u, u, u];
    super(e, e, t, n, r, s, a, o, l, c), this.image = h, this.isCubeDepthTexture = !0, this.isCubeTexture = !0;
  }
  /**
   * Alias for {@link CubeDepthTexture#image}.
   *
   * @type {Array<Image>}
   */
  get images() {
    return this.image;
  }
  set images(e) {
    this.image = e;
  }
}
class ry extends mn {
  /**
   * Creates a new raw texture.
   *
   * @param {?(WebGLTexture|GPUTexture)} [sourceTexture=null] - The external texture.
   */
  constructor(e = null) {
    super(), this.sourceTexture = e, this.isExternalTexture = !0;
  }
  copy(e) {
    return super.copy(e), this.sourceTexture = e.sourceTexture, this;
  }
}
class $a extends Pn {
  /**
   * Constructs a new box geometry.
   *
   * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis.
   * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis.
   * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis.
   * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides.
   * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides.
   * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides.
   */
  constructor(e = 1, t = 1, n = 1, r = 1, s = 1, a = 1) {
    super(), this.type = "BoxGeometry", this.parameters = {
      width: e,
      height: t,
      depth: n,
      widthSegments: r,
      heightSegments: s,
      depthSegments: a
    };
    const o = this;
    r = Math.floor(r), s = Math.floor(s), a = Math.floor(a);
    const l = [], c = [], u = [], h = [];
    let d = 0, f = 0;
    p("z", "y", "x", -1, -1, n, t, e, a, s, 0), p("z", "y", "x", 1, -1, n, t, -e, a, s, 1), p("x", "z", "y", 1, 1, e, n, t, r, a, 2), p("x", "z", "y", 1, -1, e, n, -t, r, a, 3), p("x", "y", "z", 1, -1, e, t, n, r, s, 4), p("x", "y", "z", -1, -1, e, t, -n, r, s, 5), this.setIndex(l), this.setAttribute("position", new an(c, 3)), this.setAttribute("normal", new an(u, 3)), this.setAttribute("uv", new an(h, 2));
    function p(_, g, m, x, y, b, T, S, E, v, M) {
      const F = b / E, R = T / v, I = b / 2, B = T / 2, N = S / 2, C = E + 1, L = v + 1;
      let k = 0, re = 0;
      const se = new P();
      for (let ve = 0; ve < L; ve++) {
        const X = ve * R - B;
        for (let te = 0; te < C; te++) {
          const me = te * F - I;
          se[_] = me * x, se[g] = X * y, se[m] = N, c.push(se.x, se.y, se.z), se[_] = 0, se[g] = 0, se[m] = S > 0 ? 1 : -1, u.push(se.x, se.y, se.z), h.push(te / E), h.push(1 - ve / v), k += 1;
        }
      }
      for (let ve = 0; ve < v; ve++)
        for (let X = 0; X < E; X++) {
          const te = d + X + C * ve, me = d + X + C * (ve + 1), Qe = d + (X + 1) + C * (ve + 1), ce = d + (X + 1) + C * ve;
          l.push(te, me, ce), l.push(me, Qe, ce), re += 6;
        }
      o.addGroup(f, re, M), f += re, d += k;
    }
  }
  copy(e) {
    return super.copy(e), this.parameters = Object.assign({}, e.parameters), this;
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {BoxGeometry} A new instance.
   */
  static fromJSON(e) {
    return new $a(e.width, e.height, e.depth, e.widthSegments, e.heightSegments, e.depthSegments);
  }
}
class iu extends Pn {
  /**
   * Constructs a new cylinder geometry.
   *
   * @param {number} [radiusTop=1] - Radius of the cylinder at the top.
   * @param {number} [radiusBottom=1] - Radius of the cylinder at the bottom.
   * @param {number} [height=1] - Height of the cylinder.
   * @param {number} [radialSegments=32] - Number of segmented faces around the circumference of the cylinder.
   * @param {number} [heightSegments=1] - Number of rows of faces along the height of the cylinder.
   * @param {boolean} [openEnded=false] - Whether the base of the cylinder is open or capped.
   * @param {number} [thetaStart=0] - Start angle for first segment, in radians.
   * @param {number} [thetaLength=Math.PI*2] - The central angle, often called theta, of the circular sector, in radians.
   * The default value results in a complete cylinder.
   */
  constructor(e = 1, t = 1, n = 1, r = 32, s = 1, a = !1, o = 0, l = Math.PI * 2) {
    super(), this.type = "CylinderGeometry", this.parameters = {
      radiusTop: e,
      radiusBottom: t,
      height: n,
      radialSegments: r,
      heightSegments: s,
      openEnded: a,
      thetaStart: o,
      thetaLength: l
    };
    const c = this;
    r = Math.floor(r), s = Math.floor(s);
    const u = [], h = [], d = [], f = [];
    let p = 0;
    const _ = [], g = n / 2;
    let m = 0;
    x(), a === !1 && (e > 0 && y(!0), t > 0 && y(!1)), this.setIndex(u), this.setAttribute("position", new an(h, 3)), this.setAttribute("normal", new an(d, 3)), this.setAttribute("uv", new an(f, 2));
    function x() {
      const b = new P(), T = new P();
      let S = 0;
      const E = (t - e) / n;
      for (let v = 0; v <= s; v++) {
        const M = [], F = v / s, R = F * (t - e) + e;
        for (let I = 0; I <= r; I++) {
          const B = I / r, N = B * l + o, C = Math.sin(N), L = Math.cos(N);
          T.x = R * C, T.y = -F * n + g, T.z = R * L, h.push(T.x, T.y, T.z), b.set(C, E, L).normalize(), d.push(b.x, b.y, b.z), f.push(B, 1 - F), M.push(p++);
        }
        _.push(M);
      }
      for (let v = 0; v < r; v++)
        for (let M = 0; M < s; M++) {
          const F = _[M][v], R = _[M + 1][v], I = _[M + 1][v + 1], B = _[M][v + 1];
          (e > 0 || M !== 0) && (u.push(F, R, B), S += 3), (t > 0 || M !== s - 1) && (u.push(R, I, B), S += 3);
        }
      c.addGroup(m, S, 0), m += S;
    }
    function y(b) {
      const T = p, S = new de(), E = new P();
      let v = 0;
      const M = b === !0 ? e : t, F = b === !0 ? 1 : -1;
      for (let I = 1; I <= r; I++)
        h.push(0, g * F, 0), d.push(0, F, 0), f.push(0.5, 0.5), p++;
      const R = p;
      for (let I = 0; I <= r; I++) {
        const N = I / r * l + o, C = Math.cos(N), L = Math.sin(N);
        E.x = M * L, E.y = g * F, E.z = M * C, h.push(E.x, E.y, E.z), d.push(0, F, 0), S.x = C * 0.5 + 0.5, S.y = L * 0.5 * F + 0.5, f.push(S.x, S.y), p++;
      }
      for (let I = 0; I < r; I++) {
        const B = T + I, N = R + I;
        b === !0 ? u.push(N, N + 1, B) : u.push(N + 1, N, B), v += 3;
      }
      c.addGroup(m, v, b === !0 ? 1 : 2), m += v;
    }
  }
  copy(e) {
    return super.copy(e), this.parameters = Object.assign({}, e.parameters), this;
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {CylinderGeometry} A new instance.
   */
  static fromJSON(e) {
    return new iu(e.radiusTop, e.radiusBottom, e.height, e.radialSegments, e.heightSegments, e.openEnded, e.thetaStart, e.thetaLength);
  }
}
class Jm extends iu {
  /**
   * Constructs a new cone geometry.
   *
   * @param {number} [radius=1] - Radius of the cone base.
   * @param {number} [height=1] - Height of the cone.
   * @param {number} [radialSegments=32] - Number of segmented faces around the circumference of the cone.
   * @param {number} [heightSegments=1] - Number of rows of faces along the height of the cone.
   * @param {boolean} [openEnded=false] - Whether the base of the cone is open or capped.
   * @param {number} [thetaStart=0] - Start angle for first segment, in radians.
   * @param {number} [thetaLength=Math.PI*2] - The central angle, often called theta, of the circular sector, in radians.
   * The default value results in a complete cone.
   */
  constructor(e = 1, t = 1, n = 32, r = 1, s = !1, a = 0, o = Math.PI * 2) {
    super(0, e, t, n, r, s, a, o), this.type = "ConeGeometry", this.parameters = {
      radius: e,
      height: t,
      radialSegments: n,
      heightSegments: r,
      openEnded: s,
      thetaStart: a,
      thetaLength: o
    };
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {ConeGeometry} A new instance.
   */
  static fromJSON(e) {
    return new Jm(e.radius, e.height, e.radialSegments, e.heightSegments, e.openEnded, e.thetaStart, e.thetaLength);
  }
}
class ds {
  /**
   * Constructs a new curve.
   */
  constructor() {
    this.type = "Curve", this.arcLengthDivisions = 200, this.needsUpdate = !1, this.cacheArcLengths = null;
  }
  /**
   * This method returns a vector in 2D or 3D space (depending on the curve definition)
   * for the given interpolation factor.
   *
   * @abstract
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
   * @return {(Vector2|Vector3)} The position on the curve. It can be a 2D or 3D vector depending on the curve definition.
   */
  getPoint() {
    oe("Curve: .getPoint() not implemented.");
  }
  /**
   * This method returns a vector in 2D or 3D space (depending on the curve definition)
   * for the given interpolation factor. Unlike {@link Curve#getPoint}, this method honors the length
   * of the curve which equidistant samples.
   *
   * @param {number} u - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
   * @return {(Vector2|Vector3)} The position on the curve. It can be a 2D or 3D vector depending on the curve definition.
   */
  getPointAt(e, t) {
    const n = this.getUtoTmapping(e);
    return this.getPoint(n, t);
  }
  /**
   * This method samples the curve via {@link Curve#getPoint} and returns an array of points representing
   * the curve shape.
   *
   * @param {number} [divisions=5] - The number of divisions.
   * @return {Array<(Vector2|Vector3)>} An array holding the sampled curve values. The number of points is `divisions + 1`.
   */
  getPoints(e = 5) {
    const t = [];
    for (let n = 0; n <= e; n++)
      t.push(this.getPoint(n / e));
    return t;
  }
  // Get sequence of points using getPointAt( u )
  /**
   * This method samples the curve via {@link Curve#getPointAt} and returns an array of points representing
   * the curve shape. Unlike {@link Curve#getPoints}, this method returns equi-spaced points across the entire
   * curve.
   *
   * @param {number} [divisions=5] - The number of divisions.
   * @return {Array<(Vector2|Vector3)>} An array holding the sampled curve values. The number of points is `divisions + 1`.
   */
  getSpacedPoints(e = 5) {
    const t = [];
    for (let n = 0; n <= e; n++)
      t.push(this.getPointAt(n / e));
    return t;
  }
  /**
   * Returns the total arc length of the curve.
   *
   * @return {number} The length of the curve.
   */
  getLength() {
    const e = this.getLengths();
    return e[e.length - 1];
  }
  /**
   * Returns an array of cumulative segment lengths of the curve.
   *
   * @param {number} [divisions=this.arcLengthDivisions] - The number of divisions.
   * @return {Array<number>} An array holding the cumulative segment lengths.
   */
  getLengths(e = this.arcLengthDivisions) {
    if (this.cacheArcLengths && this.cacheArcLengths.length === e + 1 && !this.needsUpdate)
      return this.cacheArcLengths;
    this.needsUpdate = !1;
    const t = [];
    let n, r = this.getPoint(0), s = 0;
    t.push(0);
    for (let a = 1; a <= e; a++)
      n = this.getPoint(a / e), s += n.distanceTo(r), t.push(s), r = n;
    return this.cacheArcLengths = t, t;
  }
  /**
   * Update the cumulative segment distance cache. The method must be called
   * every time curve parameters are changed. If an updated curve is part of a
   * composed curve like {@link CurvePath}, this method must be called on the
   * composed curve, too.
   */
  updateArcLengths() {
    this.needsUpdate = !0, this.getLengths();
  }
  /**
   * Given an interpolation factor in the range `[0,1]`, this method returns an updated
   * interpolation factor in the same range that can be ued to sample equidistant points
   * from a curve.
   *
   * @param {number} u - The interpolation factor.
   * @param {?number} distance - An optional distance on the curve.
   * @return {number} The updated interpolation factor.
   */
  getUtoTmapping(e, t = null) {
    const n = this.getLengths();
    let r = 0;
    const s = n.length;
    let a;
    t ? a = t : a = e * n[s - 1];
    let o = 0, l = s - 1, c;
    for (; o <= l; )
      if (r = Math.floor(o + (l - o) / 2), c = n[r] - a, c < 0)
        o = r + 1;
      else if (c > 0)
        l = r - 1;
      else {
        l = r;
        break;
      }
    if (r = l, n[r] === a)
      return r / (s - 1);
    const u = n[r], d = n[r + 1] - u, f = (a - u) / d;
    return (r + f) / (s - 1);
  }
  /**
   * Returns a unit vector tangent for the given interpolation factor.
   * If the derived curve does not implement its tangent derivation,
   * two points a small delta apart will be used to find its gradient
   * which seems to give a reasonable approximation.
   *
   * @param {number} t - The interpolation factor.
   * @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
   * @return {(Vector2|Vector3)} The tangent vector.
   */
  getTangent(e, t) {
    let r = e - 1e-4, s = e + 1e-4;
    r < 0 && (r = 0), s > 1 && (s = 1);
    const a = this.getPoint(r), o = this.getPoint(s), l = t || (a.isVector2 ? new de() : new P());
    return l.copy(o).sub(a).normalize(), l;
  }
  /**
   * Same as {@link Curve#getTangent} but with equidistant samples.
   *
   * @param {number} u - The interpolation factor.
   * @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
   * @return {(Vector2|Vector3)} The tangent vector.
   * @see {@link Curve#getPointAt}
   */
  getTangentAt(e, t) {
    const n = this.getUtoTmapping(e);
    return this.getTangent(n, t);
  }
  /**
   * Generates the Frenet Frames. Requires a curve definition in 3D space. Used
   * in geometries like {@link TubeGeometry} or {@link ExtrudeGeometry}.
   *
   * @param {number} segments - The number of segments.
   * @param {boolean} [closed=false] - Whether the curve is closed or not.
   * @return {{tangents: Array<Vector3>, normals: Array<Vector3>, binormals: Array<Vector3>}} The Frenet Frames.
   */
  computeFrenetFrames(e, t = !1) {
    const n = new P(), r = [], s = [], a = [], o = new P(), l = new pt();
    for (let f = 0; f <= e; f++) {
      const p = f / e;
      r[f] = this.getTangentAt(p, new P());
    }
    s[0] = new P(), a[0] = new P();
    let c = Number.MAX_VALUE;
    const u = Math.abs(r[0].x), h = Math.abs(r[0].y), d = Math.abs(r[0].z);
    u <= c && (c = u, n.set(1, 0, 0)), h <= c && (c = h, n.set(0, 1, 0)), d <= c && n.set(0, 0, 1), o.crossVectors(r[0], n).normalize(), s[0].crossVectors(r[0], o), a[0].crossVectors(r[0], s[0]);
    for (let f = 1; f <= e; f++) {
      if (s[f] = s[f - 1].clone(), a[f] = a[f - 1].clone(), o.crossVectors(r[f - 1], r[f]), o.length() > Number.EPSILON) {
        o.normalize();
        const p = Math.acos(ct(r[f - 1].dot(r[f]), -1, 1));
        s[f].applyMatrix4(l.makeRotationAxis(o, p));
      }
      a[f].crossVectors(r[f], s[f]);
    }
    if (t === !0) {
      let f = Math.acos(ct(s[0].dot(s[e]), -1, 1));
      f /= e, r[0].dot(o.crossVectors(s[0], s[e])) > 0 && (f = -f);
      for (let p = 1; p <= e; p++)
        s[p].applyMatrix4(l.makeRotationAxis(r[p], f * p)), a[p].crossVectors(r[p], s[p]);
    }
    return {
      tangents: r,
      normals: s,
      binormals: a
    };
  }
  /**
   * Returns a new curve with copied values from this instance.
   *
   * @return {Curve} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Copies the values of the given curve to this instance.
   *
   * @param {Curve} source - The curve to copy.
   * @return {Curve} A reference to this curve.
   */
  copy(e) {
    return this.arcLengthDivisions = e.arcLengthDivisions, this;
  }
  /**
   * Serializes the curve into JSON.
   *
   * @return {Object} A JSON object representing the serialized curve.
   * @see {@link ObjectLoader#parse}
   */
  toJSON() {
    const e = {
      metadata: {
        version: 4.7,
        type: "Curve",
        generator: "Curve.toJSON"
      }
    };
    return e.arcLengthDivisions = this.arcLengthDivisions, e.type = this.type, e;
  }
  /**
   * Deserializes the curve from the given JSON.
   *
   * @param {Object} json - The JSON holding the serialized curve.
   * @return {Curve} A reference to this curve.
   */
  fromJSON(e) {
    return this.arcLengthDivisions = e.arcLengthDivisions, this;
  }
}
class sy extends ds {
  /**
   * Constructs a new ellipse curve.
   *
   * @param {number} [aX=0] - The X center of the ellipse.
   * @param {number} [aY=0] - The Y center of the ellipse.
   * @param {number} [xRadius=1] - The radius of the ellipse in the x direction.
   * @param {number} [yRadius=1] - The radius of the ellipse in the y direction.
   * @param {number} [aStartAngle=0] - The start angle of the curve in radians starting from the positive X axis.
   * @param {number} [aEndAngle=Math.PI*2] - The end angle of the curve in radians starting from the positive X axis.
   * @param {boolean} [aClockwise=false] - Whether the ellipse is drawn clockwise or not.
   * @param {number} [aRotation=0] - The rotation angle of the ellipse in radians, counterclockwise from the positive X axis.
   */
  constructor(e = 0, t = 0, n = 1, r = 1, s = 0, a = Math.PI * 2, o = !1, l = 0) {
    super(), this.isEllipseCurve = !0, this.type = "EllipseCurve", this.aX = e, this.aY = t, this.xRadius = n, this.yRadius = r, this.aStartAngle = s, this.aEndAngle = a, this.aClockwise = o, this.aRotation = l;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector2} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector2} The position on the curve.
   */
  getPoint(e, t = new de()) {
    const n = t, r = Math.PI * 2;
    let s = this.aEndAngle - this.aStartAngle;
    const a = Math.abs(s) < Number.EPSILON;
    for (; s < 0; )
      s += r;
    for (; s > r; )
      s -= r;
    s < Number.EPSILON && (a ? s = 0 : s = r), this.aClockwise === !0 && !a && (s === r ? s = -r : s = s - r);
    const o = this.aStartAngle + e * s;
    let l = this.aX + this.xRadius * Math.cos(o), c = this.aY + this.yRadius * Math.sin(o);
    if (this.aRotation !== 0) {
      const u = Math.cos(this.aRotation), h = Math.sin(this.aRotation), d = l - this.aX, f = c - this.aY;
      l = d * u - f * h + this.aX, c = d * h + f * u + this.aY;
    }
    return n.set(l, c);
  }
  copy(e) {
    return super.copy(e), this.aX = e.aX, this.aY = e.aY, this.xRadius = e.xRadius, this.yRadius = e.yRadius, this.aStartAngle = e.aStartAngle, this.aEndAngle = e.aEndAngle, this.aClockwise = e.aClockwise, this.aRotation = e.aRotation, this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.aX = this.aX, e.aY = this.aY, e.xRadius = this.xRadius, e.yRadius = this.yRadius, e.aStartAngle = this.aStartAngle, e.aEndAngle = this.aEndAngle, e.aClockwise = this.aClockwise, e.aRotation = this.aRotation, e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.aX = e.aX, this.aY = e.aY, this.xRadius = e.xRadius, this.yRadius = e.yRadius, this.aStartAngle = e.aStartAngle, this.aEndAngle = e.aEndAngle, this.aClockwise = e.aClockwise, this.aRotation = e.aRotation, this;
  }
}
class _E extends sy {
  /**
   * Constructs a new arc curve.
   *
   * @param {number} [aX=0] - The X center of the ellipse.
   * @param {number} [aY=0] - The Y center of the ellipse.
   * @param {number} [aRadius=1] - The radius of the ellipse in the x direction.
   * @param {number} [aStartAngle=0] - The start angle of the curve in radians starting from the positive X axis.
   * @param {number} [aEndAngle=Math.PI*2] - The end angle of the curve in radians starting from the positive X axis.
   * @param {boolean} [aClockwise=false] - Whether the ellipse is drawn clockwise or not.
   */
  constructor(e, t, n, r, s, a) {
    super(e, t, n, n, r, s, a), this.isArcCurve = !0, this.type = "ArcCurve";
  }
}
function eg() {
  let i = 0, e = 0, t = 0, n = 0;
  function r(s, a, o, l) {
    i = s, e = o, t = -3 * s + 3 * a - 2 * o - l, n = 2 * s - 2 * a + o + l;
  }
  return {
    initCatmullRom: function(s, a, o, l, c) {
      r(a, o, c * (o - s), c * (l - a));
    },
    initNonuniformCatmullRom: function(s, a, o, l, c, u, h) {
      let d = (a - s) / c - (o - s) / (c + u) + (o - a) / u, f = (o - a) / u - (l - a) / (u + h) + (l - o) / h;
      d *= u, f *= u, r(a, o, d, f);
    },
    calc: function(s) {
      const a = s * s, o = a * s;
      return i + e * s + t * a + n * o;
    }
  };
}
const Iu = /* @__PURE__ */ new P(), lf = /* @__PURE__ */ new eg(), cf = /* @__PURE__ */ new eg(), uf = /* @__PURE__ */ new eg();
class xE extends ds {
  /**
   * Constructs a new Catmull-Rom curve.
   *
   * @param {Array<Vector3>} [points] - An array of 3D points defining the curve.
   * @param {boolean} [closed=false] - Whether the curve is closed or not.
   * @param {('centripetal'|'chordal'|'catmullrom')} [curveType='centripetal'] - The curve type.
   * @param {number} [tension=0.5] - Tension of the curve.
   */
  constructor(e = [], t = !1, n = "centripetal", r = 0.5) {
    super(), this.isCatmullRomCurve3 = !0, this.type = "CatmullRomCurve3", this.points = e, this.closed = t, this.curveType = n, this.tension = r;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector3} The position on the curve.
   */
  getPoint(e, t = new P()) {
    const n = t, r = this.points, s = r.length, a = (s - (this.closed ? 0 : 1)) * e;
    let o = Math.floor(a), l = a - o;
    this.closed ? o += o > 0 ? 0 : (Math.floor(Math.abs(o) / s) + 1) * s : l === 0 && o === s - 1 && (o = s - 2, l = 1);
    let c, u;
    this.closed || o > 0 ? c = r[(o - 1) % s] : (Iu.subVectors(r[0], r[1]).add(r[0]), c = Iu);
    const h = r[o % s], d = r[(o + 1) % s];
    if (this.closed || o + 2 < s ? u = r[(o + 2) % s] : (Iu.subVectors(r[s - 1], r[s - 2]).add(r[s - 1]), u = Iu), this.curveType === "centripetal" || this.curveType === "chordal") {
      const f = this.curveType === "chordal" ? 0.5 : 0.25;
      let p = Math.pow(c.distanceToSquared(h), f), _ = Math.pow(h.distanceToSquared(d), f), g = Math.pow(d.distanceToSquared(u), f);
      _ < 1e-4 && (_ = 1), p < 1e-4 && (p = _), g < 1e-4 && (g = _), lf.initNonuniformCatmullRom(c.x, h.x, d.x, u.x, p, _, g), cf.initNonuniformCatmullRom(c.y, h.y, d.y, u.y, p, _, g), uf.initNonuniformCatmullRom(c.z, h.z, d.z, u.z, p, _, g);
    } else
      this.curveType === "catmullrom" && (lf.initCatmullRom(c.x, h.x, d.x, u.x, this.tension), cf.initCatmullRom(c.y, h.y, d.y, u.y, this.tension), uf.initCatmullRom(c.z, h.z, d.z, u.z, this.tension));
    return n.set(
      lf.calc(l),
      cf.calc(l),
      uf.calc(l)
    ), n;
  }
  copy(e) {
    super.copy(e), this.points = [];
    for (let t = 0, n = e.points.length; t < n; t++) {
      const r = e.points[t];
      this.points.push(r.clone());
    }
    return this.closed = e.closed, this.curveType = e.curveType, this.tension = e.tension, this;
  }
  toJSON() {
    const e = super.toJSON();
    e.points = [];
    for (let t = 0, n = this.points.length; t < n; t++) {
      const r = this.points[t];
      e.points.push(r.toArray());
    }
    return e.closed = this.closed, e.curveType = this.curveType, e.tension = this.tension, e;
  }
  fromJSON(e) {
    super.fromJSON(e), this.points = [];
    for (let t = 0, n = e.points.length; t < n; t++) {
      const r = e.points[t];
      this.points.push(new P().fromArray(r));
    }
    return this.closed = e.closed, this.curveType = e.curveType, this.tension = e.tension, this;
  }
}
function A_(i, e, t, n, r) {
  const s = (n - e) * 0.5, a = (r - t) * 0.5, o = i * i, l = i * o;
  return (2 * t - 2 * n + s + a) * l + (-3 * t + 3 * n - 2 * s - a) * o + s * i + t;
}
function vE(i, e) {
  const t = 1 - i;
  return t * t * e;
}
function yE(i, e) {
  return 2 * (1 - i) * i * e;
}
function bE(i, e) {
  return i * i * e;
}
function mc(i, e, t, n) {
  return vE(i, e) + yE(i, t) + bE(i, n);
}
function SE(i, e) {
  const t = 1 - i;
  return t * t * t * e;
}
function TE(i, e) {
  const t = 1 - i;
  return 3 * t * t * i * e;
}
function ME(i, e) {
  return 3 * (1 - i) * i * i * e;
}
function EE(i, e) {
  return i * i * i * e;
}
function gc(i, e, t, n, r) {
  return SE(i, e) + TE(i, t) + ME(i, n) + EE(i, r);
}
class wE extends ds {
  /**
   * Constructs a new Cubic Bezier curve.
   *
   * @param {Vector2} [v0] - The start point.
   * @param {Vector2} [v1] - The first control point.
   * @param {Vector2} [v2] - The second control point.
   * @param {Vector2} [v3] - The end point.
   */
  constructor(e = new de(), t = new de(), n = new de(), r = new de()) {
    super(), this.isCubicBezierCurve = !0, this.type = "CubicBezierCurve", this.v0 = e, this.v1 = t, this.v2 = n, this.v3 = r;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector2} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector2} The position on the curve.
   */
  getPoint(e, t = new de()) {
    const n = t, r = this.v0, s = this.v1, a = this.v2, o = this.v3;
    return n.set(
      gc(e, r.x, s.x, a.x, o.x),
      gc(e, r.y, s.y, a.y, o.y)
    ), n;
  }
  copy(e) {
    return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this.v3.copy(e.v3), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e.v3 = this.v3.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this.v3.fromArray(e.v3), this;
  }
}
class ay extends ds {
  /**
   * Constructs a new Cubic Bezier curve.
   *
   * @param {Vector3} [v0] - The start point.
   * @param {Vector3} [v1] - The first control point.
   * @param {Vector3} [v2] - The second control point.
   * @param {Vector3} [v3] - The end point.
   */
  constructor(e = new P(), t = new P(), n = new P(), r = new P()) {
    super(), this.isCubicBezierCurve3 = !0, this.type = "CubicBezierCurve3", this.v0 = e, this.v1 = t, this.v2 = n, this.v3 = r;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector3} The position on the curve.
   */
  getPoint(e, t = new P()) {
    const n = t, r = this.v0, s = this.v1, a = this.v2, o = this.v3;
    return n.set(
      gc(e, r.x, s.x, a.x, o.x),
      gc(e, r.y, s.y, a.y, o.y),
      gc(e, r.z, s.z, a.z, o.z)
    ), n;
  }
  copy(e) {
    return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this.v3.copy(e.v3), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e.v3 = this.v3.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this.v3.fromArray(e.v3), this;
  }
}
class AE extends ds {
  /**
   * Constructs a new line curve.
   *
   * @param {Vector2} [v1] - The start point.
   * @param {Vector2} [v2] - The end point.
   */
  constructor(e = new de(), t = new de()) {
    super(), this.isLineCurve = !0, this.type = "LineCurve", this.v1 = e, this.v2 = t;
  }
  /**
   * Returns a point on the line.
   *
   * @param {number} t - A interpolation factor representing a position on the line. Must be in the range `[0,1]`.
   * @param {Vector2} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector2} The position on the line.
   */
  getPoint(e, t = new de()) {
    const n = t;
    return e === 1 ? n.copy(this.v2) : (n.copy(this.v2).sub(this.v1), n.multiplyScalar(e).add(this.v1)), n;
  }
  // Line curve is linear, so we can overwrite default getPointAt
  getPointAt(e, t) {
    return this.getPoint(e, t);
  }
  getTangent(e, t = new de()) {
    return t.subVectors(this.v2, this.v1).normalize();
  }
  getTangentAt(e, t) {
    return this.getTangent(e, t);
  }
  copy(e) {
    return super.copy(e), this.v1.copy(e.v1), this.v2.copy(e.v2), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this;
  }
}
class RE extends ds {
  /**
   * Constructs a new line curve.
   *
   * @param {Vector3} [v1] - The start point.
   * @param {Vector3} [v2] - The end point.
   */
  constructor(e = new P(), t = new P()) {
    super(), this.isLineCurve3 = !0, this.type = "LineCurve3", this.v1 = e, this.v2 = t;
  }
  /**
   * Returns a point on the line.
   *
   * @param {number} t - A interpolation factor representing a position on the line. Must be in the range `[0,1]`.
   * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector3} The position on the line.
   */
  getPoint(e, t = new P()) {
    const n = t;
    return e === 1 ? n.copy(this.v2) : (n.copy(this.v2).sub(this.v1), n.multiplyScalar(e).add(this.v1)), n;
  }
  // Line curve is linear, so we can overwrite default getPointAt
  getPointAt(e, t) {
    return this.getPoint(e, t);
  }
  getTangent(e, t = new P()) {
    return t.subVectors(this.v2, this.v1).normalize();
  }
  getTangentAt(e, t) {
    return this.getTangent(e, t);
  }
  copy(e) {
    return super.copy(e), this.v1.copy(e.v1), this.v2.copy(e.v2), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this;
  }
}
class CE extends ds {
  /**
   * Constructs a new Quadratic Bezier curve.
   *
   * @param {Vector2} [v0] - The start point.
   * @param {Vector2} [v1] - The control point.
   * @param {Vector2} [v2] - The end point.
   */
  constructor(e = new de(), t = new de(), n = new de()) {
    super(), this.isQuadraticBezierCurve = !0, this.type = "QuadraticBezierCurve", this.v0 = e, this.v1 = t, this.v2 = n;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector2} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector2} The position on the curve.
   */
  getPoint(e, t = new de()) {
    const n = t, r = this.v0, s = this.v1, a = this.v2;
    return n.set(
      mc(e, r.x, s.x, a.x),
      mc(e, r.y, s.y, a.y)
    ), n;
  }
  copy(e) {
    return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this;
  }
}
class tg extends ds {
  /**
   * Constructs a new Quadratic Bezier curve.
   *
   * @param {Vector3} [v0] - The start point.
   * @param {Vector3} [v1] - The control point.
   * @param {Vector3} [v2] - The end point.
   */
  constructor(e = new P(), t = new P(), n = new P()) {
    super(), this.isQuadraticBezierCurve3 = !0, this.type = "QuadraticBezierCurve3", this.v0 = e, this.v1 = t, this.v2 = n;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector3} The position on the curve.
   */
  getPoint(e, t = new P()) {
    const n = t, r = this.v0, s = this.v1, a = this.v2;
    return n.set(
      mc(e, r.x, s.x, a.x),
      mc(e, r.y, s.y, a.y),
      mc(e, r.z, s.z, a.z)
    ), n;
  }
  copy(e) {
    return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e;
  }
  fromJSON(e) {
    return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this;
  }
}
class NE extends ds {
  /**
   * Constructs a new 2D spline curve.
   *
   * @param {Array<Vector2>} [points] -  An array of 2D points defining the curve.
   */
  constructor(e = []) {
    super(), this.isSplineCurve = !0, this.type = "SplineCurve", this.points = e;
  }
  /**
   * Returns a point on the curve.
   *
   * @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
   * @param {Vector2} [optionalTarget] - The optional target vector the result is written to.
   * @return {Vector2} The position on the curve.
   */
  getPoint(e, t = new de()) {
    const n = t, r = this.points, s = (r.length - 1) * e, a = Math.floor(s), o = s - a, l = r[a === 0 ? a : a - 1], c = r[a], u = r[a > r.length - 2 ? r.length - 1 : a + 1], h = r[a > r.length - 3 ? r.length - 1 : a + 2];
    return n.set(
      A_(o, l.x, c.x, u.x, h.x),
      A_(o, l.y, c.y, u.y, h.y)
    ), n;
  }
  copy(e) {
    super.copy(e), this.points = [];
    for (let t = 0, n = e.points.length; t < n; t++) {
      const r = e.points[t];
      this.points.push(r.clone());
    }
    return this;
  }
  toJSON() {
    const e = super.toJSON();
    e.points = [];
    for (let t = 0, n = this.points.length; t < n; t++) {
      const r = this.points[t];
      e.points.push(r.toArray());
    }
    return e;
  }
  fromJSON(e) {
    super.fromJSON(e), this.points = [];
    for (let t = 0, n = e.points.length; t < n; t++) {
      const r = e.points[t];
      this.points.push(new de().fromArray(r));
    }
    return this;
  }
}
var PE = /* @__PURE__ */ Object.freeze({
  __proto__: null,
  ArcCurve: _E,
  CatmullRomCurve3: xE,
  CubicBezierCurve: wE,
  CubicBezierCurve3: ay,
  EllipseCurve: sy,
  LineCurve: AE,
  LineCurve3: RE,
  QuadraticBezierCurve: CE,
  QuadraticBezierCurve3: tg,
  SplineCurve: NE
});
class ru extends Pn {
  /**
   * Constructs a new plane geometry.
   *
   * @param {number} [width=1] - The width along the X axis.
   * @param {number} [height=1] - The height along the Y axis
   * @param {number} [widthSegments=1] - The number of segments along the X axis.
   * @param {number} [heightSegments=1] - The number of segments along the Y axis.
   */
  constructor(e = 1, t = 1, n = 1, r = 1) {
    super(), this.type = "PlaneGeometry", this.parameters = {
      width: e,
      height: t,
      widthSegments: n,
      heightSegments: r
    };
    const s = e / 2, a = t / 2, o = Math.floor(n), l = Math.floor(r), c = o + 1, u = l + 1, h = e / o, d = t / l, f = [], p = [], _ = [], g = [];
    for (let m = 0; m < u; m++) {
      const x = m * d - a;
      for (let y = 0; y < c; y++) {
        const b = y * h - s;
        p.push(b, -x, 0), _.push(0, 0, 1), g.push(y / o), g.push(1 - m / l);
      }
    }
    for (let m = 0; m < l; m++)
      for (let x = 0; x < o; x++) {
        const y = x + c * m, b = x + c * (m + 1), T = x + 1 + c * (m + 1), S = x + 1 + c * m;
        f.push(y, b, S), f.push(b, T, S);
      }
    this.setIndex(f), this.setAttribute("position", new an(p, 3)), this.setAttribute("normal", new an(_, 3)), this.setAttribute("uv", new an(g, 2));
  }
  copy(e) {
    return super.copy(e), this.parameters = Object.assign({}, e.parameters), this;
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {PlaneGeometry} A new instance.
   */
  static fromJSON(e) {
    return new ru(e.width, e.height, e.widthSegments, e.heightSegments);
  }
}
class su extends Pn {
  /**
   * Constructs a new sphere geometry.
   *
   * @param {number} [radius=1] - The sphere radius.
   * @param {number} [widthSegments=32] - The number of horizontal segments. Minimum value is `3`.
   * @param {number} [heightSegments=16] - The number of vertical segments. Minimum value is `2`.
   * @param {number} [phiStart=0] - The horizontal starting angle in radians.
   * @param {number} [phiLength=Math.PI*2] - The horizontal sweep angle size.
   * @param {number} [thetaStart=0] - The vertical starting angle in radians.
   * @param {number} [thetaLength=Math.PI] - The vertical sweep angle size.
   */
  constructor(e = 1, t = 32, n = 16, r = 0, s = Math.PI * 2, a = 0, o = Math.PI) {
    super(), this.type = "SphereGeometry", this.parameters = {
      radius: e,
      widthSegments: t,
      heightSegments: n,
      phiStart: r,
      phiLength: s,
      thetaStart: a,
      thetaLength: o
    }, t = Math.max(3, Math.floor(t)), n = Math.max(2, Math.floor(n));
    const l = Math.min(a + o, Math.PI);
    let c = 0;
    const u = [], h = new P(), d = new P(), f = [], p = [], _ = [], g = [];
    for (let m = 0; m <= n; m++) {
      const x = [], y = m / n;
      let b = 0;
      m === 0 && a === 0 ? b = 0.5 / t : m === n && l === Math.PI && (b = -0.5 / t);
      for (let T = 0; T <= t; T++) {
        const S = T / t;
        h.x = -e * Math.cos(r + S * s) * Math.sin(a + y * o), h.y = e * Math.cos(a + y * o), h.z = e * Math.sin(r + S * s) * Math.sin(a + y * o), p.push(h.x, h.y, h.z), d.copy(h).normalize(), _.push(d.x, d.y, d.z), g.push(S + b, 1 - y), x.push(c++);
      }
      u.push(x);
    }
    for (let m = 0; m < n; m++)
      for (let x = 0; x < t; x++) {
        const y = u[m][x + 1], b = u[m][x], T = u[m + 1][x], S = u[m + 1][x + 1];
        (m !== 0 || a > 0) && f.push(y, b, S), (m !== n - 1 || l < Math.PI) && f.push(b, T, S);
      }
    this.setIndex(f), this.setAttribute("position", new an(p, 3)), this.setAttribute("normal", new an(_, 3)), this.setAttribute("uv", new an(g, 2));
  }
  copy(e) {
    return super.copy(e), this.parameters = Object.assign({}, e.parameters), this;
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {SphereGeometry} A new instance.
   */
  static fromJSON(e) {
    return new su(e.radius, e.widthSegments, e.heightSegments, e.phiStart, e.phiLength, e.thetaStart, e.thetaLength);
  }
}
class ng extends Pn {
  /**
   * Constructs a new tube geometry.
   *
   * @param {Curve} [path=QuadraticBezierCurve3] - A 3D curve defining the path of the tube.
   * @param {number} [tubularSegments=64] - The number of segments that make up the tube.
   * @param {number} [radius=1] -The radius of the tube.
   * @param {number} [radialSegments=8] - The number of segments that make up the cross-section.
   * @param {boolean} [closed=false] - Whether the tube is closed or not.
   */
  constructor(e = new tg(new P(-1, -1, 0), new P(-1, 1, 0), new P(1, 1, 0)), t = 64, n = 1, r = 8, s = !1) {
    super(), this.type = "TubeGeometry", this.parameters = {
      path: e,
      tubularSegments: t,
      radius: n,
      radialSegments: r,
      closed: s
    };
    const a = e.computeFrenetFrames(t, s);
    this.tangents = a.tangents, this.normals = a.normals, this.binormals = a.binormals;
    const o = new P(), l = new P(), c = new de();
    let u = new P();
    const h = [], d = [], f = [], p = [];
    _(), this.setIndex(p), this.setAttribute("position", new an(h, 3)), this.setAttribute("normal", new an(d, 3)), this.setAttribute("uv", new an(f, 2));
    function _() {
      for (let y = 0; y < t; y++)
        g(y);
      g(s === !1 ? t : 0), x(), m();
    }
    function g(y) {
      u = e.getPointAt(y / t, u);
      const b = a.normals[y], T = a.binormals[y];
      for (let S = 0; S <= r; S++) {
        const E = S / r * Math.PI * 2, v = Math.sin(E), M = -Math.cos(E);
        l.x = M * b.x + v * T.x, l.y = M * b.y + v * T.y, l.z = M * b.z + v * T.z, l.normalize(), d.push(l.x, l.y, l.z), o.x = u.x + n * l.x, o.y = u.y + n * l.y, o.z = u.z + n * l.z, h.push(o.x, o.y, o.z);
      }
    }
    function m() {
      for (let y = 1; y <= t; y++)
        for (let b = 1; b <= r; b++) {
          const T = (r + 1) * (y - 1) + (b - 1), S = (r + 1) * y + (b - 1), E = (r + 1) * y + b, v = (r + 1) * (y - 1) + b;
          p.push(T, S, v), p.push(S, E, v);
        }
    }
    function x() {
      for (let y = 0; y <= t; y++)
        for (let b = 0; b <= r; b++)
          c.x = y / t, c.y = b / r, f.push(c.x, c.y);
    }
  }
  copy(e) {
    return super.copy(e), this.parameters = Object.assign({}, e.parameters), this;
  }
  toJSON() {
    const e = super.toJSON();
    return e.path = this.parameters.path.toJSON(), e;
  }
  /**
   * Factory method for creating an instance of this class from the given
   * JSON object.
   *
   * @param {Object} data - A JSON object representing the serialized geometry.
   * @return {TubeGeometry} A new instance.
   */
  static fromJSON(e) {
    return new ng(
      new PE[e.path.type]().fromJSON(e.path),
      e.tubularSegments,
      e.radius,
      e.radialSegments,
      e.closed
    );
  }
}
class DE extends jn {
  /**
   * Constructs a new shadow material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isShadowMaterial = !0, this.type = "ShadowMaterial", this.color = new He(0), this.transparent = !0, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.fog = e.fog, this;
  }
}
function ul(i) {
  const e = {};
  for (const t in i) {
    e[t] = {};
    for (const n in i[t]) {
      const r = i[t][n];
      r && (r.isColor || r.isMatrix3 || r.isMatrix4 || r.isVector2 || r.isVector3 || r.isVector4 || r.isTexture || r.isQuaternion) ? r.isRenderTargetTexture ? (oe("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."), e[t][n] = null) : e[t][n] = r.clone() : Array.isArray(r) ? e[t][n] = r.slice() : e[t][n] = r;
    }
  }
  return e;
}
function Zn(i) {
  const e = {};
  for (let t = 0; t < i.length; t++) {
    const n = ul(i[t]);
    for (const r in n)
      e[r] = n[r];
  }
  return e;
}
function LE(i) {
  const e = [];
  for (let t = 0; t < i.length; t++)
    e.push(i[t].clone());
  return e;
}
function oy(i) {
  const e = i.getRenderTarget();
  return e === null ? i.outputColorSpace : e.isXRRenderTarget === !0 ? e.texture.colorSpace : Ke.workingColorSpace;
}
const ly = { clone: ul, merge: Zn };
var FE = `void main() {
	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`, IE = `void main() {
	gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}`;
class Vi extends jn {
  /**
   * Constructs a new shader material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isShaderMaterial = !0, this.type = "ShaderMaterial", this.defines = {}, this.uniforms = {}, this.uniformsGroups = [], this.vertexShader = FE, this.fragmentShader = IE, this.linewidth = 1, this.wireframe = !1, this.wireframeLinewidth = 1, this.fog = !1, this.lights = !1, this.clipping = !1, this.forceSinglePass = !0, this.extensions = {
      clipCullDistance: !1,
      // set to use vertex shader clipping
      multiDraw: !1
      // set to use vertex shader multi_draw / enable gl_DrawID
    }, this.defaultAttributeValues = {
      color: [1, 1, 1],
      uv: [0, 0],
      uv1: [0, 0]
    }, this.index0AttributeName = void 0, this.uniformsNeedUpdate = !1, this.glslVersion = null, e !== void 0 && this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.fragmentShader = e.fragmentShader, this.vertexShader = e.vertexShader, this.uniforms = ul(e.uniforms), this.uniformsGroups = LE(e.uniformsGroups), this.defines = Object.assign({}, e.defines), this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.fog = e.fog, this.lights = e.lights, this.clipping = e.clipping, this.extensions = Object.assign({}, e.extensions), this.glslVersion = e.glslVersion, this.defaultAttributeValues = Object.assign({}, e.defaultAttributeValues), this.index0AttributeName = e.index0AttributeName, this.uniformsNeedUpdate = e.uniformsNeedUpdate, this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    t.glslVersion = this.glslVersion, t.uniforms = {};
    for (const r in this.uniforms) {
      const a = this.uniforms[r].value;
      a && a.isTexture ? t.uniforms[r] = {
        type: "t",
        value: a.toJSON(e).uuid
      } : a && a.isColor ? t.uniforms[r] = {
        type: "c",
        value: a.getHex()
      } : a && a.isVector2 ? t.uniforms[r] = {
        type: "v2",
        value: a.toArray()
      } : a && a.isVector3 ? t.uniforms[r] = {
        type: "v3",
        value: a.toArray()
      } : a && a.isVector4 ? t.uniforms[r] = {
        type: "v4",
        value: a.toArray()
      } : a && a.isMatrix3 ? t.uniforms[r] = {
        type: "m3",
        value: a.toArray()
      } : a && a.isMatrix4 ? t.uniforms[r] = {
        type: "m4",
        value: a.toArray()
      } : t.uniforms[r] = {
        value: a
      };
    }
    Object.keys(this.defines).length > 0 && (t.defines = this.defines), t.vertexShader = this.vertexShader, t.fragmentShader = this.fragmentShader, t.lights = this.lights, t.clipping = this.clipping;
    const n = {};
    for (const r in this.extensions)
      this.extensions[r] === !0 && (n[r] = !0);
    return Object.keys(n).length > 0 && (t.extensions = n), t;
  }
}
class UE extends Vi {
  /**
   * Constructs a new raw shader material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(e), this.isRawShaderMaterial = !0, this.type = "RawShaderMaterial";
  }
}
class cy extends jn {
  /**
   * Constructs a new mesh standard material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshStandardMaterial = !0, this.type = "MeshStandardMaterial", this.defines = { STANDARD: "" }, this.color = new He(16777215), this.roughness = 1, this.metalness = 0, this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new He(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.roughnessMap = null, this.metalnessMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new gi(), this.envMapIntensity = 1, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.flatShading = !1, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.defines = { STANDARD: "" }, this.color.copy(e.color), this.roughness = e.roughness, this.metalness = e.metalness, this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.roughnessMap = e.roughnessMap, this.metalnessMap = e.metalnessMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.envMapIntensity = e.envMapIntensity, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.flatShading = e.flatShading, this.fog = e.fog, this;
  }
}
class BE extends cy {
  /**
   * Constructs a new mesh physical material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshPhysicalMaterial = !0, this.defines = {
      STANDARD: "",
      PHYSICAL: ""
    }, this.type = "MeshPhysicalMaterial", this.anisotropyRotation = 0, this.anisotropyMap = null, this.clearcoatMap = null, this.clearcoatRoughness = 0, this.clearcoatRoughnessMap = null, this.clearcoatNormalScale = new de(1, 1), this.clearcoatNormalMap = null, this.ior = 1.5, Object.defineProperty(this, "reflectivity", {
      get: function() {
        return ct(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
      },
      set: function(t) {
        this.ior = (1 + 0.4 * t) / (1 - 0.4 * t);
      }
    }), this.iridescenceMap = null, this.iridescenceIOR = 1.3, this.iridescenceThicknessRange = [100, 400], this.iridescenceThicknessMap = null, this.sheenColor = new He(0), this.sheenColorMap = null, this.sheenRoughness = 1, this.sheenRoughnessMap = null, this.transmissionMap = null, this.thickness = 0, this.thicknessMap = null, this.attenuationDistance = 1 / 0, this.attenuationColor = new He(1, 1, 1), this.specularIntensity = 1, this.specularIntensityMap = null, this.specularColor = new He(1, 1, 1), this.specularColorMap = null, this._anisotropy = 0, this._clearcoat = 0, this._dispersion = 0, this._iridescence = 0, this._sheen = 0, this._transmission = 0, this.setValues(e);
  }
  /**
   * The anisotropy strength, from `0.0` to `1.0`.
   *
   * @type {number}
   * @default 0
   */
  get anisotropy() {
    return this._anisotropy;
  }
  set anisotropy(e) {
    this._anisotropy > 0 != e > 0 && this.version++, this._anisotropy = e;
  }
  /**
   * Represents the intensity of the clear coat layer, from `0.0` to `1.0`. Use
   * clear coat related properties to enable multilayer materials that have a
   * thin translucent layer over the base layer.
   *
   * @type {number}
   * @default 0
   */
  get clearcoat() {
    return this._clearcoat;
  }
  set clearcoat(e) {
    this._clearcoat > 0 != e > 0 && this.version++, this._clearcoat = e;
  }
  /**
   * The intensity of the iridescence layer, simulating RGB color shift based on the angle between
   * the surface and the viewer, from `0.0` to `1.0`.
   *
   * @type {number}
   * @default 0
   */
  get iridescence() {
    return this._iridescence;
  }
  set iridescence(e) {
    this._iridescence > 0 != e > 0 && this.version++, this._iridescence = e;
  }
  /**
   * Defines the strength of the angular separation of colors (chromatic aberration) transmitting
   * through a relatively clear volume. Any value zero or larger is valid, the typical range of
   * realistic values is `[0, 1]`. This property can be only be used with transmissive objects.
   *
   * @type {number}
   * @default 0
   */
  get dispersion() {
    return this._dispersion;
  }
  set dispersion(e) {
    this._dispersion > 0 != e > 0 && this.version++, this._dispersion = e;
  }
  /**
   * The intensity of the sheen layer, from `0.0` to `1.0`.
   *
   * @type {number}
   * @default 0
   */
  get sheen() {
    return this._sheen;
  }
  set sheen(e) {
    this._sheen > 0 != e > 0 && this.version++, this._sheen = e;
  }
  /**
   * Degree of transmission (or optical transparency), from `0.0` to `1.0`.
   *
   * Thin, transparent or semitransparent, plastic or glass materials remain
   * largely reflective even if they are fully transmissive. The transmission
   * property can be used to model these materials.
   *
   * When transmission is non-zero, `opacity` should be  set to `1`.
   *
   * @type {number}
   * @default 0
   */
  get transmission() {
    return this._transmission;
  }
  set transmission(e) {
    this._transmission > 0 != e > 0 && this.version++, this._transmission = e;
  }
  copy(e) {
    return super.copy(e), this.defines = {
      STANDARD: "",
      PHYSICAL: ""
    }, this.anisotropy = e.anisotropy, this.anisotropyRotation = e.anisotropyRotation, this.anisotropyMap = e.anisotropyMap, this.clearcoat = e.clearcoat, this.clearcoatMap = e.clearcoatMap, this.clearcoatRoughness = e.clearcoatRoughness, this.clearcoatRoughnessMap = e.clearcoatRoughnessMap, this.clearcoatNormalMap = e.clearcoatNormalMap, this.clearcoatNormalScale.copy(e.clearcoatNormalScale), this.dispersion = e.dispersion, this.ior = e.ior, this.iridescence = e.iridescence, this.iridescenceMap = e.iridescenceMap, this.iridescenceIOR = e.iridescenceIOR, this.iridescenceThicknessRange = [...e.iridescenceThicknessRange], this.iridescenceThicknessMap = e.iridescenceThicknessMap, this.sheen = e.sheen, this.sheenColor.copy(e.sheenColor), this.sheenColorMap = e.sheenColorMap, this.sheenRoughness = e.sheenRoughness, this.sheenRoughnessMap = e.sheenRoughnessMap, this.transmission = e.transmission, this.transmissionMap = e.transmissionMap, this.thickness = e.thickness, this.thicknessMap = e.thicknessMap, this.attenuationDistance = e.attenuationDistance, this.attenuationColor.copy(e.attenuationColor), this.specularIntensity = e.specularIntensity, this.specularIntensityMap = e.specularIntensityMap, this.specularColor.copy(e.specularColor), this.specularColorMap = e.specularColorMap, this;
  }
}
class OE extends jn {
  /**
   * Constructs a new mesh phong material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshPhongMaterial = !0, this.type = "MeshPhongMaterial", this.color = new He(16777215), this.specular = new He(1118481), this.shininess = 30, this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new He(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.specularMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new gi(), this.combine = Qc, this.reflectivity = 1, this.envMapIntensity = 1, this.refractionRatio = 0.98, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.flatShading = !1, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.specular.copy(e.specular), this.shininess = e.shininess, this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.specularMap = e.specularMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.combine = e.combine, this.reflectivity = e.reflectivity, this.envMapIntensity = e.envMapIntensity, this.refractionRatio = e.refractionRatio, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.flatShading = e.flatShading, this.fog = e.fog, this;
  }
}
class kE extends jn {
  /**
   * Constructs a new mesh toon material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshToonMaterial = !0, this.defines = { TOON: "" }, this.type = "MeshToonMaterial", this.color = new He(16777215), this.map = null, this.gradientMap = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new He(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.alphaMap = null, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.gradientMap = e.gradientMap, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.alphaMap = e.alphaMap, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.fog = e.fog, this;
  }
}
class GE extends jn {
  /**
   * Constructs a new mesh normal material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshNormalMaterial = !0, this.type = "MeshNormalMaterial", this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.wireframe = !1, this.wireframeLinewidth = 1, this.flatShading = !1, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.flatShading = e.flatShading, this;
  }
}
class uy extends jn {
  /**
   * Constructs a new mesh lambert material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshLambertMaterial = !0, this.type = "MeshLambertMaterial", this.color = new He(16777215), this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new He(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.specularMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new gi(), this.combine = Qc, this.reflectivity = 1, this.envMapIntensity = 1, this.refractionRatio = 0.98, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.flatShading = !1, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.color.copy(e.color), this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.specularMap = e.specularMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.combine = e.combine, this.reflectivity = e.reflectivity, this.envMapIntensity = e.envMapIntensity, this.refractionRatio = e.refractionRatio, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.flatShading = e.flatShading, this.fog = e.fog, this;
  }
}
class VE extends jn {
  /**
   * Constructs a new mesh depth material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshDepthMaterial = !0, this.type = "MeshDepthMaterial", this.depthPacking = dM, this.map = null, this.alphaMap = null, this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.wireframe = !1, this.wireframeLinewidth = 1, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.depthPacking = e.depthPacking, this.map = e.map, this.alphaMap = e.alphaMap, this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this;
  }
}
class zE extends jn {
  /**
   * Constructs a new mesh distance material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshDistanceMaterial = !0, this.type = "MeshDistanceMaterial", this.map = null, this.alphaMap = null, this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.map = e.map, this.alphaMap = e.alphaMap, this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this;
  }
}
class HE extends jn {
  /**
   * Constructs a new mesh matcap material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isMeshMatcapMaterial = !0, this.defines = { MATCAP: "" }, this.type = "MeshMatcapMaterial", this.color = new He(16777215), this.matcap = null, this.map = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = wr, this.normalScale = new de(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.alphaMap = null, this.wireframe = !1, this.wireframeLinewidth = 1, this.flatShading = !1, this.fog = !0, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.defines = { MATCAP: "" }, this.color.copy(e.color), this.matcap = e.matcap, this.map = e.map, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.alphaMap = e.alphaMap, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.flatShading = e.flatShading, this.fog = e.fog, this;
  }
}
class $E extends ud {
  /**
   * Constructs a new line dashed material.
   *
   * @param {Object} [parameters] - An object with one or more properties
   * defining the material's appearance. Any property of the material
   * (including any property from inherited materials) can be passed
   * in here. Color values can be passed any type of value accepted
   * by {@link Color#set}.
   */
  constructor(e) {
    super(), this.isLineDashedMaterial = !0, this.type = "LineDashedMaterial", this.scale = 1, this.dashSize = 3, this.gapSize = 1, this.setValues(e);
  }
  copy(e) {
    return super.copy(e), this.scale = e.scale, this.dashSize = e.dashSize, this.gapSize = e.gapSize, this;
  }
}
const hf = {
  /**
   * Whether caching is enabled or not.
   *
   * @static
   * @type {boolean}
   * @default false
   */
  enabled: !1,
  /**
   * A dictionary that holds cached files.
   *
   * @static
   * @type {Object<string,Object>}
   */
  files: {},
  /**
   * Adds a cache entry with a key to reference the file. If this key already
   * holds a file, it is overwritten.
   *
   * @static
   * @param {string} key - The key to reference the cached file.
   * @param {Object} file -  The file to be cached.
   */
  add: function(i, e) {
    this.enabled !== !1 && (R_(i) || (this.files[i] = e));
  },
  /**
   * Gets the cached value for the given key.
   *
   * @static
   * @param {string} key - The key to reference the cached file.
   * @return {Object|undefined} The cached file. If the key does not exist `undefined` is returned.
   */
  get: function(i) {
    if (this.enabled !== !1 && !R_(i))
      return this.files[i];
  },
  /**
   * Removes the cached file associated with the given key.
   *
   * @static
   * @param {string} key - The key to reference the cached file.
   */
  remove: function(i) {
    delete this.files[i];
  },
  /**
   * Remove all values from the cache.
   *
   * @static
   */
  clear: function() {
    this.files = {};
  }
};
function R_(i) {
  try {
    const e = i.slice(i.indexOf(":") + 1);
    return new URL(e).protocol === "blob:";
  } catch {
    return !1;
  }
}
class WE {
  /**
   * Constructs a new loading manager.
   *
   * @param {Function} [onLoad] - Executes when all items have been loaded.
   * @param {Function} [onProgress] - Executes when single items have been loaded.
   * @param {Function} [onError] - Executes when an error occurs.
   */
  constructor(e, t, n) {
    const r = this;
    let s = !1, a = 0, o = 0, l;
    const c = [];
    this.onStart = void 0, this.onLoad = e, this.onProgress = t, this.onError = n, this._abortController = null, this.itemStart = function(u) {
      o++, s === !1 && r.onStart !== void 0 && r.onStart(u, a, o), s = !0;
    }, this.itemEnd = function(u) {
      a++, r.onProgress !== void 0 && r.onProgress(u, a, o), a === o && (s = !1, r.onLoad !== void 0 && r.onLoad());
    }, this.itemError = function(u) {
      r.onError !== void 0 && r.onError(u);
    }, this.resolveURL = function(u) {
      return l ? l(u) : u;
    }, this.setURLModifier = function(u) {
      return l = u, this;
    }, this.addHandler = function(u, h) {
      return c.push(u, h), this;
    }, this.removeHandler = function(u) {
      const h = c.indexOf(u);
      return h !== -1 && c.splice(h, 2), this;
    }, this.getHandler = function(u) {
      for (let h = 0, d = c.length; h < d; h += 2) {
        const f = c[h], p = c[h + 1];
        if (f.global && (f.lastIndex = 0), f.test(u))
          return p;
      }
      return null;
    }, this.abort = function() {
      return this.abortController.abort(), this._abortController = null, this;
    };
  }
  // TODO: Revert this back to a single member variable once this issue has been fixed
  // https://github.com/cloudflare/workerd/issues/3657
  /**
   * Used for aborting ongoing requests in loaders using this manager.
   *
   * @type {AbortController}
   */
  get abortController() {
    return this._abortController || (this._abortController = new AbortController()), this._abortController;
  }
}
const qE = /* @__PURE__ */ new WE();
class ig {
  /**
   * Constructs a new loader.
   *
   * @param {LoadingManager} [manager] - The loading manager.
   */
  constructor(e) {
    this.manager = e !== void 0 ? e : qE, this.crossOrigin = "anonymous", this.withCredentials = !1, this.path = "", this.resourcePath = "", this.requestHeader = {}, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this }));
  }
  /**
   * This method needs to be implemented by all concrete loaders. It holds the
   * logic for loading assets from the backend.
   *
   * @abstract
   * @param {string} url - The path/URL of the file to be loaded.
   * @param {Function} onLoad - Executed when the loading process has been finished.
   * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress.
   * @param {onErrorCallback} [onError] - Executed when errors occur.
   */
  load() {
  }
  /**
   * A async version of {@link Loader#load}.
   *
   * @param {string} url - The path/URL of the file to be loaded.
   * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress.
   * @return {Promise} A Promise that resolves when the asset has been loaded.
   */
  loadAsync(e, t) {
    const n = this;
    return new Promise(function(r, s) {
      n.load(e, r, t, s);
    });
  }
  /**
   * This method needs to be implemented by all concrete loaders. It holds the
   * logic for parsing the asset into three.js entities.
   *
   * @abstract
   * @param {any} data - The data to parse.
   */
  parse() {
  }
  /**
   * Sets the `crossOrigin` String to implement CORS for loading the URL
   * from a different domain that allows CORS.
   *
   * @param {string} crossOrigin - The `crossOrigin` value.
   * @return {Loader} A reference to this instance.
   */
  setCrossOrigin(e) {
    return this.crossOrigin = e, this;
  }
  /**
   * Whether the XMLHttpRequest uses credentials such as cookies, authorization
   * headers or TLS client certificates, see [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials).
   *
   * Note: This setting has no effect if you are loading files locally or from the same domain.
   *
   * @param {boolean} value - The `withCredentials` value.
   * @return {Loader} A reference to this instance.
   */
  setWithCredentials(e) {
    return this.withCredentials = e, this;
  }
  /**
   * Sets the base path for the asset.
   *
   * @param {string} path - The base path.
   * @return {Loader} A reference to this instance.
   */
  setPath(e) {
    return this.path = e, this;
  }
  /**
   * Sets the base path for dependent resources like textures.
   *
   * @param {string} resourcePath - The resource path.
   * @return {Loader} A reference to this instance.
   */
  setResourcePath(e) {
    return this.resourcePath = e, this;
  }
  /**
   * Sets the given request header.
   *
   * @param {Object} requestHeader - A [request header](https://developer.mozilla.org/en-US/docs/Glossary/Request_header)
   * for configuring the HTTP request.
   * @return {Loader} A reference to this instance.
   */
  setRequestHeader(e) {
    return this.requestHeader = e, this;
  }
  /**
   * This method can be implemented in loaders for aborting ongoing requests.
   *
   * @abstract
   * @return {Loader} A reference to this instance.
   */
  abort() {
    return this;
  }
}
ig.DEFAULT_MATERIAL_NAME = "__DEFAULT";
const oo = /* @__PURE__ */ new WeakMap();
class XE extends ig {
  /**
   * Constructs a new image loader.
   *
   * @param {LoadingManager} [manager] - The loading manager.
   */
  constructor(e) {
    super(e);
  }
  /**
   * Starts loading from the given URL and passes the loaded image
   * to the `onLoad()` callback. The method also returns a new `Image` object which can
   * directly be used for texture creation. If you do it this way, the texture
   * may pop up in your scene once the respective loading process is finished.
   *
   * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
   * @param {function(Image)} onLoad - Executed when the loading process has been finished.
   * @param {onProgressCallback} onProgress - Unsupported in this loader.
   * @param {onErrorCallback} onError - Executed when errors occur.
   * @return {Image} The image.
   */
  load(e, t, n, r) {
    this.path !== void 0 && (e = this.path + e), e = this.manager.resolveURL(e);
    const s = this, a = hf.get(`image:${e}`);
    if (a !== void 0) {
      if (a.complete === !0)
        s.manager.itemStart(e), setTimeout(function() {
          t && t(a), s.manager.itemEnd(e);
        }, 0);
      else {
        let h = oo.get(a);
        h === void 0 && (h = [], oo.set(a, h)), h.push({ onLoad: t, onError: r });
      }
      return a;
    }
    const o = zc("img");
    function l() {
      u(), t && t(this);
      const h = oo.get(this) || [];
      for (let d = 0; d < h.length; d++) {
        const f = h[d];
        f.onLoad && f.onLoad(this);
      }
      oo.delete(this), s.manager.itemEnd(e);
    }
    function c(h) {
      u(), r && r(h), hf.remove(`image:${e}`);
      const d = oo.get(this) || [];
      for (let f = 0; f < d.length; f++) {
        const p = d[f];
        p.onError && p.onError(h);
      }
      oo.delete(this), s.manager.itemError(e), s.manager.itemEnd(e);
    }
    function u() {
      o.removeEventListener("load", l, !1), o.removeEventListener("error", c, !1);
    }
    return o.addEventListener("load", l, !1), o.addEventListener("error", c, !1), e.slice(0, 5) !== "data:" && this.crossOrigin !== void 0 && (o.crossOrigin = this.crossOrigin), hf.add(`image:${e}`, o), s.manager.itemStart(e), o.src = e, o;
  }
}
class jE extends ig {
  /**
   * Constructs a new texture loader.
   *
   * @param {LoadingManager} [manager] - The loading manager.
   */
  constructor(e) {
    super(e);
  }
  /**
   * Starts loading from the given URL and pass the fully loaded texture
   * to the `onLoad()` callback. The method also returns a new texture object which can
   * directly be used for material creation. If you do it this way, the texture
   * may pop up in your scene once the respective loading process is finished.
   *
   * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
   * @param {function(Texture)} onLoad - Executed when the loading process has been finished.
   * @param {onProgressCallback} onProgress - Unsupported in this loader.
   * @param {onErrorCallback} onError - Executed when errors occur.
   * @return {Texture} The texture.
   */
  load(e, t, n, r) {
    const s = new mn(), a = new XE(this.manager);
    return a.setCrossOrigin(this.crossOrigin), a.setPath(this.path), a.load(e, function(o) {
      s.image = o, s.needsUpdate = !0, t !== void 0 && t(s);
    }, n, r), s;
  }
}
class Wa extends gn {
  /**
   * Constructs a new light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity.
   */
  constructor(e, t = 1) {
    super(), this.isLight = !0, this.type = "Light", this.color = new He(e), this.intensity = t;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
  copy(e, t) {
    return super.copy(e, t), this.color.copy(e.color), this.intensity = e.intensity, this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.color = this.color.getHex(), t.object.intensity = this.intensity, t;
  }
}
class YE extends Wa {
  /**
   * Constructs a new hemisphere light.
   *
   * @param {(number|Color|string)} [skyColor=0xffffff] - The light's sky color.
   * @param {(number|Color|string)} [groundColor=0xffffff] - The light's ground color.
   * @param {number} [intensity=1] - The light's strength/intensity.
   */
  constructor(e, t, n) {
    super(e, n), this.isHemisphereLight = !0, this.type = "HemisphereLight", this.position.copy(gn.DEFAULT_UP), this.updateMatrix(), this.groundColor = new He(t);
  }
  copy(e, t) {
    return super.copy(e, t), this.groundColor.copy(e.groundColor), this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.groundColor = this.groundColor.getHex(), t;
  }
}
const df = /* @__PURE__ */ new pt(), C_ = /* @__PURE__ */ new P(), N_ = /* @__PURE__ */ new P();
class rg {
  /**
   * Constructs a new light shadow.
   *
   * @param {Camera} camera - The light's view of the world.
   */
  constructor(e) {
    this.camera = e, this.intensity = 1, this.bias = 0, this.biasNode = null, this.normalBias = 0, this.radius = 1, this.blurSamples = 8, this.mapSize = new de(512, 512), this.mapType = Zt, this.map = null, this.mapPass = null, this.matrix = new pt(), this.autoUpdate = !0, this.needsUpdate = !1, this._frustum = new nu(), this._frameExtents = new de(1, 1), this._viewportCount = 1, this._viewports = [
      new rt(0, 0, 1, 1)
    ];
  }
  /**
   * Used internally by the renderer to get the number of viewports that need
   * to be rendered for this shadow.
   *
   * @return {number} The viewport count.
   */
  getViewportCount() {
    return this._viewportCount;
  }
  /**
   * Gets the shadow cameras frustum. Used internally by the renderer to cull objects.
   *
   * @return {Frustum} The shadow camera frustum.
   */
  getFrustum() {
    return this._frustum;
  }
  /**
   * Update the matrices for the camera and shadow, used internally by the renderer.
   *
   * @param {Light} light - The light for which the shadow is being rendered.
   */
  updateMatrices(e) {
    const t = this.camera, n = this.matrix;
    C_.setFromMatrixPosition(e.matrixWorld), t.position.copy(C_), N_.setFromMatrixPosition(e.target.matrixWorld), t.lookAt(N_), t.updateMatrixWorld(), df.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this._frustum.setFromProjectionMatrix(df, t.coordinateSystem, t.reversedDepth), t.coordinateSystem === Cr || t.reversedDepth ? n.set(
      0.5,
      0,
      0,
      0.5,
      0,
      0.5,
      0,
      0.5,
      0,
      0,
      1,
      0,
      // Identity Z (preserving the correct [0, 1] range from the projection matrix)
      0,
      0,
      0,
      1
    ) : n.set(
      0.5,
      0,
      0,
      0.5,
      0,
      0.5,
      0,
      0.5,
      0,
      0,
      0.5,
      0.5,
      0,
      0,
      0,
      1
    ), n.multiply(df);
  }
  /**
   * Returns a viewport definition for the given viewport index.
   *
   * @param {number} viewportIndex - The viewport index.
   * @return {Vector4} The viewport.
   */
  getViewport(e) {
    return this._viewports[e];
  }
  /**
   * Returns the frame extends.
   *
   * @return {Vector2} The frame extends.
   */
  getFrameExtents() {
    return this._frameExtents;
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   */
  dispose() {
    this.map && this.map.dispose(), this.mapPass && this.mapPass.dispose();
  }
  /**
   * Copies the values of the given light shadow instance to this instance.
   *
   * @param {LightShadow} source - The light shadow to copy.
   * @return {LightShadow} A reference to this light shadow instance.
   */
  copy(e) {
    return this.camera = e.camera.clone(), this.intensity = e.intensity, this.bias = e.bias, this.radius = e.radius, this.autoUpdate = e.autoUpdate, this.needsUpdate = e.needsUpdate, this.normalBias = e.normalBias, this.blurSamples = e.blurSamples, this.mapSize.copy(e.mapSize), this.biasNode = e.biasNode, this;
  }
  /**
   * Returns a new light shadow instance with copied values from this instance.
   *
   * @return {LightShadow} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Serializes the light shadow into JSON.
   *
   * @return {Object} A JSON object representing the serialized light shadow.
   * @see {@link ObjectLoader#parse}
   */
  toJSON() {
    const e = {};
    return this.intensity !== 1 && (e.intensity = this.intensity), this.bias !== 0 && (e.bias = this.bias), this.normalBias !== 0 && (e.normalBias = this.normalBias), this.radius !== 1 && (e.radius = this.radius), (this.mapSize.x !== 512 || this.mapSize.y !== 512) && (e.mapSize = this.mapSize.toArray()), e.camera = this.camera.toJSON(!1).object, delete e.camera.matrix, e;
  }
}
const Uu = /* @__PURE__ */ new P(), Bu = /* @__PURE__ */ new Gi(), ar = /* @__PURE__ */ new P();
class hy extends gn {
  /**
   * Constructs a new camera.
   */
  constructor() {
    super(), this.isCamera = !0, this.type = "Camera", this.matrixWorldInverse = new pt(), this.projectionMatrix = new pt(), this.projectionMatrixInverse = new pt(), this.coordinateSystem = si, this._reversedDepth = !1;
  }
  /**
   * The flag that indicates whether the camera uses a reversed depth buffer.
   *
   * @type {boolean}
   * @default false
   */
  get reversedDepth() {
    return this._reversedDepth;
  }
  copy(e, t) {
    return super.copy(e, t), this.matrixWorldInverse.copy(e.matrixWorldInverse), this.projectionMatrix.copy(e.projectionMatrix), this.projectionMatrixInverse.copy(e.projectionMatrixInverse), this.coordinateSystem = e.coordinateSystem, this;
  }
  /**
   * Returns a vector representing the ("look") direction of the 3D object in world space.
   *
   * This method is overwritten since cameras have a different forward vector compared to other
   * 3D objects. A camera looks down its local, negative z-axis by default.
   *
   * @param {Vector3} target - The target vector the result is stored to.
   * @return {Vector3} The 3D object's direction in world space.
   */
  getWorldDirection(e) {
    return super.getWorldDirection(e).negate();
  }
  updateMatrixWorld(e) {
    super.updateMatrixWorld(e), this.matrixWorld.decompose(Uu, Bu, ar), ar.x === 1 && ar.y === 1 && ar.z === 1 ? this.matrixWorldInverse.copy(this.matrixWorld).invert() : this.matrixWorldInverse.compose(Uu, Bu, ar.set(1, 1, 1)).invert();
  }
  updateWorldMatrix(e, t) {
    super.updateWorldMatrix(e, t), this.matrixWorld.decompose(Uu, Bu, ar), ar.x === 1 && ar.y === 1 && ar.z === 1 ? this.matrixWorldInverse.copy(this.matrixWorld).invert() : this.matrixWorldInverse.compose(Uu, Bu, ar.set(1, 1, 1)).invert();
  }
  clone() {
    return new this.constructor().copy(this);
  }
}
const bs = /* @__PURE__ */ new P(), P_ = /* @__PURE__ */ new de(), D_ = /* @__PURE__ */ new de();
class An extends hy {
  /**
   * Constructs a new perspective camera.
   *
   * @param {number} [fov=50] - The vertical field of view.
   * @param {number} [aspect=1] - The aspect ratio.
   * @param {number} [near=0.1] - The camera's near plane.
   * @param {number} [far=2000] - The camera's far plane.
   */
  constructor(e = 50, t = 1, n = 0.1, r = 2e3) {
    super(), this.isPerspectiveCamera = !0, this.type = "PerspectiveCamera", this.fov = e, this.zoom = 1, this.near = n, this.far = r, this.focus = 10, this.aspect = t, this.view = null, this.filmGauge = 35, this.filmOffset = 0, this.updateProjectionMatrix();
  }
  copy(e, t) {
    return super.copy(e, t), this.fov = e.fov, this.zoom = e.zoom, this.near = e.near, this.far = e.far, this.focus = e.focus, this.aspect = e.aspect, this.view = e.view === null ? null : Object.assign({}, e.view), this.filmGauge = e.filmGauge, this.filmOffset = e.filmOffset, this;
  }
  /**
   * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}.
   *
   * The default film gauge is 35, so that the focal length can be specified for
   * a 35mm (full frame) camera.
   *
   * @param {number} focalLength - Values for focal length and film gauge must have the same unit.
   */
  setFocalLength(e) {
    const t = 0.5 * this.getFilmHeight() / e;
    this.fov = Fa * 2 * Math.atan(t), this.updateProjectionMatrix();
  }
  /**
   * Returns the focal length from the current {@link PerspectiveCamera#fov} and
   * {@link PerspectiveCamera#filmGauge}.
   *
   * @return {number} The computed focal length.
   */
  getFocalLength() {
    const e = Math.tan(fc * 0.5 * this.fov);
    return 0.5 * this.getFilmHeight() / e;
  }
  /**
   * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}.
   *
   * @return {number} The effective FOV.
   */
  getEffectiveFOV() {
    return Fa * 2 * Math.atan(
      Math.tan(fc * 0.5 * this.fov) / this.zoom
    );
  }
  /**
   * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
   * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
   *
   * @return {number} The film width.
   */
  getFilmWidth() {
    return this.filmGauge * Math.min(this.aspect, 1);
  }
  /**
   * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
   * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
   *
   * @return {number} The film width.
   */
  getFilmHeight() {
    return this.filmGauge / Math.max(this.aspect, 1);
  }
  /**
   * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction.
   * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle.
   *
   * @param {number} distance - The viewing distance.
   * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector.
   * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector.
   */
  getViewBounds(e, t, n) {
    bs.set(-1, -1, 0.5).applyMatrix4(this.projectionMatrixInverse), t.set(bs.x, bs.y).multiplyScalar(-e / bs.z), bs.set(1, 1, 0.5).applyMatrix4(this.projectionMatrixInverse), n.set(bs.x, bs.y).multiplyScalar(-e / bs.z);
  }
  /**
   * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction.
   *
   * @param {number} distance - The viewing distance.
   * @param {Vector2} target - The target vector that is used to store result where x is width and y is height.
   * @returns {Vector2} The view size.
   */
  getViewSize(e, t) {
    return this.getViewBounds(e, P_, D_), t.subVectors(D_, P_);
  }
  /**
   * Sets an offset in a larger frustum. This is useful for multi-window or
   * multi-monitor/multi-machine setups.
   *
   * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
   * the monitors are in grid like this
   *```
   *   +---+---+---+
   *   | A | B | C |
   *   +---+---+---+
   *   | D | E | F |
   *   +---+---+---+
   *```
   * then for each monitor you would call it like this:
   *```js
   * const w = 1920;
   * const h = 1080;
   * const fullWidth = w * 3;
   * const fullHeight = h * 2;
   *
   * // --A--
   * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
   * // --B--
   * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
   * // --C--
   * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
   * // --D--
   * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
   * // --E--
   * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
   * // --F--
   * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
   * ```
   *
   * Note there is no reason monitors have to be the same size or in a grid.
   *
   * @param {number} fullWidth - The full width of multiview setup.
   * @param {number} fullHeight - The full height of multiview setup.
   * @param {number} x - The horizontal offset of the subcamera.
   * @param {number} y - The vertical offset of the subcamera.
   * @param {number} width - The width of subcamera.
   * @param {number} height - The height of subcamera.
   */
  setViewOffset(e, t, n, r, s, a) {
    this.aspect = e / t, this.view === null && (this.view = {
      enabled: !0,
      fullWidth: 1,
      fullHeight: 1,
      offsetX: 0,
      offsetY: 0,
      width: 1,
      height: 1
    }), this.view.enabled = !0, this.view.fullWidth = e, this.view.fullHeight = t, this.view.offsetX = n, this.view.offsetY = r, this.view.width = s, this.view.height = a, this.updateProjectionMatrix();
  }
  /**
   * Removes the view offset from the projection matrix.
   */
  clearViewOffset() {
    this.view !== null && (this.view.enabled = !1), this.updateProjectionMatrix();
  }
  /**
   * Updates the camera's projection matrix. Must be called after any change of
   * camera properties.
   */
  updateProjectionMatrix() {
    const e = this.near;
    let t = e * Math.tan(fc * 0.5 * this.fov) / this.zoom, n = 2 * t, r = this.aspect * n, s = -0.5 * r;
    const a = this.view;
    if (this.view !== null && this.view.enabled) {
      const l = a.fullWidth, c = a.fullHeight;
      s += a.offsetX * r / l, t -= a.offsetY * n / c, r *= a.width / l, n *= a.height / c;
    }
    const o = this.filmOffset;
    o !== 0 && (s += e * o / this.getFilmWidth()), this.projectionMatrix.makePerspective(s, s + r, t, t - n, e, this.far, this.coordinateSystem, this.reversedDepth), this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.fov = this.fov, t.object.zoom = this.zoom, t.object.near = this.near, t.object.far = this.far, t.object.focus = this.focus, t.object.aspect = this.aspect, this.view !== null && (t.object.view = Object.assign({}, this.view)), t.object.filmGauge = this.filmGauge, t.object.filmOffset = this.filmOffset, t;
  }
}
class KE extends rg {
  /**
   * Constructs a new spot light shadow.
   */
  constructor() {
    super(new An(50, 1, 0.5, 500)), this.isSpotLightShadow = !0, this.focus = 1, this.aspect = 1;
  }
  updateMatrices(e) {
    const t = this.camera, n = Fa * 2 * e.angle * this.focus, r = this.mapSize.width / this.mapSize.height * this.aspect, s = e.distance || t.far;
    (n !== t.fov || r !== t.aspect || s !== t.far) && (t.fov = n, t.aspect = r, t.far = s, t.updateProjectionMatrix()), super.updateMatrices(e);
  }
  copy(e) {
    return super.copy(e), this.focus = e.focus, this;
  }
}
class sg extends Wa {
  /**
   * Constructs a new spot light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
   * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
   * @param {number} [angle=Math.PI/3] - Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`.
   * @param {number} [penumbra=0] - Percent of the spotlight cone that is attenuated due to penumbra. Value range is `[0,1]`.
   * @param {number} [decay=2] - The amount the light dims along the distance of the light.
   */
  constructor(e, t, n = 0, r = Math.PI / 3, s = 0, a = 2) {
    super(e, t), this.isSpotLight = !0, this.type = "SpotLight", this.position.copy(gn.DEFAULT_UP), this.updateMatrix(), this.target = new gn(), this.distance = n, this.angle = r, this.penumbra = s, this.decay = a, this.map = null, this.shadow = new KE();
  }
  /**
   * The light's power. Power is the luminous power of the light measured in lumens (lm).
   *  Changing the power will also change the light's intensity.
   *
   * @type {number}
   */
  get power() {
    return this.intensity * Math.PI;
  }
  set power(e) {
    this.intensity = e / Math.PI;
  }
  dispose() {
    super.dispose(), this.shadow.dispose();
  }
  copy(e, t) {
    return super.copy(e, t), this.distance = e.distance, this.angle = e.angle, this.penumbra = e.penumbra, this.decay = e.decay, this.target = e.target.clone(), this.map = e.map, this.shadow = e.shadow.clone(), this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.distance = this.distance, t.object.angle = this.angle, t.object.decay = this.decay, t.object.penumbra = this.penumbra, t.object.target = this.target.uuid, this.map && this.map.isTexture && (t.object.map = this.map.toJSON(e).uuid), t.object.shadow = this.shadow.toJSON(), t;
  }
}
class ZE extends rg {
  /**
   * Constructs a new point light shadow.
   */
  constructor() {
    super(new An(90, 1, 0.5, 500)), this.isPointLightShadow = !0;
  }
}
class QE extends Wa {
  /**
   * Constructs a new point light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
   * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
   * @param {number} [decay=2] - The amount the light dims along the distance of the light.
   */
  constructor(e, t, n = 0, r = 2) {
    super(e, t), this.isPointLight = !0, this.type = "PointLight", this.distance = n, this.decay = r, this.shadow = new ZE();
  }
  /**
   * The light's power. Power is the luminous power of the light measured in lumens (lm).
   * Changing the power will also change the light's intensity.
   *
   * @type {number}
   */
  get power() {
    return this.intensity * 4 * Math.PI;
  }
  set power(e) {
    this.intensity = e / (4 * Math.PI);
  }
  dispose() {
    super.dispose(), this.shadow.dispose();
  }
  copy(e, t) {
    return super.copy(e, t), this.distance = e.distance, this.decay = e.decay, this.shadow = e.shadow.clone(), this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.distance = this.distance, t.object.decay = this.decay, t.object.shadow = this.shadow.toJSON(), t;
  }
}
class bl extends hy {
  /**
   * Constructs a new orthographic camera.
   *
   * @param {number} [left=-1] - The left plane of the camera's frustum.
   * @param {number} [right=1] - The right plane of the camera's frustum.
   * @param {number} [top=1] - The top plane of the camera's frustum.
   * @param {number} [bottom=-1] - The bottom plane of the camera's frustum.
   * @param {number} [near=0.1] - The camera's near plane.
   * @param {number} [far=2000] - The camera's far plane.
   */
  constructor(e = -1, t = 1, n = 1, r = -1, s = 0.1, a = 2e3) {
    super(), this.isOrthographicCamera = !0, this.type = "OrthographicCamera", this.zoom = 1, this.view = null, this.left = e, this.right = t, this.top = n, this.bottom = r, this.near = s, this.far = a, this.updateProjectionMatrix();
  }
  copy(e, t) {
    return super.copy(e, t), this.left = e.left, this.right = e.right, this.top = e.top, this.bottom = e.bottom, this.near = e.near, this.far = e.far, this.zoom = e.zoom, this.view = e.view === null ? null : Object.assign({}, e.view), this;
  }
  /**
   * Sets an offset in a larger frustum. This is useful for multi-window or
   * multi-monitor/multi-machine setups.
   *
   * @param {number} fullWidth - The full width of multiview setup.
   * @param {number} fullHeight - The full height of multiview setup.
   * @param {number} x - The horizontal offset of the subcamera.
   * @param {number} y - The vertical offset of the subcamera.
   * @param {number} width - The width of subcamera.
   * @param {number} height - The height of subcamera.
   * @see {@link PerspectiveCamera#setViewOffset}
   */
  setViewOffset(e, t, n, r, s, a) {
    this.view === null && (this.view = {
      enabled: !0,
      fullWidth: 1,
      fullHeight: 1,
      offsetX: 0,
      offsetY: 0,
      width: 1,
      height: 1
    }), this.view.enabled = !0, this.view.fullWidth = e, this.view.fullHeight = t, this.view.offsetX = n, this.view.offsetY = r, this.view.width = s, this.view.height = a, this.updateProjectionMatrix();
  }
  /**
   * Removes the view offset from the projection matrix.
   */
  clearViewOffset() {
    this.view !== null && (this.view.enabled = !1), this.updateProjectionMatrix();
  }
  /**
   * Updates the camera's projection matrix. Must be called after any change of
   * camera properties.
   */
  updateProjectionMatrix() {
    const e = (this.right - this.left) / (2 * this.zoom), t = (this.top - this.bottom) / (2 * this.zoom), n = (this.right + this.left) / 2, r = (this.top + this.bottom) / 2;
    let s = n - e, a = n + e, o = r + t, l = r - t;
    if (this.view !== null && this.view.enabled) {
      const c = (this.right - this.left) / this.view.fullWidth / this.zoom, u = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
      s += c * this.view.offsetX, a = s + c * this.view.width, o -= u * this.view.offsetY, l = o - u * this.view.height;
    }
    this.projectionMatrix.makeOrthographic(s, a, o, l, this.near, this.far, this.coordinateSystem, this.reversedDepth), this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.zoom = this.zoom, t.object.left = this.left, t.object.right = this.right, t.object.top = this.top, t.object.bottom = this.bottom, t.object.near = this.near, t.object.far = this.far, this.view !== null && (t.object.view = Object.assign({}, this.view)), t;
  }
}
class JE extends rg {
  /**
   * Constructs a new directional light shadow.
   */
  constructor() {
    super(new bl(-5, 5, 5, -5, 0.5, 500)), this.isDirectionalLightShadow = !0;
  }
}
class dy extends Wa {
  /**
   * Constructs a new directional light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity.
   */
  constructor(e, t) {
    super(e, t), this.isDirectionalLight = !0, this.type = "DirectionalLight", this.position.copy(gn.DEFAULT_UP), this.updateMatrix(), this.target = new gn(), this.shadow = new JE();
  }
  dispose() {
    super.dispose(), this.shadow.dispose();
  }
  copy(e) {
    return super.copy(e), this.target = e.target.clone(), this.shadow = e.shadow.clone(), this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.shadow = this.shadow.toJSON(), t.object.target = this.target.uuid, t;
  }
}
class fy extends Wa {
  /**
   * Constructs a new ambient light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity.
   */
  constructor(e, t) {
    super(e, t), this.isAmbientLight = !0, this.type = "AmbientLight";
  }
}
class ew extends Wa {
  /**
   * Constructs a new area light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity.
   * @param {number} [width=10] - The width of the light.
   * @param {number} [height=10] - The height of the light.
   */
  constructor(e, t, n = 10, r = 10) {
    super(e, t), this.isRectAreaLight = !0, this.type = "RectAreaLight", this.width = n, this.height = r;
  }
  /**
   * The light's power. Power is the luminous power of the light measured in lumens (lm).
   * Changing the power will also change the light's intensity.
   *
   * @type {number}
   */
  get power() {
    return this.intensity * this.width * this.height * Math.PI;
  }
  set power(e) {
    this.intensity = e / (this.width * this.height * Math.PI);
  }
  copy(e) {
    return super.copy(e), this.width = e.width, this.height = e.height, this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.width = this.width, t.object.height = this.height, t;
  }
}
class tw {
  /**
   * Constructs a new spherical harmonics.
   */
  constructor() {
    this.isSphericalHarmonics3 = !0, this.coefficients = [];
    for (let e = 0; e < 9; e++)
      this.coefficients.push(new P());
  }
  /**
   * Sets the given SH coefficients to this instance by copying
   * the values.
   *
   * @param {Array<Vector3>} coefficients - The SH coefficients.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  set(e) {
    for (let t = 0; t < 9; t++)
      this.coefficients[t].copy(e[t]);
    return this;
  }
  /**
   * Sets all SH coefficients to `0`.
   *
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  zero() {
    for (let e = 0; e < 9; e++)
      this.coefficients[e].set(0, 0, 0);
    return this;
  }
  /**
   * Returns the radiance in the direction of the given normal.
   *
   * @param {Vector3} normal - The normal vector (assumed to be unit length)
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The radiance.
   */
  getAt(e, t) {
    const n = e.x, r = e.y, s = e.z, a = this.coefficients;
    return t.copy(a[0]).multiplyScalar(0.282095), t.addScaledVector(a[1], 0.488603 * r), t.addScaledVector(a[2], 0.488603 * s), t.addScaledVector(a[3], 0.488603 * n), t.addScaledVector(a[4], 1.092548 * (n * r)), t.addScaledVector(a[5], 1.092548 * (r * s)), t.addScaledVector(a[6], 0.315392 * (3 * s * s - 1)), t.addScaledVector(a[7], 1.092548 * (n * s)), t.addScaledVector(a[8], 0.546274 * (n * n - r * r)), t;
  }
  /**
   * Returns the irradiance (radiance convolved with cosine lobe) in the
   * direction of the given normal.
   *
   * @param {Vector3} normal - The normal vector (assumed to be unit length)
   * @param {Vector3} target - The target vector that is used to store the method's result.
   * @return {Vector3} The irradiance.
   */
  getIrradianceAt(e, t) {
    const n = e.x, r = e.y, s = e.z, a = this.coefficients;
    return t.copy(a[0]).multiplyScalar(0.886227), t.addScaledVector(a[1], 2 * 0.511664 * r), t.addScaledVector(a[2], 2 * 0.511664 * s), t.addScaledVector(a[3], 2 * 0.511664 * n), t.addScaledVector(a[4], 2 * 0.429043 * n * r), t.addScaledVector(a[5], 2 * 0.429043 * r * s), t.addScaledVector(a[6], 0.743125 * s * s - 0.247708), t.addScaledVector(a[7], 2 * 0.429043 * n * s), t.addScaledVector(a[8], 0.429043 * (n * n - r * r)), t;
  }
  /**
   * Adds the given SH to this instance.
   *
   * @param {SphericalHarmonics3} sh - The SH to add.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  add(e) {
    for (let t = 0; t < 9; t++)
      this.coefficients[t].add(e.coefficients[t]);
    return this;
  }
  /**
   * A convenience method for performing {@link SphericalHarmonics3#add} and
   * {@link SphericalHarmonics3#scale} at once.
   *
   * @param {SphericalHarmonics3} sh - The SH to add.
   * @param {number} s - The scale factor.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  addScaledSH(e, t) {
    for (let n = 0; n < 9; n++)
      this.coefficients[n].addScaledVector(e.coefficients[n], t);
    return this;
  }
  /**
   * Scales this SH by the given scale factor.
   *
   * @param {number} s - The scale factor.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  scale(e) {
    for (let t = 0; t < 9; t++)
      this.coefficients[t].multiplyScalar(e);
    return this;
  }
  /**
   * Linear interpolates between the given SH and this instance by the given
   * alpha factor.
   *
   * @param {SphericalHarmonics3} sh - The SH to interpolate with.
   * @param {number} alpha - The alpha factor.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  lerp(e, t) {
    for (let n = 0; n < 9; n++)
      this.coefficients[n].lerp(e.coefficients[n], t);
    return this;
  }
  /**
   * Returns `true` if this spherical harmonics is equal with the given one.
   *
   * @param {SphericalHarmonics3} sh - The spherical harmonics to test for equality.
   * @return {boolean} Whether this spherical harmonics is equal with the given one.
   */
  equals(e) {
    for (let t = 0; t < 9; t++)
      if (!this.coefficients[t].equals(e.coefficients[t]))
        return !1;
    return !0;
  }
  /**
   * Copies the values of the given spherical harmonics to this instance.
   *
   * @param {SphericalHarmonics3} sh - The spherical harmonics to copy.
   * @return {SphericalHarmonics3} A reference to this spherical harmonics.
   */
  copy(e) {
    return this.set(e.coefficients);
  }
  /**
   * Returns a new spherical harmonics with copied values from this instance.
   *
   * @return {SphericalHarmonics3} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
  /**
   * Sets the SH coefficients of this instance from the given array.
   *
   * @param {Array<number>} array - An array holding the SH coefficients.
   * @param {number} [offset=0] - The array offset where to start copying.
   * @return {SphericalHarmonics3} A clone of this instance.
   */
  fromArray(e, t = 0) {
    const n = this.coefficients;
    for (let r = 0; r < 9; r++)
      n[r].fromArray(e, t + r * 3);
    return this;
  }
  /**
   * Returns an array with the SH coefficients, or copies them into the provided
   * array. The coefficients are represented as numbers.
   *
   * @param {Array<number>} [array=[]] - The target array.
   * @param {number} [offset=0] - The array offset where to start copying.
   * @return {Array<number>} An array with flat SH coefficients.
   */
  toArray(e = [], t = 0) {
    const n = this.coefficients;
    for (let r = 0; r < 9; r++)
      n[r].toArray(e, t + r * 3);
    return e;
  }
  /**
   * Computes the SH basis for the given normal vector.
   *
   * @param {Vector3} normal - The normal.
   * @param {Array<number>} shBasis - The target array holding the SH basis.
   */
  static getBasisAt(e, t) {
    const n = e.x, r = e.y, s = e.z;
    t[0] = 0.282095, t[1] = 0.488603 * r, t[2] = 0.488603 * s, t[3] = 0.488603 * n, t[4] = 1.092548 * n * r, t[5] = 1.092548 * r * s, t[6] = 0.315392 * (3 * s * s - 1), t[7] = 1.092548 * n * s, t[8] = 0.546274 * (n * n - r * r);
  }
}
class nw extends Wa {
  /**
   * Constructs a new light probe.
   *
   * @param {SphericalHarmonics3} sh - The spherical harmonics which represents encoded lighting information.
   * @param {number} [intensity=1] - The light's strength/intensity.
   */
  constructor(e = new tw(), t = 1) {
    super(void 0, t), this.isLightProbe = !0, this.sh = e;
  }
  copy(e) {
    return super.copy(e), this.sh.copy(e.sh), this;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.object.sh = this.sh.toArray(), t;
  }
}
const lo = -90, co = 1;
class py extends gn {
  /**
   * Constructs a new cube camera.
   *
   * @param {number} near - The camera's near plane.
   * @param {number} far - The camera's far plane.
   * @param {WebGLCubeRenderTarget} renderTarget - The cube render target.
   */
  constructor(e, t, n) {
    super(), this.type = "CubeCamera", this.renderTarget = n, this.coordinateSystem = null, this.activeMipmapLevel = 0;
    const r = new An(lo, co, e, t);
    r.layers = this.layers, this.add(r);
    const s = new An(lo, co, e, t);
    s.layers = this.layers, this.add(s);
    const a = new An(lo, co, e, t);
    a.layers = this.layers, this.add(a);
    const o = new An(lo, co, e, t);
    o.layers = this.layers, this.add(o);
    const l = new An(lo, co, e, t);
    l.layers = this.layers, this.add(l);
    const c = new An(lo, co, e, t);
    c.layers = this.layers, this.add(c);
  }
  /**
   * Must be called when the coordinate system of the cube camera is changed.
   */
  updateCoordinateSystem() {
    const e = this.coordinateSystem, t = this.children.concat(), [n, r, s, a, o, l] = t;
    for (const c of t)
      this.remove(c);
    if (e === si)
      n.up.set(0, 1, 0), n.lookAt(1, 0, 0), r.up.set(0, 1, 0), r.lookAt(-1, 0, 0), s.up.set(0, 0, -1), s.lookAt(0, 1, 0), a.up.set(0, 0, 1), a.lookAt(0, -1, 0), o.up.set(0, 1, 0), o.lookAt(0, 0, 1), l.up.set(0, 1, 0), l.lookAt(0, 0, -1);
    else if (e === Cr)
      n.up.set(0, -1, 0), n.lookAt(-1, 0, 0), r.up.set(0, -1, 0), r.lookAt(1, 0, 0), s.up.set(0, 0, 1), s.lookAt(0, 1, 0), a.up.set(0, 0, -1), a.lookAt(0, -1, 0), o.up.set(0, -1, 0), o.lookAt(0, 0, 1), l.up.set(0, -1, 0), l.lookAt(0, 0, -1);
    else
      throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: " + e);
    for (const c of t)
      this.add(c), c.updateMatrixWorld();
  }
  /**
   * Calling this method will render the given scene with the given renderer
   * into the cube render target of the camera.
   *
   * @param {(Renderer|WebGLRenderer)} renderer - The renderer.
   * @param {Scene} scene - The scene to render.
   */
  update(e, t) {
    this.parent === null && this.updateMatrixWorld();
    const { renderTarget: n, activeMipmapLevel: r } = this;
    this.coordinateSystem !== e.coordinateSystem && (this.coordinateSystem = e.coordinateSystem, this.updateCoordinateSystem());
    const [s, a, o, l, c, u] = this.children, h = e.getRenderTarget(), d = e.getActiveCubeFace(), f = e.getActiveMipmapLevel(), p = e.xr.enabled;
    e.xr.enabled = !1;
    const _ = n.texture.generateMipmaps;
    n.texture.generateMipmaps = !1;
    let g = !1;
    e.isWebGLRenderer === !0 ? g = e.state.buffers.depth.getReversed() : g = e.reversedDepthBuffer, e.setRenderTarget(n, 0, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, s), e.setRenderTarget(n, 1, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, a), e.setRenderTarget(n, 2, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, o), e.setRenderTarget(n, 3, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, l), e.setRenderTarget(n, 4, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, c), n.texture.generateMipmaps = _, e.setRenderTarget(n, 5, r), g && e.autoClear === !1 && e.clearDepth(), e.render(t, u), e.setRenderTarget(h, d, f), e.xr.enabled = p, n.texture.needsPMREMUpdate = !0;
  }
}
class my extends An {
  /**
   * Constructs a new array camera.
   *
   * @param {Array<PerspectiveCamera>} [array=[]] - An array of perspective sub cameras.
   */
  constructor(e = []) {
    super(), this.isArrayCamera = !0, this.isMultiViewCamera = !1, this.cameras = e;
  }
}
let iw = class {
  /**
   * Constructs a new timer.
   */
  constructor() {
    this._previousTime = 0, this._currentTime = 0, this._startTime = performance.now(), this._delta = 0, this._elapsed = 0, this._timescale = 1, this._document = null, this._pageVisibilityHandler = null;
  }
  /**
   * Connect the timer to the given document.Calling this method is not mandatory to
   * use the timer but enables the usage of the Page Visibility API to avoid large time
   * delta values.
   *
   * @param {Document} document - The document.
   */
  connect(e) {
    this._document = e, e.hidden !== void 0 && (this._pageVisibilityHandler = rw.bind(this), e.addEventListener("visibilitychange", this._pageVisibilityHandler, !1));
  }
  /**
   * Disconnects the timer from the DOM and also disables the usage of the Page Visibility API.
   */
  disconnect() {
    this._pageVisibilityHandler !== null && (this._document.removeEventListener("visibilitychange", this._pageVisibilityHandler), this._pageVisibilityHandler = null), this._document = null;
  }
  /**
   * Returns the time delta in seconds.
   *
   * @return {number} The time delta in second.
   */
  getDelta() {
    return this._delta / 1e3;
  }
  /**
   * Returns the elapsed time in seconds.
   *
   * @return {number} The elapsed time in second.
   */
  getElapsed() {
    return this._elapsed / 1e3;
  }
  /**
   * Returns the timescale.
   *
   * @return {number} The timescale.
   */
  getTimescale() {
    return this._timescale;
  }
  /**
   * Sets the given timescale which scale the time delta computation
   * in `update()`.
   *
   * @param {number} timescale - The timescale to set.
   * @return {Timer} A reference to this timer.
   */
  setTimescale(e) {
    return this._timescale = e, this;
  }
  /**
   * Resets the time computation for the current simulation step.
   *
   * @return {Timer} A reference to this timer.
   */
  reset() {
    return this._currentTime = performance.now() - this._startTime, this;
  }
  /**
   * Can be used to free all internal resources. Usually called when
   * the timer instance isn't required anymore.
   */
  dispose() {
    this.disconnect();
  }
  /**
   * Updates the internal state of the timer. This method should be called
   * once per simulation step and before you perform queries against the timer
   * (e.g. via `getDelta()`).
   *
   * @param {number} timestamp - The current time in milliseconds. Can be obtained
   * from the `requestAnimationFrame` callback argument. If not provided, the current
   * time will be determined with `performance.now`.
   * @return {Timer} A reference to this timer.
   */
  update(e) {
    return this._pageVisibilityHandler !== null && this._document.hidden === !0 ? this._delta = 0 : (this._previousTime = this._currentTime, this._currentTime = (e !== void 0 ? e : performance.now()) - this._startTime, this._delta = (this._currentTime - this._previousTime) * this._timescale, this._elapsed += this._delta), this;
  }
};
function rw() {
  this._document.hidden === !1 && this.reset();
}
class sw extends ty {
  /**
   * Constructs a new instanced interleaved buffer.
   *
   * @param {TypedArray} array - A typed array with a shared buffer storing attribute data.
   * @param {number} stride - The number of typed-array elements per vertex.
   * @param {number} [meshPerAttribute=1] - Defines how often a value of this interleaved buffer should be repeated.
   */
  constructor(e, t, n = 1) {
    super(e, t), this.isInstancedInterleavedBuffer = !0, this.meshPerAttribute = n;
  }
  copy(e) {
    return super.copy(e), this.meshPerAttribute = e.meshPerAttribute, this;
  }
  clone(e) {
    const t = super.clone(e);
    return t.meshPerAttribute = this.meshPerAttribute, t;
  }
  toJSON(e) {
    const t = super.toJSON(e);
    return t.isInstancedInterleavedBuffer = !0, t.meshPerAttribute = this.meshPerAttribute, t;
  }
}
const L_ = /* @__PURE__ */ new pt();
class gy {
  /**
   * Constructs a new raycaster.
   *
   * @param {Vector3} origin - The origin vector where the ray casts from.
   * @param {Vector3} direction - The (normalized) direction vector that gives direction to the ray.
   * @param {number} [near=0] - All results returned are further away than near. Near can't be negative.
   * @param {number} [far=Infinity] - All results returned are closer than far. Far can't be lower than near.
   */
  constructor(e, t, n = 0, r = 1 / 0) {
    this.ray = new cd(e, t), this.near = n, this.far = r, this.camera = null, this.layers = new qm(), this.params = {
      Mesh: {},
      Line: { threshold: 1 },
      LOD: {},
      Points: { threshold: 1 },
      Sprite: {}
    };
  }
  /**
   * Updates the ray with a new origin and direction by copying the values from the arguments.
   *
   * @param {Vector3} origin - The origin vector where the ray casts from.
   * @param {Vector3} direction - The (normalized) direction vector that gives direction to the ray.
   */
  set(e, t) {
    this.ray.set(e, t);
  }
  /**
   * Uses the given coordinates and camera to compute a new origin and direction for the internal ray.
   *
   * @param {Vector2} coords - 2D coordinates of the mouse, in normalized device coordinates (NDC).
   * X and Y components should be between `-1` and `1`.
   * @param {Camera} camera - The camera from which the ray should originate.
   */
  setFromCamera(e, t) {
    t.isPerspectiveCamera ? (this.ray.origin.setFromMatrixPosition(t.matrixWorld), this.ray.direction.set(e.x, e.y, 0.5).unproject(t).sub(this.ray.origin).normalize(), this.camera = t) : t.isOrthographicCamera ? (this.ray.origin.set(e.x, e.y, (t.near + t.far) / (t.near - t.far)).unproject(t), this.ray.direction.set(0, 0, -1).transformDirection(t.matrixWorld), this.camera = t) : le("Raycaster: Unsupported camera type: " + t.type);
  }
  /**
   * Uses the given WebXR controller to compute a new origin and direction for the internal ray.
   *
   * @param {WebXRController} controller - The controller to copy the position and direction from.
   * @return {Raycaster} A reference to this raycaster.
   */
  setFromXRController(e) {
    return L_.identity().extractRotation(e.matrixWorld), this.ray.origin.setFromMatrixPosition(e.matrixWorld), this.ray.direction.set(0, 0, -1).applyMatrix4(L_), this;
  }
  /**
   * The intersection point of a raycaster intersection test.
   * @typedef {Object} Raycaster~Intersection
   * @property {number} distance - The distance from the ray's origin to the intersection point.
   * @property {number} distanceToRay -  Some 3D objects e.g. {@link Points} provide the distance of the
   * intersection to the nearest point on the ray. For other objects it will be `undefined`.
   * @property {Vector3} point - The intersection point, in world coordinates.
   * @property {Object} face - The face that has been intersected.
   * @property {number} faceIndex - The face index.
   * @property {Object3D} object - The 3D object that has been intersected.
   * @property {Vector2} uv - U,V coordinates at point of intersection.
   * @property {Vector2} uv1 - Second set of U,V coordinates at point of intersection.
   * @property {Vector3} normal - Interpolated normal vector at point of intersection.
   * @property {number} instanceId - The index number of the instance where the ray
   * intersects the {@link InstancedMesh}.
   */
  /**
   * Checks all intersection between the ray and the object with or without the
   * descendants. Intersections are returned sorted by distance, closest first.
   *
   * `Raycaster` delegates to the `raycast()` method of the passed 3D object, when
   * evaluating whether the ray intersects the object or not. This allows meshes to respond
   * differently to ray casting than lines or points.
   *
   * Note that for meshes, faces must be pointed towards the origin of the ray in order
   * to be detected; intersections of the ray passing through the back of a face will not
   * be detected. To raycast against both faces of an object, you'll want to set  {@link Material#side}
   * to `THREE.DoubleSide`.
   *
   * @param {Object3D} object - The 3D object to check for intersection with the ray.
   * @param {boolean} [recursive=true] - If set to `true`, it also checks all descendants.
   * Otherwise it only checks intersection with the object.
   * @param {Array<Raycaster~Intersection>} [intersects=[]] The target array that holds the result of the method.
   * @return {Array<Raycaster~Intersection>} An array holding the intersection points.
   */
  intersectObject(e, t = !0, n = []) {
    return Rp(e, this, n, t), n.sort(F_), n;
  }
  /**
   * Checks all intersection between the ray and the objects with or without
   * the descendants. Intersections are returned sorted by distance, closest first.
   *
   * @param {Array<Object3D>} objects - The 3D objects to check for intersection with the ray.
   * @param {boolean} [recursive=true] - If set to `true`, it also checks all descendants.
   * Otherwise it only checks intersection with the object.
   * @param {Array<Raycaster~Intersection>} [intersects=[]] The target array that holds the result of the method.
   * @return {Array<Raycaster~Intersection>} An array holding the intersection points.
   */
  intersectObjects(e, t = !0, n = []) {
    for (let r = 0, s = e.length; r < s; r++)
      Rp(e[r], this, n, t);
    return n.sort(F_), n;
  }
}
function F_(i, e) {
  return i.distance - e.distance;
}
function Rp(i, e, t, n) {
  let r = !0;
  if (i.layers.test(e.layers) && i.raycast(e, t) === !1 && (r = !1), r === !0 && n === !0) {
    const s = i.children;
    for (let a = 0, o = s.length; a < o; a++)
      Rp(s[a], e, t, !0);
  }
}
class aw {
  /**
   * Constructs a new clock.
   *
   * @deprecated since 183.
   * @param {boolean} [autoStart=true] - Whether to automatically start the clock when
   * `getDelta()` is called for the first time.
   */
  constructor(e = !0) {
    this.autoStart = e, this.startTime = 0, this.oldTime = 0, this.elapsedTime = 0, this.running = !1, oe("THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.");
  }
  /**
   * Starts the clock. When `autoStart` is set to `true`, the method is automatically
   * called by the class.
   */
  start() {
    this.startTime = performance.now(), this.oldTime = this.startTime, this.elapsedTime = 0, this.running = !0;
  }
  /**
   * Stops the clock.
   */
  stop() {
    this.getElapsedTime(), this.running = !1, this.autoStart = !1;
  }
  /**
   * Returns the elapsed time in seconds.
   *
   * @return {number} The elapsed time.
   */
  getElapsedTime() {
    return this.getDelta(), this.elapsedTime;
  }
  /**
   * Returns the delta time in seconds.
   *
   * @return {number} The delta time.
   */
  getDelta() {
    let e = 0;
    if (this.autoStart && !this.running)
      return this.start(), 0;
    if (this.running) {
      const t = performance.now();
      e = (t - this.oldTime) / 1e3, this.oldTime = t, this.elapsedTime += e;
    }
    return e;
  }
}
class I_ {
  /**
   * Constructs a new spherical.
   *
   * @param {number} [radius=1] - The radius, or the Euclidean distance (straight-line distance) from the point to the origin.
   * @param {number} [phi=0] - The polar angle in radians from the y (up) axis.
   * @param {number} [theta=0] - The equator/azimuthal angle in radians around the y (up) axis.
   */
  constructor(e = 1, t = 0, n = 0) {
    this.radius = e, this.phi = t, this.theta = n;
  }
  /**
   * Sets the spherical components by copying the given values.
   *
   * @param {number} radius - The radius.
   * @param {number} phi - The polar angle.
   * @param {number} theta - The azimuthal angle.
   * @return {Spherical} A reference to this spherical.
   */
  set(e, t, n) {
    return this.radius = e, this.phi = t, this.theta = n, this;
  }
  /**
   * Copies the values of the given spherical to this instance.
   *
   * @param {Spherical} other - The spherical to copy.
   * @return {Spherical} A reference to this spherical.
   */
  copy(e) {
    return this.radius = e.radius, this.phi = e.phi, this.theta = e.theta, this;
  }
  /**
   * Restricts the polar angle [page:.phi phi] to be between `0.000001` and pi -
   * `0.000001`.
   *
   * @return {Spherical} A reference to this spherical.
   */
  makeSafe() {
    return this.phi = ct(this.phi, 1e-6, Math.PI - 1e-6), this;
  }
  /**
   * Sets the spherical components from the given vector which is assumed to hold
   * Cartesian coordinates.
   *
   * @param {Vector3} v - The vector to set.
   * @return {Spherical} A reference to this spherical.
   */
  setFromVector3(e) {
    return this.setFromCartesianCoords(e.x, e.y, e.z);
  }
  /**
   * Sets the spherical components from the given Cartesian coordinates.
   *
   * @param {number} x - The x value.
   * @param {number} y - The y value.
   * @param {number} z - The z value.
   * @return {Spherical} A reference to this spherical.
   */
  setFromCartesianCoords(e, t, n) {
    return this.radius = Math.sqrt(e * e + t * t + n * n), this.radius === 0 ? (this.theta = 0, this.phi = 0) : (this.theta = Math.atan2(e, n), this.phi = Math.acos(ct(t / this.radius, -1, 1))), this;
  }
  /**
   * Returns a new spherical with copied values from this instance.
   *
   * @return {Spherical} A clone of this instance.
   */
  clone() {
    return new this.constructor().copy(this);
  }
}
class hd {
  /**
   * Constructs a new 2x2 matrix. The arguments are supposed to be
   * in row-major order. If no arguments are provided, the constructor
   * initializes the matrix as an identity matrix.
   *
   * @param {number} [n11] - 1-1 matrix element.
   * @param {number} [n12] - 1-2 matrix element.
   * @param {number} [n21] - 2-1 matrix element.
   * @param {number} [n22] - 2-2 matrix element.
   */
  constructor(e, t, n, r) {
    hd.prototype.isMatrix2 = !0, this.elements = [
      1,
      0,
      0,
      1
    ], e !== void 0 && this.set(e, t, n, r);
  }
  /**
   * Sets this matrix to the 2x2 identity matrix.
   *
   * @return {Matrix2} A reference to this matrix.
   */
  identity() {
    return this.set(
      1,
      0,
      0,
      1
    ), this;
  }
  /**
   * Sets the elements of the matrix from the given array.
   *
   * @param {Array<number>} array - The matrix elements in column-major order.
   * @param {number} [offset=0] - Index of the first element in the array.
   * @return {Matrix2} A reference to this matrix.
   */
  fromArray(e, t = 0) {
    for (let n = 0; n < 4; n++)
      this.elements[n] = e[n + t];
    return this;
  }
  /**
   * Sets the elements of the matrix.The arguments are supposed to be
   * in row-major order.
   *
   * @param {number} n11 - 1-1 matrix element.
   * @param {number} n12 - 1-2 matrix element.
   * @param {number} n21 - 2-1 matrix element.
   * @param {number} n22 - 2-2 matrix element.
   * @return {Matrix2} A reference to this matrix.
   */
  set(e, t, n, r) {
    const s = this.elements;
    return s[0] = e, s[2] = t, s[1] = n, s[3] = r, this;
  }
}
class dd extends Fr {
  /**
   * Constructs a new controls instance.
   *
   * @param {Object3D} object - The object that is managed by the controls.
   * @param {?HTMLElement} domElement - The HTML element used for event listeners.
   */
  constructor(e, t = null) {
    super(), this.object = e, this.domElement = t, this.enabled = !0, this.state = -1, this.keys = {}, this.mouseButtons = { LEFT: null, MIDDLE: null, RIGHT: null }, this.touches = { ONE: null, TWO: null };
  }
  /**
   * Connects the controls to the DOM. This method has so called "side effects" since
   * it adds the module's event listeners to the DOM.
   *
   * @param {HTMLElement} element - The DOM element to connect to.
   */
  connect(e) {
    if (e === void 0) {
      oe("Controls: connect() now requires an element.");
      return;
    }
    this.domElement !== null && this.disconnect(), this.domElement = e;
  }
  /**
   * Disconnects the controls from the DOM.
   */
  disconnect() {
  }
  /**
   * Call this method if you no longer want use to the controls. It frees all internal
   * resources and removes all event listeners.
   */
  dispose() {
  }
  /**
   * Controls should implement this method if they have to update their internal state
   * per simulation step.
   *
   * @param {number} [delta] - The time delta in seconds.
   */
  update() {
  }
}
function Cp(i, e, t, n) {
  const r = ow(n);
  switch (t) {
    case Bm:
      return i * e;
    case eu:
      return i * e / r.components * r.byteLength;
    case _l:
      return i * e / r.components * r.byteLength;
    case ri:
      return i * e * 2 / r.components * r.byteLength;
    case xl:
      return i * e * 2 / r.components * r.byteLength;
    case Jc:
      return i * e * 3 / r.components * r.byteLength;
    case cn:
      return i * e * 4 / r.components * r.byteLength;
    case vl:
      return i * e * 4 / r.components * r.byteLength;
    case Us:
    case Bs:
      return Math.floor((i + 3) / 4) * Math.floor((e + 3) / 4) * 8;
    case Os:
    case ks:
      return Math.floor((i + 3) / 4) * Math.floor((e + 3) / 4) * 16;
    case Oc:
    case Gc:
      return Math.max(i, 16) * Math.max(e, 8) / 4;
    case Bc:
    case kc:
      return Math.max(i, 8) * Math.max(e, 8) / 2;
    case Oo:
    case ko:
    case Vo:
    case zo:
      return Math.floor((i + 3) / 4) * Math.floor((e + 3) / 4) * 8;
    case Go:
    case Pa:
    case Ho:
      return Math.floor((i + 3) / 4) * Math.floor((e + 3) / 4) * 16;
    case $o:
      return Math.floor((i + 3) / 4) * Math.floor((e + 3) / 4) * 16;
    case Wo:
      return Math.floor((i + 4) / 5) * Math.floor((e + 3) / 4) * 16;
    case qo:
      return Math.floor((i + 4) / 5) * Math.floor((e + 4) / 5) * 16;
    case Xo:
      return Math.floor((i + 5) / 6) * Math.floor((e + 4) / 5) * 16;
    case jo:
      return Math.floor((i + 5) / 6) * Math.floor((e + 5) / 6) * 16;
    case Yo:
      return Math.floor((i + 7) / 8) * Math.floor((e + 4) / 5) * 16;
    case Ko:
      return Math.floor((i + 7) / 8) * Math.floor((e + 5) / 6) * 16;
    case Zo:
      return Math.floor((i + 7) / 8) * Math.floor((e + 7) / 8) * 16;
    case Qo:
      return Math.floor((i + 9) / 10) * Math.floor((e + 4) / 5) * 16;
    case Jo:
      return Math.floor((i + 9) / 10) * Math.floor((e + 5) / 6) * 16;
    case el:
      return Math.floor((i + 9) / 10) * Math.floor((e + 7) / 8) * 16;
    case tl:
      return Math.floor((i + 9) / 10) * Math.floor((e + 9) / 10) * 16;
    case nl:
      return Math.floor((i + 11) / 12) * Math.floor((e + 9) / 10) * 16;
    case il:
      return Math.floor((i + 11) / 12) * Math.floor((e + 11) / 12) * 16;
    case rl:
    case Ep:
    case wp:
      return Math.ceil(i / 4) * Math.ceil(e / 4) * 16;
    case sl:
    case al:
      return Math.ceil(i / 4) * Math.ceil(e / 4) * 8;
    case Da:
    case ol:
      return Math.ceil(i / 4) * Math.ceil(e / 4) * 16;
  }
  throw new Error(
    `Unable to determine texture byte length for ${t} format.`
  );
}
function ow(i) {
  switch (i) {
    case Zt:
    case ba:
      return { byteLength: 1, components: 1 };
    case Ji:
    case Sa:
    case nn:
      return { byteLength: 2, components: 1 };
    case rd:
    case sd:
      return { byteLength: 2, components: 4 };
    case Dt:
    case wn:
    case ln:
      return { byteLength: 4, components: 1 };
    case ad:
    case od:
      return { byteLength: 4, components: 3 };
  }
  throw new Error(`Unknown texture type ${i}.`);
}
typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: {
  revision: za
} }));
typeof window < "u" && (window.__THREE__ ? oe("WARNING: Multiple instances of Three.js being imported.") : window.__THREE__ = za);
/**
 * @license
 * Copyright 2010-2026 Three.js Authors
 * SPDX-License-Identifier: MIT
 */
function _y() {
  let i = null, e = !1, t = null, n = null;
  function r(s, a) {
    t(s, a), n = i.requestAnimationFrame(r);
  }
  return {
    start: function() {
      e !== !0 && t !== null && (n = i.requestAnimationFrame(r), e = !0);
    },
    stop: function() {
      i.cancelAnimationFrame(n), e = !1;
    },
    setAnimationLoop: function(s) {
      t = s;
    },
    setContext: function(s) {
      i = s;
    }
  };
}
function lw(i) {
  const e = /* @__PURE__ */ new WeakMap();
  function t(o, l) {
    const c = o.array, u = o.usage, h = c.byteLength, d = i.createBuffer();
    i.bindBuffer(l, d), i.bufferData(l, c, u), o.onUploadCallback();
    let f;
    if (c instanceof Float32Array)
      f = i.FLOAT;
    else if (typeof Float16Array < "u" && c instanceof Float16Array)
      f = i.HALF_FLOAT;
    else if (c instanceof Uint16Array)
      o.isFloat16BufferAttribute ? f = i.HALF_FLOAT : f = i.UNSIGNED_SHORT;
    else if (c instanceof Int16Array)
      f = i.SHORT;
    else if (c instanceof Uint32Array)
      f = i.UNSIGNED_INT;
    else if (c instanceof Int32Array)
      f = i.INT;
    else if (c instanceof Int8Array)
      f = i.BYTE;
    else if (c instanceof Uint8Array)
      f = i.UNSIGNED_BYTE;
    else if (c instanceof Uint8ClampedArray)
      f = i.UNSIGNED_BYTE;
    else
      throw new Error("THREE.WebGLAttributes: Unsupported buffer data format: " + c);
    return {
      buffer: d,
      type: f,
      bytesPerElement: c.BYTES_PER_ELEMENT,
      version: o.version,
      size: h
    };
  }
  function n(o, l, c) {
    const u = l.array, h = l.updateRanges;
    if (i.bindBuffer(c, o), h.length === 0)
      i.bufferSubData(c, 0, u);
    else {
      h.sort((f, p) => f.start - p.start);
      let d = 0;
      for (let f = 1; f < h.length; f++) {
        const p = h[d], _ = h[f];
        _.start <= p.start + p.count + 1 ? p.count = Math.max(
          p.count,
          _.start + _.count - p.start
        ) : (++d, h[d] = _);
      }
      h.length = d + 1;
      for (let f = 0, p = h.length; f < p; f++) {
        const _ = h[f];
        i.bufferSubData(
          c,
          _.start * u.BYTES_PER_ELEMENT,
          u,
          _.start,
          _.count
        );
      }
      l.clearUpdateRanges();
    }
    l.onUploadCallback();
  }
  function r(o) {
    return o.isInterleavedBufferAttribute && (o = o.data), e.get(o);
  }
  function s(o) {
    o.isInterleavedBufferAttribute && (o = o.data);
    const l = e.get(o);
    l && (i.deleteBuffer(l.buffer), e.delete(o));
  }
  function a(o, l) {
    if (o.isInterleavedBufferAttribute && (o = o.data), o.isGLBufferAttribute) {
      const u = e.get(o);
      (!u || u.version < o.version) && e.set(o, {
        buffer: o.buffer,
        type: o.type,
        bytesPerElement: o.elementSize,
        version: o.version
      });
      return;
    }
    const c = e.get(o);
    if (c === void 0)
      e.set(o, t(o, l));
    else if (c.version < o.version) {
      if (c.size !== o.array.byteLength)
        throw new Error("THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported.");
      n(c.buffer, o, l), c.version = o.version;
    }
  }
  return {
    get: r,
    remove: s,
    update: a
  };
}
var cw = `#ifdef USE_ALPHAHASH
	if ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;
#endif`, uw = `#ifdef USE_ALPHAHASH
	const float ALPHA_HASH_SCALE = 0.05;
	float hash2D( vec2 value ) {
		return fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );
	}
	float hash3D( vec3 value ) {
		return hash2D( vec2( hash2D( value.xy ), value.z ) );
	}
	float getAlphaHashThreshold( vec3 position ) {
		float maxDeriv = max(
			length( dFdx( position.xyz ) ),
			length( dFdy( position.xyz ) )
		);
		float pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );
		vec2 pixScales = vec2(
			exp2( floor( log2( pixScale ) ) ),
			exp2( ceil( log2( pixScale ) ) )
		);
		vec2 alpha = vec2(
			hash3D( floor( pixScales.x * position.xyz ) ),
			hash3D( floor( pixScales.y * position.xyz ) )
		);
		float lerpFactor = fract( log2( pixScale ) );
		float x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;
		float a = min( lerpFactor, 1.0 - lerpFactor );
		vec3 cases = vec3(
			x * x / ( 2.0 * a * ( 1.0 - a ) ),
			( x - 0.5 * a ) / ( 1.0 - a ),
			1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )
		);
		float threshold = ( x < ( 1.0 - a ) )
			? ( ( x < a ) ? cases.x : cases.y )
			: cases.z;
		return clamp( threshold , 1.0e-6, 1.0 );
	}
#endif`, hw = `#ifdef USE_ALPHAMAP
	diffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;
#endif`, dw = `#ifdef USE_ALPHAMAP
	uniform sampler2D alphaMap;
#endif`, fw = `#ifdef USE_ALPHATEST
	#ifdef ALPHA_TO_COVERAGE
	diffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );
	if ( diffuseColor.a == 0.0 ) discard;
	#else
	if ( diffuseColor.a < alphaTest ) discard;
	#endif
#endif`, pw = `#ifdef USE_ALPHATEST
	uniform float alphaTest;
#endif`, mw = `#ifdef USE_AOMAP
	float ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;
	reflectedLight.indirectDiffuse *= ambientOcclusion;
	#if defined( USE_CLEARCOAT ) 
		clearcoatSpecularIndirect *= ambientOcclusion;
	#endif
	#if defined( USE_SHEEN ) 
		sheenSpecularIndirect *= ambientOcclusion;
	#endif
	#if defined( USE_ENVMAP ) && defined( STANDARD )
		float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );
		reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );
	#endif
#endif`, gw = `#ifdef USE_AOMAP
	uniform sampler2D aoMap;
	uniform float aoMapIntensity;
#endif`, _w = `#ifdef USE_BATCHING
	#if ! defined( GL_ANGLE_multi_draw )
	#define gl_DrawID _gl_DrawID
	uniform int _gl_DrawID;
	#endif
	uniform highp sampler2D batchingTexture;
	uniform highp usampler2D batchingIdTexture;
	mat4 getBatchingMatrix( const in float i ) {
		int size = textureSize( batchingTexture, 0 ).x;
		int j = int( i ) * 4;
		int x = j % size;
		int y = j / size;
		vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );
		vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );
		vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );
		vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );
		return mat4( v1, v2, v3, v4 );
	}
	float getIndirectIndex( const in int i ) {
		int size = textureSize( batchingIdTexture, 0 ).x;
		int x = i % size;
		int y = i / size;
		return float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );
	}
#endif
#ifdef USE_BATCHING_COLOR
	uniform sampler2D batchingColorTexture;
	vec4 getBatchingColor( const in float i ) {
		int size = textureSize( batchingColorTexture, 0 ).x;
		int j = int( i );
		int x = j % size;
		int y = j / size;
		return texelFetch( batchingColorTexture, ivec2( x, y ), 0 );
	}
#endif`, xw = `#ifdef USE_BATCHING
	mat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );
#endif`, vw = `vec3 transformed = vec3( position );
#ifdef USE_ALPHAHASH
	vPosition = vec3( position );
#endif`, yw = `vec3 objectNormal = vec3( normal );
#ifdef USE_TANGENT
	vec3 objectTangent = vec3( tangent.xyz );
#endif`, bw = `float G_BlinnPhong_Implicit( ) {
	return 0.25;
}
float D_BlinnPhong( const in float shininess, const in float dotNH ) {
	return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
}
vec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {
	vec3 halfDir = normalize( lightDir + viewDir );
	float dotNH = saturate( dot( normal, halfDir ) );
	float dotVH = saturate( dot( viewDir, halfDir ) );
	vec3 F = F_Schlick( specularColor, 1.0, dotVH );
	float G = G_BlinnPhong_Implicit( );
	float D = D_BlinnPhong( shininess, dotNH );
	return F * ( G * D );
} // validated`, Sw = `#ifdef USE_IRIDESCENCE
	const mat3 XYZ_TO_REC709 = mat3(
		 3.2404542, -0.9692660,  0.0556434,
		-1.5371385,  1.8760108, -0.2040259,
		-0.4985314,  0.0415560,  1.0572252
	);
	vec3 Fresnel0ToIor( vec3 fresnel0 ) {
		vec3 sqrtF0 = sqrt( fresnel0 );
		return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );
	}
	vec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {
		return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );
	}
	float IorToFresnel0( float transmittedIor, float incidentIor ) {
		return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));
	}
	vec3 evalSensitivity( float OPD, vec3 shift ) {
		float phase = 2.0 * PI * OPD * 1.0e-9;
		vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );
		vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );
		vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );
		vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );
		xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );
		xyz /= 1.0685e-7;
		vec3 rgb = XYZ_TO_REC709 * xyz;
		return rgb;
	}
	vec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {
		vec3 I;
		float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
		float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );
		float cosTheta2Sq = 1.0 - sinTheta2Sq;
		if ( cosTheta2Sq < 0.0 ) {
			return vec3( 1.0 );
		}
		float cosTheta2 = sqrt( cosTheta2Sq );
		float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );
		float R12 = F_Schlick( R0, 1.0, cosTheta1 );
		float T121 = 1.0 - R12;
		float phi12 = 0.0;
		if ( iridescenceIOR < outsideIOR ) phi12 = PI;
		float phi21 = PI - phi12;
		vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );		vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );
		vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );
		vec3 phi23 = vec3( 0.0 );
		if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;
		if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;
		if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;
		float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;
		vec3 phi = vec3( phi21 ) + phi23;
		vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );
		vec3 r123 = sqrt( R123 );
		vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );
		vec3 C0 = R12 + Rs;
		I = C0;
		vec3 Cm = Rs - T121;
		for ( int m = 1; m <= 2; ++ m ) {
			Cm *= r123;
			vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );
			I += Cm * Sm;
		}
		return max( I, vec3( 0.0 ) );
	}
#endif`, Tw = `#ifdef USE_BUMPMAP
	uniform sampler2D bumpMap;
	uniform float bumpScale;
	vec2 dHdxy_fwd() {
		vec2 dSTdx = dFdx( vBumpMapUv );
		vec2 dSTdy = dFdy( vBumpMapUv );
		float Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;
		float dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;
		float dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;
		return vec2( dBx, dBy );
	}
	vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {
		vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );
		vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );
		vec3 vN = surf_norm;
		vec3 R1 = cross( vSigmaY, vN );
		vec3 R2 = cross( vN, vSigmaX );
		float fDet = dot( vSigmaX, R1 ) * faceDirection;
		vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );
		return normalize( abs( fDet ) * surf_norm - vGrad );
	}
#endif`, Mw = `#if NUM_CLIPPING_PLANES > 0
	vec4 plane;
	#ifdef ALPHA_TO_COVERAGE
		float distanceToPlane, distanceGradient;
		float clipOpacity = 1.0;
		#pragma unroll_loop_start
		for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {
			plane = clippingPlanes[ i ];
			distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;
			distanceGradient = fwidth( distanceToPlane ) / 2.0;
			clipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );
			if ( clipOpacity == 0.0 ) discard;
		}
		#pragma unroll_loop_end
		#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
			float unionClipOpacity = 1.0;
			#pragma unroll_loop_start
			for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {
				plane = clippingPlanes[ i ];
				distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;
				distanceGradient = fwidth( distanceToPlane ) / 2.0;
				unionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );
			}
			#pragma unroll_loop_end
			clipOpacity *= 1.0 - unionClipOpacity;
		#endif
		diffuseColor.a *= clipOpacity;
		if ( diffuseColor.a == 0.0 ) discard;
	#else
		#pragma unroll_loop_start
		for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {
			plane = clippingPlanes[ i ];
			if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;
		}
		#pragma unroll_loop_end
		#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
			bool clipped = true;
			#pragma unroll_loop_start
			for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {
				plane = clippingPlanes[ i ];
				clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;
			}
			#pragma unroll_loop_end
			if ( clipped ) discard;
		#endif
	#endif
#endif`, Ew = `#if NUM_CLIPPING_PLANES > 0
	varying vec3 vClipPosition;
	uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];
#endif`, ww = `#if NUM_CLIPPING_PLANES > 0
	varying vec3 vClipPosition;
#endif`, Aw = `#if NUM_CLIPPING_PLANES > 0
	vClipPosition = - mvPosition.xyz;
#endif`, Rw = `#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
	diffuseColor *= vColor;
#endif`, Cw = `#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
	varying vec4 vColor;
#endif`, Nw = `#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )
	varying vec4 vColor;
#endif`, Pw = `#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )
	vColor = vec4( 1.0 );
#endif
#ifdef USE_COLOR_ALPHA
	vColor *= color;
#elif defined( USE_COLOR )
	vColor.rgb *= color;
#endif
#ifdef USE_INSTANCING_COLOR
	vColor.rgb *= instanceColor.rgb;
#endif
#ifdef USE_BATCHING_COLOR
	vColor *= getBatchingColor( getIndirectIndex( gl_DrawID ) );
#endif`, Dw = `#define PI 3.141592653589793
#define PI2 6.283185307179586
#define PI_HALF 1.5707963267948966
#define RECIPROCAL_PI 0.3183098861837907
#define RECIPROCAL_PI2 0.15915494309189535
#define EPSILON 1e-6
#ifndef saturate
#define saturate( a ) clamp( a, 0.0, 1.0 )
#endif
#define whiteComplement( a ) ( 1.0 - saturate( a ) )
float pow2( const in float x ) { return x*x; }
vec3 pow2( const in vec3 x ) { return x*x; }
float pow3( const in float x ) { return x*x*x; }
float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
float max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }
float average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }
highp float rand( const in vec2 uv ) {
	const highp float a = 12.9898, b = 78.233, c = 43758.5453;
	highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
	return fract( sin( sn ) * c );
}
#ifdef HIGH_PRECISION
	float precisionSafeLength( vec3 v ) { return length( v ); }
#else
	float precisionSafeLength( vec3 v ) {
		float maxComponent = max3( abs( v ) );
		return length( v / maxComponent ) * maxComponent;
	}
#endif
struct IncidentLight {
	vec3 color;
	vec3 direction;
	bool visible;
};
struct ReflectedLight {
	vec3 directDiffuse;
	vec3 directSpecular;
	vec3 indirectDiffuse;
	vec3 indirectSpecular;
};
#ifdef USE_ALPHAHASH
	varying vec3 vPosition;
#endif
vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
	return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
}
vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
	return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
}
bool isPerspectiveMatrix( mat4 m ) {
	return m[ 2 ][ 3 ] == - 1.0;
}
vec2 equirectUv( in vec3 dir ) {
	float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;
	float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
	return vec2( u, v );
}
vec3 BRDF_Lambert( const in vec3 diffuseColor ) {
	return RECIPROCAL_PI * diffuseColor;
}
vec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {
	float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );
	return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );
}
float F_Schlick( const in float f0, const in float f90, const in float dotVH ) {
	float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );
	return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );
} // validated`, Lw = `#ifdef ENVMAP_TYPE_CUBE_UV
	#define cubeUV_minMipLevel 4.0
	#define cubeUV_minTileSize 16.0
	float getFace( vec3 direction ) {
		vec3 absDirection = abs( direction );
		float face = - 1.0;
		if ( absDirection.x > absDirection.z ) {
			if ( absDirection.x > absDirection.y )
				face = direction.x > 0.0 ? 0.0 : 3.0;
			else
				face = direction.y > 0.0 ? 1.0 : 4.0;
		} else {
			if ( absDirection.z > absDirection.y )
				face = direction.z > 0.0 ? 2.0 : 5.0;
			else
				face = direction.y > 0.0 ? 1.0 : 4.0;
		}
		return face;
	}
	vec2 getUV( vec3 direction, float face ) {
		vec2 uv;
		if ( face == 0.0 ) {
			uv = vec2( direction.z, direction.y ) / abs( direction.x );
		} else if ( face == 1.0 ) {
			uv = vec2( - direction.x, - direction.z ) / abs( direction.y );
		} else if ( face == 2.0 ) {
			uv = vec2( - direction.x, direction.y ) / abs( direction.z );
		} else if ( face == 3.0 ) {
			uv = vec2( - direction.z, direction.y ) / abs( direction.x );
		} else if ( face == 4.0 ) {
			uv = vec2( - direction.x, direction.z ) / abs( direction.y );
		} else {
			uv = vec2( direction.x, direction.y ) / abs( direction.z );
		}
		return 0.5 * ( uv + 1.0 );
	}
	vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {
		float face = getFace( direction );
		float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );
		mipInt = max( mipInt, cubeUV_minMipLevel );
		float faceSize = exp2( mipInt );
		highp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;
		if ( face > 2.0 ) {
			uv.y += faceSize;
			face -= 3.0;
		}
		uv.x += face * faceSize;
		uv.x += filterInt * 3.0 * cubeUV_minTileSize;
		uv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );
		uv.x *= CUBEUV_TEXEL_WIDTH;
		uv.y *= CUBEUV_TEXEL_HEIGHT;
		#ifdef texture2DGradEXT
			return texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;
		#else
			return texture2D( envMap, uv ).rgb;
		#endif
	}
	#define cubeUV_r0 1.0
	#define cubeUV_m0 - 2.0
	#define cubeUV_r1 0.8
	#define cubeUV_m1 - 1.0
	#define cubeUV_r4 0.4
	#define cubeUV_m4 2.0
	#define cubeUV_r5 0.305
	#define cubeUV_m5 3.0
	#define cubeUV_r6 0.21
	#define cubeUV_m6 4.0
	float roughnessToMip( float roughness ) {
		float mip = 0.0;
		if ( roughness >= cubeUV_r1 ) {
			mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;
		} else if ( roughness >= cubeUV_r4 ) {
			mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;
		} else if ( roughness >= cubeUV_r5 ) {
			mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;
		} else if ( roughness >= cubeUV_r6 ) {
			mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;
		} else {
			mip = - 2.0 * log2( 1.16 * roughness );		}
		return mip;
	}
	vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {
		float mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );
		float mipF = fract( mip );
		float mipInt = floor( mip );
		vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );
		if ( mipF == 0.0 ) {
			return vec4( color0, 1.0 );
		} else {
			vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );
			return vec4( mix( color0, color1, mipF ), 1.0 );
		}
	}
#endif`, Fw = `vec3 transformedNormal = objectNormal;
#ifdef USE_TANGENT
	vec3 transformedTangent = objectTangent;
#endif
#ifdef USE_BATCHING
	mat3 bm = mat3( batchingMatrix );
	transformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );
	transformedNormal = bm * transformedNormal;
	#ifdef USE_TANGENT
		transformedTangent = bm * transformedTangent;
	#endif
#endif
#ifdef USE_INSTANCING
	mat3 im = mat3( instanceMatrix );
	transformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );
	transformedNormal = im * transformedNormal;
	#ifdef USE_TANGENT
		transformedTangent = im * transformedTangent;
	#endif
#endif
transformedNormal = normalMatrix * transformedNormal;
#ifdef FLIP_SIDED
	transformedNormal = - transformedNormal;
#endif
#ifdef USE_TANGENT
	transformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;
	#ifdef FLIP_SIDED
		transformedTangent = - transformedTangent;
	#endif
#endif`, Iw = `#ifdef USE_DISPLACEMENTMAP
	uniform sampler2D displacementMap;
	uniform float displacementScale;
	uniform float displacementBias;
#endif`, Uw = `#ifdef USE_DISPLACEMENTMAP
	transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );
#endif`, Bw = `#ifdef USE_EMISSIVEMAP
	vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );
	#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE
		emissiveColor = sRGBTransferEOTF( emissiveColor );
	#endif
	totalEmissiveRadiance *= emissiveColor.rgb;
#endif`, Ow = `#ifdef USE_EMISSIVEMAP
	uniform sampler2D emissiveMap;
#endif`, kw = "gl_FragColor = linearToOutputTexel( gl_FragColor );", Gw = `vec4 LinearTransferOETF( in vec4 value ) {
	return value;
}
vec4 sRGBTransferEOTF( in vec4 value ) {
	return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );
}
vec4 sRGBTransferOETF( in vec4 value ) {
	return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
}`, Vw = `#ifdef USE_ENVMAP
	#ifdef ENV_WORLDPOS
		vec3 cameraToFrag;
		if ( isOrthographic ) {
			cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
		} else {
			cameraToFrag = normalize( vWorldPosition - cameraPosition );
		}
		vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
		#ifdef ENVMAP_MODE_REFLECTION
			vec3 reflectVec = reflect( cameraToFrag, worldNormal );
		#else
			vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );
		#endif
	#else
		vec3 reflectVec = vReflect;
	#endif
	#ifdef ENVMAP_TYPE_CUBE
		vec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
		#ifdef ENVMAP_BLENDING_MULTIPLY
			outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
		#elif defined( ENVMAP_BLENDING_MIX )
			outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
		#elif defined( ENVMAP_BLENDING_ADD )
			outgoingLight += envColor.xyz * specularStrength * reflectivity;
		#endif
	#endif
#endif`, zw = `#ifdef USE_ENVMAP
	uniform float envMapIntensity;
	uniform float flipEnvMap;
	uniform mat3 envMapRotation;
	#ifdef ENVMAP_TYPE_CUBE
		uniform samplerCube envMap;
	#else
		uniform sampler2D envMap;
	#endif
#endif`, Hw = `#ifdef USE_ENVMAP
	uniform float reflectivity;
	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )
		#define ENV_WORLDPOS
	#endif
	#ifdef ENV_WORLDPOS
		varying vec3 vWorldPosition;
		uniform float refractionRatio;
	#else
		varying vec3 vReflect;
	#endif
#endif`, $w = `#ifdef USE_ENVMAP
	#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )
		#define ENV_WORLDPOS
	#endif
	#ifdef ENV_WORLDPOS
		
		varying vec3 vWorldPosition;
	#else
		varying vec3 vReflect;
		uniform float refractionRatio;
	#endif
#endif`, Ww = `#ifdef USE_ENVMAP
	#ifdef ENV_WORLDPOS
		vWorldPosition = worldPosition.xyz;
	#else
		vec3 cameraToVertex;
		if ( isOrthographic ) {
			cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
		} else {
			cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
		}
		vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
		#ifdef ENVMAP_MODE_REFLECTION
			vReflect = reflect( cameraToVertex, worldNormal );
		#else
			vReflect = refract( cameraToVertex, worldNormal, refractionRatio );
		#endif
	#endif
#endif`, qw = `#ifdef USE_FOG
	vFogDepth = - mvPosition.z;
#endif`, Xw = `#ifdef USE_FOG
	varying float vFogDepth;
#endif`, jw = `#ifdef USE_FOG
	#ifdef FOG_EXP2
		float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );
	#else
		float fogFactor = smoothstep( fogNear, fogFar, vFogDepth );
	#endif
	gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
#endif`, Yw = `#ifdef USE_FOG
	uniform vec3 fogColor;
	varying float vFogDepth;
	#ifdef FOG_EXP2
		uniform float fogDensity;
	#else
		uniform float fogNear;
		uniform float fogFar;
	#endif
#endif`, Kw = `#ifdef USE_GRADIENTMAP
	uniform sampler2D gradientMap;
#endif
vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {
	float dotNL = dot( normal, lightDirection );
	vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );
	#ifdef USE_GRADIENTMAP
		return vec3( texture2D( gradientMap, coord ).r );
	#else
		vec2 fw = fwidth( coord ) * 0.5;
		return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );
	#endif
}`, Zw = `#ifdef USE_LIGHTMAP
	uniform sampler2D lightMap;
	uniform float lightMapIntensity;
#endif`, Qw = `LambertMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.specularStrength = specularStrength;`, Jw = `varying vec3 vViewPosition;
struct LambertMaterial {
	vec3 diffuseColor;
	float specularStrength;
};
void RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {
	float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
	vec3 irradiance = dotNL * directLight.color;
	reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {
	reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
#define RE_Direct				RE_Direct_Lambert
#define RE_IndirectDiffuse		RE_IndirectDiffuse_Lambert`, eA = `uniform bool receiveShadow;
uniform vec3 ambientLightColor;
#if defined( USE_LIGHT_PROBES )
	uniform vec3 lightProbe[ 9 ];
#endif
vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {
	float x = normal.x, y = normal.y, z = normal.z;
	vec3 result = shCoefficients[ 0 ] * 0.886227;
	result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;
	result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;
	result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;
	result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;
	result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;
	result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );
	result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;
	result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );
	return result;
}
vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {
	vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
	vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );
	return irradiance;
}
vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
	vec3 irradiance = ambientLightColor;
	return irradiance;
}
float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
	float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );
	if ( cutoffDistance > 0.0 ) {
		distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
	}
	return distanceFalloff;
}
float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
	return smoothstep( coneCosine, penumbraCosine, angleCosine );
}
#if NUM_DIR_LIGHTS > 0
	struct DirectionalLight {
		vec3 direction;
		vec3 color;
	};
	uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
	void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {
		light.color = directionalLight.color;
		light.direction = directionalLight.direction;
		light.visible = true;
	}
#endif
#if NUM_POINT_LIGHTS > 0
	struct PointLight {
		vec3 position;
		vec3 color;
		float distance;
		float decay;
	};
	uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
	void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {
		vec3 lVector = pointLight.position - geometryPosition;
		light.direction = normalize( lVector );
		float lightDistance = length( lVector );
		light.color = pointLight.color;
		light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );
		light.visible = ( light.color != vec3( 0.0 ) );
	}
#endif
#if NUM_SPOT_LIGHTS > 0
	struct SpotLight {
		vec3 position;
		vec3 direction;
		vec3 color;
		float distance;
		float decay;
		float coneCos;
		float penumbraCos;
	};
	uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
	void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {
		vec3 lVector = spotLight.position - geometryPosition;
		light.direction = normalize( lVector );
		float angleCos = dot( light.direction, spotLight.direction );
		float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );
		if ( spotAttenuation > 0.0 ) {
			float lightDistance = length( lVector );
			light.color = spotLight.color * spotAttenuation;
			light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );
			light.visible = ( light.color != vec3( 0.0 ) );
		} else {
			light.color = vec3( 0.0 );
			light.visible = false;
		}
	}
#endif
#if NUM_RECT_AREA_LIGHTS > 0
	struct RectAreaLight {
		vec3 color;
		vec3 position;
		vec3 halfWidth;
		vec3 halfHeight;
	};
	uniform sampler2D ltc_1;	uniform sampler2D ltc_2;
	uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];
#endif
#if NUM_HEMI_LIGHTS > 0
	struct HemisphereLight {
		vec3 direction;
		vec3 skyColor;
		vec3 groundColor;
	};
	uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];
	vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {
		float dotNL = dot( normal, hemiLight.direction );
		float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
		vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
		return irradiance;
	}
#endif`, tA = `#ifdef USE_ENVMAP
	vec3 getIBLIrradiance( const in vec3 normal ) {
		#ifdef ENVMAP_TYPE_CUBE_UV
			vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
			vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );
			return PI * envMapColor.rgb * envMapIntensity;
		#else
			return vec3( 0.0 );
		#endif
	}
	vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {
		#ifdef ENVMAP_TYPE_CUBE_UV
			vec3 reflectVec = reflect( - viewDir, normal );
			reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );
			reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
			vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );
			return envMapColor.rgb * envMapIntensity;
		#else
			return vec3( 0.0 );
		#endif
	}
	#ifdef USE_ANISOTROPY
		vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {
			#ifdef ENVMAP_TYPE_CUBE_UV
				vec3 bentNormal = cross( bitangent, viewDir );
				bentNormal = normalize( cross( bentNormal, bitangent ) );
				bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );
				return getIBLRadiance( viewDir, bentNormal, roughness );
			#else
				return vec3( 0.0 );
			#endif
		}
	#endif
#endif`, nA = `ToonMaterial material;
material.diffuseColor = diffuseColor.rgb;`, iA = `varying vec3 vViewPosition;
struct ToonMaterial {
	vec3 diffuseColor;
};
void RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
	vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;
	reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
	reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
#define RE_Direct				RE_Direct_Toon
#define RE_IndirectDiffuse		RE_IndirectDiffuse_Toon`, rA = `BlinnPhongMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.specularColor = specular;
material.specularShininess = shininess;
material.specularStrength = specularStrength;`, sA = `varying vec3 vViewPosition;
struct BlinnPhongMaterial {
	vec3 diffuseColor;
	vec3 specularColor;
	float specularShininess;
	float specularStrength;
};
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
	float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
	vec3 irradiance = dotNL * directLight.color;
	reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
	reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
	reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );
}
#define RE_Direct				RE_Direct_BlinnPhong
#define RE_IndirectDiffuse		RE_IndirectDiffuse_BlinnPhong`, aA = `PhysicalMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );
material.metalness = metalnessFactor;
vec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );
float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );
material.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;
material.roughness = min( material.roughness, 1.0 );
#ifdef IOR
	material.ior = ior;
	#ifdef USE_SPECULAR
		float specularIntensityFactor = specularIntensity;
		vec3 specularColorFactor = specularColor;
		#ifdef USE_SPECULAR_COLORMAP
			specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;
		#endif
		#ifdef USE_SPECULAR_INTENSITYMAP
			specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;
		#endif
		material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );
	#else
		float specularIntensityFactor = 1.0;
		vec3 specularColorFactor = vec3( 1.0 );
		material.specularF90 = 1.0;
	#endif
	material.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;
	material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );
#else
	material.specularColor = vec3( 0.04 );
	material.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );
	material.specularF90 = 1.0;
#endif
#ifdef USE_CLEARCOAT
	material.clearcoat = clearcoat;
	material.clearcoatRoughness = clearcoatRoughness;
	material.clearcoatF0 = vec3( 0.04 );
	material.clearcoatF90 = 1.0;
	#ifdef USE_CLEARCOATMAP
		material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;
	#endif
	#ifdef USE_CLEARCOAT_ROUGHNESSMAP
		material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;
	#endif
	material.clearcoat = saturate( material.clearcoat );	material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );
	material.clearcoatRoughness += geometryRoughness;
	material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );
#endif
#ifdef USE_DISPERSION
	material.dispersion = dispersion;
#endif
#ifdef USE_IRIDESCENCE
	material.iridescence = iridescence;
	material.iridescenceIOR = iridescenceIOR;
	#ifdef USE_IRIDESCENCEMAP
		material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;
	#endif
	#ifdef USE_IRIDESCENCE_THICKNESSMAP
		material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;
	#else
		material.iridescenceThickness = iridescenceThicknessMaximum;
	#endif
#endif
#ifdef USE_SHEEN
	material.sheenColor = sheenColor;
	#ifdef USE_SHEEN_COLORMAP
		material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;
	#endif
	material.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );
	#ifdef USE_SHEEN_ROUGHNESSMAP
		material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;
	#endif
#endif
#ifdef USE_ANISOTROPY
	#ifdef USE_ANISOTROPYMAP
		mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );
		vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;
		vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;
	#else
		vec2 anisotropyV = anisotropyVector;
	#endif
	material.anisotropy = length( anisotropyV );
	if( material.anisotropy == 0.0 ) {
		anisotropyV = vec2( 1.0, 0.0 );
	} else {
		anisotropyV /= material.anisotropy;
		material.anisotropy = saturate( material.anisotropy );
	}
	material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );
	material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;
	material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;
#endif`, oA = `uniform sampler2D dfgLUT;
struct PhysicalMaterial {
	vec3 diffuseColor;
	vec3 diffuseContribution;
	vec3 specularColor;
	vec3 specularColorBlended;
	float roughness;
	float metalness;
	float specularF90;
	float dispersion;
	#ifdef USE_CLEARCOAT
		float clearcoat;
		float clearcoatRoughness;
		vec3 clearcoatF0;
		float clearcoatF90;
	#endif
	#ifdef USE_IRIDESCENCE
		float iridescence;
		float iridescenceIOR;
		float iridescenceThickness;
		vec3 iridescenceFresnel;
		vec3 iridescenceF0;
		vec3 iridescenceFresnelDielectric;
		vec3 iridescenceFresnelMetallic;
	#endif
	#ifdef USE_SHEEN
		vec3 sheenColor;
		float sheenRoughness;
	#endif
	#ifdef IOR
		float ior;
	#endif
	#ifdef USE_TRANSMISSION
		float transmission;
		float transmissionAlpha;
		float thickness;
		float attenuationDistance;
		vec3 attenuationColor;
	#endif
	#ifdef USE_ANISOTROPY
		float anisotropy;
		float alphaT;
		vec3 anisotropyT;
		vec3 anisotropyB;
	#endif
};
vec3 clearcoatSpecularDirect = vec3( 0.0 );
vec3 clearcoatSpecularIndirect = vec3( 0.0 );
vec3 sheenSpecularDirect = vec3( 0.0 );
vec3 sheenSpecularIndirect = vec3(0.0 );
vec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {
    float x = clamp( 1.0 - dotVH, 0.0, 1.0 );
    float x2 = x * x;
    float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );
    return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );
}
float V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
	float a2 = pow2( alpha );
	float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
	float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
	return 0.5 / max( gv + gl, EPSILON );
}
float D_GGX( const in float alpha, const in float dotNH ) {
	float a2 = pow2( alpha );
	float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;
	return RECIPROCAL_PI * a2 / pow2( denom );
}
#ifdef USE_ANISOTROPY
	float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {
		float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );
		float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );
		float v = 0.5 / ( gv + gl );
		return v;
	}
	float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {
		float a2 = alphaT * alphaB;
		highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );
		highp float v2 = dot( v, v );
		float w2 = a2 / v2;
		return RECIPROCAL_PI * a2 * pow2 ( w2 );
	}
#endif
#ifdef USE_CLEARCOAT
	vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {
		vec3 f0 = material.clearcoatF0;
		float f90 = material.clearcoatF90;
		float roughness = material.clearcoatRoughness;
		float alpha = pow2( roughness );
		vec3 halfDir = normalize( lightDir + viewDir );
		float dotNL = saturate( dot( normal, lightDir ) );
		float dotNV = saturate( dot( normal, viewDir ) );
		float dotNH = saturate( dot( normal, halfDir ) );
		float dotVH = saturate( dot( viewDir, halfDir ) );
		vec3 F = F_Schlick( f0, f90, dotVH );
		float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );
		float D = D_GGX( alpha, dotNH );
		return F * ( V * D );
	}
#endif
vec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {
	vec3 f0 = material.specularColorBlended;
	float f90 = material.specularF90;
	float roughness = material.roughness;
	float alpha = pow2( roughness );
	vec3 halfDir = normalize( lightDir + viewDir );
	float dotNL = saturate( dot( normal, lightDir ) );
	float dotNV = saturate( dot( normal, viewDir ) );
	float dotNH = saturate( dot( normal, halfDir ) );
	float dotVH = saturate( dot( viewDir, halfDir ) );
	vec3 F = F_Schlick( f0, f90, dotVH );
	#ifdef USE_IRIDESCENCE
		F = mix( F, material.iridescenceFresnel, material.iridescence );
	#endif
	#ifdef USE_ANISOTROPY
		float dotTL = dot( material.anisotropyT, lightDir );
		float dotTV = dot( material.anisotropyT, viewDir );
		float dotTH = dot( material.anisotropyT, halfDir );
		float dotBL = dot( material.anisotropyB, lightDir );
		float dotBV = dot( material.anisotropyB, viewDir );
		float dotBH = dot( material.anisotropyB, halfDir );
		float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );
		float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );
	#else
		float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );
		float D = D_GGX( alpha, dotNH );
	#endif
	return F * ( V * D );
}
vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
	const float LUT_SIZE = 64.0;
	const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
	const float LUT_BIAS = 0.5 / LUT_SIZE;
	float dotNV = saturate( dot( N, V ) );
	vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );
	uv = uv * LUT_SCALE + LUT_BIAS;
	return uv;
}
float LTC_ClippedSphereFormFactor( const in vec3 f ) {
	float l = length( f );
	return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );
}
vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {
	float x = dot( v1, v2 );
	float y = abs( x );
	float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;
	float b = 3.4175940 + ( 4.1616724 + y ) * y;
	float v = a / b;
	float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;
	return cross( v1, v2 ) * theta_sintheta;
}
vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {
	vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];
	vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];
	vec3 lightNormal = cross( v1, v2 );
	if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );
	vec3 T1, T2;
	T1 = normalize( V - N * dot( V, N ) );
	T2 = - cross( N, T1 );
	mat3 mat = mInv * transpose( mat3( T1, T2, N ) );
	vec3 coords[ 4 ];
	coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );
	coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );
	coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );
	coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );
	coords[ 0 ] = normalize( coords[ 0 ] );
	coords[ 1 ] = normalize( coords[ 1 ] );
	coords[ 2 ] = normalize( coords[ 2 ] );
	coords[ 3 ] = normalize( coords[ 3 ] );
	vec3 vectorFormFactor = vec3( 0.0 );
	vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );
	vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );
	vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );
	vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );
	float result = LTC_ClippedSphereFormFactor( vectorFormFactor );
	return vec3( result );
}
#if defined( USE_SHEEN )
float D_Charlie( float roughness, float dotNH ) {
	float alpha = pow2( roughness );
	float invAlpha = 1.0 / alpha;
	float cos2h = dotNH * dotNH;
	float sin2h = max( 1.0 - cos2h, 0.0078125 );
	return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );
}
float V_Neubelt( float dotNV, float dotNL ) {
	return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );
}
vec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {
	vec3 halfDir = normalize( lightDir + viewDir );
	float dotNL = saturate( dot( normal, lightDir ) );
	float dotNV = saturate( dot( normal, viewDir ) );
	float dotNH = saturate( dot( normal, halfDir ) );
	float D = D_Charlie( sheenRoughness, dotNH );
	float V = V_Neubelt( dotNV, dotNL );
	return sheenColor * ( D * V );
}
#endif
float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {
	float dotNV = saturate( dot( normal, viewDir ) );
	float r2 = roughness * roughness;
	float rInv = 1.0 / ( roughness + 0.1 );
	float a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;
	float b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;
	float DG = exp( a * dotNV + b );
	return saturate( DG );
}
vec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {
	float dotNV = saturate( dot( normal, viewDir ) );
	vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;
	return specularColor * fab.x + specularF90 * fab.y;
}
#ifdef USE_IRIDESCENCE
void computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
#else
void computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
#endif
	float dotNV = saturate( dot( normal, viewDir ) );
	vec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;
	#ifdef USE_IRIDESCENCE
		vec3 Fr = mix( specularColor, iridescenceF0, iridescence );
	#else
		vec3 Fr = specularColor;
	#endif
	vec3 FssEss = Fr * fab.x + specularF90 * fab.y;
	float Ess = fab.x + fab.y;
	float Ems = 1.0 - Ess;
	vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;	vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );
	singleScatter += FssEss;
	multiScatter += Fms * Ems;
}
vec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {
	vec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );
	float dotNL = saturate( dot( normal, lightDir ) );
	float dotNV = saturate( dot( normal, viewDir ) );
	vec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;
	vec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;
	vec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;
	vec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;
	float Ess_V = dfgV.x + dfgV.y;
	float Ess_L = dfgL.x + dfgL.y;
	float Ems_V = 1.0 - Ess_V;
	float Ems_L = 1.0 - Ess_L;
	vec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;
	vec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );
	float compensationFactor = Ems_V * Ems_L;
	vec3 multiScatter = Fms * compensationFactor;
	return singleScatter + multiScatter;
}
#if NUM_RECT_AREA_LIGHTS > 0
	void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
		vec3 normal = geometryNormal;
		vec3 viewDir = geometryViewDir;
		vec3 position = geometryPosition;
		vec3 lightPos = rectAreaLight.position;
		vec3 halfWidth = rectAreaLight.halfWidth;
		vec3 halfHeight = rectAreaLight.halfHeight;
		vec3 lightColor = rectAreaLight.color;
		float roughness = material.roughness;
		vec3 rectCoords[ 4 ];
		rectCoords[ 0 ] = lightPos + halfWidth - halfHeight;		rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;
		rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;
		rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;
		vec2 uv = LTC_Uv( normal, viewDir, roughness );
		vec4 t1 = texture2D( ltc_1, uv );
		vec4 t2 = texture2D( ltc_2, uv );
		mat3 mInv = mat3(
			vec3( t1.x, 0, t1.y ),
			vec3(    0, 1,    0 ),
			vec3( t1.z, 0, t1.w )
		);
		vec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );
		reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );
		reflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );
		#ifdef USE_CLEARCOAT
			vec3 Ncc = geometryClearcoatNormal;
			vec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );
			vec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );
			vec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );
			mat3 mInvClearcoat = mat3(
				vec3( t1Clearcoat.x, 0, t1Clearcoat.y ),
				vec3(             0, 1,             0 ),
				vec3( t1Clearcoat.z, 0, t1Clearcoat.w )
			);
			vec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;
			clearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );
		#endif
	}
#endif
void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
	float dotNL = saturate( dot( geometryNormal, directLight.direction ) );
	vec3 irradiance = dotNL * directLight.color;
	#ifdef USE_CLEARCOAT
		float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );
		vec3 ccIrradiance = dotNLcc * directLight.color;
		clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );
	#endif
	#ifdef USE_SHEEN
 
 		sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );
 
 		float sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );
 		float sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );
 
 		float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );
 
 		irradiance *= sheenEnergyComp;
 
 	#endif
	reflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );
	reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );
}
void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
	vec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );
	#ifdef USE_SHEEN
		float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );
		float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;
		diffuse *= sheenEnergyComp;
	#endif
	reflectedLight.indirectDiffuse += diffuse;
}
void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
	#ifdef USE_CLEARCOAT
		clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
	#endif
	#ifdef USE_SHEEN
		sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;
 	#endif
	vec3 singleScatteringDielectric = vec3( 0.0 );
	vec3 multiScatteringDielectric = vec3( 0.0 );
	vec3 singleScatteringMetallic = vec3( 0.0 );
	vec3 multiScatteringMetallic = vec3( 0.0 );
	#ifdef USE_IRIDESCENCE
		computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );
		computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );
	#else
		computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );
		computeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );
	#endif
	vec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );
	vec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );
	vec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;
	vec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );
	vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;
	vec3 indirectSpecular = radiance * singleScattering;
	indirectSpecular += multiScattering * cosineWeightedIrradiance;
	vec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;
	#ifdef USE_SHEEN
		float sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );
		float sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;
		indirectSpecular *= sheenEnergyComp;
		indirectDiffuse *= sheenEnergyComp;
	#endif
	reflectedLight.indirectSpecular += indirectSpecular;
	reflectedLight.indirectDiffuse += indirectDiffuse;
}
#define RE_Direct				RE_Direct_Physical
#define RE_Direct_RectArea		RE_Direct_RectArea_Physical
#define RE_IndirectDiffuse		RE_IndirectDiffuse_Physical
#define RE_IndirectSpecular		RE_IndirectSpecular_Physical
float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {
	return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );
}`, lA = `
vec3 geometryPosition = - vViewPosition;
vec3 geometryNormal = normal;
vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
vec3 geometryClearcoatNormal = vec3( 0.0 );
#ifdef USE_CLEARCOAT
	geometryClearcoatNormal = clearcoatNormal;
#endif
#ifdef USE_IRIDESCENCE
	float dotNVi = saturate( dot( normal, geometryViewDir ) );
	if ( material.iridescenceThickness == 0.0 ) {
		material.iridescence = 0.0;
	} else {
		material.iridescence = saturate( material.iridescence );
	}
	if ( material.iridescence > 0.0 ) {
		material.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );
		material.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );
		material.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );
		material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );
	}
#endif
IncidentLight directLight;
#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )
	PointLight pointLight;
	#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0
	PointLightShadow pointLightShadow;
	#endif
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
		pointLight = pointLights[ i ];
		getPointLightInfo( pointLight, geometryPosition, directLight );
		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )
		pointLightShadow = pointLightShadows[ i ];
		directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;
		#endif
		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
	}
	#pragma unroll_loop_end
#endif
#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
	SpotLight spotLight;
	vec4 spotColor;
	vec3 spotLightCoord;
	bool inSpotLightMap;
	#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
	SpotLightShadow spotLightShadow;
	#endif
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
		spotLight = spotLights[ i ];
		getSpotLightInfo( spotLight, geometryPosition, directLight );
		#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )
		#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX
		#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
		#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS
		#else
		#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )
		#endif
		#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )
			spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;
			inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );
			spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );
			directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;
		#endif
		#undef SPOT_LIGHT_MAP_INDEX
		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
		spotLightShadow = spotLightShadows[ i ];
		directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;
		#endif
		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
	}
	#pragma unroll_loop_end
#endif
#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )
	DirectionalLight directionalLight;
	#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0
	DirectionalLightShadow directionalLightShadow;
	#endif
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
		directionalLight = directionalLights[ i ];
		getDirectionalLightInfo( directionalLight, directLight );
		#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
		directionalLightShadow = directionalLightShadows[ i ];
		directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
		#endif
		RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
	}
	#pragma unroll_loop_end
#endif
#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )
	RectAreaLight rectAreaLight;
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
		rectAreaLight = rectAreaLights[ i ];
		RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
	}
	#pragma unroll_loop_end
#endif
#if defined( RE_IndirectDiffuse )
	vec3 iblIrradiance = vec3( 0.0 );
	vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
	#if defined( USE_LIGHT_PROBES )
		irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );
	#endif
	#if ( NUM_HEMI_LIGHTS > 0 )
		#pragma unroll_loop_start
		for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
			irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );
		}
		#pragma unroll_loop_end
	#endif
#endif
#if defined( RE_IndirectSpecular )
	vec3 radiance = vec3( 0.0 );
	vec3 clearcoatRadiance = vec3( 0.0 );
#endif`, cA = `#if defined( RE_IndirectDiffuse )
	#ifdef USE_LIGHTMAP
		vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );
		vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;
		irradiance += lightMapIrradiance;
	#endif
	#if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )
		#if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )
			iblIrradiance += getIBLIrradiance( geometryNormal );
		#endif
	#endif
#endif
#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )
	#ifdef USE_ANISOTROPY
		radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );
	#else
		radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );
	#endif
	#ifdef USE_CLEARCOAT
		clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );
	#endif
#endif`, uA = `#if defined( RE_IndirectDiffuse )
	#if defined( LAMBERT ) || defined( PHONG )
		irradiance += iblIrradiance;
	#endif
	RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
#endif
#if defined( RE_IndirectSpecular )
	RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
#endif`, hA = `#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )
	gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;
#endif`, dA = `#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )
	uniform float logDepthBufFC;
	varying float vFragDepth;
	varying float vIsPerspective;
#endif`, fA = `#ifdef USE_LOGARITHMIC_DEPTH_BUFFER
	varying float vFragDepth;
	varying float vIsPerspective;
#endif`, pA = `#ifdef USE_LOGARITHMIC_DEPTH_BUFFER
	vFragDepth = 1.0 + gl_Position.w;
	vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );
#endif`, mA = `#ifdef USE_MAP
	vec4 sampledDiffuseColor = texture2D( map, vMapUv );
	#ifdef DECODE_VIDEO_TEXTURE
		sampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );
	#endif
	diffuseColor *= sampledDiffuseColor;
#endif`, gA = `#ifdef USE_MAP
	uniform sampler2D map;
#endif`, _A = `#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
	#if defined( USE_POINTS_UV )
		vec2 uv = vUv;
	#else
		vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;
	#endif
#endif
#ifdef USE_MAP
	diffuseColor *= texture2D( map, uv );
#endif
#ifdef USE_ALPHAMAP
	diffuseColor.a *= texture2D( alphaMap, uv ).g;
#endif`, xA = `#if defined( USE_POINTS_UV )
	varying vec2 vUv;
#else
	#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
		uniform mat3 uvTransform;
	#endif
#endif
#ifdef USE_MAP
	uniform sampler2D map;
#endif
#ifdef USE_ALPHAMAP
	uniform sampler2D alphaMap;
#endif`, vA = `float metalnessFactor = metalness;
#ifdef USE_METALNESSMAP
	vec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );
	metalnessFactor *= texelMetalness.b;
#endif`, yA = `#ifdef USE_METALNESSMAP
	uniform sampler2D metalnessMap;
#endif`, bA = `#ifdef USE_INSTANCING_MORPH
	float morphTargetInfluences[ MORPHTARGETS_COUNT ];
	float morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;
	for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
		morphTargetInfluences[i] =  texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;
	}
#endif`, SA = `#if defined( USE_MORPHCOLORS )
	vColor *= morphTargetBaseInfluence;
	for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
		#if defined( USE_COLOR_ALPHA )
			if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];
		#elif defined( USE_COLOR )
			if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];
		#endif
	}
#endif`, TA = `#ifdef USE_MORPHNORMALS
	objectNormal *= morphTargetBaseInfluence;
	for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
		if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];
	}
#endif`, MA = `#ifdef USE_MORPHTARGETS
	#ifndef USE_INSTANCING_MORPH
		uniform float morphTargetBaseInfluence;
		uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];
	#endif
	uniform sampler2DArray morphTargetsTexture;
	uniform ivec2 morphTargetsTextureSize;
	vec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {
		int texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;
		int y = texelIndex / morphTargetsTextureSize.x;
		int x = texelIndex - y * morphTargetsTextureSize.x;
		ivec3 morphUV = ivec3( x, y, morphTargetIndex );
		return texelFetch( morphTargetsTexture, morphUV, 0 );
	}
#endif`, EA = `#ifdef USE_MORPHTARGETS
	transformed *= morphTargetBaseInfluence;
	for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {
		if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];
	}
#endif`, wA = `float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;
#ifdef FLAT_SHADED
	vec3 fdx = dFdx( vViewPosition );
	vec3 fdy = dFdy( vViewPosition );
	vec3 normal = normalize( cross( fdx, fdy ) );
#else
	vec3 normal = normalize( vNormal );
	#ifdef DOUBLE_SIDED
		normal *= faceDirection;
	#endif
#endif
#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )
	#ifdef USE_TANGENT
		mat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );
	#else
		mat3 tbn = getTangentFrame( - vViewPosition, normal,
		#if defined( USE_NORMALMAP )
			vNormalMapUv
		#elif defined( USE_CLEARCOAT_NORMALMAP )
			vClearcoatNormalMapUv
		#else
			vUv
		#endif
		);
	#endif
	#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )
		tbn[0] *= faceDirection;
		tbn[1] *= faceDirection;
	#endif
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
	#ifdef USE_TANGENT
		mat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );
	#else
		mat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );
	#endif
	#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )
		tbn2[0] *= faceDirection;
		tbn2[1] *= faceDirection;
	#endif
#endif
vec3 nonPerturbedNormal = normal;`, AA = `#ifdef USE_NORMALMAP_OBJECTSPACE
	normal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;
	#ifdef FLIP_SIDED
		normal = - normal;
	#endif
	#ifdef DOUBLE_SIDED
		normal = normal * faceDirection;
	#endif
	normal = normalize( normalMatrix * normal );
#elif defined( USE_NORMALMAP_TANGENTSPACE )
	vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;
	mapN.xy *= normalScale;
	normal = normalize( tbn * mapN );
#elif defined( USE_BUMPMAP )
	normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );
#endif`, RA = `#ifndef FLAT_SHADED
	varying vec3 vNormal;
	#ifdef USE_TANGENT
		varying vec3 vTangent;
		varying vec3 vBitangent;
	#endif
#endif`, CA = `#ifndef FLAT_SHADED
	varying vec3 vNormal;
	#ifdef USE_TANGENT
		varying vec3 vTangent;
		varying vec3 vBitangent;
	#endif
#endif`, NA = `#ifndef FLAT_SHADED
	vNormal = normalize( transformedNormal );
	#ifdef USE_TANGENT
		vTangent = normalize( transformedTangent );
		vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );
	#endif
#endif`, PA = `#ifdef USE_NORMALMAP
	uniform sampler2D normalMap;
	uniform vec2 normalScale;
#endif
#ifdef USE_NORMALMAP_OBJECTSPACE
	uniform mat3 normalMatrix;
#endif
#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )
	mat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {
		vec3 q0 = dFdx( eye_pos.xyz );
		vec3 q1 = dFdy( eye_pos.xyz );
		vec2 st0 = dFdx( uv.st );
		vec2 st1 = dFdy( uv.st );
		vec3 N = surf_norm;
		vec3 q1perp = cross( q1, N );
		vec3 q0perp = cross( N, q0 );
		vec3 T = q1perp * st0.x + q0perp * st1.x;
		vec3 B = q1perp * st0.y + q0perp * st1.y;
		float det = max( dot( T, T ), dot( B, B ) );
		float scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );
		return mat3( T * scale, B * scale, N );
	}
#endif`, DA = `#ifdef USE_CLEARCOAT
	vec3 clearcoatNormal = nonPerturbedNormal;
#endif`, LA = `#ifdef USE_CLEARCOAT_NORMALMAP
	vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;
	clearcoatMapN.xy *= clearcoatNormalScale;
	clearcoatNormal = normalize( tbn2 * clearcoatMapN );
#endif`, FA = `#ifdef USE_CLEARCOATMAP
	uniform sampler2D clearcoatMap;
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
	uniform sampler2D clearcoatNormalMap;
	uniform vec2 clearcoatNormalScale;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
	uniform sampler2D clearcoatRoughnessMap;
#endif`, IA = `#ifdef USE_IRIDESCENCEMAP
	uniform sampler2D iridescenceMap;
#endif
#ifdef USE_IRIDESCENCE_THICKNESSMAP
	uniform sampler2D iridescenceThicknessMap;
#endif`, UA = `#ifdef OPAQUE
diffuseColor.a = 1.0;
#endif
#ifdef USE_TRANSMISSION
diffuseColor.a *= material.transmissionAlpha;
#endif
gl_FragColor = vec4( outgoingLight, diffuseColor.a );`, BA = `vec3 packNormalToRGB( const in vec3 normal ) {
	return normalize( normal ) * 0.5 + 0.5;
}
vec3 unpackRGBToNormal( const in vec3 rgb ) {
	return 2.0 * rgb.xyz - 1.0;
}
const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;
const float Inv255 = 1. / 255.;
const vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );
const vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );
const vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );
const vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );
vec4 packDepthToRGBA( const in float v ) {
	if( v <= 0.0 )
		return vec4( 0., 0., 0., 0. );
	if( v >= 1.0 )
		return vec4( 1., 1., 1., 1. );
	float vuf;
	float af = modf( v * PackFactors.a, vuf );
	float bf = modf( vuf * ShiftRight8, vuf );
	float gf = modf( vuf * ShiftRight8, vuf );
	return vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );
}
vec3 packDepthToRGB( const in float v ) {
	if( v <= 0.0 )
		return vec3( 0., 0., 0. );
	if( v >= 1.0 )
		return vec3( 1., 1., 1. );
	float vuf;
	float bf = modf( v * PackFactors.b, vuf );
	float gf = modf( vuf * ShiftRight8, vuf );
	return vec3( vuf * Inv255, gf * PackUpscale, bf );
}
vec2 packDepthToRG( const in float v ) {
	if( v <= 0.0 )
		return vec2( 0., 0. );
	if( v >= 1.0 )
		return vec2( 1., 1. );
	float vuf;
	float gf = modf( v * 256., vuf );
	return vec2( vuf * Inv255, gf );
}
float unpackRGBAToDepth( const in vec4 v ) {
	return dot( v, UnpackFactors4 );
}
float unpackRGBToDepth( const in vec3 v ) {
	return dot( v, UnpackFactors3 );
}
float unpackRGToDepth( const in vec2 v ) {
	return v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;
}
vec4 pack2HalfToRGBA( const in vec2 v ) {
	vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );
	return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );
}
vec2 unpackRGBATo2Half( const in vec4 v ) {
	return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
}
float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
	return ( viewZ + near ) / ( near - far );
}
float orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {
	#ifdef USE_REVERSED_DEPTH_BUFFER
	
		return depth * ( far - near ) - far;
	#else
		return depth * ( near - far ) - near;
	#endif
}
float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
	return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );
}
float perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {
	
	#ifdef USE_REVERSED_DEPTH_BUFFER
		return ( near * far ) / ( ( near - far ) * depth - near );
	#else
		return ( near * far ) / ( ( far - near ) * depth - far );
	#endif
}`, OA = `#ifdef PREMULTIPLIED_ALPHA
	gl_FragColor.rgb *= gl_FragColor.a;
#endif`, kA = `vec4 mvPosition = vec4( transformed, 1.0 );
#ifdef USE_BATCHING
	mvPosition = batchingMatrix * mvPosition;
#endif
#ifdef USE_INSTANCING
	mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;`, GA = `#ifdef DITHERING
	gl_FragColor.rgb = dithering( gl_FragColor.rgb );
#endif`, VA = `#ifdef DITHERING
	vec3 dithering( vec3 color ) {
		float grid_position = rand( gl_FragCoord.xy );
		vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );
		dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );
		return color + dither_shift_RGB;
	}
#endif`, zA = `float roughnessFactor = roughness;
#ifdef USE_ROUGHNESSMAP
	vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );
	roughnessFactor *= texelRoughness.g;
#endif`, HA = `#ifdef USE_ROUGHNESSMAP
	uniform sampler2D roughnessMap;
#endif`, $A = `#if NUM_SPOT_LIGHT_COORDS > 0
	varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];
#endif
#if NUM_SPOT_LIGHT_MAPS > 0
	uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];
#endif
#ifdef USE_SHADOWMAP
	#if NUM_DIR_LIGHT_SHADOWS > 0
		#if defined( SHADOWMAP_TYPE_PCF )
			uniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];
		#else
			uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];
		#endif
		varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
		struct DirectionalLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
		};
		uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];
	#endif
	#if NUM_SPOT_LIGHT_SHADOWS > 0
		#if defined( SHADOWMAP_TYPE_PCF )
			uniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];
		#else
			uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];
		#endif
		struct SpotLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
		};
		uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];
	#endif
	#if NUM_POINT_LIGHT_SHADOWS > 0
		#if defined( SHADOWMAP_TYPE_PCF )
			uniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];
		#elif defined( SHADOWMAP_TYPE_BASIC )
			uniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];
		#endif
		varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
		struct PointLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
			float shadowCameraNear;
			float shadowCameraFar;
		};
		uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];
	#endif
	#if defined( SHADOWMAP_TYPE_PCF )
		float interleavedGradientNoise( vec2 position ) {
			return fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );
		}
		vec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {
			const float goldenAngle = 2.399963229728653;
			float r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );
			float theta = float( sampleIndex ) * goldenAngle + phi;
			return vec2( cos( theta ), sin( theta ) ) * r;
		}
	#endif
	#if defined( SHADOWMAP_TYPE_PCF )
		float getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
			float shadow = 1.0;
			shadowCoord.xyz /= shadowCoord.w;
			shadowCoord.z += shadowBias;
			bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;
			bool frustumTest = inFrustum && shadowCoord.z <= 1.0;
			if ( frustumTest ) {
				vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
				float radius = shadowRadius * texelSize.x;
				float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;
				shadow = (
					texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +
					texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +
					texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +
					texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +
					texture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )
				) * 0.2;
			}
			return mix( 1.0, shadow, shadowIntensity );
		}
	#elif defined( SHADOWMAP_TYPE_VSM )
		float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
			float shadow = 1.0;
			shadowCoord.xyz /= shadowCoord.w;
			#ifdef USE_REVERSED_DEPTH_BUFFER
				shadowCoord.z -= shadowBias;
			#else
				shadowCoord.z += shadowBias;
			#endif
			bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;
			bool frustumTest = inFrustum && shadowCoord.z <= 1.0;
			if ( frustumTest ) {
				vec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;
				float mean = distribution.x;
				float variance = distribution.y * distribution.y;
				#ifdef USE_REVERSED_DEPTH_BUFFER
					float hard_shadow = step( mean, shadowCoord.z );
				#else
					float hard_shadow = step( shadowCoord.z, mean );
				#endif
				
				if ( hard_shadow == 1.0 ) {
					shadow = 1.0;
				} else {
					variance = max( variance, 0.0000001 );
					float d = shadowCoord.z - mean;
					float p_max = variance / ( variance + d * d );
					p_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );
					shadow = max( hard_shadow, p_max );
				}
			}
			return mix( 1.0, shadow, shadowIntensity );
		}
	#else
		float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
			float shadow = 1.0;
			shadowCoord.xyz /= shadowCoord.w;
			#ifdef USE_REVERSED_DEPTH_BUFFER
				shadowCoord.z -= shadowBias;
			#else
				shadowCoord.z += shadowBias;
			#endif
			bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;
			bool frustumTest = inFrustum && shadowCoord.z <= 1.0;
			if ( frustumTest ) {
				float depth = texture2D( shadowMap, shadowCoord.xy ).r;
				#ifdef USE_REVERSED_DEPTH_BUFFER
					shadow = step( depth, shadowCoord.z );
				#else
					shadow = step( shadowCoord.z, depth );
				#endif
			}
			return mix( 1.0, shadow, shadowIntensity );
		}
	#endif
	#if NUM_POINT_LIGHT_SHADOWS > 0
	#if defined( SHADOWMAP_TYPE_PCF )
	float getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
		float shadow = 1.0;
		vec3 lightToPosition = shadowCoord.xyz;
		vec3 bd3D = normalize( lightToPosition );
		vec3 absVec = abs( lightToPosition );
		float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );
		if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {
			#ifdef USE_REVERSED_DEPTH_BUFFER
				float dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );
				dp -= shadowBias;
			#else
				float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );
				dp += shadowBias;
			#endif
			float texelSize = shadowRadius / shadowMapSize.x;
			vec3 absDir = abs( bd3D );
			vec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );
			tangent = normalize( cross( bd3D, tangent ) );
			vec3 bitangent = cross( bd3D, tangent );
			float phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;
			vec2 sample0 = vogelDiskSample( 0, 5, phi );
			vec2 sample1 = vogelDiskSample( 1, 5, phi );
			vec2 sample2 = vogelDiskSample( 2, 5, phi );
			vec2 sample3 = vogelDiskSample( 3, 5, phi );
			vec2 sample4 = vogelDiskSample( 4, 5, phi );
			shadow = (
				texture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +
				texture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +
				texture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +
				texture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +
				texture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )
			) * 0.2;
		}
		return mix( 1.0, shadow, shadowIntensity );
	}
	#elif defined( SHADOWMAP_TYPE_BASIC )
	float getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
		float shadow = 1.0;
		vec3 lightToPosition = shadowCoord.xyz;
		vec3 absVec = abs( lightToPosition );
		float viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );
		if ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {
			float dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );
			dp += shadowBias;
			vec3 bd3D = normalize( lightToPosition );
			float depth = textureCube( shadowMap, bd3D ).r;
			#ifdef USE_REVERSED_DEPTH_BUFFER
				depth = 1.0 - depth;
			#endif
			shadow = step( dp, depth );
		}
		return mix( 1.0, shadow, shadowIntensity );
	}
	#endif
	#endif
#endif`, WA = `#if NUM_SPOT_LIGHT_COORDS > 0
	uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];
	varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];
#endif
#ifdef USE_SHADOWMAP
	#if NUM_DIR_LIGHT_SHADOWS > 0
		uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];
		varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
		struct DirectionalLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
		};
		uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];
	#endif
	#if NUM_SPOT_LIGHT_SHADOWS > 0
		struct SpotLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
		};
		uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];
	#endif
	#if NUM_POINT_LIGHT_SHADOWS > 0
		uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];
		varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
		struct PointLightShadow {
			float shadowIntensity;
			float shadowBias;
			float shadowNormalBias;
			float shadowRadius;
			vec2 shadowMapSize;
			float shadowCameraNear;
			float shadowCameraFar;
		};
		uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];
	#endif
#endif`, qA = `#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )
	vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
	vec4 shadowWorldPosition;
#endif
#if defined( USE_SHADOWMAP )
	#if NUM_DIR_LIGHT_SHADOWS > 0
		#pragma unroll_loop_start
		for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
			shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );
			vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;
		}
		#pragma unroll_loop_end
	#endif
	#if NUM_POINT_LIGHT_SHADOWS > 0
		#pragma unroll_loop_start
		for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
			shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );
			vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;
		}
		#pragma unroll_loop_end
	#endif
#endif
#if NUM_SPOT_LIGHT_COORDS > 0
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {
		shadowWorldPosition = worldPosition;
		#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
			shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;
		#endif
		vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;
	}
	#pragma unroll_loop_end
#endif`, XA = `float getShadowMask() {
	float shadow = 1.0;
	#ifdef USE_SHADOWMAP
	#if NUM_DIR_LIGHT_SHADOWS > 0
	DirectionalLightShadow directionalLight;
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
		directionalLight = directionalLightShadows[ i ];
		shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
	}
	#pragma unroll_loop_end
	#endif
	#if NUM_SPOT_LIGHT_SHADOWS > 0
	SpotLightShadow spotLight;
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
		spotLight = spotLightShadows[ i ];
		shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;
	}
	#pragma unroll_loop_end
	#endif
	#if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )
	PointLightShadow pointLight;
	#pragma unroll_loop_start
	for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
		pointLight = pointLightShadows[ i ];
		shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
	}
	#pragma unroll_loop_end
	#endif
	#endif
	return shadow;
}`, jA = `#ifdef USE_SKINNING
	mat4 boneMatX = getBoneMatrix( skinIndex.x );
	mat4 boneMatY = getBoneMatrix( skinIndex.y );
	mat4 boneMatZ = getBoneMatrix( skinIndex.z );
	mat4 boneMatW = getBoneMatrix( skinIndex.w );
#endif`, YA = `#ifdef USE_SKINNING
	uniform mat4 bindMatrix;
	uniform mat4 bindMatrixInverse;
	uniform highp sampler2D boneTexture;
	mat4 getBoneMatrix( const in float i ) {
		int size = textureSize( boneTexture, 0 ).x;
		int j = int( i ) * 4;
		int x = j % size;
		int y = j / size;
		vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );
		vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );
		vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );
		vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );
		return mat4( v1, v2, v3, v4 );
	}
#endif`, KA = `#ifdef USE_SKINNING
	vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
	vec4 skinned = vec4( 0.0 );
	skinned += boneMatX * skinVertex * skinWeight.x;
	skinned += boneMatY * skinVertex * skinWeight.y;
	skinned += boneMatZ * skinVertex * skinWeight.z;
	skinned += boneMatW * skinVertex * skinWeight.w;
	transformed = ( bindMatrixInverse * skinned ).xyz;
#endif`, ZA = `#ifdef USE_SKINNING
	mat4 skinMatrix = mat4( 0.0 );
	skinMatrix += skinWeight.x * boneMatX;
	skinMatrix += skinWeight.y * boneMatY;
	skinMatrix += skinWeight.z * boneMatZ;
	skinMatrix += skinWeight.w * boneMatW;
	skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
	objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
	#ifdef USE_TANGENT
		objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;
	#endif
#endif`, QA = `float specularStrength;
#ifdef USE_SPECULARMAP
	vec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );
	specularStrength = texelSpecular.r;
#else
	specularStrength = 1.0;
#endif`, JA = `#ifdef USE_SPECULARMAP
	uniform sampler2D specularMap;
#endif`, eR = `#if defined( TONE_MAPPING )
	gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );
#endif`, tR = `#ifndef saturate
#define saturate( a ) clamp( a, 0.0, 1.0 )
#endif
uniform float toneMappingExposure;
vec3 LinearToneMapping( vec3 color ) {
	return saturate( toneMappingExposure * color );
}
vec3 ReinhardToneMapping( vec3 color ) {
	color *= toneMappingExposure;
	return saturate( color / ( vec3( 1.0 ) + color ) );
}
vec3 CineonToneMapping( vec3 color ) {
	color *= toneMappingExposure;
	color = max( vec3( 0.0 ), color - 0.004 );
	return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
}
vec3 RRTAndODTFit( vec3 v ) {
	vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
	vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
	return a / b;
}
vec3 ACESFilmicToneMapping( vec3 color ) {
	const mat3 ACESInputMat = mat3(
		vec3( 0.59719, 0.07600, 0.02840 ),		vec3( 0.35458, 0.90834, 0.13383 ),
		vec3( 0.04823, 0.01566, 0.83777 )
	);
	const mat3 ACESOutputMat = mat3(
		vec3(  1.60475, -0.10208, -0.00327 ),		vec3( -0.53108,  1.10813, -0.07276 ),
		vec3( -0.07367, -0.00605,  1.07602 )
	);
	color *= toneMappingExposure / 0.6;
	color = ACESInputMat * color;
	color = RRTAndODTFit( color );
	color = ACESOutputMat * color;
	return saturate( color );
}
const mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(
	vec3( 1.6605, - 0.1246, - 0.0182 ),
	vec3( - 0.5876, 1.1329, - 0.1006 ),
	vec3( - 0.0728, - 0.0083, 1.1187 )
);
const mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(
	vec3( 0.6274, 0.0691, 0.0164 ),
	vec3( 0.3293, 0.9195, 0.0880 ),
	vec3( 0.0433, 0.0113, 0.8956 )
);
vec3 agxDefaultContrastApprox( vec3 x ) {
	vec3 x2 = x * x;
	vec3 x4 = x2 * x2;
	return + 15.5 * x4 * x2
		- 40.14 * x4 * x
		+ 31.96 * x4
		- 6.868 * x2 * x
		+ 0.4298 * x2
		+ 0.1191 * x
		- 0.00232;
}
vec3 AgXToneMapping( vec3 color ) {
	const mat3 AgXInsetMatrix = mat3(
		vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),
		vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),
		vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )
	);
	const mat3 AgXOutsetMatrix = mat3(
		vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),
		vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),
		vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )
	);
	const float AgxMinEv = - 12.47393;	const float AgxMaxEv = 4.026069;
	color *= toneMappingExposure;
	color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;
	color = AgXInsetMatrix * color;
	color = max( color, 1e-10 );	color = log2( color );
	color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );
	color = clamp( color, 0.0, 1.0 );
	color = agxDefaultContrastApprox( color );
	color = AgXOutsetMatrix * color;
	color = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );
	color = LINEAR_REC2020_TO_LINEAR_SRGB * color;
	color = clamp( color, 0.0, 1.0 );
	return color;
}
vec3 NeutralToneMapping( vec3 color ) {
	const float StartCompression = 0.8 - 0.04;
	const float Desaturation = 0.15;
	color *= toneMappingExposure;
	float x = min( color.r, min( color.g, color.b ) );
	float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
	color -= offset;
	float peak = max( color.r, max( color.g, color.b ) );
	if ( peak < StartCompression ) return color;
	float d = 1. - StartCompression;
	float newPeak = 1. - d * d / ( peak + d - StartCompression );
	color *= newPeak / peak;
	float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );
	return mix( color, vec3( newPeak ), g );
}
vec3 CustomToneMapping( vec3 color ) { return color; }`, nR = `#ifdef USE_TRANSMISSION
	material.transmission = transmission;
	material.transmissionAlpha = 1.0;
	material.thickness = thickness;
	material.attenuationDistance = attenuationDistance;
	material.attenuationColor = attenuationColor;
	#ifdef USE_TRANSMISSIONMAP
		material.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;
	#endif
	#ifdef USE_THICKNESSMAP
		material.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;
	#endif
	vec3 pos = vWorldPosition;
	vec3 v = normalize( cameraPosition - pos );
	vec3 n = inverseTransformDirection( normal, viewMatrix );
	vec4 transmitted = getIBLVolumeRefraction(
		n, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,
		pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,
		material.attenuationColor, material.attenuationDistance );
	material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );
	totalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );
#endif`, iR = `#ifdef USE_TRANSMISSION
	uniform float transmission;
	uniform float thickness;
	uniform float attenuationDistance;
	uniform vec3 attenuationColor;
	#ifdef USE_TRANSMISSIONMAP
		uniform sampler2D transmissionMap;
	#endif
	#ifdef USE_THICKNESSMAP
		uniform sampler2D thicknessMap;
	#endif
	uniform vec2 transmissionSamplerSize;
	uniform sampler2D transmissionSamplerMap;
	uniform mat4 modelMatrix;
	uniform mat4 projectionMatrix;
	varying vec3 vWorldPosition;
	float w0( float a ) {
		return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );
	}
	float w1( float a ) {
		return ( 1.0 / 6.0 ) * ( a *  a * ( 3.0 * a - 6.0 ) + 4.0 );
	}
	float w2( float a ){
		return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );
	}
	float w3( float a ) {
		return ( 1.0 / 6.0 ) * ( a * a * a );
	}
	float g0( float a ) {
		return w0( a ) + w1( a );
	}
	float g1( float a ) {
		return w2( a ) + w3( a );
	}
	float h0( float a ) {
		return - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );
	}
	float h1( float a ) {
		return 1.0 + w3( a ) / ( w2( a ) + w3( a ) );
	}
	vec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {
		uv = uv * texelSize.zw + 0.5;
		vec2 iuv = floor( uv );
		vec2 fuv = fract( uv );
		float g0x = g0( fuv.x );
		float g1x = g1( fuv.x );
		float h0x = h0( fuv.x );
		float h1x = h1( fuv.x );
		float h0y = h0( fuv.y );
		float h1y = h1( fuv.y );
		vec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;
		vec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;
		vec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;
		vec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;
		return g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +
			g1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );
	}
	vec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {
		vec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );
		vec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );
		vec2 fLodSizeInv = 1.0 / fLodSize;
		vec2 cLodSizeInv = 1.0 / cLodSize;
		vec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );
		vec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );
		return mix( fSample, cSample, fract( lod ) );
	}
	vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {
		vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );
		vec3 modelScale;
		modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );
		modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );
		modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );
		return normalize( refractionVector ) * thickness * modelScale;
	}
	float applyIorToRoughness( const in float roughness, const in float ior ) {
		return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );
	}
	vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {
		float lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );
		return textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );
	}
	vec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {
		if ( isinf( attenuationDistance ) ) {
			return vec3( 1.0 );
		} else {
			vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;
			vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );			return transmittance;
		}
	}
	vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,
		const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,
		const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,
		const in vec3 attenuationColor, const in float attenuationDistance ) {
		vec4 transmittedLight;
		vec3 transmittance;
		#ifdef USE_DISPERSION
			float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;
			vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );
			for ( int i = 0; i < 3; i ++ ) {
				vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );
				vec3 refractedRayExit = position + transmissionRay;
				vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
				vec2 refractionCoords = ndcPos.xy / ndcPos.w;
				refractionCoords += 1.0;
				refractionCoords /= 2.0;
				vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );
				transmittedLight[ i ] = transmissionSample[ i ];
				transmittedLight.a += transmissionSample.a;
				transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];
			}
			transmittedLight.a /= 3.0;
		#else
			vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );
			vec3 refractedRayExit = position + transmissionRay;
			vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );
			vec2 refractionCoords = ndcPos.xy / ndcPos.w;
			refractionCoords += 1.0;
			refractionCoords /= 2.0;
			transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
			transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );
		#endif
		vec3 attenuatedColor = transmittance * transmittedLight.rgb;
		vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );
		float transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;
		return vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );
	}
#endif`, rR = `#if defined( USE_UV ) || defined( USE_ANISOTROPY )
	varying vec2 vUv;
#endif
#ifdef USE_MAP
	varying vec2 vMapUv;
#endif
#ifdef USE_ALPHAMAP
	varying vec2 vAlphaMapUv;
#endif
#ifdef USE_LIGHTMAP
	varying vec2 vLightMapUv;
#endif
#ifdef USE_AOMAP
	varying vec2 vAoMapUv;
#endif
#ifdef USE_BUMPMAP
	varying vec2 vBumpMapUv;
#endif
#ifdef USE_NORMALMAP
	varying vec2 vNormalMapUv;
#endif
#ifdef USE_EMISSIVEMAP
	varying vec2 vEmissiveMapUv;
#endif
#ifdef USE_METALNESSMAP
	varying vec2 vMetalnessMapUv;
#endif
#ifdef USE_ROUGHNESSMAP
	varying vec2 vRoughnessMapUv;
#endif
#ifdef USE_ANISOTROPYMAP
	varying vec2 vAnisotropyMapUv;
#endif
#ifdef USE_CLEARCOATMAP
	varying vec2 vClearcoatMapUv;
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
	varying vec2 vClearcoatNormalMapUv;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
	varying vec2 vClearcoatRoughnessMapUv;
#endif
#ifdef USE_IRIDESCENCEMAP
	varying vec2 vIridescenceMapUv;
#endif
#ifdef USE_IRIDESCENCE_THICKNESSMAP
	varying vec2 vIridescenceThicknessMapUv;
#endif
#ifdef USE_SHEEN_COLORMAP
	varying vec2 vSheenColorMapUv;
#endif
#ifdef USE_SHEEN_ROUGHNESSMAP
	varying vec2 vSheenRoughnessMapUv;
#endif
#ifdef USE_SPECULARMAP
	varying vec2 vSpecularMapUv;
#endif
#ifdef USE_SPECULAR_COLORMAP
	varying vec2 vSpecularColorMapUv;
#endif
#ifdef USE_SPECULAR_INTENSITYMAP
	varying vec2 vSpecularIntensityMapUv;
#endif
#ifdef USE_TRANSMISSIONMAP
	uniform mat3 transmissionMapTransform;
	varying vec2 vTransmissionMapUv;
#endif
#ifdef USE_THICKNESSMAP
	uniform mat3 thicknessMapTransform;
	varying vec2 vThicknessMapUv;
#endif`, sR = `#if defined( USE_UV ) || defined( USE_ANISOTROPY )
	varying vec2 vUv;
#endif
#ifdef USE_MAP
	uniform mat3 mapTransform;
	varying vec2 vMapUv;
#endif
#ifdef USE_ALPHAMAP
	uniform mat3 alphaMapTransform;
	varying vec2 vAlphaMapUv;
#endif
#ifdef USE_LIGHTMAP
	uniform mat3 lightMapTransform;
	varying vec2 vLightMapUv;
#endif
#ifdef USE_AOMAP
	uniform mat3 aoMapTransform;
	varying vec2 vAoMapUv;
#endif
#ifdef USE_BUMPMAP
	uniform mat3 bumpMapTransform;
	varying vec2 vBumpMapUv;
#endif
#ifdef USE_NORMALMAP
	uniform mat3 normalMapTransform;
	varying vec2 vNormalMapUv;
#endif
#ifdef USE_DISPLACEMENTMAP
	uniform mat3 displacementMapTransform;
	varying vec2 vDisplacementMapUv;
#endif
#ifdef USE_EMISSIVEMAP
	uniform mat3 emissiveMapTransform;
	varying vec2 vEmissiveMapUv;
#endif
#ifdef USE_METALNESSMAP
	uniform mat3 metalnessMapTransform;
	varying vec2 vMetalnessMapUv;
#endif
#ifdef USE_ROUGHNESSMAP
	uniform mat3 roughnessMapTransform;
	varying vec2 vRoughnessMapUv;
#endif
#ifdef USE_ANISOTROPYMAP
	uniform mat3 anisotropyMapTransform;
	varying vec2 vAnisotropyMapUv;
#endif
#ifdef USE_CLEARCOATMAP
	uniform mat3 clearcoatMapTransform;
	varying vec2 vClearcoatMapUv;
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
	uniform mat3 clearcoatNormalMapTransform;
	varying vec2 vClearcoatNormalMapUv;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
	uniform mat3 clearcoatRoughnessMapTransform;
	varying vec2 vClearcoatRoughnessMapUv;
#endif
#ifdef USE_SHEEN_COLORMAP
	uniform mat3 sheenColorMapTransform;
	varying vec2 vSheenColorMapUv;
#endif
#ifdef USE_SHEEN_ROUGHNESSMAP
	uniform mat3 sheenRoughnessMapTransform;
	varying vec2 vSheenRoughnessMapUv;
#endif
#ifdef USE_IRIDESCENCEMAP
	uniform mat3 iridescenceMapTransform;
	varying vec2 vIridescenceMapUv;
#endif
#ifdef USE_IRIDESCENCE_THICKNESSMAP
	uniform mat3 iridescenceThicknessMapTransform;
	varying vec2 vIridescenceThicknessMapUv;
#endif
#ifdef USE_SPECULARMAP
	uniform mat3 specularMapTransform;
	varying vec2 vSpecularMapUv;
#endif
#ifdef USE_SPECULAR_COLORMAP
	uniform mat3 specularColorMapTransform;
	varying vec2 vSpecularColorMapUv;
#endif
#ifdef USE_SPECULAR_INTENSITYMAP
	uniform mat3 specularIntensityMapTransform;
	varying vec2 vSpecularIntensityMapUv;
#endif
#ifdef USE_TRANSMISSIONMAP
	uniform mat3 transmissionMapTransform;
	varying vec2 vTransmissionMapUv;
#endif
#ifdef USE_THICKNESSMAP
	uniform mat3 thicknessMapTransform;
	varying vec2 vThicknessMapUv;
#endif`, aR = `#if defined( USE_UV ) || defined( USE_ANISOTROPY )
	vUv = vec3( uv, 1 ).xy;
#endif
#ifdef USE_MAP
	vMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;
#endif
#ifdef USE_ALPHAMAP
	vAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_LIGHTMAP
	vLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_AOMAP
	vAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_BUMPMAP
	vBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_NORMALMAP
	vNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_DISPLACEMENTMAP
	vDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_EMISSIVEMAP
	vEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_METALNESSMAP
	vMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_ROUGHNESSMAP
	vRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_ANISOTROPYMAP
	vAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_CLEARCOATMAP
	vClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_CLEARCOAT_NORMALMAP
	vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_CLEARCOAT_ROUGHNESSMAP
	vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_IRIDESCENCEMAP
	vIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_IRIDESCENCE_THICKNESSMAP
	vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_SHEEN_COLORMAP
	vSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_SHEEN_ROUGHNESSMAP
	vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_SPECULARMAP
	vSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_SPECULAR_COLORMAP
	vSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_SPECULAR_INTENSITYMAP
	vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_TRANSMISSIONMAP
	vTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;
#endif
#ifdef USE_THICKNESSMAP
	vThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;
#endif`, oR = `#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0
	vec4 worldPosition = vec4( transformed, 1.0 );
	#ifdef USE_BATCHING
		worldPosition = batchingMatrix * worldPosition;
	#endif
	#ifdef USE_INSTANCING
		worldPosition = instanceMatrix * worldPosition;
	#endif
	worldPosition = modelMatrix * worldPosition;
#endif`;
const lR = `varying vec2 vUv;
uniform mat3 uvTransform;
void main() {
	vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
	gl_Position = vec4( position.xy, 1.0, 1.0 );
}`, cR = `uniform sampler2D t2D;
uniform float backgroundIntensity;
varying vec2 vUv;
void main() {
	vec4 texColor = texture2D( t2D, vUv );
	#ifdef DECODE_VIDEO_TEXTURE
		texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );
	#endif
	texColor.rgb *= backgroundIntensity;
	gl_FragColor = texColor;
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
}`, uR = `varying vec3 vWorldDirection;
#include <common>
void main() {
	vWorldDirection = transformDirection( position, modelMatrix );
	#include <begin_vertex>
	#include <project_vertex>
	gl_Position.z = gl_Position.w;
}`, hR = `#ifdef ENVMAP_TYPE_CUBE
	uniform samplerCube envMap;
#elif defined( ENVMAP_TYPE_CUBE_UV )
	uniform sampler2D envMap;
#endif
uniform float flipEnvMap;
uniform float backgroundBlurriness;
uniform float backgroundIntensity;
uniform mat3 backgroundRotation;
varying vec3 vWorldDirection;
#include <cube_uv_reflection_fragment>
void main() {
	#ifdef ENVMAP_TYPE_CUBE
		vec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );
	#elif defined( ENVMAP_TYPE_CUBE_UV )
		vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );
	#else
		vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );
	#endif
	texColor.rgb *= backgroundIntensity;
	gl_FragColor = texColor;
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
}`, dR = `varying vec3 vWorldDirection;
#include <common>
void main() {
	vWorldDirection = transformDirection( position, modelMatrix );
	#include <begin_vertex>
	#include <project_vertex>
	gl_Position.z = gl_Position.w;
}`, fR = `uniform samplerCube tCube;
uniform float tFlip;
uniform float opacity;
varying vec3 vWorldDirection;
void main() {
	vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );
	gl_FragColor = texColor;
	gl_FragColor.a *= opacity;
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
}`, pR = `#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
varying vec2 vHighPrecisionZW;
void main() {
	#include <uv_vertex>
	#include <batching_vertex>
	#include <skinbase_vertex>
	#include <morphinstance_vertex>
	#ifdef USE_DISPLACEMENTMAP
		#include <beginnormal_vertex>
		#include <morphnormal_vertex>
		#include <skinnormal_vertex>
	#endif
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	vHighPrecisionZW = gl_Position.zw;
}`, mR = `#if DEPTH_PACKING == 3200
	uniform float opacity;
#endif
#include <common>
#include <packing>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
varying vec2 vHighPrecisionZW;
void main() {
	vec4 diffuseColor = vec4( 1.0 );
	#include <clipping_planes_fragment>
	#if DEPTH_PACKING == 3200
		diffuseColor.a = opacity;
	#endif
	#include <map_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <logdepthbuf_fragment>
	#ifdef USE_REVERSED_DEPTH_BUFFER
		float fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ];
	#else
		float fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5;
	#endif
	#if DEPTH_PACKING == 3200
		gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );
	#elif DEPTH_PACKING == 3201
		gl_FragColor = packDepthToRGBA( fragCoordZ );
	#elif DEPTH_PACKING == 3202
		gl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );
	#elif DEPTH_PACKING == 3203
		gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );
	#endif
}`, gR = `#define DISTANCE
varying vec3 vWorldPosition;
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <batching_vertex>
	#include <skinbase_vertex>
	#include <morphinstance_vertex>
	#ifdef USE_DISPLACEMENTMAP
		#include <beginnormal_vertex>
		#include <morphnormal_vertex>
		#include <skinnormal_vertex>
	#endif
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <worldpos_vertex>
	#include <clipping_planes_vertex>
	vWorldPosition = worldPosition.xyz;
}`, _R = `#define DISTANCE
uniform vec3 referencePosition;
uniform float nearDistance;
uniform float farDistance;
varying vec3 vWorldPosition;
#include <common>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <clipping_planes_pars_fragment>
void main () {
	vec4 diffuseColor = vec4( 1.0 );
	#include <clipping_planes_fragment>
	#include <map_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	float dist = length( vWorldPosition - referencePosition );
	dist = ( dist - nearDistance ) / ( farDistance - nearDistance );
	dist = saturate( dist );
	gl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );
}`, xR = `varying vec3 vWorldDirection;
#include <common>
void main() {
	vWorldDirection = transformDirection( position, modelMatrix );
	#include <begin_vertex>
	#include <project_vertex>
}`, vR = `uniform sampler2D tEquirect;
varying vec3 vWorldDirection;
#include <common>
void main() {
	vec3 direction = normalize( vWorldDirection );
	vec2 sampleUV = equirectUv( direction );
	gl_FragColor = texture2D( tEquirect, sampleUV );
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
}`, yR = `uniform float scale;
attribute float lineDistance;
varying float vLineDistance;
#include <common>
#include <uv_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	vLineDistance = scale * lineDistance;
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	#include <fog_vertex>
}`, bR = `uniform vec3 diffuse;
uniform float opacity;
uniform float dashSize;
uniform float totalSize;
varying float vLineDistance;
#include <common>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	if ( mod( vLineDistance, totalSize ) > dashSize ) {
		discard;
	}
	vec3 outgoingLight = vec3( 0.0 );
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	outgoingLight = diffuseColor.rgb;
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
}`, SR = `#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )
		#include <beginnormal_vertex>
		#include <morphnormal_vertex>
		#include <skinbase_vertex>
		#include <skinnormal_vertex>
		#include <defaultnormal_vertex>
	#endif
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	#include <worldpos_vertex>
	#include <envmap_vertex>
	#include <fog_vertex>
}`, TR = `uniform vec3 diffuse;
uniform float opacity;
#ifndef FLAT_SHADED
	varying vec3 vNormal;
#endif
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <fog_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <specularmap_fragment>
	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	#ifdef USE_LIGHTMAP
		vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );
		reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;
	#else
		reflectedLight.indirectDiffuse += vec3( 1.0 );
	#endif
	#include <aomap_fragment>
	reflectedLight.indirectDiffuse *= diffuseColor.rgb;
	vec3 outgoingLight = reflectedLight.indirectDiffuse;
	#include <envmap_fragment>
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, MR = `#define LAMBERT
varying vec3 vViewPosition;
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	vViewPosition = - mvPosition.xyz;
	#include <worldpos_vertex>
	#include <envmap_vertex>
	#include <shadowmap_vertex>
	#include <fog_vertex>
}`, ER = `#define LAMBERT
uniform vec3 diffuse;
uniform vec3 emissive;
uniform float opacity;
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <envmap_physical_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <normal_pars_fragment>
#include <lights_lambert_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	vec3 totalEmissiveRadiance = emissive;
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <specularmap_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	#include <emissivemap_fragment>
	#include <lights_lambert_fragment>
	#include <lights_fragment_begin>
	#include <lights_fragment_maps>
	#include <lights_fragment_end>
	#include <aomap_fragment>
	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;
	#include <envmap_fragment>
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, wR = `#define MATCAP
varying vec3 vViewPosition;
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <color_pars_vertex>
#include <displacementmap_pars_vertex>
#include <fog_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	#include <fog_vertex>
	vViewPosition = - mvPosition.xyz;
}`, AR = `#define MATCAP
uniform vec3 diffuse;
uniform float opacity;
uniform sampler2D matcap;
varying vec3 vViewPosition;
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <normal_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	vec3 viewDir = normalize( vViewPosition );
	vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );
	vec3 y = cross( viewDir, x );
	vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;
	#ifdef USE_MATCAP
		vec4 matcapColor = texture2D( matcap, uv );
	#else
		vec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );
	#endif
	vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, RR = `#define NORMAL
#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )
	varying vec3 vViewPosition;
#endif
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphinstance_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )
	vViewPosition = - mvPosition.xyz;
#endif
}`, CR = `#define NORMAL
uniform float opacity;
#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )
	varying vec3 vViewPosition;
#endif
#include <uv_pars_fragment>
#include <normal_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );
	#include <clipping_planes_fragment>
	#include <logdepthbuf_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	gl_FragColor = vec4( normalize( normal ) * 0.5 + 0.5, diffuseColor.a );
	#ifdef OPAQUE
		gl_FragColor.a = 1.0;
	#endif
}`, NR = `#define PHONG
varying vec3 vViewPosition;
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphinstance_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	vViewPosition = - mvPosition.xyz;
	#include <worldpos_vertex>
	#include <envmap_vertex>
	#include <shadowmap_vertex>
	#include <fog_vertex>
}`, PR = `#define PHONG
uniform vec3 diffuse;
uniform vec3 emissive;
uniform vec3 specular;
uniform float shininess;
uniform float opacity;
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <envmap_physical_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <normal_pars_fragment>
#include <lights_phong_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	vec3 totalEmissiveRadiance = emissive;
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <specularmap_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	#include <emissivemap_fragment>
	#include <lights_phong_fragment>
	#include <lights_fragment_begin>
	#include <lights_fragment_maps>
	#include <lights_fragment_end>
	#include <aomap_fragment>
	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
	#include <envmap_fragment>
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, DR = `#define STANDARD
varying vec3 vViewPosition;
#ifdef USE_TRANSMISSION
	varying vec3 vWorldPosition;
#endif
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	vViewPosition = - mvPosition.xyz;
	#include <worldpos_vertex>
	#include <shadowmap_vertex>
	#include <fog_vertex>
#ifdef USE_TRANSMISSION
	vWorldPosition = worldPosition.xyz;
#endif
}`, LR = `#define STANDARD
#ifdef PHYSICAL
	#define IOR
	#define USE_SPECULAR
#endif
uniform vec3 diffuse;
uniform vec3 emissive;
uniform float roughness;
uniform float metalness;
uniform float opacity;
#ifdef IOR
	uniform float ior;
#endif
#ifdef USE_SPECULAR
	uniform float specularIntensity;
	uniform vec3 specularColor;
	#ifdef USE_SPECULAR_COLORMAP
		uniform sampler2D specularColorMap;
	#endif
	#ifdef USE_SPECULAR_INTENSITYMAP
		uniform sampler2D specularIntensityMap;
	#endif
#endif
#ifdef USE_CLEARCOAT
	uniform float clearcoat;
	uniform float clearcoatRoughness;
#endif
#ifdef USE_DISPERSION
	uniform float dispersion;
#endif
#ifdef USE_IRIDESCENCE
	uniform float iridescence;
	uniform float iridescenceIOR;
	uniform float iridescenceThicknessMinimum;
	uniform float iridescenceThicknessMaximum;
#endif
#ifdef USE_SHEEN
	uniform vec3 sheenColor;
	uniform float sheenRoughness;
	#ifdef USE_SHEEN_COLORMAP
		uniform sampler2D sheenColorMap;
	#endif
	#ifdef USE_SHEEN_ROUGHNESSMAP
		uniform sampler2D sheenRoughnessMap;
	#endif
#endif
#ifdef USE_ANISOTROPY
	uniform vec2 anisotropyVector;
	#ifdef USE_ANISOTROPYMAP
		uniform sampler2D anisotropyMap;
	#endif
#endif
varying vec3 vViewPosition;
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <iridescence_fragment>
#include <cube_uv_reflection_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_physical_pars_fragment>
#include <fog_pars_fragment>
#include <lights_pars_begin>
#include <normal_pars_fragment>
#include <lights_physical_pars_fragment>
#include <transmission_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <clearcoat_pars_fragment>
#include <iridescence_pars_fragment>
#include <roughnessmap_pars_fragment>
#include <metalnessmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	vec3 totalEmissiveRadiance = emissive;
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <roughnessmap_fragment>
	#include <metalnessmap_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	#include <clearcoat_normal_fragment_begin>
	#include <clearcoat_normal_fragment_maps>
	#include <emissivemap_fragment>
	#include <lights_physical_fragment>
	#include <lights_fragment_begin>
	#include <lights_fragment_maps>
	#include <lights_fragment_end>
	#include <aomap_fragment>
	vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;
	vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;
	#include <transmission_fragment>
	vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;
	#ifdef USE_SHEEN
 
		outgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;
 
 	#endif
	#ifdef USE_CLEARCOAT
		float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );
		vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );
		outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;
	#endif
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, FR = `#define TOON
varying vec3 vViewPosition;
#include <common>
#include <batching_pars_vertex>
#include <uv_pars_vertex>
#include <displacementmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <normal_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <normal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <displacementmap_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	vViewPosition = - mvPosition.xyz;
	#include <worldpos_vertex>
	#include <shadowmap_vertex>
	#include <fog_vertex>
}`, IR = `#define TOON
uniform vec3 diffuse;
uniform vec3 emissive;
uniform float opacity;
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <gradientmap_pars_fragment>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <normal_pars_fragment>
#include <lights_toon_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
	vec3 totalEmissiveRadiance = emissive;
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <color_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	#include <normal_fragment_begin>
	#include <normal_fragment_maps>
	#include <emissivemap_fragment>
	#include <lights_toon_fragment>
	#include <lights_fragment_begin>
	#include <lights_fragment_maps>
	#include <lights_fragment_end>
	#include <aomap_fragment>
	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
	#include <dithering_fragment>
}`, UR = `uniform float size;
uniform float scale;
#include <common>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
#ifdef USE_POINTS_UV
	varying vec2 vUv;
	uniform mat3 uvTransform;
#endif
void main() {
	#ifdef USE_POINTS_UV
		vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
	#endif
	#include <color_vertex>
	#include <morphinstance_vertex>
	#include <morphcolor_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <project_vertex>
	gl_PointSize = size;
	#ifdef USE_SIZEATTENUATION
		bool isPerspective = isPerspectiveMatrix( projectionMatrix );
		if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );
	#endif
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	#include <worldpos_vertex>
	#include <fog_vertex>
}`, BR = `uniform vec3 diffuse;
uniform float opacity;
#include <common>
#include <color_pars_fragment>
#include <map_particle_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	vec3 outgoingLight = vec3( 0.0 );
	#include <logdepthbuf_fragment>
	#include <map_particle_fragment>
	#include <color_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	outgoingLight = diffuseColor.rgb;
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
}`, OR = `#include <common>
#include <batching_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <shadowmap_pars_vertex>
void main() {
	#include <batching_vertex>
	#include <beginnormal_vertex>
	#include <morphinstance_vertex>
	#include <morphnormal_vertex>
	#include <skinbase_vertex>
	#include <skinnormal_vertex>
	#include <defaultnormal_vertex>
	#include <begin_vertex>
	#include <morphtarget_vertex>
	#include <skinning_vertex>
	#include <project_vertex>
	#include <logdepthbuf_vertex>
	#include <worldpos_vertex>
	#include <shadowmap_vertex>
	#include <fog_vertex>
}`, kR = `uniform vec3 color;
uniform float opacity;
#include <common>
#include <fog_pars_fragment>
#include <bsdfs>
#include <lights_pars_begin>
#include <logdepthbuf_pars_fragment>
#include <shadowmap_pars_fragment>
#include <shadowmask_pars_fragment>
void main() {
	#include <logdepthbuf_fragment>
	gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
	#include <premultiplied_alpha_fragment>
}`, GR = `uniform float rotation;
uniform vec2 center;
#include <common>
#include <uv_pars_vertex>
#include <fog_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
	#include <uv_vertex>
	vec4 mvPosition = modelViewMatrix[ 3 ];
	vec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );
	#ifndef USE_SIZEATTENUATION
		bool isPerspective = isPerspectiveMatrix( projectionMatrix );
		if ( isPerspective ) scale *= - mvPosition.z;
	#endif
	vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;
	vec2 rotatedPosition;
	rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
	rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
	mvPosition.xy += rotatedPosition;
	gl_Position = projectionMatrix * mvPosition;
	#include <logdepthbuf_vertex>
	#include <clipping_planes_vertex>
	#include <fog_vertex>
}`, VR = `uniform vec3 diffuse;
uniform float opacity;
#include <common>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
	vec4 diffuseColor = vec4( diffuse, opacity );
	#include <clipping_planes_fragment>
	vec3 outgoingLight = vec3( 0.0 );
	#include <logdepthbuf_fragment>
	#include <map_fragment>
	#include <alphamap_fragment>
	#include <alphatest_fragment>
	#include <alphahash_fragment>
	outgoingLight = diffuseColor.rgb;
	#include <opaque_fragment>
	#include <tonemapping_fragment>
	#include <colorspace_fragment>
	#include <fog_fragment>
}`, ht = {
  alphahash_fragment: cw,
  alphahash_pars_fragment: uw,
  alphamap_fragment: hw,
  alphamap_pars_fragment: dw,
  alphatest_fragment: fw,
  alphatest_pars_fragment: pw,
  aomap_fragment: mw,
  aomap_pars_fragment: gw,
  batching_pars_vertex: _w,
  batching_vertex: xw,
  begin_vertex: vw,
  beginnormal_vertex: yw,
  bsdfs: bw,
  iridescence_fragment: Sw,
  bumpmap_pars_fragment: Tw,
  clipping_planes_fragment: Mw,
  clipping_planes_pars_fragment: Ew,
  clipping_planes_pars_vertex: ww,
  clipping_planes_vertex: Aw,
  color_fragment: Rw,
  color_pars_fragment: Cw,
  color_pars_vertex: Nw,
  color_vertex: Pw,
  common: Dw,
  cube_uv_reflection_fragment: Lw,
  defaultnormal_vertex: Fw,
  displacementmap_pars_vertex: Iw,
  displacementmap_vertex: Uw,
  emissivemap_fragment: Bw,
  emissivemap_pars_fragment: Ow,
  colorspace_fragment: kw,
  colorspace_pars_fragment: Gw,
  envmap_fragment: Vw,
  envmap_common_pars_fragment: zw,
  envmap_pars_fragment: Hw,
  envmap_pars_vertex: $w,
  envmap_physical_pars_fragment: tA,
  envmap_vertex: Ww,
  fog_vertex: qw,
  fog_pars_vertex: Xw,
  fog_fragment: jw,
  fog_pars_fragment: Yw,
  gradientmap_pars_fragment: Kw,
  lightmap_pars_fragment: Zw,
  lights_lambert_fragment: Qw,
  lights_lambert_pars_fragment: Jw,
  lights_pars_begin: eA,
  lights_toon_fragment: nA,
  lights_toon_pars_fragment: iA,
  lights_phong_fragment: rA,
  lights_phong_pars_fragment: sA,
  lights_physical_fragment: aA,
  lights_physical_pars_fragment: oA,
  lights_fragment_begin: lA,
  lights_fragment_maps: cA,
  lights_fragment_end: uA,
  logdepthbuf_fragment: hA,
  logdepthbuf_pars_fragment: dA,
  logdepthbuf_pars_vertex: fA,
  logdepthbuf_vertex: pA,
  map_fragment: mA,
  map_pars_fragment: gA,
  map_particle_fragment: _A,
  map_particle_pars_fragment: xA,
  metalnessmap_fragment: vA,
  metalnessmap_pars_fragment: yA,
  morphinstance_vertex: bA,
  morphcolor_vertex: SA,
  morphnormal_vertex: TA,
  morphtarget_pars_vertex: MA,
  morphtarget_vertex: EA,
  normal_fragment_begin: wA,
  normal_fragment_maps: AA,
  normal_pars_fragment: RA,
  normal_pars_vertex: CA,
  normal_vertex: NA,
  normalmap_pars_fragment: PA,
  clearcoat_normal_fragment_begin: DA,
  clearcoat_normal_fragment_maps: LA,
  clearcoat_pars_fragment: FA,
  iridescence_pars_fragment: IA,
  opaque_fragment: UA,
  packing: BA,
  premultiplied_alpha_fragment: OA,
  project_vertex: kA,
  dithering_fragment: GA,
  dithering_pars_fragment: VA,
  roughnessmap_fragment: zA,
  roughnessmap_pars_fragment: HA,
  shadowmap_pars_fragment: $A,
  shadowmap_pars_vertex: WA,
  shadowmap_vertex: qA,
  shadowmask_pars_fragment: XA,
  skinbase_vertex: jA,
  skinning_pars_vertex: YA,
  skinning_vertex: KA,
  skinnormal_vertex: ZA,
  specularmap_fragment: QA,
  specularmap_pars_fragment: JA,
  tonemapping_fragment: eR,
  tonemapping_pars_fragment: tR,
  transmission_fragment: nR,
  transmission_pars_fragment: iR,
  uv_pars_fragment: rR,
  uv_pars_vertex: sR,
  uv_vertex: aR,
  worldpos_vertex: oR,
  background_vert: lR,
  background_frag: cR,
  backgroundCube_vert: uR,
  backgroundCube_frag: hR,
  cube_vert: dR,
  cube_frag: fR,
  depth_vert: pR,
  depth_frag: mR,
  distance_vert: gR,
  distance_frag: _R,
  equirect_vert: xR,
  equirect_frag: vR,
  linedashed_vert: yR,
  linedashed_frag: bR,
  meshbasic_vert: SR,
  meshbasic_frag: TR,
  meshlambert_vert: MR,
  meshlambert_frag: ER,
  meshmatcap_vert: wR,
  meshmatcap_frag: AR,
  meshnormal_vert: RR,
  meshnormal_frag: CR,
  meshphong_vert: NR,
  meshphong_frag: PR,
  meshphysical_vert: DR,
  meshphysical_frag: LR,
  meshtoon_vert: FR,
  meshtoon_frag: IR,
  points_vert: UR,
  points_frag: BR,
  shadow_vert: OR,
  shadow_frag: kR,
  sprite_vert: GR,
  sprite_frag: VR
}, Se = {
  common: {
    diffuse: { value: /* @__PURE__ */ new He(16777215) },
    opacity: { value: 1 },
    map: { value: null },
    mapTransform: { value: /* @__PURE__ */ new nt() },
    alphaMap: { value: null },
    alphaMapTransform: { value: /* @__PURE__ */ new nt() },
    alphaTest: { value: 0 }
  },
  specularmap: {
    specularMap: { value: null },
    specularMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  envmap: {
    envMap: { value: null },
    envMapRotation: { value: /* @__PURE__ */ new nt() },
    flipEnvMap: { value: -1 },
    reflectivity: { value: 1 },
    // basic, lambert, phong
    ior: { value: 1.5 },
    // physical
    refractionRatio: { value: 0.98 },
    // basic, lambert, phong
    dfgLUT: { value: null }
    // DFG LUT for physically-based rendering
  },
  aomap: {
    aoMap: { value: null },
    aoMapIntensity: { value: 1 },
    aoMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  lightmap: {
    lightMap: { value: null },
    lightMapIntensity: { value: 1 },
    lightMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  bumpmap: {
    bumpMap: { value: null },
    bumpMapTransform: { value: /* @__PURE__ */ new nt() },
    bumpScale: { value: 1 }
  },
  normalmap: {
    normalMap: { value: null },
    normalMapTransform: { value: /* @__PURE__ */ new nt() },
    normalScale: { value: /* @__PURE__ */ new de(1, 1) }
  },
  displacementmap: {
    displacementMap: { value: null },
    displacementMapTransform: { value: /* @__PURE__ */ new nt() },
    displacementScale: { value: 1 },
    displacementBias: { value: 0 }
  },
  emissivemap: {
    emissiveMap: { value: null },
    emissiveMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  metalnessmap: {
    metalnessMap: { value: null },
    metalnessMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  roughnessmap: {
    roughnessMap: { value: null },
    roughnessMapTransform: { value: /* @__PURE__ */ new nt() }
  },
  gradientmap: {
    gradientMap: { value: null }
  },
  fog: {
    fogDensity: { value: 25e-5 },
    fogNear: { value: 1 },
    fogFar: { value: 2e3 },
    fogColor: { value: /* @__PURE__ */ new He(16777215) }
  },
  lights: {
    ambientLightColor: { value: [] },
    lightProbe: { value: [] },
    directionalLights: { value: [], properties: {
      direction: {},
      color: {}
    } },
    directionalLightShadows: { value: [], properties: {
      shadowIntensity: 1,
      shadowBias: {},
      shadowNormalBias: {},
      shadowRadius: {},
      shadowMapSize: {}
    } },
    directionalShadowMatrix: { value: [] },
    spotLights: { value: [], properties: {
      color: {},
      position: {},
      direction: {},
      distance: {},
      coneCos: {},
      penumbraCos: {},
      decay: {}
    } },
    spotLightShadows: { value: [], properties: {
      shadowIntensity: 1,
      shadowBias: {},
      shadowNormalBias: {},
      shadowRadius: {},
      shadowMapSize: {}
    } },
    spotLightMap: { value: [] },
    spotLightMatrix: { value: [] },
    pointLights: { value: [], properties: {
      color: {},
      position: {},
      decay: {},
      distance: {}
    } },
    pointLightShadows: { value: [], properties: {
      shadowIntensity: 1,
      shadowBias: {},
      shadowNormalBias: {},
      shadowRadius: {},
      shadowMapSize: {},
      shadowCameraNear: {},
      shadowCameraFar: {}
    } },
    pointShadowMatrix: { value: [] },
    hemisphereLights: { value: [], properties: {
      direction: {},
      skyColor: {},
      groundColor: {}
    } },
    // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
    rectAreaLights: { value: [], properties: {
      color: {},
      position: {},
      width: {},
      height: {}
    } },
    ltc_1: { value: null },
    ltc_2: { value: null }
  },
  points: {
    diffuse: { value: /* @__PURE__ */ new He(16777215) },
    opacity: { value: 1 },
    size: { value: 1 },
    scale: { value: 1 },
    map: { value: null },
    alphaMap: { value: null },
    alphaMapTransform: { value: /* @__PURE__ */ new nt() },
    alphaTest: { value: 0 },
    uvTransform: { value: /* @__PURE__ */ new nt() }
  },
  sprite: {
    diffuse: { value: /* @__PURE__ */ new He(16777215) },
    opacity: { value: 1 },
    center: { value: /* @__PURE__ */ new de(0.5, 0.5) },
    rotation: { value: 0 },
    map: { value: null },
    mapTransform: { value: /* @__PURE__ */ new nt() },
    alphaMap: { value: null },
    alphaMapTransform: { value: /* @__PURE__ */ new nt() },
    alphaTest: { value: 0 }
  }
}, mr = {
  basic: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.specularmap,
      Se.envmap,
      Se.aomap,
      Se.lightmap,
      Se.fog
    ]),
    vertexShader: ht.meshbasic_vert,
    fragmentShader: ht.meshbasic_frag
  },
  lambert: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.specularmap,
      Se.envmap,
      Se.aomap,
      Se.lightmap,
      Se.emissivemap,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      Se.fog,
      Se.lights,
      {
        emissive: { value: /* @__PURE__ */ new He(0) },
        envMapIntensity: { value: 1 }
      }
    ]),
    vertexShader: ht.meshlambert_vert,
    fragmentShader: ht.meshlambert_frag
  },
  phong: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.specularmap,
      Se.envmap,
      Se.aomap,
      Se.lightmap,
      Se.emissivemap,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      Se.fog,
      Se.lights,
      {
        emissive: { value: /* @__PURE__ */ new He(0) },
        specular: { value: /* @__PURE__ */ new He(1118481) },
        shininess: { value: 30 },
        envMapIntensity: { value: 1 }
      }
    ]),
    vertexShader: ht.meshphong_vert,
    fragmentShader: ht.meshphong_frag
  },
  standard: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.envmap,
      Se.aomap,
      Se.lightmap,
      Se.emissivemap,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      Se.roughnessmap,
      Se.metalnessmap,
      Se.fog,
      Se.lights,
      {
        emissive: { value: /* @__PURE__ */ new He(0) },
        roughness: { value: 1 },
        metalness: { value: 0 },
        envMapIntensity: { value: 1 }
      }
    ]),
    vertexShader: ht.meshphysical_vert,
    fragmentShader: ht.meshphysical_frag
  },
  toon: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.aomap,
      Se.lightmap,
      Se.emissivemap,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      Se.gradientmap,
      Se.fog,
      Se.lights,
      {
        emissive: { value: /* @__PURE__ */ new He(0) }
      }
    ]),
    vertexShader: ht.meshtoon_vert,
    fragmentShader: ht.meshtoon_frag
  },
  matcap: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      Se.fog,
      {
        matcap: { value: null }
      }
    ]),
    vertexShader: ht.meshmatcap_vert,
    fragmentShader: ht.meshmatcap_frag
  },
  points: {
    uniforms: /* @__PURE__ */ Zn([
      Se.points,
      Se.fog
    ]),
    vertexShader: ht.points_vert,
    fragmentShader: ht.points_frag
  },
  dashed: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.fog,
      {
        scale: { value: 1 },
        dashSize: { value: 1 },
        totalSize: { value: 2 }
      }
    ]),
    vertexShader: ht.linedashed_vert,
    fragmentShader: ht.linedashed_frag
  },
  depth: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.displacementmap
    ]),
    vertexShader: ht.depth_vert,
    fragmentShader: ht.depth_frag
  },
  normal: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.bumpmap,
      Se.normalmap,
      Se.displacementmap,
      {
        opacity: { value: 1 }
      }
    ]),
    vertexShader: ht.meshnormal_vert,
    fragmentShader: ht.meshnormal_frag
  },
  sprite: {
    uniforms: /* @__PURE__ */ Zn([
      Se.sprite,
      Se.fog
    ]),
    vertexShader: ht.sprite_vert,
    fragmentShader: ht.sprite_frag
  },
  background: {
    uniforms: {
      uvTransform: { value: /* @__PURE__ */ new nt() },
      t2D: { value: null },
      backgroundIntensity: { value: 1 }
    },
    vertexShader: ht.background_vert,
    fragmentShader: ht.background_frag
  },
  backgroundCube: {
    uniforms: {
      envMap: { value: null },
      flipEnvMap: { value: -1 },
      backgroundBlurriness: { value: 0 },
      backgroundIntensity: { value: 1 },
      backgroundRotation: { value: /* @__PURE__ */ new nt() }
    },
    vertexShader: ht.backgroundCube_vert,
    fragmentShader: ht.backgroundCube_frag
  },
  cube: {
    uniforms: {
      tCube: { value: null },
      tFlip: { value: -1 },
      opacity: { value: 1 }
    },
    vertexShader: ht.cube_vert,
    fragmentShader: ht.cube_frag
  },
  equirect: {
    uniforms: {
      tEquirect: { value: null }
    },
    vertexShader: ht.equirect_vert,
    fragmentShader: ht.equirect_frag
  },
  distance: {
    uniforms: /* @__PURE__ */ Zn([
      Se.common,
      Se.displacementmap,
      {
        referencePosition: { value: /* @__PURE__ */ new P() },
        nearDistance: { value: 1 },
        farDistance: { value: 1e3 }
      }
    ]),
    vertexShader: ht.distance_vert,
    fragmentShader: ht.distance_frag
  },
  shadow: {
    uniforms: /* @__PURE__ */ Zn([
      Se.lights,
      Se.fog,
      {
        color: { value: /* @__PURE__ */ new He(0) },
        opacity: { value: 1 }
      }
    ]),
    vertexShader: ht.shadow_vert,
    fragmentShader: ht.shadow_frag
  }
};
mr.physical = {
  uniforms: /* @__PURE__ */ Zn([
    mr.standard.uniforms,
    {
      clearcoat: { value: 0 },
      clearcoatMap: { value: null },
      clearcoatMapTransform: { value: /* @__PURE__ */ new nt() },
      clearcoatNormalMap: { value: null },
      clearcoatNormalMapTransform: { value: /* @__PURE__ */ new nt() },
      clearcoatNormalScale: { value: /* @__PURE__ */ new de(1, 1) },
      clearcoatRoughness: { value: 0 },
      clearcoatRoughnessMap: { value: null },
      clearcoatRoughnessMapTransform: { value: /* @__PURE__ */ new nt() },
      dispersion: { value: 0 },
      iridescence: { value: 0 },
      iridescenceMap: { value: null },
      iridescenceMapTransform: { value: /* @__PURE__ */ new nt() },
      iridescenceIOR: { value: 1.3 },
      iridescenceThicknessMinimum: { value: 100 },
      iridescenceThicknessMaximum: { value: 400 },
      iridescenceThicknessMap: { value: null },
      iridescenceThicknessMapTransform: { value: /* @__PURE__ */ new nt() },
      sheen: { value: 0 },
      sheenColor: { value: /* @__PURE__ */ new He(0) },
      sheenColorMap: { value: null },
      sheenColorMapTransform: { value: /* @__PURE__ */ new nt() },
      sheenRoughness: { value: 1 },
      sheenRoughnessMap: { value: null },
      sheenRoughnessMapTransform: { value: /* @__PURE__ */ new nt() },
      transmission: { value: 0 },
      transmissionMap: { value: null },
      transmissionMapTransform: { value: /* @__PURE__ */ new nt() },
      transmissionSamplerSize: { value: /* @__PURE__ */ new de() },
      transmissionSamplerMap: { value: null },
      thickness: { value: 0 },
      thicknessMap: { value: null },
      thicknessMapTransform: { value: /* @__PURE__ */ new nt() },
      attenuationDistance: { value: 0 },
      attenuationColor: { value: /* @__PURE__ */ new He(0) },
      specularColor: { value: /* @__PURE__ */ new He(1, 1, 1) },
      specularColorMap: { value: null },
      specularColorMapTransform: { value: /* @__PURE__ */ new nt() },
      specularIntensity: { value: 1 },
      specularIntensityMap: { value: null },
      specularIntensityMapTransform: { value: /* @__PURE__ */ new nt() },
      anisotropyVector: { value: /* @__PURE__ */ new de() },
      anisotropyMap: { value: null },
      anisotropyMapTransform: { value: /* @__PURE__ */ new nt() }
    }
  ]),
  vertexShader: ht.meshphysical_vert,
  fragmentShader: ht.meshphysical_frag
};
const Ou = { r: 0, b: 0, g: 0 }, aa = /* @__PURE__ */ new gi(), zR = /* @__PURE__ */ new pt();
function HR(i, e, t, n, r, s) {
  const a = new He(0);
  let o = r === !0 ? 0 : 1, l, c, u = null, h = 0, d = null;
  function f(x) {
    let y = x.isScene === !0 ? x.background : null;
    if (y && y.isTexture) {
      const b = x.backgroundBlurriness > 0;
      y = e.get(y, b);
    }
    return y;
  }
  function p(x) {
    let y = !1;
    const b = f(x);
    b === null ? g(a, o) : b && b.isColor && (g(b, 1), y = !0);
    const T = i.xr.getEnvironmentBlendMode();
    T === "additive" ? t.buffers.color.setClear(0, 0, 0, 1, s) : T === "alpha-blend" && t.buffers.color.setClear(0, 0, 0, 0, s), (i.autoClear || y) && (t.buffers.depth.setTest(!0), t.buffers.depth.setMask(!0), t.buffers.color.setMask(!0), i.clear(i.autoClearColor, i.autoClearDepth, i.autoClearStencil));
  }
  function _(x, y) {
    const b = f(y);
    b && (b.isCubeTexture || b.mapping === Ra) ? (c === void 0 && (c = new _n(
      new $a(1, 1, 1),
      new Vi({
        name: "BackgroundCubeMaterial",
        uniforms: ul(mr.backgroundCube.uniforms),
        vertexShader: mr.backgroundCube.vertexShader,
        fragmentShader: mr.backgroundCube.fragmentShader,
        side: Ft,
        depthTest: !1,
        depthWrite: !1,
        fog: !1,
        allowOverride: !1
      })
    ), c.geometry.deleteAttribute("normal"), c.geometry.deleteAttribute("uv"), c.onBeforeRender = function(T, S, E) {
      this.matrixWorld.copyPosition(E.matrixWorld);
    }, Object.defineProperty(c.material, "envMap", {
      get: function() {
        return this.uniforms.envMap.value;
      }
    }), n.update(c)), aa.copy(y.backgroundRotation), aa.x *= -1, aa.y *= -1, aa.z *= -1, b.isCubeTexture && b.isRenderTargetTexture === !1 && (aa.y *= -1, aa.z *= -1), c.material.uniforms.envMap.value = b, c.material.uniforms.flipEnvMap.value = b.isCubeTexture && b.isRenderTargetTexture === !1 ? -1 : 1, c.material.uniforms.backgroundBlurriness.value = y.backgroundBlurriness, c.material.uniforms.backgroundIntensity.value = y.backgroundIntensity, c.material.uniforms.backgroundRotation.value.setFromMatrix4(zR.makeRotationFromEuler(aa)), c.material.toneMapped = Ke.getTransfer(b.colorSpace) !== Te, (u !== b || h !== b.version || d !== i.toneMapping) && (c.material.needsUpdate = !0, u = b, h = b.version, d = i.toneMapping), c.layers.enableAll(), x.unshift(c, c.geometry, c.material, 0, 0, null)) : b && b.isTexture && (l === void 0 && (l = new _n(
      new ru(2, 2),
      new Vi({
        name: "BackgroundMaterial",
        uniforms: ul(mr.background.uniforms),
        vertexShader: mr.background.vertexShader,
        fragmentShader: mr.background.fragmentShader,
        side: ai,
        depthTest: !1,
        depthWrite: !1,
        fog: !1,
        allowOverride: !1
      })
    ), l.geometry.deleteAttribute("normal"), Object.defineProperty(l.material, "map", {
      get: function() {
        return this.uniforms.t2D.value;
      }
    }), n.update(l)), l.material.uniforms.t2D.value = b, l.material.uniforms.backgroundIntensity.value = y.backgroundIntensity, l.material.toneMapped = Ke.getTransfer(b.colorSpace) !== Te, b.matrixAutoUpdate === !0 && b.updateMatrix(), l.material.uniforms.uvTransform.value.copy(b.matrix), (u !== b || h !== b.version || d !== i.toneMapping) && (l.material.needsUpdate = !0, u = b, h = b.version, d = i.toneMapping), l.layers.enableAll(), x.unshift(l, l.geometry, l.material, 0, 0, null));
  }
  function g(x, y) {
    x.getRGB(Ou, oy(i)), t.buffers.color.setClear(Ou.r, Ou.g, Ou.b, y, s);
  }
  function m() {
    c !== void 0 && (c.geometry.dispose(), c.material.dispose(), c = void 0), l !== void 0 && (l.geometry.dispose(), l.material.dispose(), l = void 0);
  }
  return {
    getClearColor: function() {
      return a;
    },
    setClearColor: function(x, y = 1) {
      a.set(x), o = y, g(a, o);
    },
    getClearAlpha: function() {
      return o;
    },
    setClearAlpha: function(x) {
      o = x, g(a, o);
    },
    render: p,
    addToRenderList: _,
    dispose: m
  };
}
function $R(i, e) {
  const t = i.getParameter(i.MAX_VERTEX_ATTRIBS), n = {}, r = d(null);
  let s = r, a = !1;
  function o(R, I, B, N, C) {
    let L = !1;
    const k = h(R, N, B, I);
    s !== k && (s = k, c(s.object)), L = f(R, N, B, C), L && p(R, N, B, C), C !== null && e.update(C, i.ELEMENT_ARRAY_BUFFER), (L || a) && (a = !1, b(R, I, B, N), C !== null && i.bindBuffer(i.ELEMENT_ARRAY_BUFFER, e.get(C).buffer));
  }
  function l() {
    return i.createVertexArray();
  }
  function c(R) {
    return i.bindVertexArray(R);
  }
  function u(R) {
    return i.deleteVertexArray(R);
  }
  function h(R, I, B, N) {
    const C = N.wireframe === !0;
    let L = n[I.id];
    L === void 0 && (L = {}, n[I.id] = L);
    const k = R.isInstancedMesh === !0 ? R.id : 0;
    let re = L[k];
    re === void 0 && (re = {}, L[k] = re);
    let se = re[B.id];
    se === void 0 && (se = {}, re[B.id] = se);
    let ve = se[C];
    return ve === void 0 && (ve = d(l()), se[C] = ve), ve;
  }
  function d(R) {
    const I = [], B = [], N = [];
    for (let C = 0; C < t; C++)
      I[C] = 0, B[C] = 0, N[C] = 0;
    return {
      // for backward compatibility on non-VAO support browser
      geometry: null,
      program: null,
      wireframe: !1,
      newAttributes: I,
      enabledAttributes: B,
      attributeDivisors: N,
      object: R,
      attributes: {},
      index: null
    };
  }
  function f(R, I, B, N) {
    const C = s.attributes, L = I.attributes;
    let k = 0;
    const re = B.getAttributes();
    for (const se in re)
      if (re[se].location >= 0) {
        const X = C[se];
        let te = L[se];
        if (te === void 0 && (se === "instanceMatrix" && R.instanceMatrix && (te = R.instanceMatrix), se === "instanceColor" && R.instanceColor && (te = R.instanceColor)), X === void 0 || X.attribute !== te || te && X.data !== te.data)
          return !0;
        k++;
      }
    return s.attributesNum !== k || s.index !== N;
  }
  function p(R, I, B, N) {
    const C = {}, L = I.attributes;
    let k = 0;
    const re = B.getAttributes();
    for (const se in re)
      if (re[se].location >= 0) {
        let X = L[se];
        X === void 0 && (se === "instanceMatrix" && R.instanceMatrix && (X = R.instanceMatrix), se === "instanceColor" && R.instanceColor && (X = R.instanceColor));
        const te = {};
        te.attribute = X, X && X.data && (te.data = X.data), C[se] = te, k++;
      }
    s.attributes = C, s.attributesNum = k, s.index = N;
  }
  function _() {
    const R = s.newAttributes;
    for (let I = 0, B = R.length; I < B; I++)
      R[I] = 0;
  }
  function g(R) {
    m(R, 0);
  }
  function m(R, I) {
    const B = s.newAttributes, N = s.enabledAttributes, C = s.attributeDivisors;
    B[R] = 1, N[R] === 0 && (i.enableVertexAttribArray(R), N[R] = 1), C[R] !== I && (i.vertexAttribDivisor(R, I), C[R] = I);
  }
  function x() {
    const R = s.newAttributes, I = s.enabledAttributes;
    for (let B = 0, N = I.length; B < N; B++)
      I[B] !== R[B] && (i.disableVertexAttribArray(B), I[B] = 0);
  }
  function y(R, I, B, N, C, L, k) {
    k === !0 ? i.vertexAttribIPointer(R, I, B, C, L) : i.vertexAttribPointer(R, I, B, N, C, L);
  }
  function b(R, I, B, N) {
    _();
    const C = N.attributes, L = B.getAttributes(), k = I.defaultAttributeValues;
    for (const re in L) {
      const se = L[re];
      if (se.location >= 0) {
        let ve = C[re];
        if (ve === void 0 && (re === "instanceMatrix" && R.instanceMatrix && (ve = R.instanceMatrix), re === "instanceColor" && R.instanceColor && (ve = R.instanceColor)), ve !== void 0) {
          const X = ve.normalized, te = ve.itemSize, me = e.get(ve);
          if (me === void 0)
            continue;
          const Qe = me.buffer, ce = me.type, z = me.bytesPerElement, Z = ce === i.INT || ce === i.UNSIGNED_INT || ve.gpuType === wn;
          if (ve.isInterleavedBufferAttribute) {
            const ue = ve.data, Ie = ue.stride, we = ve.offset;
            if (ue.isInstancedInterleavedBuffer) {
              for (let Re = 0; Re < se.locationSize; Re++)
                m(se.location + Re, ue.meshPerAttribute);
              R.isInstancedMesh !== !0 && N._maxInstanceCount === void 0 && (N._maxInstanceCount = ue.meshPerAttribute * ue.count);
            } else
              for (let Re = 0; Re < se.locationSize; Re++)
                g(se.location + Re);
            i.bindBuffer(i.ARRAY_BUFFER, Qe);
            for (let Re = 0; Re < se.locationSize; Re++)
              y(
                se.location + Re,
                te / se.locationSize,
                ce,
                X,
                Ie * z,
                (we + te / se.locationSize * Re) * z,
                Z
              );
          } else {
            if (ve.isInstancedBufferAttribute) {
              for (let ue = 0; ue < se.locationSize; ue++)
                m(se.location + ue, ve.meshPerAttribute);
              R.isInstancedMesh !== !0 && N._maxInstanceCount === void 0 && (N._maxInstanceCount = ve.meshPerAttribute * ve.count);
            } else
              for (let ue = 0; ue < se.locationSize; ue++)
                g(se.location + ue);
            i.bindBuffer(i.ARRAY_BUFFER, Qe);
            for (let ue = 0; ue < se.locationSize; ue++)
              y(
                se.location + ue,
                te / se.locationSize,
                ce,
                X,
                te * z,
                te / se.locationSize * ue * z,
                Z
              );
          }
        } else if (k !== void 0) {
          const X = k[re];
          if (X !== void 0)
            switch (X.length) {
              case 2:
                i.vertexAttrib2fv(se.location, X);
                break;
              case 3:
                i.vertexAttrib3fv(se.location, X);
                break;
              case 4:
                i.vertexAttrib4fv(se.location, X);
                break;
              default:
                i.vertexAttrib1fv(se.location, X);
            }
        }
      }
    }
    x();
  }
  function T() {
    M();
    for (const R in n) {
      const I = n[R];
      for (const B in I) {
        const N = I[B];
        for (const C in N) {
          const L = N[C];
          for (const k in L)
            u(L[k].object), delete L[k];
          delete N[C];
        }
      }
      delete n[R];
    }
  }
  function S(R) {
    if (n[R.id] === void 0)
      return;
    const I = n[R.id];
    for (const B in I) {
      const N = I[B];
      for (const C in N) {
        const L = N[C];
        for (const k in L)
          u(L[k].object), delete L[k];
        delete N[C];
      }
    }
    delete n[R.id];
  }
  function E(R) {
    for (const I in n) {
      const B = n[I];
      for (const N in B) {
        const C = B[N];
        if (C[R.id] === void 0)
          continue;
        const L = C[R.id];
        for (const k in L)
          u(L[k].object), delete L[k];
        delete C[R.id];
      }
    }
  }
  function v(R) {
    for (const I in n) {
      const B = n[I], N = R.isInstancedMesh === !0 ? R.id : 0, C = B[N];
      if (C !== void 0) {
        for (const L in C) {
          const k = C[L];
          for (const re in k)
            u(k[re].object), delete k[re];
          delete C[L];
        }
        delete B[N], Object.keys(B).length === 0 && delete n[I];
      }
    }
  }
  function M() {
    F(), a = !0, s !== r && (s = r, c(s.object));
  }
  function F() {
    r.geometry = null, r.program = null, r.wireframe = !1;
  }
  return {
    setup: o,
    reset: M,
    resetDefaultState: F,
    dispose: T,
    releaseStatesOfGeometry: S,
    releaseStatesOfObject: v,
    releaseStatesOfProgram: E,
    initAttributes: _,
    enableAttribute: g,
    disableUnusedAttributes: x
  };
}
function WR(i, e, t) {
  let n;
  function r(c) {
    n = c;
  }
  function s(c, u) {
    i.drawArrays(n, c, u), t.update(u, n, 1);
  }
  function a(c, u, h) {
    h !== 0 && (i.drawArraysInstanced(n, c, u, h), t.update(u, n, h));
  }
  function o(c, u, h) {
    if (h === 0)
      return;
    e.get("WEBGL_multi_draw").multiDrawArraysWEBGL(n, c, 0, u, 0, h);
    let f = 0;
    for (let p = 0; p < h; p++)
      f += u[p];
    t.update(f, n, 1);
  }
  function l(c, u, h, d) {
    if (h === 0)
      return;
    const f = e.get("WEBGL_multi_draw");
    if (f === null)
      for (let p = 0; p < c.length; p++)
        a(c[p], u[p], d[p]);
    else {
      f.multiDrawArraysInstancedWEBGL(n, c, 0, u, 0, d, 0, h);
      let p = 0;
      for (let _ = 0; _ < h; _++)
        p += u[_] * d[_];
      t.update(p, n, 1);
    }
  }
  this.setMode = r, this.render = s, this.renderInstances = a, this.renderMultiDraw = o, this.renderMultiDrawInstances = l;
}
function qR(i, e, t, n) {
  let r;
  function s() {
    if (r !== void 0)
      return r;
    if (e.has("EXT_texture_filter_anisotropic") === !0) {
      const E = e.get("EXT_texture_filter_anisotropic");
      r = i.getParameter(E.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
    } else
      r = 0;
    return r;
  }
  function a(E) {
    return !(E !== cn && n.convert(E) !== i.getParameter(i.IMPLEMENTATION_COLOR_READ_FORMAT));
  }
  function o(E) {
    const v = E === nn && (e.has("EXT_color_buffer_half_float") || e.has("EXT_color_buffer_float"));
    return !(E !== Zt && n.convert(E) !== i.getParameter(i.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513)
    E !== ln && !v);
  }
  function l(E) {
    if (E === "highp") {
      if (i.getShaderPrecisionFormat(i.VERTEX_SHADER, i.HIGH_FLOAT).precision > 0 && i.getShaderPrecisionFormat(i.FRAGMENT_SHADER, i.HIGH_FLOAT).precision > 0)
        return "highp";
      E = "mediump";
    }
    return E === "mediump" && i.getShaderPrecisionFormat(i.VERTEX_SHADER, i.MEDIUM_FLOAT).precision > 0 && i.getShaderPrecisionFormat(i.FRAGMENT_SHADER, i.MEDIUM_FLOAT).precision > 0 ? "mediump" : "lowp";
  }
  let c = t.precision !== void 0 ? t.precision : "highp";
  const u = l(c);
  u !== c && (oe("WebGLRenderer:", c, "not supported, using", u, "instead."), c = u);
  const h = t.logarithmicDepthBuffer === !0, d = t.reversedDepthBuffer === !0 && e.has("EXT_clip_control"), f = i.getParameter(i.MAX_TEXTURE_IMAGE_UNITS), p = i.getParameter(i.MAX_VERTEX_TEXTURE_IMAGE_UNITS), _ = i.getParameter(i.MAX_TEXTURE_SIZE), g = i.getParameter(i.MAX_CUBE_MAP_TEXTURE_SIZE), m = i.getParameter(i.MAX_VERTEX_ATTRIBS), x = i.getParameter(i.MAX_VERTEX_UNIFORM_VECTORS), y = i.getParameter(i.MAX_VARYING_VECTORS), b = i.getParameter(i.MAX_FRAGMENT_UNIFORM_VECTORS), T = i.getParameter(i.MAX_SAMPLES), S = i.getParameter(i.SAMPLES);
  return {
    isWebGL2: !0,
    // keeping this for backwards compatibility
    getMaxAnisotropy: s,
    getMaxPrecision: l,
    textureFormatReadable: a,
    textureTypeReadable: o,
    precision: c,
    logarithmicDepthBuffer: h,
    reversedDepthBuffer: d,
    maxTextures: f,
    maxVertexTextures: p,
    maxTextureSize: _,
    maxCubemapSize: g,
    maxAttributes: m,
    maxVertexUniforms: x,
    maxVaryings: y,
    maxFragmentUniforms: b,
    maxSamples: T,
    samples: S
  };
}
function XR(i) {
  const e = this;
  let t = null, n = 0, r = !1, s = !1;
  const a = new Zi(), o = new nt(), l = { value: null, needsUpdate: !1 };
  this.uniform = l, this.numPlanes = 0, this.numIntersection = 0, this.init = function(h, d) {
    const f = h.length !== 0 || d || // enable state of previous frame - the clipping code has to
    // run another frame in order to reset the state:
    n !== 0 || r;
    return r = d, n = h.length, f;
  }, this.beginShadows = function() {
    s = !0, u(null);
  }, this.endShadows = function() {
    s = !1;
  }, this.setGlobalState = function(h, d) {
    t = u(h, d, 0);
  }, this.setState = function(h, d, f) {
    const p = h.clippingPlanes, _ = h.clipIntersection, g = h.clipShadows, m = i.get(h);
    if (!r || p === null || p.length === 0 || s && !g)
      s ? u(null) : c();
    else {
      const x = s ? 0 : n, y = x * 4;
      let b = m.clippingState || null;
      l.value = b, b = u(p, d, y, f);
      for (let T = 0; T !== y; ++T)
        b[T] = t[T];
      m.clippingState = b, this.numIntersection = _ ? this.numPlanes : 0, this.numPlanes += x;
    }
  };
  function c() {
    l.value !== t && (l.value = t, l.needsUpdate = n > 0), e.numPlanes = n, e.numIntersection = 0;
  }
  function u(h, d, f, p) {
    const _ = h !== null ? h.length : 0;
    let g = null;
    if (_ !== 0) {
      if (g = l.value, p !== !0 || g === null) {
        const m = f + _ * 4, x = d.matrixWorldInverse;
        o.getNormalMatrix(x), (g === null || g.length < m) && (g = new Float32Array(m));
        for (let y = 0, b = f; y !== _; ++y, b += 4)
          a.copy(h[y]).applyMatrix4(x, o), a.normal.toArray(g, b), g[b + 3] = a.constant;
      }
      l.value = g, l.needsUpdate = !0;
    }
    return e.numPlanes = _, e.numIntersection = 0, g;
  }
}
const Ls = 4, U_ = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582], pa = 20, jR = 256, kl = /* @__PURE__ */ new bl(), B_ = /* @__PURE__ */ new He();
let ff = null, pf = 0, mf = 0, gf = !1;
const YR = /* @__PURE__ */ new P();
let O_ = class {
  /**
   * Constructs a new PMREM generator.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   */
  constructor(e) {
    this._renderer = e, this._pingPongRenderTarget = null, this._lodMax = 0, this._cubeSize = 0, this._sizeLods = [], this._sigmas = [], this._lodMeshes = [], this._backgroundBox = null, this._cubemapMaterial = null, this._equirectMaterial = null, this._blurMaterial = null, this._ggxMaterial = null;
  }
  /**
   * Generates a PMREM from a supplied Scene, which can be faster than using an
   * image if networking bandwidth is low. Optional sigma specifies a blur radius
   * in radians to be applied to the scene before PMREM generation. Optional near
   * and far planes ensure the scene is rendered in its entirety.
   *
   * @param {Scene} scene - The scene to be captured.
   * @param {number} [sigma=0] - The blur radius in radians.
   * @param {number} [near=0.1] - The near plane distance.
   * @param {number} [far=100] - The far plane distance.
   * @param {Object} [options={}] - The configuration options.
   * @param {number} [options.size=256] - The texture size of the PMREM.
   * @param {Vector3} [options.position=origin] - The position of the internal cube camera that renders the scene.
   * @return {WebGLRenderTarget} The resulting PMREM.
   */
  fromScene(e, t = 0, n = 0.1, r = 100, s = {}) {
    const {
      size: a = 256,
      position: o = YR
    } = s;
    ff = this._renderer.getRenderTarget(), pf = this._renderer.getActiveCubeFace(), mf = this._renderer.getActiveMipmapLevel(), gf = this._renderer.xr.enabled, this._renderer.xr.enabled = !1, this._setSize(a);
    const l = this._allocateTargets();
    return l.depthBuffer = !0, this._sceneToCubeUV(e, n, r, l, o), t > 0 && this._blur(l, 0, 0, t), this._applyPMREM(l), this._cleanup(l), l;
  }
  /**
   * Generates a PMREM from an equirectangular texture, which can be either LDR
   * or HDR. The ideal input image size is 1k (1024 x 512),
   * as this matches best with the 256 x 256 cubemap output.
   *
   * @param {Texture} equirectangular - The equirectangular texture to be converted.
   * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use.
   * @return {WebGLRenderTarget} The resulting PMREM.
   */
  fromEquirectangular(e, t = null) {
    return this._fromTexture(e, t);
  }
  /**
   * Generates a PMREM from an cubemap texture, which can be either LDR
   * or HDR. The ideal input cube size is 256 x 256,
   * as this matches best with the 256 x 256 cubemap output.
   *
   * @param {Texture} cubemap - The cubemap texture to be converted.
   * @param {?WebGLRenderTarget} [renderTarget=null] - The render target to use.
   * @return {WebGLRenderTarget} The resulting PMREM.
   */
  fromCubemap(e, t = null) {
    return this._fromTexture(e, t);
  }
  /**
   * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
   * your texture's network fetch for increased concurrency.
   */
  compileCubemapShader() {
    this._cubemapMaterial === null && (this._cubemapMaterial = V_(), this._compileMaterial(this._cubemapMaterial));
  }
  /**
   * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
   * your texture's network fetch for increased concurrency.
   */
  compileEquirectangularShader() {
    this._equirectMaterial === null && (this._equirectMaterial = G_(), this._compileMaterial(this._equirectMaterial));
  }
  /**
   * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
   * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
   * one of them will cause any others to also become unusable.
   */
  dispose() {
    this._dispose(), this._cubemapMaterial !== null && this._cubemapMaterial.dispose(), this._equirectMaterial !== null && this._equirectMaterial.dispose(), this._backgroundBox !== null && (this._backgroundBox.geometry.dispose(), this._backgroundBox.material.dispose());
  }
  // private interface
  _setSize(e) {
    this._lodMax = Math.floor(Math.log2(e)), this._cubeSize = Math.pow(2, this._lodMax);
  }
  _dispose() {
    this._blurMaterial !== null && this._blurMaterial.dispose(), this._ggxMaterial !== null && this._ggxMaterial.dispose(), this._pingPongRenderTarget !== null && this._pingPongRenderTarget.dispose();
    for (let e = 0; e < this._lodMeshes.length; e++)
      this._lodMeshes[e].geometry.dispose();
  }
  _cleanup(e) {
    this._renderer.setRenderTarget(ff, pf, mf), this._renderer.xr.enabled = gf, e.scissorTest = !1, uo(e, 0, 0, e.width, e.height);
  }
  _fromTexture(e, t) {
    e.mapping === nr || e.mapping === Rr ? this._setSize(e.image.length === 0 ? 16 : e.image[0].width || e.image[0].image.width) : this._setSize(e.image.width / 4), ff = this._renderer.getRenderTarget(), pf = this._renderer.getActiveCubeFace(), mf = this._renderer.getActiveMipmapLevel(), gf = this._renderer.xr.enabled, this._renderer.xr.enabled = !1;
    const n = t || this._allocateTargets();
    return this._textureToCubeUV(e, n), this._applyPMREM(n), this._cleanup(n), n;
  }
  _allocateTargets() {
    const e = 3 * Math.max(this._cubeSize, 112), t = 4 * this._cubeSize, n = {
      magFilter: Ot,
      minFilter: Ot,
      generateMipmaps: !1,
      type: nn,
      format: cn,
      colorSpace: La,
      depthBuffer: !1
    }, r = k_(e, t, n);
    if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== e || this._pingPongRenderTarget.height !== t) {
      this._pingPongRenderTarget !== null && this._dispose(), this._pingPongRenderTarget = k_(e, t, n);
      const { _lodMax: s } = this;
      ({ lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = KR(s)), this._blurMaterial = QR(s, e, t), this._ggxMaterial = ZR(s, e, t);
    }
    return r;
  }
  _compileMaterial(e) {
    const t = new _n(new Pn(), e);
    this._renderer.compile(t, kl);
  }
  _sceneToCubeUV(e, t, n, r, s) {
    const l = new An(90, 1, t, n), c = [1, -1, 1, 1, 1, 1], u = [1, 1, 1, -1, -1, -1], h = this._renderer, d = h.autoClear, f = h.toneMapping;
    h.getClearColor(B_), h.toneMapping = In, h.autoClear = !1, h.state.buffers.depth.getReversed() && (h.setRenderTarget(r), h.clearDepth(), h.setRenderTarget(null)), this._backgroundBox === null && (this._backgroundBox = new _n(
      new $a(),
      new xr({
        name: "PMREM.Background",
        side: Ft,
        depthWrite: !1,
        depthTest: !1
      })
    ));
    const _ = this._backgroundBox, g = _.material;
    let m = !1;
    const x = e.background;
    x ? x.isColor && (g.color.copy(x), e.background = null, m = !0) : (g.color.copy(B_), m = !0);
    for (let y = 0; y < 6; y++) {
      const b = y % 3;
      b === 0 ? (l.up.set(0, c[y], 0), l.position.set(s.x, s.y, s.z), l.lookAt(s.x + u[y], s.y, s.z)) : b === 1 ? (l.up.set(0, 0, c[y]), l.position.set(s.x, s.y, s.z), l.lookAt(s.x, s.y + u[y], s.z)) : (l.up.set(0, c[y], 0), l.position.set(s.x, s.y, s.z), l.lookAt(s.x, s.y, s.z + u[y]));
      const T = this._cubeSize;
      uo(r, b * T, y > 2 ? T : 0, T, T), h.setRenderTarget(r), m && h.render(_, l), h.render(e, l);
    }
    h.toneMapping = f, h.autoClear = d, e.background = x;
  }
  _textureToCubeUV(e, t) {
    const n = this._renderer, r = e.mapping === nr || e.mapping === Rr;
    r ? (this._cubemapMaterial === null && (this._cubemapMaterial = V_()), this._cubemapMaterial.uniforms.flipEnvMap.value = e.isRenderTargetTexture === !1 ? -1 : 1) : this._equirectMaterial === null && (this._equirectMaterial = G_());
    const s = r ? this._cubemapMaterial : this._equirectMaterial, a = this._lodMeshes[0];
    a.material = s;
    const o = s.uniforms;
    o.envMap.value = e;
    const l = this._cubeSize;
    uo(t, 0, 0, 3 * l, 2 * l), n.setRenderTarget(t), n.render(a, kl);
  }
  _applyPMREM(e) {
    const t = this._renderer, n = t.autoClear;
    t.autoClear = !1;
    const r = this._lodMeshes.length;
    for (let s = 1; s < r; s++)
      this._applyGGXFilter(e, s - 1, s);
    t.autoClear = n;
  }
  /**
   * Applies GGX VNDF importance sampling filter to generate a prefiltered environment map.
   * Uses Monte Carlo integration with VNDF importance sampling to accurately represent the
   * GGX BRDF for physically-based rendering. Reads from the previous LOD level and
   * applies incremental roughness filtering to avoid over-blurring.
   *
   * @private
   * @param {WebGLRenderTarget} cubeUVRenderTarget
   * @param {number} lodIn - Source LOD level to read from
   * @param {number} lodOut - Target LOD level to write to
   */
  _applyGGXFilter(e, t, n) {
    const r = this._renderer, s = this._pingPongRenderTarget, a = this._ggxMaterial, o = this._lodMeshes[n];
    o.material = a;
    const l = a.uniforms, c = n / (this._lodMeshes.length - 1), u = t / (this._lodMeshes.length - 1), h = Math.sqrt(c * c - u * u), d = 0 + c * 1.25, f = h * d, { _lodMax: p } = this, _ = this._sizeLods[n], g = 3 * _ * (n > p - Ls ? n - p + Ls : 0), m = 4 * (this._cubeSize - _);
    l.envMap.value = e.texture, l.roughness.value = f, l.mipInt.value = p - t, uo(s, g, m, 3 * _, 2 * _), r.setRenderTarget(s), r.render(o, kl), l.envMap.value = s.texture, l.roughness.value = 0, l.mipInt.value = p - n, uo(e, g, m, 3 * _, 2 * _), r.setRenderTarget(e), r.render(o, kl);
  }
  /**
   * This is a two-pass Gaussian blur for a cubemap. Normally this is done
   * vertically and horizontally, but this breaks down on a cube. Here we apply
   * the blur latitudinally (around the poles), and then longitudinally (towards
   * the poles) to approximate the orthogonally-separable blur. It is least
   * accurate at the poles, but still does a decent job.
   *
   * Used for initial scene blur in fromScene() method when sigma > 0.
   *
   * @private
   * @param {WebGLRenderTarget} cubeUVRenderTarget
   * @param {number} lodIn
   * @param {number} lodOut
   * @param {number} sigma
   * @param {Vector3} [poleAxis]
   */
  _blur(e, t, n, r, s) {
    const a = this._pingPongRenderTarget;
    this._halfBlur(
      e,
      a,
      t,
      n,
      r,
      "latitudinal",
      s
    ), this._halfBlur(
      a,
      e,
      n,
      n,
      r,
      "longitudinal",
      s
    );
  }
  _halfBlur(e, t, n, r, s, a, o) {
    const l = this._renderer, c = this._blurMaterial;
    a !== "latitudinal" && a !== "longitudinal" && le(
      "blur direction must be either latitudinal or longitudinal!"
    );
    const u = 3, h = this._lodMeshes[r];
    h.material = c;
    const d = c.uniforms, f = this._sizeLods[n] - 1, p = isFinite(s) ? Math.PI / (2 * f) : 2 * Math.PI / (2 * pa - 1), _ = s / p, g = isFinite(s) ? 1 + Math.floor(u * _) : pa;
    g > pa && oe(`sigmaRadians, ${s}, is too large and will clip, as it requested ${g} samples when the maximum is set to ${pa}`);
    const m = [];
    let x = 0;
    for (let E = 0; E < pa; ++E) {
      const v = E / _, M = Math.exp(-v * v / 2);
      m.push(M), E === 0 ? x += M : E < g && (x += 2 * M);
    }
    for (let E = 0; E < m.length; E++)
      m[E] = m[E] / x;
    d.envMap.value = e.texture, d.samples.value = g, d.weights.value = m, d.latitudinal.value = a === "latitudinal", o && (d.poleAxis.value = o);
    const { _lodMax: y } = this;
    d.dTheta.value = p, d.mipInt.value = y - n;
    const b = this._sizeLods[r], T = 3 * b * (r > y - Ls ? r - y + Ls : 0), S = 4 * (this._cubeSize - b);
    uo(t, T, S, 3 * b, 2 * b), l.setRenderTarget(t), l.render(h, kl);
  }
};
function KR(i) {
  const e = [], t = [], n = [];
  let r = i;
  const s = i - Ls + 1 + U_.length;
  for (let a = 0; a < s; a++) {
    const o = Math.pow(2, r);
    e.push(o);
    let l = 1 / o;
    a > i - Ls ? l = U_[a - i + Ls - 1] : a === 0 && (l = 0), t.push(l);
    const c = 1 / (o - 2), u = -c, h = 1 + c, d = [u, u, h, u, h, h, u, u, h, h, u, h], f = 6, p = 6, _ = 3, g = 2, m = 1, x = new Float32Array(_ * p * f), y = new Float32Array(g * p * f), b = new Float32Array(m * p * f);
    for (let S = 0; S < f; S++) {
      const E = S % 3 * 2 / 3 - 1, v = S > 2 ? 0 : -1, M = [
        E,
        v,
        0,
        E + 2 / 3,
        v,
        0,
        E + 2 / 3,
        v + 1,
        0,
        E,
        v,
        0,
        E + 2 / 3,
        v + 1,
        0,
        E,
        v + 1,
        0
      ];
      x.set(M, _ * p * S), y.set(d, g * p * S);
      const F = [S, S, S, S, S, S];
      b.set(F, m * p * S);
    }
    const T = new Pn();
    T.setAttribute("position", new Bn(x, _)), T.setAttribute("uv", new Bn(y, g)), T.setAttribute("faceIndex", new Bn(b, m)), n.push(new _n(T, null)), r > Ls && r--;
  }
  return { lodMeshes: n, sizeLods: e, sigmas: t };
}
function k_(i, e, t) {
  const n = new tr(i, e, t);
  return n.texture.mapping = Ra, n.texture.name = "PMREM.cubeUv", n.scissorTest = !0, n;
}
function uo(i, e, t, n, r) {
  i.viewport.set(e, t, n, r), i.scissor.set(e, t, n, r);
}
function ZR(i, e, t) {
  return new Vi({
    name: "PMREMGGXConvolution",
    defines: {
      GGX_SAMPLES: jR,
      CUBEUV_TEXEL_WIDTH: 1 / e,
      CUBEUV_TEXEL_HEIGHT: 1 / t,
      CUBEUV_MAX_MIP: `${i}.0`
    },
    uniforms: {
      envMap: { value: null },
      roughness: { value: 0 },
      mipInt: { value: 0 }
    },
    vertexShader: fd(),
    fragmentShader: (
      /* glsl */
      `

			precision highp float;
			precision highp int;

			varying vec3 vOutputDirection;

			uniform sampler2D envMap;
			uniform float roughness;
			uniform float mipInt;

			#define ENVMAP_TYPE_CUBE_UV
			#include <cube_uv_reflection_fragment>

			#define PI 3.14159265359

			// Van der Corput radical inverse
			float radicalInverse_VdC(uint bits) {
				bits = (bits << 16u) | (bits >> 16u);
				bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
				bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
				bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
				bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
				return float(bits) * 2.3283064365386963e-10; // / 0x100000000
			}

			// Hammersley sequence
			vec2 hammersley(uint i, uint N) {
				return vec2(float(i) / float(N), radicalInverse_VdC(i));
			}

			// GGX VNDF importance sampling (Eric Heitz 2018)
			// "Sampling the GGX Distribution of Visible Normals"
			// https://jcgt.org/published/0007/04/01/
			vec3 importanceSampleGGX_VNDF(vec2 Xi, vec3 V, float roughness) {
				float alpha = roughness * roughness;

				// Section 4.1: Orthonormal basis
				vec3 T1 = vec3(1.0, 0.0, 0.0);
				vec3 T2 = cross(V, T1);

				// Section 4.2: Parameterization of projected area
				float r = sqrt(Xi.x);
				float phi = 2.0 * PI * Xi.y;
				float t1 = r * cos(phi);
				float t2 = r * sin(phi);
				float s = 0.5 * (1.0 + V.z);
				t2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2;

				// Section 4.3: Reprojection onto hemisphere
				vec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * V;

				// Section 3.4: Transform back to ellipsoid configuration
				return normalize(vec3(alpha * Nh.x, alpha * Nh.y, max(0.0, Nh.z)));
			}

			void main() {
				vec3 N = normalize(vOutputDirection);
				vec3 V = N; // Assume view direction equals normal for pre-filtering

				vec3 prefilteredColor = vec3(0.0);
				float totalWeight = 0.0;

				// For very low roughness, just sample the environment directly
				if (roughness < 0.001) {
					gl_FragColor = vec4(bilinearCubeUV(envMap, N, mipInt), 1.0);
					return;
				}

				// Tangent space basis for VNDF sampling
				vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
				vec3 tangent = normalize(cross(up, N));
				vec3 bitangent = cross(N, tangent);

				for(uint i = 0u; i < uint(GGX_SAMPLES); i++) {
					vec2 Xi = hammersley(i, uint(GGX_SAMPLES));

					// For PMREM, V = N, so in tangent space V is always (0, 0, 1)
					vec3 H_tangent = importanceSampleGGX_VNDF(Xi, vec3(0.0, 0.0, 1.0), roughness);

					// Transform H back to world space
					vec3 H = normalize(tangent * H_tangent.x + bitangent * H_tangent.y + N * H_tangent.z);
					vec3 L = normalize(2.0 * dot(V, H) * H - V);

					float NdotL = max(dot(N, L), 0.0);

					if(NdotL > 0.0) {
						// Sample environment at fixed mip level
						// VNDF importance sampling handles the distribution filtering
						vec3 sampleColor = bilinearCubeUV(envMap, L, mipInt);

						// Weight by NdotL for the split-sum approximation
						// VNDF PDF naturally accounts for the visible microfacet distribution
						prefilteredColor += sampleColor * NdotL;
						totalWeight += NdotL;
					}
				}

				if (totalWeight > 0.0) {
					prefilteredColor = prefilteredColor / totalWeight;
				}

				gl_FragColor = vec4(prefilteredColor, 1.0);
			}
		`
    ),
    blending: Nn,
    depthTest: !1,
    depthWrite: !1
  });
}
function QR(i, e, t) {
  const n = new Float32Array(pa), r = new P(0, 1, 0);
  return new Vi({
    name: "SphericalGaussianBlur",
    defines: {
      n: pa,
      CUBEUV_TEXEL_WIDTH: 1 / e,
      CUBEUV_TEXEL_HEIGHT: 1 / t,
      CUBEUV_MAX_MIP: `${i}.0`
    },
    uniforms: {
      envMap: { value: null },
      samples: { value: 1 },
      weights: { value: n },
      latitudinal: { value: !1 },
      dTheta: { value: 0 },
      mipInt: { value: 0 },
      poleAxis: { value: r }
    },
    vertexShader: fd(),
    fragmentShader: (
      /* glsl */
      `

			precision mediump float;
			precision mediump int;

			varying vec3 vOutputDirection;

			uniform sampler2D envMap;
			uniform int samples;
			uniform float weights[ n ];
			uniform bool latitudinal;
			uniform float dTheta;
			uniform float mipInt;
			uniform vec3 poleAxis;

			#define ENVMAP_TYPE_CUBE_UV
			#include <cube_uv_reflection_fragment>

			vec3 getSample( float theta, vec3 axis ) {

				float cosTheta = cos( theta );
				// Rodrigues' axis-angle rotation
				vec3 sampleDirection = vOutputDirection * cosTheta
					+ cross( axis, vOutputDirection ) * sin( theta )
					+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );

				return bilinearCubeUV( envMap, sampleDirection, mipInt );

			}

			void main() {

				vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );

				if ( all( equal( axis, vec3( 0.0 ) ) ) ) {

					axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );

				}

				axis = normalize( axis );

				gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
				gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );

				for ( int i = 1; i < n; i++ ) {

					if ( i >= samples ) {

						break;

					}

					float theta = dTheta * float( i );
					gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
					gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );

				}

			}
		`
    ),
    blending: Nn,
    depthTest: !1,
    depthWrite: !1
  });
}
function G_() {
  return new Vi({
    name: "EquirectangularToCubeUV",
    uniforms: {
      envMap: { value: null }
    },
    vertexShader: fd(),
    fragmentShader: (
      /* glsl */
      `

			precision mediump float;
			precision mediump int;

			varying vec3 vOutputDirection;

			uniform sampler2D envMap;

			#include <common>

			void main() {

				vec3 outputDirection = normalize( vOutputDirection );
				vec2 uv = equirectUv( outputDirection );

				gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );

			}
		`
    ),
    blending: Nn,
    depthTest: !1,
    depthWrite: !1
  });
}
function V_() {
  return new Vi({
    name: "CubemapToCubeUV",
    uniforms: {
      envMap: { value: null },
      flipEnvMap: { value: -1 }
    },
    vertexShader: fd(),
    fragmentShader: (
      /* glsl */
      `

			precision mediump float;
			precision mediump int;

			uniform float flipEnvMap;

			varying vec3 vOutputDirection;

			uniform samplerCube envMap;

			void main() {

				gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );

			}
		`
    ),
    blending: Nn,
    depthTest: !1,
    depthWrite: !1
  });
}
function fd() {
  return (
    /* glsl */
    `

		precision mediump float;
		precision mediump int;

		attribute float faceIndex;

		varying vec3 vOutputDirection;

		// RH coordinate system; PMREM face-indexing convention
		vec3 getDirection( vec2 uv, float face ) {

			uv = 2.0 * uv - 1.0;

			vec3 direction = vec3( uv, 1.0 );

			if ( face == 0.0 ) {

				direction = direction.zyx; // ( 1, v, u ) pos x

			} else if ( face == 1.0 ) {

				direction = direction.xzy;
				direction.xz *= -1.0; // ( -u, 1, -v ) pos y

			} else if ( face == 2.0 ) {

				direction.x *= -1.0; // ( -u, v, 1 ) pos z

			} else if ( face == 3.0 ) {

				direction = direction.zyx;
				direction.xz *= -1.0; // ( -1, v, -u ) neg x

			} else if ( face == 4.0 ) {

				direction = direction.xzy;
				direction.xy *= -1.0; // ( -u, -1, v ) neg y

			} else if ( face == 5.0 ) {

				direction.z *= -1.0; // ( u, v, -1 ) neg z

			}

			return direction;

		}

		void main() {

			vOutputDirection = getDirection( uv, faceIndex );
			gl_Position = vec4( position, 1.0 );

		}
	`
  );
}
class xy extends tr {
  /**
   * Constructs a new cube render target.
   *
   * @param {number} [size=1] - The size of the render target.
   * @param {RenderTarget~Options} [options] - The configuration object.
   */
  constructor(e = 1, t = {}) {
    super(e, e, t), this.isWebGLCubeRenderTarget = !0;
    const n = { width: e, height: e, depth: 1 }, r = [n, n, n, n, n, n];
    this.texture = new yl(r), this._setTextureOptions(t), this.texture.isRenderTargetTexture = !0;
  }
  /**
   * Converts the given equirectangular texture to a cube map.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {Texture} texture - The equirectangular texture.
   * @return {WebGLCubeRenderTarget} A reference to this cube render target.
   */
  fromEquirectangularTexture(e, t) {
    this.texture.type = t.type, this.texture.colorSpace = t.colorSpace, this.texture.generateMipmaps = t.generateMipmaps, this.texture.minFilter = t.minFilter, this.texture.magFilter = t.magFilter;
    const n = {
      uniforms: {
        tEquirect: { value: null }
      },
      vertexShader: (
        /* glsl */
        `

				varying vec3 vWorldDirection;

				vec3 transformDirection( in vec3 dir, in mat4 matrix ) {

					return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );

				}

				void main() {

					vWorldDirection = transformDirection( position, modelMatrix );

					#include <begin_vertex>
					#include <project_vertex>

				}
			`
      ),
      fragmentShader: (
        /* glsl */
        `

				uniform sampler2D tEquirect;

				varying vec3 vWorldDirection;

				#include <common>

				void main() {

					vec3 direction = normalize( vWorldDirection );

					vec2 sampleUV = equirectUv( direction );

					gl_FragColor = texture2D( tEquirect, sampleUV );

				}
			`
      )
    }, r = new $a(5, 5, 5), s = new Vi({
      name: "CubemapFromEquirect",
      uniforms: ul(n.uniforms),
      vertexShader: n.vertexShader,
      fragmentShader: n.fragmentShader,
      side: Ft,
      blending: Nn
    });
    s.uniforms.tEquirect.value = t;
    const a = new _n(r, s), o = t.minFilter;
    return t.minFilter === pi && (t.minFilter = Ot), new py(1, 10, this).update(e, a), t.minFilter = o, a.geometry.dispose(), a.material.dispose(), this;
  }
  /**
   * Clears this cube render target.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {boolean} [color=true] - Whether the color buffer should be cleared or not.
   * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not.
   * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not.
   */
  clear(e, t = !0, n = !0, r = !0) {
    const s = e.getRenderTarget();
    for (let a = 0; a < 6; a++)
      e.setRenderTarget(this, a), e.clear(t, n, r);
    e.setRenderTarget(s);
  }
}
function JR(i) {
  let e = /* @__PURE__ */ new WeakMap(), t = /* @__PURE__ */ new WeakMap(), n = null;
  function r(d, f = !1) {
    return d == null ? null : f ? a(d) : s(d);
  }
  function s(d) {
    if (d && d.isTexture) {
      const f = d.mapping;
      if (f === Co || f === No)
        if (e.has(d)) {
          const p = e.get(d).texture;
          return o(p, d.mapping);
        } else {
          const p = d.image;
          if (p && p.height > 0) {
            const _ = new xy(p.height);
            return _.fromEquirectangularTexture(i, d), e.set(d, _), d.addEventListener("dispose", c), o(_.texture, d.mapping);
          } else
            return null;
        }
    }
    return d;
  }
  function a(d) {
    if (d && d.isTexture) {
      const f = d.mapping, p = f === Co || f === No, _ = f === nr || f === Rr;
      if (p || _) {
        let g = t.get(d);
        const m = g !== void 0 ? g.texture.pmremVersion : 0;
        if (d.isRenderTargetTexture && d.pmremVersion !== m)
          return n === null && (n = new O_(i)), g = p ? n.fromEquirectangular(d, g) : n.fromCubemap(d, g), g.texture.pmremVersion = d.pmremVersion, t.set(d, g), g.texture;
        if (g !== void 0)
          return g.texture;
        {
          const x = d.image;
          return p && x && x.height > 0 || _ && x && l(x) ? (n === null && (n = new O_(i)), g = p ? n.fromEquirectangular(d) : n.fromCubemap(d), g.texture.pmremVersion = d.pmremVersion, t.set(d, g), d.addEventListener("dispose", u), g.texture) : null;
        }
      }
    }
    return d;
  }
  function o(d, f) {
    return f === Co ? d.mapping = nr : f === No && (d.mapping = Rr), d;
  }
  function l(d) {
    let f = 0;
    const p = 6;
    for (let _ = 0; _ < p; _++)
      d[_] !== void 0 && f++;
    return f === p;
  }
  function c(d) {
    const f = d.target;
    f.removeEventListener("dispose", c);
    const p = e.get(f);
    p !== void 0 && (e.delete(f), p.dispose());
  }
  function u(d) {
    const f = d.target;
    f.removeEventListener("dispose", u);
    const p = t.get(f);
    p !== void 0 && (t.delete(f), p.dispose());
  }
  function h() {
    e = /* @__PURE__ */ new WeakMap(), t = /* @__PURE__ */ new WeakMap(), n !== null && (n.dispose(), n = null);
  }
  return {
    get: r,
    dispose: h
  };
}
function eC(i) {
  const e = {};
  function t(n) {
    if (e[n] !== void 0)
      return e[n];
    const r = i.getExtension(n);
    return e[n] = r, r;
  }
  return {
    has: function(n) {
      return t(n) !== null;
    },
    init: function() {
      t("EXT_color_buffer_float"), t("WEBGL_clip_cull_distance"), t("OES_texture_float_linear"), t("EXT_color_buffer_half_float"), t("WEBGL_multisampled_render_to_texture"), t("WEBGL_render_shared_exponent");
    },
    get: function(n) {
      const r = t(n);
      return r === null && Pt("WebGLRenderer: " + n + " extension not supported."), r;
    }
  };
}
function tC(i, e, t, n) {
  const r = {}, s = /* @__PURE__ */ new WeakMap();
  function a(h) {
    const d = h.target;
    d.index !== null && e.remove(d.index);
    for (const p in d.attributes)
      e.remove(d.attributes[p]);
    d.removeEventListener("dispose", a), delete r[d.id];
    const f = s.get(d);
    f && (e.remove(f), s.delete(d)), n.releaseStatesOfGeometry(d), d.isInstancedBufferGeometry === !0 && delete d._maxInstanceCount, t.memory.geometries--;
  }
  function o(h, d) {
    return r[d.id] === !0 || (d.addEventListener("dispose", a), r[d.id] = !0, t.memory.geometries++), d;
  }
  function l(h) {
    const d = h.attributes;
    for (const f in d)
      e.update(d[f], i.ARRAY_BUFFER);
  }
  function c(h) {
    const d = [], f = h.index, p = h.attributes.position;
    let _ = 0;
    if (p === void 0)
      return;
    if (f !== null) {
      const x = f.array;
      _ = f.version;
      for (let y = 0, b = x.length; y < b; y += 3) {
        const T = x[y + 0], S = x[y + 1], E = x[y + 2];
        d.push(T, S, S, E, E, T);
      }
    } else {
      const x = p.array;
      _ = p.version;
      for (let y = 0, b = x.length / 3 - 1; y < b; y += 3) {
        const T = y + 0, S = y + 1, E = y + 2;
        d.push(T, S, S, E, E, T);
      }
    }
    const g = new (p.count >= 65535 ? Ym : jm)(d, 1);
    g.version = _;
    const m = s.get(h);
    m && e.remove(m), s.set(h, g);
  }
  function u(h) {
    const d = s.get(h);
    if (d) {
      const f = h.index;
      f !== null && d.version < f.version && c(h);
    } else
      c(h);
    return s.get(h);
  }
  return {
    get: o,
    update: l,
    getWireframeAttribute: u
  };
}
function nC(i, e, t) {
  let n;
  function r(d) {
    n = d;
  }
  let s, a;
  function o(d) {
    s = d.type, a = d.bytesPerElement;
  }
  function l(d, f) {
    i.drawElements(n, f, s, d * a), t.update(f, n, 1);
  }
  function c(d, f, p) {
    p !== 0 && (i.drawElementsInstanced(n, f, s, d * a, p), t.update(f, n, p));
  }
  function u(d, f, p) {
    if (p === 0)
      return;
    e.get("WEBGL_multi_draw").multiDrawElementsWEBGL(n, f, 0, s, d, 0, p);
    let g = 0;
    for (let m = 0; m < p; m++)
      g += f[m];
    t.update(g, n, 1);
  }
  function h(d, f, p, _) {
    if (p === 0)
      return;
    const g = e.get("WEBGL_multi_draw");
    if (g === null)
      for (let m = 0; m < d.length; m++)
        c(d[m] / a, f[m], _[m]);
    else {
      g.multiDrawElementsInstancedWEBGL(n, f, 0, s, d, 0, _, 0, p);
      let m = 0;
      for (let x = 0; x < p; x++)
        m += f[x] * _[x];
      t.update(m, n, 1);
    }
  }
  this.setMode = r, this.setIndex = o, this.render = l, this.renderInstances = c, this.renderMultiDraw = u, this.renderMultiDrawInstances = h;
}
function iC(i) {
  const e = {
    geometries: 0,
    textures: 0
  }, t = {
    frame: 0,
    calls: 0,
    triangles: 0,
    points: 0,
    lines: 0
  };
  function n(s, a, o) {
    switch (t.calls++, a) {
      case i.TRIANGLES:
        t.triangles += o * (s / 3);
        break;
      case i.LINES:
        t.lines += o * (s / 2);
        break;
      case i.LINE_STRIP:
        t.lines += o * (s - 1);
        break;
      case i.LINE_LOOP:
        t.lines += o * s;
        break;
      case i.POINTS:
        t.points += o * s;
        break;
      default:
        le("WebGLInfo: Unknown draw mode:", a);
        break;
    }
  }
  function r() {
    t.calls = 0, t.triangles = 0, t.points = 0, t.lines = 0;
  }
  return {
    memory: e,
    render: t,
    programs: null,
    autoReset: !0,
    reset: r,
    update: n
  };
}
function rC(i, e, t) {
  const n = /* @__PURE__ */ new WeakMap(), r = new rt();
  function s(a, o, l) {
    const c = a.morphTargetInfluences, u = o.morphAttributes.position || o.morphAttributes.normal || o.morphAttributes.color, h = u !== void 0 ? u.length : 0;
    let d = n.get(o);
    if (d === void 0 || d.count !== h) {
      let M = function() {
        E.dispose(), n.delete(o), o.removeEventListener("dispose", M);
      };
      d !== void 0 && d.texture.dispose();
      const f = o.morphAttributes.position !== void 0, p = o.morphAttributes.normal !== void 0, _ = o.morphAttributes.color !== void 0, g = o.morphAttributes.position || [], m = o.morphAttributes.normal || [], x = o.morphAttributes.color || [];
      let y = 0;
      f === !0 && (y = 1), p === !0 && (y = 2), _ === !0 && (y = 3);
      let b = o.attributes.position.count * y, T = 1;
      b > e.maxTextureSize && (T = Math.ceil(b / e.maxTextureSize), b = e.maxTextureSize);
      const S = new Float32Array(b * T * 4 * h), E = new Wm(S, b, T, h);
      E.type = ln, E.needsUpdate = !0;
      const v = y * 4;
      for (let F = 0; F < h; F++) {
        const R = g[F], I = m[F], B = x[F], N = b * T * 4 * F;
        for (let C = 0; C < R.count; C++) {
          const L = C * v;
          f === !0 && (r.fromBufferAttribute(R, C), S[N + L + 0] = r.x, S[N + L + 1] = r.y, S[N + L + 2] = r.z, S[N + L + 3] = 0), p === !0 && (r.fromBufferAttribute(I, C), S[N + L + 4] = r.x, S[N + L + 5] = r.y, S[N + L + 6] = r.z, S[N + L + 7] = 0), _ === !0 && (r.fromBufferAttribute(B, C), S[N + L + 8] = r.x, S[N + L + 9] = r.y, S[N + L + 10] = r.z, S[N + L + 11] = B.itemSize === 4 ? r.w : 1);
        }
      }
      d = {
        count: h,
        texture: E,
        size: new de(b, T)
      }, n.set(o, d), o.addEventListener("dispose", M);
    }
    if (a.isInstancedMesh === !0 && a.morphTexture !== null)
      l.getUniforms().setValue(i, "morphTexture", a.morphTexture, t);
    else {
      let f = 0;
      for (let _ = 0; _ < c.length; _++)
        f += c[_];
      const p = o.morphTargetsRelative ? 1 : 1 - f;
      l.getUniforms().setValue(i, "morphTargetBaseInfluence", p), l.getUniforms().setValue(i, "morphTargetInfluences", c);
    }
    l.getUniforms().setValue(i, "morphTargetsTexture", d.texture, t), l.getUniforms().setValue(i, "morphTargetsTextureSize", d.size);
  }
  return {
    update: s
  };
}
function sC(i, e, t, n, r) {
  let s = /* @__PURE__ */ new WeakMap();
  function a(c) {
    const u = r.render.frame, h = c.geometry, d = e.get(c, h);
    if (s.get(d) !== u && (e.update(d), s.set(d, u)), c.isInstancedMesh && (c.hasEventListener("dispose", l) === !1 && c.addEventListener("dispose", l), s.get(c) !== u && (t.update(c.instanceMatrix, i.ARRAY_BUFFER), c.instanceColor !== null && t.update(c.instanceColor, i.ARRAY_BUFFER), s.set(c, u))), c.isSkinnedMesh) {
      const f = c.skeleton;
      s.get(f) !== u && (f.update(), s.set(f, u));
    }
    return d;
  }
  function o() {
    s = /* @__PURE__ */ new WeakMap();
  }
  function l(c) {
    const u = c.target;
    u.removeEventListener("dispose", l), n.releaseStatesOfObject(u), t.remove(u.instanceMatrix), u.instanceColor !== null && t.remove(u.instanceColor);
  }
  return {
    update: a,
    dispose: o
  };
}
const aC = {
  [Cm]: "LINEAR_TONE_MAPPING",
  [Nm]: "REINHARD_TONE_MAPPING",
  [Pm]: "CINEON_TONE_MAPPING",
  [Dm]: "ACES_FILMIC_TONE_MAPPING",
  [Lm]: "AGX_TONE_MAPPING",
  [Fm]: "NEUTRAL_TONE_MAPPING",
  [jv]: "CUSTOM_TONE_MAPPING"
};
function oC(i, e, t, n, r) {
  const s = new tr(e, t, {
    type: i,
    depthBuffer: n,
    stencilBuffer: r
  }), a = new tr(e, t, {
    type: nn,
    depthBuffer: !1,
    stencilBuffer: !1
  }), o = new Pn();
  o.setAttribute("position", new an([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)), o.setAttribute("uv", new an([0, 2, 0, 0, 2, 0], 2));
  const l = new UE({
    uniforms: {
      tDiffuse: { value: null }
    },
    vertexShader: (
      /* glsl */
      `
			precision highp float;

			uniform mat4 modelViewMatrix;
			uniform mat4 projectionMatrix;

			attribute vec3 position;
			attribute vec2 uv;

			varying vec2 vUv;

			void main() {
				vUv = uv;
				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
			}`
    ),
    fragmentShader: (
      /* glsl */
      `
			precision highp float;

			uniform sampler2D tDiffuse;

			varying vec2 vUv;

			#include <tonemapping_pars_fragment>
			#include <colorspace_pars_fragment>

			void main() {
				gl_FragColor = texture2D( tDiffuse, vUv );

				#ifdef LINEAR_TONE_MAPPING
					gl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb );
				#elif defined( REINHARD_TONE_MAPPING )
					gl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb );
				#elif defined( CINEON_TONE_MAPPING )
					gl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb );
				#elif defined( ACES_FILMIC_TONE_MAPPING )
					gl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb );
				#elif defined( AGX_TONE_MAPPING )
					gl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb );
				#elif defined( NEUTRAL_TONE_MAPPING )
					gl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb );
				#elif defined( CUSTOM_TONE_MAPPING )
					gl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb );
				#endif

				#ifdef SRGB_TRANSFER
					gl_FragColor = sRGBTransferOETF( gl_FragColor );
				#endif
			}`
    ),
    depthTest: !1,
    depthWrite: !1
  }), c = new _n(o, l), u = new bl(-1, 1, 1, -1, 0, 1);
  let h = null, d = null, f = !1, p, _ = null, g = [], m = !1;
  this.setSize = function(x, y) {
    s.setSize(x, y), a.setSize(x, y);
    for (let b = 0; b < g.length; b++) {
      const T = g[b];
      T.setSize && T.setSize(x, y);
    }
  }, this.setEffects = function(x) {
    g = x, m = g.length > 0 && g[0].isRenderPass === !0;
    const y = s.width, b = s.height;
    for (let T = 0; T < g.length; T++) {
      const S = g[T];
      S.setSize && S.setSize(y, b);
    }
  }, this.begin = function(x, y) {
    if (f || x.toneMapping === In && g.length === 0)
      return !1;
    if (_ = y, y !== null) {
      const b = y.width, T = y.height;
      (s.width !== b || s.height !== T) && this.setSize(b, T);
    }
    return m === !1 && x.setRenderTarget(s), p = x.toneMapping, x.toneMapping = In, !0;
  }, this.hasRenderPass = function() {
    return m;
  }, this.end = function(x, y) {
    x.toneMapping = p, f = !0;
    let b = s, T = a;
    for (let S = 0; S < g.length; S++) {
      const E = g[S];
      if (E.enabled !== !1 && (E.render(x, T, b, y), E.needsSwap !== !1)) {
        const v = b;
        b = T, T = v;
      }
    }
    if (h !== x.outputColorSpace || d !== x.toneMapping) {
      h = x.outputColorSpace, d = x.toneMapping, l.defines = {}, Ke.getTransfer(h) === Te && (l.defines.SRGB_TRANSFER = "");
      const S = aC[d];
      S && (l.defines[S] = ""), l.needsUpdate = !0;
    }
    l.uniforms.tDiffuse.value = b.texture, x.setRenderTarget(_), x.render(c, u), _ = null, f = !1;
  }, this.isCompositing = function() {
    return f;
  }, this.dispose = function() {
    s.dispose(), a.dispose(), o.dispose(), l.dispose();
  };
}
const vy = /* @__PURE__ */ new mn(), Np = /* @__PURE__ */ new oi(1, 1), yy = /* @__PURE__ */ new Wm(), by = /* @__PURE__ */ new KM(), Sy = /* @__PURE__ */ new yl(), z_ = [], H_ = [], $_ = new Float32Array(16), W_ = new Float32Array(9), q_ = new Float32Array(4);
function Sl(i, e, t) {
  const n = i[0];
  if (n <= 0 || n > 0)
    return i;
  const r = e * t;
  let s = z_[r];
  if (s === void 0 && (s = new Float32Array(r), z_[r] = s), e !== 0) {
    n.toArray(s, 0);
    for (let a = 1, o = 0; a !== e; ++a)
      o += t, i[a].toArray(s, o);
  }
  return s;
}
function bn(i, e) {
  if (i.length !== e.length)
    return !1;
  for (let t = 0, n = i.length; t < n; t++)
    if (i[t] !== e[t])
      return !1;
  return !0;
}
function Sn(i, e) {
  for (let t = 0, n = e.length; t < n; t++)
    i[t] = e[t];
}
function pd(i, e) {
  let t = H_[e];
  t === void 0 && (t = new Int32Array(e), H_[e] = t);
  for (let n = 0; n !== e; ++n)
    t[n] = i.allocateTextureUnit();
  return t;
}
function lC(i, e) {
  const t = this.cache;
  t[0] !== e && (i.uniform1f(this.addr, e), t[0] = e);
}
function cC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y) && (i.uniform2f(this.addr, e.x, e.y), t[0] = e.x, t[1] = e.y);
  else {
    if (bn(t, e))
      return;
    i.uniform2fv(this.addr, e), Sn(t, e);
  }
}
function uC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z) && (i.uniform3f(this.addr, e.x, e.y, e.z), t[0] = e.x, t[1] = e.y, t[2] = e.z);
  else if (e.r !== void 0)
    (t[0] !== e.r || t[1] !== e.g || t[2] !== e.b) && (i.uniform3f(this.addr, e.r, e.g, e.b), t[0] = e.r, t[1] = e.g, t[2] = e.b);
  else {
    if (bn(t, e))
      return;
    i.uniform3fv(this.addr, e), Sn(t, e);
  }
}
function hC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z || t[3] !== e.w) && (i.uniform4f(this.addr, e.x, e.y, e.z, e.w), t[0] = e.x, t[1] = e.y, t[2] = e.z, t[3] = e.w);
  else {
    if (bn(t, e))
      return;
    i.uniform4fv(this.addr, e), Sn(t, e);
  }
}
function dC(i, e) {
  const t = this.cache, n = e.elements;
  if (n === void 0) {
    if (bn(t, e))
      return;
    i.uniformMatrix2fv(this.addr, !1, e), Sn(t, e);
  } else {
    if (bn(t, n))
      return;
    q_.set(n), i.uniformMatrix2fv(this.addr, !1, q_), Sn(t, n);
  }
}
function fC(i, e) {
  const t = this.cache, n = e.elements;
  if (n === void 0) {
    if (bn(t, e))
      return;
    i.uniformMatrix3fv(this.addr, !1, e), Sn(t, e);
  } else {
    if (bn(t, n))
      return;
    W_.set(n), i.uniformMatrix3fv(this.addr, !1, W_), Sn(t, n);
  }
}
function pC(i, e) {
  const t = this.cache, n = e.elements;
  if (n === void 0) {
    if (bn(t, e))
      return;
    i.uniformMatrix4fv(this.addr, !1, e), Sn(t, e);
  } else {
    if (bn(t, n))
      return;
    $_.set(n), i.uniformMatrix4fv(this.addr, !1, $_), Sn(t, n);
  }
}
function mC(i, e) {
  const t = this.cache;
  t[0] !== e && (i.uniform1i(this.addr, e), t[0] = e);
}
function gC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y) && (i.uniform2i(this.addr, e.x, e.y), t[0] = e.x, t[1] = e.y);
  else {
    if (bn(t, e))
      return;
    i.uniform2iv(this.addr, e), Sn(t, e);
  }
}
function _C(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z) && (i.uniform3i(this.addr, e.x, e.y, e.z), t[0] = e.x, t[1] = e.y, t[2] = e.z);
  else {
    if (bn(t, e))
      return;
    i.uniform3iv(this.addr, e), Sn(t, e);
  }
}
function xC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z || t[3] !== e.w) && (i.uniform4i(this.addr, e.x, e.y, e.z, e.w), t[0] = e.x, t[1] = e.y, t[2] = e.z, t[3] = e.w);
  else {
    if (bn(t, e))
      return;
    i.uniform4iv(this.addr, e), Sn(t, e);
  }
}
function vC(i, e) {
  const t = this.cache;
  t[0] !== e && (i.uniform1ui(this.addr, e), t[0] = e);
}
function yC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y) && (i.uniform2ui(this.addr, e.x, e.y), t[0] = e.x, t[1] = e.y);
  else {
    if (bn(t, e))
      return;
    i.uniform2uiv(this.addr, e), Sn(t, e);
  }
}
function bC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z) && (i.uniform3ui(this.addr, e.x, e.y, e.z), t[0] = e.x, t[1] = e.y, t[2] = e.z);
  else {
    if (bn(t, e))
      return;
    i.uniform3uiv(this.addr, e), Sn(t, e);
  }
}
function SC(i, e) {
  const t = this.cache;
  if (e.x !== void 0)
    (t[0] !== e.x || t[1] !== e.y || t[2] !== e.z || t[3] !== e.w) && (i.uniform4ui(this.addr, e.x, e.y, e.z, e.w), t[0] = e.x, t[1] = e.y, t[2] = e.z, t[3] = e.w);
  else {
    if (bn(t, e))
      return;
    i.uniform4uiv(this.addr, e), Sn(t, e);
  }
}
function TC(i, e, t) {
  const n = this.cache, r = t.allocateTextureUnit();
  n[0] !== r && (i.uniform1i(this.addr, r), n[0] = r);
  let s;
  this.type === i.SAMPLER_2D_SHADOW ? (Np.compareFunction = t.isReversedDepthBuffer() ? us : Xs, s = Np) : s = vy, t.setTexture2D(e || s, r);
}
function MC(i, e, t) {
  const n = this.cache, r = t.allocateTextureUnit();
  n[0] !== r && (i.uniform1i(this.addr, r), n[0] = r), t.setTexture3D(e || by, r);
}
function EC(i, e, t) {
  const n = this.cache, r = t.allocateTextureUnit();
  n[0] !== r && (i.uniform1i(this.addr, r), n[0] = r), t.setTextureCube(e || Sy, r);
}
function wC(i, e, t) {
  const n = this.cache, r = t.allocateTextureUnit();
  n[0] !== r && (i.uniform1i(this.addr, r), n[0] = r), t.setTexture2DArray(e || yy, r);
}
function AC(i) {
  switch (i) {
    case 5126:
      return lC;
    case 35664:
      return cC;
    case 35665:
      return uC;
    case 35666:
      return hC;
    case 35674:
      return dC;
    case 35675:
      return fC;
    case 35676:
      return pC;
    case 5124:
    case 35670:
      return mC;
    case 35667:
    case 35671:
      return gC;
    case 35668:
    case 35672:
      return _C;
    case 35669:
    case 35673:
      return xC;
    case 5125:
      return vC;
    case 36294:
      return yC;
    case 36295:
      return bC;
    case 36296:
      return SC;
    case 35678:
    case 36198:
    case 36298:
    case 36306:
    case 35682:
      return TC;
    case 35679:
    case 36299:
    case 36307:
      return MC;
    case 35680:
    case 36300:
    case 36308:
    case 36293:
      return EC;
    case 36289:
    case 36303:
    case 36311:
    case 36292:
      return wC;
  }
}
function RC(i, e) {
  i.uniform1fv(this.addr, e);
}
function CC(i, e) {
  const t = Sl(e, this.size, 2);
  i.uniform2fv(this.addr, t);
}
function NC(i, e) {
  const t = Sl(e, this.size, 3);
  i.uniform3fv(this.addr, t);
}
function PC(i, e) {
  const t = Sl(e, this.size, 4);
  i.uniform4fv(this.addr, t);
}
function DC(i, e) {
  const t = Sl(e, this.size, 4);
  i.uniformMatrix2fv(this.addr, !1, t);
}
function LC(i, e) {
  const t = Sl(e, this.size, 9);
  i.uniformMatrix3fv(this.addr, !1, t);
}
function FC(i, e) {
  const t = Sl(e, this.size, 16);
  i.uniformMatrix4fv(this.addr, !1, t);
}
function IC(i, e) {
  i.uniform1iv(this.addr, e);
}
function UC(i, e) {
  i.uniform2iv(this.addr, e);
}
function BC(i, e) {
  i.uniform3iv(this.addr, e);
}
function OC(i, e) {
  i.uniform4iv(this.addr, e);
}
function kC(i, e) {
  i.uniform1uiv(this.addr, e);
}
function GC(i, e) {
  i.uniform2uiv(this.addr, e);
}
function VC(i, e) {
  i.uniform3uiv(this.addr, e);
}
function zC(i, e) {
  i.uniform4uiv(this.addr, e);
}
function HC(i, e, t) {
  const n = this.cache, r = e.length, s = pd(t, r);
  bn(n, s) || (i.uniform1iv(this.addr, s), Sn(n, s));
  let a;
  this.type === i.SAMPLER_2D_SHADOW ? a = Np : a = vy;
  for (let o = 0; o !== r; ++o)
    t.setTexture2D(e[o] || a, s[o]);
}
function $C(i, e, t) {
  const n = this.cache, r = e.length, s = pd(t, r);
  bn(n, s) || (i.uniform1iv(this.addr, s), Sn(n, s));
  for (let a = 0; a !== r; ++a)
    t.setTexture3D(e[a] || by, s[a]);
}
function WC(i, e, t) {
  const n = this.cache, r = e.length, s = pd(t, r);
  bn(n, s) || (i.uniform1iv(this.addr, s), Sn(n, s));
  for (let a = 0; a !== r; ++a)
    t.setTextureCube(e[a] || Sy, s[a]);
}
function qC(i, e, t) {
  const n = this.cache, r = e.length, s = pd(t, r);
  bn(n, s) || (i.uniform1iv(this.addr, s), Sn(n, s));
  for (let a = 0; a !== r; ++a)
    t.setTexture2DArray(e[a] || yy, s[a]);
}
function XC(i) {
  switch (i) {
    case 5126:
      return RC;
    case 35664:
      return CC;
    case 35665:
      return NC;
    case 35666:
      return PC;
    case 35674:
      return DC;
    case 35675:
      return LC;
    case 35676:
      return FC;
    case 5124:
    case 35670:
      return IC;
    case 35667:
    case 35671:
      return UC;
    case 35668:
    case 35672:
      return BC;
    case 35669:
    case 35673:
      return OC;
    case 5125:
      return kC;
    case 36294:
      return GC;
    case 36295:
      return VC;
    case 36296:
      return zC;
    case 35678:
    case 36198:
    case 36298:
    case 36306:
    case 35682:
      return HC;
    case 35679:
    case 36299:
    case 36307:
      return $C;
    case 35680:
    case 36300:
    case 36308:
    case 36293:
      return WC;
    case 36289:
    case 36303:
    case 36311:
    case 36292:
      return qC;
  }
}
class jC {
  constructor(e, t, n) {
    this.id = e, this.addr = n, this.cache = [], this.type = t.type, this.setValue = AC(t.type);
  }
}
class YC {
  constructor(e, t, n) {
    this.id = e, this.addr = n, this.cache = [], this.type = t.type, this.size = t.size, this.setValue = XC(t.type);
  }
}
class KC {
  constructor(e) {
    this.id = e, this.seq = [], this.map = {};
  }
  setValue(e, t, n) {
    const r = this.seq;
    for (let s = 0, a = r.length; s !== a; ++s) {
      const o = r[s];
      o.setValue(e, t[o.id], n);
    }
  }
}
const _f = /(\w+)(\])?(\[|\.)?/g;
function X_(i, e) {
  i.seq.push(e), i.map[e.id] = e;
}
function ZC(i, e, t) {
  const n = i.name, r = n.length;
  for (_f.lastIndex = 0; ; ) {
    const s = _f.exec(n), a = _f.lastIndex;
    let o = s[1];
    const l = s[2] === "]", c = s[3];
    if (l && (o = o | 0), c === void 0 || c === "[" && a + 2 === r) {
      X_(t, c === void 0 ? new jC(o, i, e) : new YC(o, i, e));
      break;
    } else {
      let h = t.map[o];
      h === void 0 && (h = new KC(o), X_(t, h)), t = h;
    }
  }
}
class Sh {
  constructor(e, t) {
    this.seq = [], this.map = {};
    const n = e.getProgramParameter(t, e.ACTIVE_UNIFORMS);
    for (let a = 0; a < n; ++a) {
      const o = e.getActiveUniform(t, a), l = e.getUniformLocation(t, o.name);
      ZC(o, l, this);
    }
    const r = [], s = [];
    for (const a of this.seq)
      a.type === e.SAMPLER_2D_SHADOW || a.type === e.SAMPLER_CUBE_SHADOW || a.type === e.SAMPLER_2D_ARRAY_SHADOW ? r.push(a) : s.push(a);
    r.length > 0 && (this.seq = r.concat(s));
  }
  setValue(e, t, n, r) {
    const s = this.map[t];
    s !== void 0 && s.setValue(e, n, r);
  }
  setOptional(e, t, n) {
    const r = t[n];
    r !== void 0 && this.setValue(e, n, r);
  }
  static upload(e, t, n, r) {
    for (let s = 0, a = t.length; s !== a; ++s) {
      const o = t[s], l = n[o.id];
      l.needsUpdate !== !1 && o.setValue(e, l.value, r);
    }
  }
  static seqWithValue(e, t) {
    const n = [];
    for (let r = 0, s = e.length; r !== s; ++r) {
      const a = e[r];
      a.id in t && n.push(a);
    }
    return n;
  }
}
function j_(i, e, t) {
  const n = i.createShader(e);
  return i.shaderSource(n, t), i.compileShader(n), n;
}
const QC = 37297;
let JC = 0;
function e1(i, e) {
  const t = i.split(`
`), n = [], r = Math.max(e - 6, 0), s = Math.min(e + 6, t.length);
  for (let a = r; a < s; a++) {
    const o = a + 1;
    n.push(`${o === e ? ">" : " "} ${o}: ${t[a]}`);
  }
  return n.join(`
`);
}
const Y_ = /* @__PURE__ */ new nt();
function t1(i) {
  Ke._getMatrix(Y_, Ke.workingColorSpace, i);
  const e = `mat3( ${Y_.elements.map((t) => t.toFixed(4))} )`;
  switch (Ke.getTransfer(i)) {
    case ll:
      return [e, "LinearTransferOETF"];
    case Te:
      return [e, "sRGBTransferOETF"];
    default:
      return oe("WebGLProgram: Unsupported color space: ", i), [e, "LinearTransferOETF"];
  }
}
function K_(i, e, t) {
  const n = i.getShaderParameter(e, i.COMPILE_STATUS), s = (i.getShaderInfoLog(e) || "").trim();
  if (n && s === "")
    return "";
  const a = /ERROR: 0:(\d+)/.exec(s);
  if (a) {
    const o = parseInt(a[1]);
    return t.toUpperCase() + `

` + s + `

` + e1(i.getShaderSource(e), o);
  } else
    return s;
}
function n1(i, e) {
  const t = t1(e);
  return [
    `vec4 ${i}( vec4 value ) {`,
    `	return ${t[1]}( vec4( value.rgb * ${t[0]}, value.a ) );`,
    "}"
  ].join(`
`);
}
const i1 = {
  [Cm]: "Linear",
  [Nm]: "Reinhard",
  [Pm]: "Cineon",
  [Dm]: "ACESFilmic",
  [Lm]: "AgX",
  [Fm]: "Neutral",
  [jv]: "Custom"
};
function r1(i, e) {
  const t = i1[e];
  return t === void 0 ? (oe("WebGLProgram: Unsupported toneMapping:", e), "vec3 " + i + "( vec3 color ) { return LinearToneMapping( color ); }") : "vec3 " + i + "( vec3 color ) { return " + t + "ToneMapping( color ); }";
}
const ku = /* @__PURE__ */ new P();
function s1() {
  Ke.getLuminanceCoefficients(ku);
  const i = ku.x.toFixed(4), e = ku.y.toFixed(4), t = ku.z.toFixed(4);
  return [
    "float luminance( const in vec3 rgb ) {",
    `	const vec3 weights = vec3( ${i}, ${e}, ${t} );`,
    "	return dot( weights, rgb );",
    "}"
  ].join(`
`);
}
function a1(i) {
  return [
    i.extensionClipCullDistance ? "#extension GL_ANGLE_clip_cull_distance : require" : "",
    i.extensionMultiDraw ? "#extension GL_ANGLE_multi_draw : require" : ""
  ].filter(sc).join(`
`);
}
function o1(i) {
  const e = [];
  for (const t in i) {
    const n = i[t];
    n !== !1 && e.push("#define " + t + " " + n);
  }
  return e.join(`
`);
}
function l1(i, e) {
  const t = {}, n = i.getProgramParameter(e, i.ACTIVE_ATTRIBUTES);
  for (let r = 0; r < n; r++) {
    const s = i.getActiveAttrib(e, r), a = s.name;
    let o = 1;
    s.type === i.FLOAT_MAT2 && (o = 2), s.type === i.FLOAT_MAT3 && (o = 3), s.type === i.FLOAT_MAT4 && (o = 4), t[a] = {
      type: s.type,
      location: i.getAttribLocation(e, a),
      locationSize: o
    };
  }
  return t;
}
function sc(i) {
  return i !== "";
}
function Z_(i, e) {
  const t = e.numSpotLightShadows + e.numSpotLightMaps - e.numSpotLightShadowsWithMaps;
  return i.replace(/NUM_DIR_LIGHTS/g, e.numDirLights).replace(/NUM_SPOT_LIGHTS/g, e.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, e.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, t).replace(/NUM_RECT_AREA_LIGHTS/g, e.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, e.numPointLights).replace(/NUM_HEMI_LIGHTS/g, e.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, e.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g, e.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, e.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, e.numPointLightShadows);
}
function Q_(i, e) {
  return i.replace(/NUM_CLIPPING_PLANES/g, e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, e.numClippingPlanes - e.numClipIntersection);
}
const c1 = /^[ \t]*#include +<([\w\d./]+)>/gm;
function Pp(i) {
  return i.replace(c1, h1);
}
const u1 = /* @__PURE__ */ new Map();
function h1(i, e) {
  let t = ht[e];
  if (t === void 0) {
    const n = u1.get(e);
    if (n !== void 0)
      t = ht[n], oe('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.', e, n);
    else
      throw new Error("Can not resolve #include <" + e + ">");
  }
  return Pp(t);
}
const d1 = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;
function J_(i) {
  return i.replace(d1, f1);
}
function f1(i, e, t, n) {
  let r = "";
  for (let s = parseInt(e); s < parseInt(t); s++)
    r += n.replace(/\[\s*i\s*\]/g, "[ " + s + " ]").replace(/UNROLLED_LOOP_INDEX/g, s);
  return r;
}
function e0(i) {
  let e = `precision ${i.precision} float;
	precision ${i.precision} int;
	precision ${i.precision} sampler2D;
	precision ${i.precision} samplerCube;
	precision ${i.precision} sampler3D;
	precision ${i.precision} sampler2DArray;
	precision ${i.precision} sampler2DShadow;
	precision ${i.precision} samplerCubeShadow;
	precision ${i.precision} sampler2DArrayShadow;
	precision ${i.precision} isampler2D;
	precision ${i.precision} isampler3D;
	precision ${i.precision} isamplerCube;
	precision ${i.precision} isampler2DArray;
	precision ${i.precision} usampler2D;
	precision ${i.precision} usampler3D;
	precision ${i.precision} usamplerCube;
	precision ${i.precision} usampler2DArray;
	`;
  return i.precision === "highp" ? e += `
#define HIGH_PRECISION` : i.precision === "mediump" ? e += `
#define MEDIUM_PRECISION` : i.precision === "lowp" && (e += `
#define LOW_PRECISION`), e;
}
const p1 = {
  [Ro]: "SHADOWMAP_TYPE_PCF",
  [br]: "SHADOWMAP_TYPE_VSM"
};
function m1(i) {
  return p1[i.shadowMapType] || "SHADOWMAP_TYPE_BASIC";
}
const g1 = {
  [nr]: "ENVMAP_TYPE_CUBE",
  [Rr]: "ENVMAP_TYPE_CUBE",
  [Ra]: "ENVMAP_TYPE_CUBE_UV"
};
function _1(i) {
  return i.envMap === !1 ? "ENVMAP_TYPE_CUBE" : g1[i.envMapMode] || "ENVMAP_TYPE_CUBE";
}
const x1 = {
  [Rr]: "ENVMAP_MODE_REFRACTION"
};
function v1(i) {
  return i.envMap === !1 ? "ENVMAP_MODE_REFLECTION" : x1[i.envMapMode] || "ENVMAP_MODE_REFLECTION";
}
const y1 = {
  [Qc]: "ENVMAP_BLENDING_MULTIPLY",
  [qv]: "ENVMAP_BLENDING_MIX",
  [Xv]: "ENVMAP_BLENDING_ADD"
};
function b1(i) {
  return i.envMap === !1 ? "ENVMAP_BLENDING_NONE" : y1[i.combine] || "ENVMAP_BLENDING_NONE";
}
function S1(i) {
  const e = i.envMapCubeUVHeight;
  if (e === null)
    return null;
  const t = Math.log2(e) - 2, n = 1 / e;
  return { texelWidth: 1 / (3 * Math.max(Math.pow(2, t), 7 * 16)), texelHeight: n, maxMip: t };
}
function T1(i, e, t, n) {
  const r = i.getContext(), s = t.defines;
  let a = t.vertexShader, o = t.fragmentShader;
  const l = m1(t), c = _1(t), u = v1(t), h = b1(t), d = S1(t), f = a1(t), p = o1(s), _ = r.createProgram();
  let g, m, x = t.glslVersion ? "#version " + t.glslVersion + `
` : "";
  t.isRawShaderMaterial ? (g = [
    "#define SHADER_TYPE " + t.shaderType,
    "#define SHADER_NAME " + t.shaderName,
    p
  ].filter(sc).join(`
`), g.length > 0 && (g += `
`), m = [
    "#define SHADER_TYPE " + t.shaderType,
    "#define SHADER_NAME " + t.shaderName,
    p
  ].filter(sc).join(`
`), m.length > 0 && (m += `
`)) : (g = [
    e0(t),
    "#define SHADER_TYPE " + t.shaderType,
    "#define SHADER_NAME " + t.shaderName,
    p,
    t.extensionClipCullDistance ? "#define USE_CLIP_DISTANCE" : "",
    t.batching ? "#define USE_BATCHING" : "",
    t.batchingColor ? "#define USE_BATCHING_COLOR" : "",
    t.instancing ? "#define USE_INSTANCING" : "",
    t.instancingColor ? "#define USE_INSTANCING_COLOR" : "",
    t.instancingMorph ? "#define USE_INSTANCING_MORPH" : "",
    t.useFog && t.fog ? "#define USE_FOG" : "",
    t.useFog && t.fogExp2 ? "#define FOG_EXP2" : "",
    t.map ? "#define USE_MAP" : "",
    t.envMap ? "#define USE_ENVMAP" : "",
    t.envMap ? "#define " + u : "",
    t.lightMap ? "#define USE_LIGHTMAP" : "",
    t.aoMap ? "#define USE_AOMAP" : "",
    t.bumpMap ? "#define USE_BUMPMAP" : "",
    t.normalMap ? "#define USE_NORMALMAP" : "",
    t.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "",
    t.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "",
    t.displacementMap ? "#define USE_DISPLACEMENTMAP" : "",
    t.emissiveMap ? "#define USE_EMISSIVEMAP" : "",
    t.anisotropy ? "#define USE_ANISOTROPY" : "",
    t.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "",
    t.clearcoatMap ? "#define USE_CLEARCOATMAP" : "",
    t.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "",
    t.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "",
    t.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "",
    t.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "",
    t.specularMap ? "#define USE_SPECULARMAP" : "",
    t.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "",
    t.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "",
    t.roughnessMap ? "#define USE_ROUGHNESSMAP" : "",
    t.metalnessMap ? "#define USE_METALNESSMAP" : "",
    t.alphaMap ? "#define USE_ALPHAMAP" : "",
    t.alphaHash ? "#define USE_ALPHAHASH" : "",
    t.transmission ? "#define USE_TRANSMISSION" : "",
    t.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "",
    t.thicknessMap ? "#define USE_THICKNESSMAP" : "",
    t.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "",
    t.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "",
    //
    t.mapUv ? "#define MAP_UV " + t.mapUv : "",
    t.alphaMapUv ? "#define ALPHAMAP_UV " + t.alphaMapUv : "",
    t.lightMapUv ? "#define LIGHTMAP_UV " + t.lightMapUv : "",
    t.aoMapUv ? "#define AOMAP_UV " + t.aoMapUv : "",
    t.emissiveMapUv ? "#define EMISSIVEMAP_UV " + t.emissiveMapUv : "",
    t.bumpMapUv ? "#define BUMPMAP_UV " + t.bumpMapUv : "",
    t.normalMapUv ? "#define NORMALMAP_UV " + t.normalMapUv : "",
    t.displacementMapUv ? "#define DISPLACEMENTMAP_UV " + t.displacementMapUv : "",
    t.metalnessMapUv ? "#define METALNESSMAP_UV " + t.metalnessMapUv : "",
    t.roughnessMapUv ? "#define ROUGHNESSMAP_UV " + t.roughnessMapUv : "",
    t.anisotropyMapUv ? "#define ANISOTROPYMAP_UV " + t.anisotropyMapUv : "",
    t.clearcoatMapUv ? "#define CLEARCOATMAP_UV " + t.clearcoatMapUv : "",
    t.clearcoatNormalMapUv ? "#define CLEARCOAT_NORMALMAP_UV " + t.clearcoatNormalMapUv : "",
    t.clearcoatRoughnessMapUv ? "#define CLEARCOAT_ROUGHNESSMAP_UV " + t.clearcoatRoughnessMapUv : "",
    t.iridescenceMapUv ? "#define IRIDESCENCEMAP_UV " + t.iridescenceMapUv : "",
    t.iridescenceThicknessMapUv ? "#define IRIDESCENCE_THICKNESSMAP_UV " + t.iridescenceThicknessMapUv : "",
    t.sheenColorMapUv ? "#define SHEEN_COLORMAP_UV " + t.sheenColorMapUv : "",
    t.sheenRoughnessMapUv ? "#define SHEEN_ROUGHNESSMAP_UV " + t.sheenRoughnessMapUv : "",
    t.specularMapUv ? "#define SPECULARMAP_UV " + t.specularMapUv : "",
    t.specularColorMapUv ? "#define SPECULAR_COLORMAP_UV " + t.specularColorMapUv : "",
    t.specularIntensityMapUv ? "#define SPECULAR_INTENSITYMAP_UV " + t.specularIntensityMapUv : "",
    t.transmissionMapUv ? "#define TRANSMISSIONMAP_UV " + t.transmissionMapUv : "",
    t.thicknessMapUv ? "#define THICKNESSMAP_UV " + t.thicknessMapUv : "",
    //
    t.vertexTangents && t.flatShading === !1 ? "#define USE_TANGENT" : "",
    t.vertexColors ? "#define USE_COLOR" : "",
    t.vertexAlphas ? "#define USE_COLOR_ALPHA" : "",
    t.vertexUv1s ? "#define USE_UV1" : "",
    t.vertexUv2s ? "#define USE_UV2" : "",
    t.vertexUv3s ? "#define USE_UV3" : "",
    t.pointsUvs ? "#define USE_POINTS_UV" : "",
    t.flatShading ? "#define FLAT_SHADED" : "",
    t.skinning ? "#define USE_SKINNING" : "",
    t.morphTargets ? "#define USE_MORPHTARGETS" : "",
    t.morphNormals && t.flatShading === !1 ? "#define USE_MORPHNORMALS" : "",
    t.morphColors ? "#define USE_MORPHCOLORS" : "",
    t.morphTargetsCount > 0 ? "#define MORPHTARGETS_TEXTURE_STRIDE " + t.morphTextureStride : "",
    t.morphTargetsCount > 0 ? "#define MORPHTARGETS_COUNT " + t.morphTargetsCount : "",
    t.doubleSided ? "#define DOUBLE_SIDED" : "",
    t.flipSided ? "#define FLIP_SIDED" : "",
    t.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
    t.shadowMapEnabled ? "#define " + l : "",
    t.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
    t.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "",
    t.logarithmicDepthBuffer ? "#define USE_LOGARITHMIC_DEPTH_BUFFER" : "",
    t.reversedDepthBuffer ? "#define USE_REVERSED_DEPTH_BUFFER" : "",
    "uniform mat4 modelMatrix;",
    "uniform mat4 modelViewMatrix;",
    "uniform mat4 projectionMatrix;",
    "uniform mat4 viewMatrix;",
    "uniform mat3 normalMatrix;",
    "uniform vec3 cameraPosition;",
    "uniform bool isOrthographic;",
    "#ifdef USE_INSTANCING",
    "	attribute mat4 instanceMatrix;",
    "#endif",
    "#ifdef USE_INSTANCING_COLOR",
    "	attribute vec3 instanceColor;",
    "#endif",
    "#ifdef USE_INSTANCING_MORPH",
    "	uniform sampler2D morphTexture;",
    "#endif",
    "attribute vec3 position;",
    "attribute vec3 normal;",
    "attribute vec2 uv;",
    "#ifdef USE_UV1",
    "	attribute vec2 uv1;",
    "#endif",
    "#ifdef USE_UV2",
    "	attribute vec2 uv2;",
    "#endif",
    "#ifdef USE_UV3",
    "	attribute vec2 uv3;",
    "#endif",
    "#ifdef USE_TANGENT",
    "	attribute vec4 tangent;",
    "#endif",
    "#if defined( USE_COLOR_ALPHA )",
    "	attribute vec4 color;",
    "#elif defined( USE_COLOR )",
    "	attribute vec3 color;",
    "#endif",
    "#ifdef USE_SKINNING",
    "	attribute vec4 skinIndex;",
    "	attribute vec4 skinWeight;",
    "#endif",
    `
`
  ].filter(sc).join(`
`), m = [
    e0(t),
    "#define SHADER_TYPE " + t.shaderType,
    "#define SHADER_NAME " + t.shaderName,
    p,
    t.useFog && t.fog ? "#define USE_FOG" : "",
    t.useFog && t.fogExp2 ? "#define FOG_EXP2" : "",
    t.alphaToCoverage ? "#define ALPHA_TO_COVERAGE" : "",
    t.map ? "#define USE_MAP" : "",
    t.matcap ? "#define USE_MATCAP" : "",
    t.envMap ? "#define USE_ENVMAP" : "",
    t.envMap ? "#define " + c : "",
    t.envMap ? "#define " + u : "",
    t.envMap ? "#define " + h : "",
    d ? "#define CUBEUV_TEXEL_WIDTH " + d.texelWidth : "",
    d ? "#define CUBEUV_TEXEL_HEIGHT " + d.texelHeight : "",
    d ? "#define CUBEUV_MAX_MIP " + d.maxMip + ".0" : "",
    t.lightMap ? "#define USE_LIGHTMAP" : "",
    t.aoMap ? "#define USE_AOMAP" : "",
    t.bumpMap ? "#define USE_BUMPMAP" : "",
    t.normalMap ? "#define USE_NORMALMAP" : "",
    t.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "",
    t.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "",
    t.emissiveMap ? "#define USE_EMISSIVEMAP" : "",
    t.anisotropy ? "#define USE_ANISOTROPY" : "",
    t.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "",
    t.clearcoat ? "#define USE_CLEARCOAT" : "",
    t.clearcoatMap ? "#define USE_CLEARCOATMAP" : "",
    t.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "",
    t.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "",
    t.dispersion ? "#define USE_DISPERSION" : "",
    t.iridescence ? "#define USE_IRIDESCENCE" : "",
    t.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "",
    t.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "",
    t.specularMap ? "#define USE_SPECULARMAP" : "",
    t.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "",
    t.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "",
    t.roughnessMap ? "#define USE_ROUGHNESSMAP" : "",
    t.metalnessMap ? "#define USE_METALNESSMAP" : "",
    t.alphaMap ? "#define USE_ALPHAMAP" : "",
    t.alphaTest ? "#define USE_ALPHATEST" : "",
    t.alphaHash ? "#define USE_ALPHAHASH" : "",
    t.sheen ? "#define USE_SHEEN" : "",
    t.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "",
    t.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "",
    t.transmission ? "#define USE_TRANSMISSION" : "",
    t.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "",
    t.thicknessMap ? "#define USE_THICKNESSMAP" : "",
    t.vertexTangents && t.flatShading === !1 ? "#define USE_TANGENT" : "",
    t.vertexColors || t.instancingColor ? "#define USE_COLOR" : "",
    t.vertexAlphas || t.batchingColor ? "#define USE_COLOR_ALPHA" : "",
    t.vertexUv1s ? "#define USE_UV1" : "",
    t.vertexUv2s ? "#define USE_UV2" : "",
    t.vertexUv3s ? "#define USE_UV3" : "",
    t.pointsUvs ? "#define USE_POINTS_UV" : "",
    t.gradientMap ? "#define USE_GRADIENTMAP" : "",
    t.flatShading ? "#define FLAT_SHADED" : "",
    t.doubleSided ? "#define DOUBLE_SIDED" : "",
    t.flipSided ? "#define FLIP_SIDED" : "",
    t.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
    t.shadowMapEnabled ? "#define " + l : "",
    t.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : "",
    t.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "",
    t.decodeVideoTexture ? "#define DECODE_VIDEO_TEXTURE" : "",
    t.decodeVideoTextureEmissive ? "#define DECODE_VIDEO_TEXTURE_EMISSIVE" : "",
    t.logarithmicDepthBuffer ? "#define USE_LOGARITHMIC_DEPTH_BUFFER" : "",
    t.reversedDepthBuffer ? "#define USE_REVERSED_DEPTH_BUFFER" : "",
    "uniform mat4 viewMatrix;",
    "uniform vec3 cameraPosition;",
    "uniform bool isOrthographic;",
    t.toneMapping !== In ? "#define TONE_MAPPING" : "",
    t.toneMapping !== In ? ht.tonemapping_pars_fragment : "",
    // this code is required here because it is used by the toneMapping() function defined below
    t.toneMapping !== In ? r1("toneMapping", t.toneMapping) : "",
    t.dithering ? "#define DITHERING" : "",
    t.opaque ? "#define OPAQUE" : "",
    ht.colorspace_pars_fragment,
    // this code is required here because it is used by the various encoding/decoding function defined below
    n1("linearToOutputTexel", t.outputColorSpace),
    s1(),
    t.useDepthPacking ? "#define DEPTH_PACKING " + t.depthPacking : "",
    `
`
  ].filter(sc).join(`
`)), a = Pp(a), a = Z_(a, t), a = Q_(a, t), o = Pp(o), o = Z_(o, t), o = Q_(o, t), a = J_(a), o = J_(o), t.isRawShaderMaterial !== !0 && (x = `#version 300 es
`, g = [
    f,
    "#define attribute in",
    "#define varying out",
    "#define texture2D texture"
  ].join(`
`) + `
` + g, m = [
    "#define varying in",
    t.glslVersion === l_ ? "" : "layout(location = 0) out highp vec4 pc_fragColor;",
    t.glslVersion === l_ ? "" : "#define gl_FragColor pc_fragColor",
    "#define gl_FragDepthEXT gl_FragDepth",
    "#define texture2D texture",
    "#define textureCube texture",
    "#define texture2DProj textureProj",
    "#define texture2DLodEXT textureLod",
    "#define texture2DProjLodEXT textureProjLod",
    "#define textureCubeLodEXT textureLod",
    "#define texture2DGradEXT textureGrad",
    "#define texture2DProjGradEXT textureProjGrad",
    "#define textureCubeGradEXT textureGrad"
  ].join(`
`) + `
` + m);
  const y = x + g + a, b = x + m + o, T = j_(r, r.VERTEX_SHADER, y), S = j_(r, r.FRAGMENT_SHADER, b);
  r.attachShader(_, T), r.attachShader(_, S), t.index0AttributeName !== void 0 ? r.bindAttribLocation(_, 0, t.index0AttributeName) : t.morphTargets === !0 && r.bindAttribLocation(_, 0, "position"), r.linkProgram(_);
  function E(R) {
    if (i.debug.checkShaderErrors) {
      const I = r.getProgramInfoLog(_) || "", B = r.getShaderInfoLog(T) || "", N = r.getShaderInfoLog(S) || "", C = I.trim(), L = B.trim(), k = N.trim();
      let re = !0, se = !0;
      if (r.getProgramParameter(_, r.LINK_STATUS) === !1)
        if (re = !1, typeof i.debug.onShaderError == "function")
          i.debug.onShaderError(r, _, T, S);
        else {
          const ve = K_(r, T, "vertex"), X = K_(r, S, "fragment");
          le(
            "THREE.WebGLProgram: Shader Error " + r.getError() + " - VALIDATE_STATUS " + r.getProgramParameter(_, r.VALIDATE_STATUS) + `

Material Name: ` + R.name + `
Material Type: ` + R.type + `

Program Info Log: ` + C + `
` + ve + `
` + X
          );
        }
      else
        C !== "" ? oe("WebGLProgram: Program Info Log:", C) : (L === "" || k === "") && (se = !1);
      se && (R.diagnostics = {
        runnable: re,
        programLog: C,
        vertexShader: {
          log: L,
          prefix: g
        },
        fragmentShader: {
          log: k,
          prefix: m
        }
      });
    }
    r.deleteShader(T), r.deleteShader(S), v = new Sh(r, _), M = l1(r, _);
  }
  let v;
  this.getUniforms = function() {
    return v === void 0 && E(this), v;
  };
  let M;
  this.getAttributes = function() {
    return M === void 0 && E(this), M;
  };
  let F = t.rendererExtensionParallelShaderCompile === !1;
  return this.isReady = function() {
    return F === !1 && (F = r.getProgramParameter(_, QC)), F;
  }, this.destroy = function() {
    n.releaseStatesOfProgram(this), r.deleteProgram(_), this.program = void 0;
  }, this.type = t.shaderType, this.name = t.shaderName, this.id = JC++, this.cacheKey = e, this.usedTimes = 1, this.program = _, this.vertexShader = T, this.fragmentShader = S, this;
}
let M1 = 0;
class E1 {
  constructor() {
    this.shaderCache = /* @__PURE__ */ new Map(), this.materialCache = /* @__PURE__ */ new Map();
  }
  update(e) {
    const t = e.vertexShader, n = e.fragmentShader, r = this._getShaderStage(t), s = this._getShaderStage(n), a = this._getShaderCacheForMaterial(e);
    return a.has(r) === !1 && (a.add(r), r.usedTimes++), a.has(s) === !1 && (a.add(s), s.usedTimes++), this;
  }
  remove(e) {
    const t = this.materialCache.get(e);
    for (const n of t)
      n.usedTimes--, n.usedTimes === 0 && this.shaderCache.delete(n.code);
    return this.materialCache.delete(e), this;
  }
  getVertexShaderID(e) {
    return this._getShaderStage(e.vertexShader).id;
  }
  getFragmentShaderID(e) {
    return this._getShaderStage(e.fragmentShader).id;
  }
  dispose() {
    this.shaderCache.clear(), this.materialCache.clear();
  }
  _getShaderCacheForMaterial(e) {
    const t = this.materialCache;
    let n = t.get(e);
    return n === void 0 && (n = /* @__PURE__ */ new Set(), t.set(e, n)), n;
  }
  _getShaderStage(e) {
    const t = this.shaderCache;
    let n = t.get(e);
    return n === void 0 && (n = new w1(e), t.set(e, n)), n;
  }
}
class w1 {
  constructor(e) {
    this.id = M1++, this.code = e, this.usedTimes = 0;
  }
}
function A1(i, e, t, n, r, s) {
  const a = new qm(), o = new E1(), l = /* @__PURE__ */ new Set(), c = [], u = /* @__PURE__ */ new Map(), h = n.logarithmicDepthBuffer;
  let d = n.precision;
  const f = {
    MeshDepthMaterial: "depth",
    MeshDistanceMaterial: "distance",
    MeshNormalMaterial: "normal",
    MeshBasicMaterial: "basic",
    MeshLambertMaterial: "lambert",
    MeshPhongMaterial: "phong",
    MeshToonMaterial: "toon",
    MeshStandardMaterial: "physical",
    MeshPhysicalMaterial: "physical",
    MeshMatcapMaterial: "matcap",
    LineBasicMaterial: "basic",
    LineDashedMaterial: "dashed",
    PointsMaterial: "points",
    ShadowMaterial: "shadow",
    SpriteMaterial: "sprite"
  };
  function p(v) {
    return l.add(v), v === 0 ? "uv" : `uv${v}`;
  }
  function _(v, M, F, R, I) {
    const B = R.fog, N = I.geometry, C = v.isMeshStandardMaterial || v.isMeshLambertMaterial || v.isMeshPhongMaterial ? R.environment : null, L = v.isMeshStandardMaterial || v.isMeshLambertMaterial && !v.envMap || v.isMeshPhongMaterial && !v.envMap, k = e.get(v.envMap || C, L), re = k && k.mapping === Ra ? k.image.height : null, se = f[v.type];
    v.precision !== null && (d = n.getMaxPrecision(v.precision), d !== v.precision && oe("WebGLProgram.getParameters:", v.precision, "not supported, using", d, "instead."));
    const ve = N.morphAttributes.position || N.morphAttributes.normal || N.morphAttributes.color, X = ve !== void 0 ? ve.length : 0;
    let te = 0;
    N.morphAttributes.position !== void 0 && (te = 1), N.morphAttributes.normal !== void 0 && (te = 2), N.morphAttributes.color !== void 0 && (te = 3);
    let me, Qe, ce, z;
    if (se) {
      const Ut = mr[se];
      me = Ut.vertexShader, Qe = Ut.fragmentShader;
    } else
      me = v.vertexShader, Qe = v.fragmentShader, o.update(v), ce = o.getVertexShaderID(v), z = o.getFragmentShaderID(v);
    const Z = i.getRenderTarget(), ue = i.state.buffers.depth.getReversed(), Ie = I.isInstancedMesh === !0, we = I.isBatchedMesh === !0, Re = !!v.map, It = !!v.matcap, ut = !!k, mt = !!v.aoMap, bt = !!v.lightMap, tt = !!v.bumpMap, Rt = !!v.normalMap, O = !!v.displacementMap, fn = !!v.emissiveMap, Ct = !!v.metalnessMap, Xt = !!v.roughnessMap, Ve = v.anisotropy > 0, D = v.clearcoat > 0, w = v.dispersion > 0, V = v.iridescence > 0, ae = v.sheen > 0, he = v.transmission > 0, ie = Ve && !!v.anisotropyMap, Ue = D && !!v.clearcoatMap, ye = D && !!v.clearcoatNormalMap, Ye = D && !!v.clearcoatRoughnessMap, Je = V && !!v.iridescenceMap, fe = V && !!v.iridescenceThicknessMap, ge = ae && !!v.sheenColorMap, Be = ae && !!v.sheenRoughnessMap, ke = !!v.specularMap, Ce = !!v.specularColorMap, dt = !!v.specularIntensityMap, G = he && !!v.transmissionMap, be = he && !!v.thicknessMap, _e = !!v.gradientMap, De = !!v.alphaMap, pe = v.alphaTest > 0, ne = !!v.alphaHash, Oe = !!v.extensions;
    let st = In;
    v.toneMapped && (Z === null || Z.isXRRenderTarget === !0) && (st = i.toneMapping);
    const jt = {
      shaderID: se,
      shaderType: v.type,
      shaderName: v.name,
      vertexShader: me,
      fragmentShader: Qe,
      defines: v.defines,
      customVertexShaderID: ce,
      customFragmentShaderID: z,
      isRawShaderMaterial: v.isRawShaderMaterial === !0,
      glslVersion: v.glslVersion,
      precision: d,
      batching: we,
      batchingColor: we && I._colorsTexture !== null,
      instancing: Ie,
      instancingColor: Ie && I.instanceColor !== null,
      instancingMorph: Ie && I.morphTexture !== null,
      outputColorSpace: Z === null ? i.outputColorSpace : Z.isXRRenderTarget === !0 ? Z.texture.colorSpace : La,
      alphaToCoverage: !!v.alphaToCoverage,
      map: Re,
      matcap: It,
      envMap: ut,
      envMapMode: ut && k.mapping,
      envMapCubeUVHeight: re,
      aoMap: mt,
      lightMap: bt,
      bumpMap: tt,
      normalMap: Rt,
      displacementMap: O,
      emissiveMap: fn,
      normalMapObjectSpace: Rt && v.normalMapType === Yv,
      normalMapTangentSpace: Rt && v.normalMapType === wr,
      metalnessMap: Ct,
      roughnessMap: Xt,
      anisotropy: Ve,
      anisotropyMap: ie,
      clearcoat: D,
      clearcoatMap: Ue,
      clearcoatNormalMap: ye,
      clearcoatRoughnessMap: Ye,
      dispersion: w,
      iridescence: V,
      iridescenceMap: Je,
      iridescenceThicknessMap: fe,
      sheen: ae,
      sheenColorMap: ge,
      sheenRoughnessMap: Be,
      specularMap: ke,
      specularColorMap: Ce,
      specularIntensityMap: dt,
      transmission: he,
      transmissionMap: G,
      thicknessMap: be,
      gradientMap: _e,
      opaque: v.transparent === !1 && v.blending === ei && v.alphaToCoverage === !1,
      alphaMap: De,
      alphaTest: pe,
      alphaHash: ne,
      combine: v.combine,
      //
      mapUv: Re && p(v.map.channel),
      aoMapUv: mt && p(v.aoMap.channel),
      lightMapUv: bt && p(v.lightMap.channel),
      bumpMapUv: tt && p(v.bumpMap.channel),
      normalMapUv: Rt && p(v.normalMap.channel),
      displacementMapUv: O && p(v.displacementMap.channel),
      emissiveMapUv: fn && p(v.emissiveMap.channel),
      metalnessMapUv: Ct && p(v.metalnessMap.channel),
      roughnessMapUv: Xt && p(v.roughnessMap.channel),
      anisotropyMapUv: ie && p(v.anisotropyMap.channel),
      clearcoatMapUv: Ue && p(v.clearcoatMap.channel),
      clearcoatNormalMapUv: ye && p(v.clearcoatNormalMap.channel),
      clearcoatRoughnessMapUv: Ye && p(v.clearcoatRoughnessMap.channel),
      iridescenceMapUv: Je && p(v.iridescenceMap.channel),
      iridescenceThicknessMapUv: fe && p(v.iridescenceThicknessMap.channel),
      sheenColorMapUv: ge && p(v.sheenColorMap.channel),
      sheenRoughnessMapUv: Be && p(v.sheenRoughnessMap.channel),
      specularMapUv: ke && p(v.specularMap.channel),
      specularColorMapUv: Ce && p(v.specularColorMap.channel),
      specularIntensityMapUv: dt && p(v.specularIntensityMap.channel),
      transmissionMapUv: G && p(v.transmissionMap.channel),
      thicknessMapUv: be && p(v.thicknessMap.channel),
      alphaMapUv: De && p(v.alphaMap.channel),
      //
      vertexTangents: !!N.attributes.tangent && (Rt || Ve),
      vertexColors: v.vertexColors,
      vertexAlphas: v.vertexColors === !0 && !!N.attributes.color && N.attributes.color.itemSize === 4,
      pointsUvs: I.isPoints === !0 && !!N.attributes.uv && (Re || De),
      fog: !!B,
      useFog: v.fog === !0,
      fogExp2: !!B && B.isFogExp2,
      flatShading: v.wireframe === !1 && (v.flatShading === !0 || N.attributes.normal === void 0 && Rt === !1 && (v.isMeshLambertMaterial || v.isMeshPhongMaterial || v.isMeshStandardMaterial || v.isMeshPhysicalMaterial)),
      sizeAttenuation: v.sizeAttenuation === !0,
      logarithmicDepthBuffer: h,
      reversedDepthBuffer: ue,
      skinning: I.isSkinnedMesh === !0,
      morphTargets: N.morphAttributes.position !== void 0,
      morphNormals: N.morphAttributes.normal !== void 0,
      morphColors: N.morphAttributes.color !== void 0,
      morphTargetsCount: X,
      morphTextureStride: te,
      numDirLights: M.directional.length,
      numPointLights: M.point.length,
      numSpotLights: M.spot.length,
      numSpotLightMaps: M.spotLightMap.length,
      numRectAreaLights: M.rectArea.length,
      numHemiLights: M.hemi.length,
      numDirLightShadows: M.directionalShadowMap.length,
      numPointLightShadows: M.pointShadowMap.length,
      numSpotLightShadows: M.spotShadowMap.length,
      numSpotLightShadowsWithMaps: M.numSpotLightShadowsWithMaps,
      numLightProbes: M.numLightProbes,
      numClippingPlanes: s.numPlanes,
      numClipIntersection: s.numIntersection,
      dithering: v.dithering,
      shadowMapEnabled: i.shadowMap.enabled && F.length > 0,
      shadowMapType: i.shadowMap.type,
      toneMapping: st,
      decodeVideoTexture: Re && v.map.isVideoTexture === !0 && Ke.getTransfer(v.map.colorSpace) === Te,
      decodeVideoTextureEmissive: fn && v.emissiveMap.isVideoTexture === !0 && Ke.getTransfer(v.emissiveMap.colorSpace) === Te,
      premultipliedAlpha: v.premultipliedAlpha,
      doubleSided: v.side === Rn,
      flipSided: v.side === Ft,
      useDepthPacking: v.depthPacking >= 0,
      depthPacking: v.depthPacking || 0,
      index0AttributeName: v.index0AttributeName,
      extensionClipCullDistance: Oe && v.extensions.clipCullDistance === !0 && t.has("WEBGL_clip_cull_distance"),
      extensionMultiDraw: (Oe && v.extensions.multiDraw === !0 || we) && t.has("WEBGL_multi_draw"),
      rendererExtensionParallelShaderCompile: t.has("KHR_parallel_shader_compile"),
      customProgramCacheKey: v.customProgramCacheKey()
    };
    return jt.vertexUv1s = l.has(1), jt.vertexUv2s = l.has(2), jt.vertexUv3s = l.has(3), l.clear(), jt;
  }
  function g(v) {
    const M = [];
    if (v.shaderID ? M.push(v.shaderID) : (M.push(v.customVertexShaderID), M.push(v.customFragmentShaderID)), v.defines !== void 0)
      for (const F in v.defines)
        M.push(F), M.push(v.defines[F]);
    return v.isRawShaderMaterial === !1 && (m(M, v), x(M, v), M.push(i.outputColorSpace)), M.push(v.customProgramCacheKey), M.join();
  }
  function m(v, M) {
    v.push(M.precision), v.push(M.outputColorSpace), v.push(M.envMapMode), v.push(M.envMapCubeUVHeight), v.push(M.mapUv), v.push(M.alphaMapUv), v.push(M.lightMapUv), v.push(M.aoMapUv), v.push(M.bumpMapUv), v.push(M.normalMapUv), v.push(M.displacementMapUv), v.push(M.emissiveMapUv), v.push(M.metalnessMapUv), v.push(M.roughnessMapUv), v.push(M.anisotropyMapUv), v.push(M.clearcoatMapUv), v.push(M.clearcoatNormalMapUv), v.push(M.clearcoatRoughnessMapUv), v.push(M.iridescenceMapUv), v.push(M.iridescenceThicknessMapUv), v.push(M.sheenColorMapUv), v.push(M.sheenRoughnessMapUv), v.push(M.specularMapUv), v.push(M.specularColorMapUv), v.push(M.specularIntensityMapUv), v.push(M.transmissionMapUv), v.push(M.thicknessMapUv), v.push(M.combine), v.push(M.fogExp2), v.push(M.sizeAttenuation), v.push(M.morphTargetsCount), v.push(M.morphAttributeCount), v.push(M.numDirLights), v.push(M.numPointLights), v.push(M.numSpotLights), v.push(M.numSpotLightMaps), v.push(M.numHemiLights), v.push(M.numRectAreaLights), v.push(M.numDirLightShadows), v.push(M.numPointLightShadows), v.push(M.numSpotLightShadows), v.push(M.numSpotLightShadowsWithMaps), v.push(M.numLightProbes), v.push(M.shadowMapType), v.push(M.toneMapping), v.push(M.numClippingPlanes), v.push(M.numClipIntersection), v.push(M.depthPacking);
  }
  function x(v, M) {
    a.disableAll(), M.instancing && a.enable(0), M.instancingColor && a.enable(1), M.instancingMorph && a.enable(2), M.matcap && a.enable(3), M.envMap && a.enable(4), M.normalMapObjectSpace && a.enable(5), M.normalMapTangentSpace && a.enable(6), M.clearcoat && a.enable(7), M.iridescence && a.enable(8), M.alphaTest && a.enable(9), M.vertexColors && a.enable(10), M.vertexAlphas && a.enable(11), M.vertexUv1s && a.enable(12), M.vertexUv2s && a.enable(13), M.vertexUv3s && a.enable(14), M.vertexTangents && a.enable(15), M.anisotropy && a.enable(16), M.alphaHash && a.enable(17), M.batching && a.enable(18), M.dispersion && a.enable(19), M.batchingColor && a.enable(20), M.gradientMap && a.enable(21), v.push(a.mask), a.disableAll(), M.fog && a.enable(0), M.useFog && a.enable(1), M.flatShading && a.enable(2), M.logarithmicDepthBuffer && a.enable(3), M.reversedDepthBuffer && a.enable(4), M.skinning && a.enable(5), M.morphTargets && a.enable(6), M.morphNormals && a.enable(7), M.morphColors && a.enable(8), M.premultipliedAlpha && a.enable(9), M.shadowMapEnabled && a.enable(10), M.doubleSided && a.enable(11), M.flipSided && a.enable(12), M.useDepthPacking && a.enable(13), M.dithering && a.enable(14), M.transmission && a.enable(15), M.sheen && a.enable(16), M.opaque && a.enable(17), M.pointsUvs && a.enable(18), M.decodeVideoTexture && a.enable(19), M.decodeVideoTextureEmissive && a.enable(20), M.alphaToCoverage && a.enable(21), v.push(a.mask);
  }
  function y(v) {
    const M = f[v.type];
    let F;
    if (M) {
      const R = mr[M];
      F = ly.clone(R.uniforms);
    } else
      F = v.uniforms;
    return F;
  }
  function b(v, M) {
    let F = u.get(M);
    return F !== void 0 ? ++F.usedTimes : (F = new T1(i, M, v, r), c.push(F), u.set(M, F)), F;
  }
  function T(v) {
    if (--v.usedTimes === 0) {
      const M = c.indexOf(v);
      c[M] = c[c.length - 1], c.pop(), u.delete(v.cacheKey), v.destroy();
    }
  }
  function S(v) {
    o.remove(v);
  }
  function E() {
    o.dispose();
  }
  return {
    getParameters: _,
    getProgramCacheKey: g,
    getUniforms: y,
    acquireProgram: b,
    releaseProgram: T,
    releaseShaderCache: S,
    // Exposed for resource monitoring & error feedback via renderer.info:
    programs: c,
    dispose: E
  };
}
function R1() {
  let i = /* @__PURE__ */ new WeakMap();
  function e(a) {
    return i.has(a);
  }
  function t(a) {
    let o = i.get(a);
    return o === void 0 && (o = {}, i.set(a, o)), o;
  }
  function n(a) {
    i.delete(a);
  }
  function r(a, o, l) {
    i.get(a)[o] = l;
  }
  function s() {
    i = /* @__PURE__ */ new WeakMap();
  }
  return {
    has: e,
    get: t,
    remove: n,
    update: r,
    dispose: s
  };
}
function C1(i, e) {
  return i.groupOrder !== e.groupOrder ? i.groupOrder - e.groupOrder : i.renderOrder !== e.renderOrder ? i.renderOrder - e.renderOrder : i.material.id !== e.material.id ? i.material.id - e.material.id : i.materialVariant !== e.materialVariant ? i.materialVariant - e.materialVariant : i.z !== e.z ? i.z - e.z : i.id - e.id;
}
function t0(i, e) {
  return i.groupOrder !== e.groupOrder ? i.groupOrder - e.groupOrder : i.renderOrder !== e.renderOrder ? i.renderOrder - e.renderOrder : i.z !== e.z ? e.z - i.z : i.id - e.id;
}
function n0() {
  const i = [];
  let e = 0;
  const t = [], n = [], r = [];
  function s() {
    e = 0, t.length = 0, n.length = 0, r.length = 0;
  }
  function a(d) {
    let f = 0;
    return d.isInstancedMesh && (f += 2), d.isSkinnedMesh && (f += 1), f;
  }
  function o(d, f, p, _, g, m) {
    let x = i[e];
    return x === void 0 ? (x = {
      id: d.id,
      object: d,
      geometry: f,
      material: p,
      materialVariant: a(d),
      groupOrder: _,
      renderOrder: d.renderOrder,
      z: g,
      group: m
    }, i[e] = x) : (x.id = d.id, x.object = d, x.geometry = f, x.material = p, x.materialVariant = a(d), x.groupOrder = _, x.renderOrder = d.renderOrder, x.z = g, x.group = m), e++, x;
  }
  function l(d, f, p, _, g, m) {
    const x = o(d, f, p, _, g, m);
    p.transmission > 0 ? n.push(x) : p.transparent === !0 ? r.push(x) : t.push(x);
  }
  function c(d, f, p, _, g, m) {
    const x = o(d, f, p, _, g, m);
    p.transmission > 0 ? n.unshift(x) : p.transparent === !0 ? r.unshift(x) : t.unshift(x);
  }
  function u(d, f) {
    t.length > 1 && t.sort(d || C1), n.length > 1 && n.sort(f || t0), r.length > 1 && r.sort(f || t0);
  }
  function h() {
    for (let d = e, f = i.length; d < f; d++) {
      const p = i[d];
      if (p.id === null)
        break;
      p.id = null, p.object = null, p.geometry = null, p.material = null, p.group = null;
    }
  }
  return {
    opaque: t,
    transmissive: n,
    transparent: r,
    init: s,
    push: l,
    unshift: c,
    finish: h,
    sort: u
  };
}
function N1() {
  let i = /* @__PURE__ */ new WeakMap();
  function e(n, r) {
    const s = i.get(n);
    let a;
    return s === void 0 ? (a = new n0(), i.set(n, [a])) : r >= s.length ? (a = new n0(), s.push(a)) : a = s[r], a;
  }
  function t() {
    i = /* @__PURE__ */ new WeakMap();
  }
  return {
    get: e,
    dispose: t
  };
}
function P1() {
  const i = {};
  return {
    get: function(e) {
      if (i[e.id] !== void 0)
        return i[e.id];
      let t;
      switch (e.type) {
        case "DirectionalLight":
          t = {
            direction: new P(),
            color: new He()
          };
          break;
        case "SpotLight":
          t = {
            position: new P(),
            direction: new P(),
            color: new He(),
            distance: 0,
            coneCos: 0,
            penumbraCos: 0,
            decay: 0
          };
          break;
        case "PointLight":
          t = {
            position: new P(),
            color: new He(),
            distance: 0,
            decay: 0
          };
          break;
        case "HemisphereLight":
          t = {
            direction: new P(),
            skyColor: new He(),
            groundColor: new He()
          };
          break;
        case "RectAreaLight":
          t = {
            color: new He(),
            position: new P(),
            halfWidth: new P(),
            halfHeight: new P()
          };
          break;
      }
      return i[e.id] = t, t;
    }
  };
}
function D1() {
  const i = {};
  return {
    get: function(e) {
      if (i[e.id] !== void 0)
        return i[e.id];
      let t;
      switch (e.type) {
        case "DirectionalLight":
          t = {
            shadowIntensity: 1,
            shadowBias: 0,
            shadowNormalBias: 0,
            shadowRadius: 1,
            shadowMapSize: new de()
          };
          break;
        case "SpotLight":
          t = {
            shadowIntensity: 1,
            shadowBias: 0,
            shadowNormalBias: 0,
            shadowRadius: 1,
            shadowMapSize: new de()
          };
          break;
        case "PointLight":
          t = {
            shadowIntensity: 1,
            shadowBias: 0,
            shadowNormalBias: 0,
            shadowRadius: 1,
            shadowMapSize: new de(),
            shadowCameraNear: 1,
            shadowCameraFar: 1e3
          };
          break;
      }
      return i[e.id] = t, t;
    }
  };
}
let L1 = 0;
function F1(i, e) {
  return (e.castShadow ? 2 : 0) - (i.castShadow ? 2 : 0) + (e.map ? 1 : 0) - (i.map ? 1 : 0);
}
function I1(i) {
  const e = new P1(), t = D1(), n = {
    version: 0,
    hash: {
      directionalLength: -1,
      pointLength: -1,
      spotLength: -1,
      rectAreaLength: -1,
      hemiLength: -1,
      numDirectionalShadows: -1,
      numPointShadows: -1,
      numSpotShadows: -1,
      numSpotMaps: -1,
      numLightProbes: -1
    },
    ambient: [0, 0, 0],
    probe: [],
    directional: [],
    directionalShadow: [],
    directionalShadowMap: [],
    directionalShadowMatrix: [],
    spot: [],
    spotLightMap: [],
    spotShadow: [],
    spotShadowMap: [],
    spotLightMatrix: [],
    rectArea: [],
    rectAreaLTC1: null,
    rectAreaLTC2: null,
    point: [],
    pointShadow: [],
    pointShadowMap: [],
    pointShadowMatrix: [],
    hemi: [],
    numSpotLightShadowsWithMaps: 0,
    numLightProbes: 0
  };
  for (let c = 0; c < 9; c++)
    n.probe.push(new P());
  const r = new P(), s = new pt(), a = new pt();
  function o(c) {
    let u = 0, h = 0, d = 0;
    for (let M = 0; M < 9; M++)
      n.probe[M].set(0, 0, 0);
    let f = 0, p = 0, _ = 0, g = 0, m = 0, x = 0, y = 0, b = 0, T = 0, S = 0, E = 0;
    c.sort(F1);
    for (let M = 0, F = c.length; M < F; M++) {
      const R = c[M], I = R.color, B = R.intensity, N = R.distance;
      let C = null;
      if (R.shadow && R.shadow.map && (R.shadow.map.texture.format === ri ? C = R.shadow.map.texture : C = R.shadow.map.depthTexture || R.shadow.map.texture), R.isAmbientLight)
        u += I.r * B, h += I.g * B, d += I.b * B;
      else if (R.isLightProbe) {
        for (let L = 0; L < 9; L++)
          n.probe[L].addScaledVector(R.sh.coefficients[L], B);
        E++;
      } else if (R.isDirectionalLight) {
        const L = e.get(R);
        if (L.color.copy(R.color).multiplyScalar(R.intensity), R.castShadow) {
          const k = R.shadow, re = t.get(R);
          re.shadowIntensity = k.intensity, re.shadowBias = k.bias, re.shadowNormalBias = k.normalBias, re.shadowRadius = k.radius, re.shadowMapSize = k.mapSize, n.directionalShadow[f] = re, n.directionalShadowMap[f] = C, n.directionalShadowMatrix[f] = R.shadow.matrix, x++;
        }
        n.directional[f] = L, f++;
      } else if (R.isSpotLight) {
        const L = e.get(R);
        L.position.setFromMatrixPosition(R.matrixWorld), L.color.copy(I).multiplyScalar(B), L.distance = N, L.coneCos = Math.cos(R.angle), L.penumbraCos = Math.cos(R.angle * (1 - R.penumbra)), L.decay = R.decay, n.spot[_] = L;
        const k = R.shadow;
        if (R.map && (n.spotLightMap[T] = R.map, T++, k.updateMatrices(R), R.castShadow && S++), n.spotLightMatrix[_] = k.matrix, R.castShadow) {
          const re = t.get(R);
          re.shadowIntensity = k.intensity, re.shadowBias = k.bias, re.shadowNormalBias = k.normalBias, re.shadowRadius = k.radius, re.shadowMapSize = k.mapSize, n.spotShadow[_] = re, n.spotShadowMap[_] = C, b++;
        }
        _++;
      } else if (R.isRectAreaLight) {
        const L = e.get(R);
        L.color.copy(I).multiplyScalar(B), L.halfWidth.set(R.width * 0.5, 0, 0), L.halfHeight.set(0, R.height * 0.5, 0), n.rectArea[g] = L, g++;
      } else if (R.isPointLight) {
        const L = e.get(R);
        if (L.color.copy(R.color).multiplyScalar(R.intensity), L.distance = R.distance, L.decay = R.decay, R.castShadow) {
          const k = R.shadow, re = t.get(R);
          re.shadowIntensity = k.intensity, re.shadowBias = k.bias, re.shadowNormalBias = k.normalBias, re.shadowRadius = k.radius, re.shadowMapSize = k.mapSize, re.shadowCameraNear = k.camera.near, re.shadowCameraFar = k.camera.far, n.pointShadow[p] = re, n.pointShadowMap[p] = C, n.pointShadowMatrix[p] = R.shadow.matrix, y++;
        }
        n.point[p] = L, p++;
      } else if (R.isHemisphereLight) {
        const L = e.get(R);
        L.skyColor.copy(R.color).multiplyScalar(B), L.groundColor.copy(R.groundColor).multiplyScalar(B), n.hemi[m] = L, m++;
      }
    }
    g > 0 && (i.has("OES_texture_float_linear") === !0 ? (n.rectAreaLTC1 = Se.LTC_FLOAT_1, n.rectAreaLTC2 = Se.LTC_FLOAT_2) : (n.rectAreaLTC1 = Se.LTC_HALF_1, n.rectAreaLTC2 = Se.LTC_HALF_2)), n.ambient[0] = u, n.ambient[1] = h, n.ambient[2] = d;
    const v = n.hash;
    (v.directionalLength !== f || v.pointLength !== p || v.spotLength !== _ || v.rectAreaLength !== g || v.hemiLength !== m || v.numDirectionalShadows !== x || v.numPointShadows !== y || v.numSpotShadows !== b || v.numSpotMaps !== T || v.numLightProbes !== E) && (n.directional.length = f, n.spot.length = _, n.rectArea.length = g, n.point.length = p, n.hemi.length = m, n.directionalShadow.length = x, n.directionalShadowMap.length = x, n.pointShadow.length = y, n.pointShadowMap.length = y, n.spotShadow.length = b, n.spotShadowMap.length = b, n.directionalShadowMatrix.length = x, n.pointShadowMatrix.length = y, n.spotLightMatrix.length = b + T - S, n.spotLightMap.length = T, n.numSpotLightShadowsWithMaps = S, n.numLightProbes = E, v.directionalLength = f, v.pointLength = p, v.spotLength = _, v.rectAreaLength = g, v.hemiLength = m, v.numDirectionalShadows = x, v.numPointShadows = y, v.numSpotShadows = b, v.numSpotMaps = T, v.numLightProbes = E, n.version = L1++);
  }
  function l(c, u) {
    let h = 0, d = 0, f = 0, p = 0, _ = 0;
    const g = u.matrixWorldInverse;
    for (let m = 0, x = c.length; m < x; m++) {
      const y = c[m];
      if (y.isDirectionalLight) {
        const b = n.directional[h];
        b.direction.setFromMatrixPosition(y.matrixWorld), r.setFromMatrixPosition(y.target.matrixWorld), b.direction.sub(r), b.direction.transformDirection(g), h++;
      } else if (y.isSpotLight) {
        const b = n.spot[f];
        b.position.setFromMatrixPosition(y.matrixWorld), b.position.applyMatrix4(g), b.direction.setFromMatrixPosition(y.matrixWorld), r.setFromMatrixPosition(y.target.matrixWorld), b.direction.sub(r), b.direction.transformDirection(g), f++;
      } else if (y.isRectAreaLight) {
        const b = n.rectArea[p];
        b.position.setFromMatrixPosition(y.matrixWorld), b.position.applyMatrix4(g), a.identity(), s.copy(y.matrixWorld), s.premultiply(g), a.extractRotation(s), b.halfWidth.set(y.width * 0.5, 0, 0), b.halfHeight.set(0, y.height * 0.5, 0), b.halfWidth.applyMatrix4(a), b.halfHeight.applyMatrix4(a), p++;
      } else if (y.isPointLight) {
        const b = n.point[d];
        b.position.setFromMatrixPosition(y.matrixWorld), b.position.applyMatrix4(g), d++;
      } else if (y.isHemisphereLight) {
        const b = n.hemi[_];
        b.direction.setFromMatrixPosition(y.matrixWorld), b.direction.transformDirection(g), _++;
      }
    }
  }
  return {
    setup: o,
    setupView: l,
    state: n
  };
}
function i0(i) {
  const e = new I1(i), t = [], n = [];
  function r(u) {
    c.camera = u, t.length = 0, n.length = 0;
  }
  function s(u) {
    t.push(u);
  }
  function a(u) {
    n.push(u);
  }
  function o() {
    e.setup(t);
  }
  function l(u) {
    e.setupView(t, u);
  }
  const c = {
    lightsArray: t,
    shadowsArray: n,
    camera: null,
    lights: e,
    transmissionRenderTarget: {}
  };
  return {
    init: r,
    state: c,
    setupLights: o,
    setupLightsView: l,
    pushLight: s,
    pushShadow: a
  };
}
function U1(i) {
  let e = /* @__PURE__ */ new WeakMap();
  function t(r, s = 0) {
    const a = e.get(r);
    let o;
    return a === void 0 ? (o = new i0(i), e.set(r, [o])) : s >= a.length ? (o = new i0(i), a.push(o)) : o = a[s], o;
  }
  function n() {
    e = /* @__PURE__ */ new WeakMap();
  }
  return {
    get: t,
    dispose: n
  };
}
const B1 = `void main() {
	gl_Position = vec4( position, 1.0 );
}`, O1 = `uniform sampler2D shadow_pass;
uniform vec2 resolution;
uniform float radius;
void main() {
	const float samples = float( VSM_SAMPLES );
	float mean = 0.0;
	float squared_mean = 0.0;
	float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );
	float uvStart = samples <= 1.0 ? 0.0 : - 1.0;
	for ( float i = 0.0; i < samples; i ++ ) {
		float uvOffset = uvStart + i * uvStride;
		#ifdef HORIZONTAL_PASS
			vec2 distribution = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ).rg;
			mean += distribution.x;
			squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;
		#else
			float depth = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ).r;
			mean += depth;
			squared_mean += depth * depth;
		#endif
	}
	mean = mean / samples;
	squared_mean = squared_mean / samples;
	float std_dev = sqrt( max( 0.0, squared_mean - mean * mean ) );
	gl_FragColor = vec4( mean, std_dev, 0.0, 1.0 );
}`, k1 = [
  /* @__PURE__ */ new P(1, 0, 0),
  /* @__PURE__ */ new P(-1, 0, 0),
  /* @__PURE__ */ new P(0, 1, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, 0, -1)
], G1 = [
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, 0, -1),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0)
], r0 = /* @__PURE__ */ new pt(), Gl = /* @__PURE__ */ new P(), xf = /* @__PURE__ */ new P();
function V1(i, e, t) {
  let n = new nu();
  const r = new de(), s = new de(), a = new rt(), o = new VE(), l = new zE(), c = {}, u = t.maxTextureSize, h = { [ai]: Ft, [Ft]: ai, [Rn]: Rn }, d = new Vi({
    defines: {
      VSM_SAMPLES: 8
    },
    uniforms: {
      shadow_pass: { value: null },
      resolution: { value: new de() },
      radius: { value: 4 }
    },
    vertexShader: B1,
    fragmentShader: O1
  }), f = d.clone();
  f.defines.HORIZONTAL_PASS = 1;
  const p = new Pn();
  p.setAttribute(
    "position",
    new Bn(
      new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]),
      3
    )
  );
  const _ = new _n(p, d), g = this;
  this.enabled = !1, this.autoUpdate = !0, this.needsUpdate = !1, this.type = Ro;
  let m = this.type;
  this.render = function(S, E, v) {
    if (g.enabled === !1 || g.autoUpdate === !1 && g.needsUpdate === !1 || S.length === 0)
      return;
    this.type === zv && (oe("WebGLShadowMap: PCFSoftShadowMap has been deprecated. Using PCFShadowMap instead."), this.type = Ro);
    const M = i.getRenderTarget(), F = i.getActiveCubeFace(), R = i.getActiveMipmapLevel(), I = i.state;
    I.setBlending(Nn), I.buffers.depth.getReversed() === !0 ? I.buffers.color.setClear(0, 0, 0, 0) : I.buffers.color.setClear(1, 1, 1, 1), I.buffers.depth.setTest(!0), I.setScissorTest(!1);
    const B = m !== this.type;
    B && E.traverse(function(N) {
      N.material && (Array.isArray(N.material) ? N.material.forEach((C) => C.needsUpdate = !0) : N.material.needsUpdate = !0);
    });
    for (let N = 0, C = S.length; N < C; N++) {
      const L = S[N], k = L.shadow;
      if (k === void 0) {
        oe("WebGLShadowMap:", L, "has no shadow.");
        continue;
      }
      if (k.autoUpdate === !1 && k.needsUpdate === !1)
        continue;
      r.copy(k.mapSize);
      const re = k.getFrameExtents();
      r.multiply(re), s.copy(k.mapSize), (r.x > u || r.y > u) && (r.x > u && (s.x = Math.floor(u / re.x), r.x = s.x * re.x, k.mapSize.x = s.x), r.y > u && (s.y = Math.floor(u / re.y), r.y = s.y * re.y, k.mapSize.y = s.y));
      const se = i.state.buffers.depth.getReversed();
      if (k.camera._reversedDepth = se, k.map === null || B === !0) {
        if (k.map !== null && (k.map.depthTexture !== null && (k.map.depthTexture.dispose(), k.map.depthTexture = null), k.map.dispose()), this.type === br) {
          if (L.isPointLight) {
            oe("WebGLShadowMap: VSM shadow maps are not supported for PointLights. Use PCF or BasicShadowMap instead.");
            continue;
          }
          k.map = new tr(r.x, r.y, {
            format: ri,
            type: nn,
            minFilter: Ot,
            magFilter: Ot,
            generateMipmaps: !1
          }), k.map.texture.name = L.name + ".shadowMap", k.map.depthTexture = new oi(r.x, r.y, ln), k.map.depthTexture.name = L.name + ".shadowMapDepth", k.map.depthTexture.format = Un, k.map.depthTexture.compareFunction = null, k.map.depthTexture.minFilter = Tt, k.map.depthTexture.magFilter = Tt;
        } else
          L.isPointLight ? (k.map = new xy(r.x), k.map.depthTexture = new iy(r.x, Dt)) : (k.map = new tr(r.x, r.y), k.map.depthTexture = new oi(r.x, r.y, Dt)), k.map.depthTexture.name = L.name + ".shadowMap", k.map.depthTexture.format = Un, this.type === Ro ? (k.map.depthTexture.compareFunction = se ? us : Xs, k.map.depthTexture.minFilter = Ot, k.map.depthTexture.magFilter = Ot) : (k.map.depthTexture.compareFunction = null, k.map.depthTexture.minFilter = Tt, k.map.depthTexture.magFilter = Tt);
        k.camera.updateProjectionMatrix();
      }
      const ve = k.map.isWebGLCubeRenderTarget ? 6 : 1;
      for (let X = 0; X < ve; X++) {
        if (k.map.isWebGLCubeRenderTarget)
          i.setRenderTarget(k.map, X), i.clear();
        else {
          X === 0 && (i.setRenderTarget(k.map), i.clear());
          const te = k.getViewport(X);
          a.set(
            s.x * te.x,
            s.y * te.y,
            s.x * te.z,
            s.y * te.w
          ), I.viewport(a);
        }
        if (L.isPointLight) {
          const te = k.camera, me = k.matrix, Qe = L.distance || te.far;
          Qe !== te.far && (te.far = Qe, te.updateProjectionMatrix()), Gl.setFromMatrixPosition(L.matrixWorld), te.position.copy(Gl), xf.copy(te.position), xf.add(k1[X]), te.up.copy(G1[X]), te.lookAt(xf), te.updateMatrixWorld(), me.makeTranslation(-Gl.x, -Gl.y, -Gl.z), r0.multiplyMatrices(te.projectionMatrix, te.matrixWorldInverse), k._frustum.setFromProjectionMatrix(r0, te.coordinateSystem, te.reversedDepth);
        } else
          k.updateMatrices(L);
        n = k.getFrustum(), b(E, v, k.camera, L, this.type);
      }
      k.isPointLightShadow !== !0 && this.type === br && x(k, v), k.needsUpdate = !1;
    }
    m = this.type, g.needsUpdate = !1, i.setRenderTarget(M, F, R);
  };
  function x(S, E) {
    const v = e.update(_);
    d.defines.VSM_SAMPLES !== S.blurSamples && (d.defines.VSM_SAMPLES = S.blurSamples, f.defines.VSM_SAMPLES = S.blurSamples, d.needsUpdate = !0, f.needsUpdate = !0), S.mapPass === null && (S.mapPass = new tr(r.x, r.y, {
      format: ri,
      type: nn
    })), d.uniforms.shadow_pass.value = S.map.depthTexture, d.uniforms.resolution.value = S.mapSize, d.uniforms.radius.value = S.radius, i.setRenderTarget(S.mapPass), i.clear(), i.renderBufferDirect(E, null, v, d, _, null), f.uniforms.shadow_pass.value = S.mapPass.texture, f.uniforms.resolution.value = S.mapSize, f.uniforms.radius.value = S.radius, i.setRenderTarget(S.map), i.clear(), i.renderBufferDirect(E, null, v, f, _, null);
  }
  function y(S, E, v, M) {
    let F = null;
    const R = v.isPointLight === !0 ? S.customDistanceMaterial : S.customDepthMaterial;
    if (R !== void 0)
      F = R;
    else if (F = v.isPointLight === !0 ? l : o, i.localClippingEnabled && E.clipShadows === !0 && Array.isArray(E.clippingPlanes) && E.clippingPlanes.length !== 0 || E.displacementMap && E.displacementScale !== 0 || E.alphaMap && E.alphaTest > 0 || E.map && E.alphaTest > 0 || E.alphaToCoverage === !0) {
      const I = F.uuid, B = E.uuid;
      let N = c[I];
      N === void 0 && (N = {}, c[I] = N);
      let C = N[B];
      C === void 0 && (C = F.clone(), N[B] = C, E.addEventListener("dispose", T)), F = C;
    }
    if (F.visible = E.visible, F.wireframe = E.wireframe, M === br ? F.side = E.shadowSide !== null ? E.shadowSide : E.side : F.side = E.shadowSide !== null ? E.shadowSide : h[E.side], F.alphaMap = E.alphaMap, F.alphaTest = E.alphaToCoverage === !0 ? 0.5 : E.alphaTest, F.map = E.map, F.clipShadows = E.clipShadows, F.clippingPlanes = E.clippingPlanes, F.clipIntersection = E.clipIntersection, F.displacementMap = E.displacementMap, F.displacementScale = E.displacementScale, F.displacementBias = E.displacementBias, F.wireframeLinewidth = E.wireframeLinewidth, F.linewidth = E.linewidth, v.isPointLight === !0 && F.isMeshDistanceMaterial === !0) {
      const I = i.properties.get(F);
      I.light = v;
    }
    return F;
  }
  function b(S, E, v, M, F) {
    if (S.visible === !1)
      return;
    if (S.layers.test(E.layers) && (S.isMesh || S.isLine || S.isPoints) && (S.castShadow || S.receiveShadow && F === br) && (!S.frustumCulled || n.intersectsObject(S))) {
      S.modelViewMatrix.multiplyMatrices(v.matrixWorldInverse, S.matrixWorld);
      const B = e.update(S), N = S.material;
      if (Array.isArray(N)) {
        const C = B.groups;
        for (let L = 0, k = C.length; L < k; L++) {
          const re = C[L], se = N[re.materialIndex];
          if (se && se.visible) {
            const ve = y(S, se, M, F);
            S.onBeforeShadow(i, S, E, v, B, ve, re), i.renderBufferDirect(v, null, B, ve, S, re), S.onAfterShadow(i, S, E, v, B, ve, re);
          }
        }
      } else if (N.visible) {
        const C = y(S, N, M, F);
        S.onBeforeShadow(i, S, E, v, B, C, null), i.renderBufferDirect(v, null, B, C, S, null), S.onAfterShadow(i, S, E, v, B, C, null);
      }
    }
    const I = S.children;
    for (let B = 0, N = I.length; B < N; B++)
      b(I[B], E, v, M, F);
  }
  function T(S) {
    S.target.removeEventListener("dispose", T);
    for (const v in c) {
      const M = c[v], F = S.target.uuid;
      F in M && (M[F].dispose(), delete M[F]);
    }
  }
}
function z1(i, e) {
  function t() {
    let G = !1;
    const be = new rt();
    let _e = null;
    const De = new rt(0, 0, 0, 0);
    return {
      setMask: function(pe) {
        _e !== pe && !G && (i.colorMask(pe, pe, pe, pe), _e = pe);
      },
      setLocked: function(pe) {
        G = pe;
      },
      setClear: function(pe, ne, Oe, st, jt) {
        jt === !0 && (pe *= st, ne *= st, Oe *= st), be.set(pe, ne, Oe, st), De.equals(be) === !1 && (i.clearColor(pe, ne, Oe, st), De.copy(be));
      },
      reset: function() {
        G = !1, _e = null, De.set(-1, 0, 0, 0);
      }
    };
  }
  function n() {
    let G = !1, be = !1, _e = null, De = null, pe = null;
    return {
      setReversed: function(ne) {
        if (be !== ne) {
          const Oe = e.get("EXT_clip_control");
          ne ? Oe.clipControlEXT(Oe.LOWER_LEFT_EXT, Oe.ZERO_TO_ONE_EXT) : Oe.clipControlEXT(Oe.LOWER_LEFT_EXT, Oe.NEGATIVE_ONE_TO_ONE_EXT), be = ne;
          const st = pe;
          pe = null, this.setClear(st);
        }
      },
      getReversed: function() {
        return be;
      },
      setTest: function(ne) {
        ne ? Z(i.DEPTH_TEST) : ue(i.DEPTH_TEST);
      },
      setMask: function(ne) {
        _e !== ne && !G && (i.depthMask(ne), _e = ne);
      },
      setFunc: function(ne) {
        if (be && (ne = zm[ne]), De !== ne) {
          switch (ne) {
            case Nc:
              i.depthFunc(i.NEVER);
              break;
            case Pc:
              i.depthFunc(i.ALWAYS);
              break;
            case Dc:
              i.depthFunc(i.LESS);
              break;
            case Hs:
              i.depthFunc(i.LEQUAL);
              break;
            case Lc:
              i.depthFunc(i.EQUAL);
              break;
            case Fc:
              i.depthFunc(i.GEQUAL);
              break;
            case Ic:
              i.depthFunc(i.GREATER);
              break;
            case Uc:
              i.depthFunc(i.NOTEQUAL);
              break;
            default:
              i.depthFunc(i.LEQUAL);
          }
          De = ne;
        }
      },
      setLocked: function(ne) {
        G = ne;
      },
      setClear: function(ne) {
        pe !== ne && (pe = ne, be && (ne = 1 - ne), i.clearDepth(ne));
      },
      reset: function() {
        G = !1, _e = null, De = null, pe = null, be = !1;
      }
    };
  }
  function r() {
    let G = !1, be = null, _e = null, De = null, pe = null, ne = null, Oe = null, st = null, jt = null;
    return {
      setTest: function(Ut) {
        G || (Ut ? Z(i.STENCIL_TEST) : ue(i.STENCIL_TEST));
      },
      setMask: function(Ut) {
        be !== Ut && !G && (i.stencilMask(Ut), be = Ut);
      },
      setFunc: function(Ut, Br, Or) {
        (_e !== Ut || De !== Br || pe !== Or) && (i.stencilFunc(Ut, Br, Or), _e = Ut, De = Br, pe = Or);
      },
      setOp: function(Ut, Br, Or) {
        (ne !== Ut || Oe !== Br || st !== Or) && (i.stencilOp(Ut, Br, Or), ne = Ut, Oe = Br, st = Or);
      },
      setLocked: function(Ut) {
        G = Ut;
      },
      setClear: function(Ut) {
        jt !== Ut && (i.clearStencil(Ut), jt = Ut);
      },
      reset: function() {
        G = !1, be = null, _e = null, De = null, pe = null, ne = null, Oe = null, st = null, jt = null;
      }
    };
  }
  const s = new t(), a = new n(), o = new r(), l = /* @__PURE__ */ new WeakMap(), c = /* @__PURE__ */ new WeakMap();
  let u = {}, h = {}, d = /* @__PURE__ */ new WeakMap(), f = [], p = null, _ = !1, g = null, m = null, x = null, y = null, b = null, T = null, S = null, E = new He(0, 0, 0), v = 0, M = !1, F = null, R = null, I = null, B = null, N = null;
  const C = i.getParameter(i.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
  let L = !1, k = 0;
  const re = i.getParameter(i.VERSION);
  re.indexOf("WebGL") !== -1 ? (k = parseFloat(/^WebGL (\d)/.exec(re)[1]), L = k >= 1) : re.indexOf("OpenGL ES") !== -1 && (k = parseFloat(/^OpenGL ES (\d)/.exec(re)[1]), L = k >= 2);
  let se = null, ve = {};
  const X = i.getParameter(i.SCISSOR_BOX), te = i.getParameter(i.VIEWPORT), me = new rt().fromArray(X), Qe = new rt().fromArray(te);
  function ce(G, be, _e, De) {
    const pe = new Uint8Array(4), ne = i.createTexture();
    i.bindTexture(G, ne), i.texParameteri(G, i.TEXTURE_MIN_FILTER, i.NEAREST), i.texParameteri(G, i.TEXTURE_MAG_FILTER, i.NEAREST);
    for (let Oe = 0; Oe < _e; Oe++)
      G === i.TEXTURE_3D || G === i.TEXTURE_2D_ARRAY ? i.texImage3D(be, 0, i.RGBA, 1, 1, De, 0, i.RGBA, i.UNSIGNED_BYTE, pe) : i.texImage2D(be + Oe, 0, i.RGBA, 1, 1, 0, i.RGBA, i.UNSIGNED_BYTE, pe);
    return ne;
  }
  const z = {};
  z[i.TEXTURE_2D] = ce(i.TEXTURE_2D, i.TEXTURE_2D, 1), z[i.TEXTURE_CUBE_MAP] = ce(i.TEXTURE_CUBE_MAP, i.TEXTURE_CUBE_MAP_POSITIVE_X, 6), z[i.TEXTURE_2D_ARRAY] = ce(i.TEXTURE_2D_ARRAY, i.TEXTURE_2D_ARRAY, 1, 1), z[i.TEXTURE_3D] = ce(i.TEXTURE_3D, i.TEXTURE_3D, 1, 1), s.setClear(0, 0, 0, 1), a.setClear(1), o.setClear(0), Z(i.DEPTH_TEST), a.setFunc(Hs), tt(!1), Rt(Mp), Z(i.CULL_FACE), mt(Nn);
  function Z(G) {
    u[G] !== !0 && (i.enable(G), u[G] = !0);
  }
  function ue(G) {
    u[G] !== !1 && (i.disable(G), u[G] = !1);
  }
  function Ie(G, be) {
    return h[G] !== be ? (i.bindFramebuffer(G, be), h[G] = be, G === i.DRAW_FRAMEBUFFER && (h[i.FRAMEBUFFER] = be), G === i.FRAMEBUFFER && (h[i.DRAW_FRAMEBUFFER] = be), !0) : !1;
  }
  function we(G, be) {
    let _e = f, De = !1;
    if (G) {
      _e = d.get(be), _e === void 0 && (_e = [], d.set(be, _e));
      const pe = G.textures;
      if (_e.length !== pe.length || _e[0] !== i.COLOR_ATTACHMENT0) {
        for (let ne = 0, Oe = pe.length; ne < Oe; ne++)
          _e[ne] = i.COLOR_ATTACHMENT0 + ne;
        _e.length = pe.length, De = !0;
      }
    } else
      _e[0] !== i.BACK && (_e[0] = i.BACK, De = !0);
    De && i.drawBuffers(_e);
  }
  function Re(G) {
    return p !== G ? (i.useProgram(G), p = G, !0) : !1;
  }
  const It = {
    [Xn]: i.FUNC_ADD,
    [vm]: i.FUNC_SUBTRACT,
    [ym]: i.FUNC_REVERSE_SUBTRACT
  };
  It[$v] = i.MIN, It[Wv] = i.MAX;
  const ut = {
    [jr]: i.ZERO,
    [bm]: i.ONE,
    [Sm]: i.SRC_COLOR,
    [Rc]: i.SRC_ALPHA,
    [Rm]: i.SRC_ALPHA_SATURATE,
    [wm]: i.DST_COLOR,
    [Mm]: i.DST_ALPHA,
    [Tm]: i.ONE_MINUS_SRC_COLOR,
    [Cc]: i.ONE_MINUS_SRC_ALPHA,
    [Am]: i.ONE_MINUS_DST_COLOR,
    [Em]: i.ONE_MINUS_DST_ALPHA,
    [oM]: i.CONSTANT_COLOR,
    [lM]: i.ONE_MINUS_CONSTANT_COLOR,
    [cM]: i.CONSTANT_ALPHA,
    [uM]: i.ONE_MINUS_CONSTANT_ALPHA
  };
  function mt(G, be, _e, De, pe, ne, Oe, st, jt, Ut) {
    if (G === Nn) {
      _ === !0 && (ue(i.BLEND), _ = !1);
      return;
    }
    if (_ === !1 && (Z(i.BLEND), _ = !0), G !== ya) {
      if (G !== g || Ut !== M) {
        if ((m !== Xn || b !== Xn) && (i.blendEquation(i.FUNC_ADD), m = Xn, b = Xn), Ut)
          switch (G) {
            case ei:
              i.blendFuncSeparate(i.ONE, i.ONE_MINUS_SRC_ALPHA, i.ONE, i.ONE_MINUS_SRC_ALPHA);
              break;
            case Ns:
              i.blendFunc(i.ONE, i.ONE);
              break;
            case Ps:
              i.blendFuncSeparate(i.ZERO, i.ONE_MINUS_SRC_COLOR, i.ZERO, i.ONE);
              break;
            case Ds:
              i.blendFuncSeparate(i.DST_COLOR, i.ONE_MINUS_SRC_ALPHA, i.ZERO, i.ONE);
              break;
            default:
              le("WebGLState: Invalid blending: ", G);
              break;
          }
        else
          switch (G) {
            case ei:
              i.blendFuncSeparate(i.SRC_ALPHA, i.ONE_MINUS_SRC_ALPHA, i.ONE, i.ONE_MINUS_SRC_ALPHA);
              break;
            case Ns:
              i.blendFuncSeparate(i.SRC_ALPHA, i.ONE, i.ONE, i.ONE);
              break;
            case Ps:
              le("WebGLState: SubtractiveBlending requires material.premultipliedAlpha = true");
              break;
            case Ds:
              le("WebGLState: MultiplyBlending requires material.premultipliedAlpha = true");
              break;
            default:
              le("WebGLState: Invalid blending: ", G);
              break;
          }
        x = null, y = null, T = null, S = null, E.set(0, 0, 0), v = 0, g = G, M = Ut;
      }
      return;
    }
    pe = pe || be, ne = ne || _e, Oe = Oe || De, (be !== m || pe !== b) && (i.blendEquationSeparate(It[be], It[pe]), m = be, b = pe), (_e !== x || De !== y || ne !== T || Oe !== S) && (i.blendFuncSeparate(ut[_e], ut[De], ut[ne], ut[Oe]), x = _e, y = De, T = ne, S = Oe), (st.equals(E) === !1 || jt !== v) && (i.blendColor(st.r, st.g, st.b, jt), E.copy(st), v = jt), g = G, M = !1;
  }
  function bt(G, be) {
    G.side === Rn ? ue(i.CULL_FACE) : Z(i.CULL_FACE);
    let _e = G.side === Ft;
    be && (_e = !_e), tt(_e), G.blending === ei && G.transparent === !1 ? mt(Nn) : mt(G.blending, G.blendEquation, G.blendSrc, G.blendDst, G.blendEquationAlpha, G.blendSrcAlpha, G.blendDstAlpha, G.blendColor, G.blendAlpha, G.premultipliedAlpha), a.setFunc(G.depthFunc), a.setTest(G.depthTest), a.setMask(G.depthWrite), s.setMask(G.colorWrite);
    const De = G.stencilWrite;
    o.setTest(De), De && (o.setMask(G.stencilWriteMask), o.setFunc(G.stencilFunc, G.stencilRef, G.stencilFuncMask), o.setOp(G.stencilFail, G.stencilZFail, G.stencilZPass)), fn(G.polygonOffset, G.polygonOffsetFactor, G.polygonOffsetUnits), G.alphaToCoverage === !0 ? Z(i.SAMPLE_ALPHA_TO_COVERAGE) : ue(i.SAMPLE_ALPHA_TO_COVERAGE);
  }
  function tt(G) {
    F !== G && (G ? i.frontFace(i.CW) : i.frontFace(i.CCW), F = G);
  }
  function Rt(G) {
    G !== Gv ? (Z(i.CULL_FACE), G !== R && (G === Mp ? i.cullFace(i.BACK) : G === Vv ? i.cullFace(i.FRONT) : i.cullFace(i.FRONT_AND_BACK))) : ue(i.CULL_FACE), R = G;
  }
  function O(G) {
    G !== I && (L && i.lineWidth(G), I = G);
  }
  function fn(G, be, _e) {
    G ? (Z(i.POLYGON_OFFSET_FILL), (B !== be || N !== _e) && (B = be, N = _e, a.getReversed() && (be = -be), i.polygonOffset(be, _e))) : ue(i.POLYGON_OFFSET_FILL);
  }
  function Ct(G) {
    G ? Z(i.SCISSOR_TEST) : ue(i.SCISSOR_TEST);
  }
  function Xt(G) {
    G === void 0 && (G = i.TEXTURE0 + C - 1), se !== G && (i.activeTexture(G), se = G);
  }
  function Ve(G, be, _e) {
    _e === void 0 && (se === null ? _e = i.TEXTURE0 + C - 1 : _e = se);
    let De = ve[_e];
    De === void 0 && (De = { type: void 0, texture: void 0 }, ve[_e] = De), (De.type !== G || De.texture !== be) && (se !== _e && (i.activeTexture(_e), se = _e), i.bindTexture(G, be || z[G]), De.type = G, De.texture = be);
  }
  function D() {
    const G = ve[se];
    G !== void 0 && G.type !== void 0 && (i.bindTexture(G.type, null), G.type = void 0, G.texture = void 0);
  }
  function w() {
    try {
      i.compressedTexImage2D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function V() {
    try {
      i.compressedTexImage3D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function ae() {
    try {
      i.texSubImage2D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function he() {
    try {
      i.texSubImage3D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function ie() {
    try {
      i.compressedTexSubImage2D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function Ue() {
    try {
      i.compressedTexSubImage3D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function ye() {
    try {
      i.texStorage2D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function Ye() {
    try {
      i.texStorage3D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function Je() {
    try {
      i.texImage2D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function fe() {
    try {
      i.texImage3D(...arguments);
    } catch (G) {
      le("WebGLState:", G);
    }
  }
  function ge(G) {
    me.equals(G) === !1 && (i.scissor(G.x, G.y, G.z, G.w), me.copy(G));
  }
  function Be(G) {
    Qe.equals(G) === !1 && (i.viewport(G.x, G.y, G.z, G.w), Qe.copy(G));
  }
  function ke(G, be) {
    let _e = c.get(be);
    _e === void 0 && (_e = /* @__PURE__ */ new WeakMap(), c.set(be, _e));
    let De = _e.get(G);
    De === void 0 && (De = i.getUniformBlockIndex(be, G.name), _e.set(G, De));
  }
  function Ce(G, be) {
    const De = c.get(be).get(G);
    l.get(be) !== De && (i.uniformBlockBinding(be, De, G.__bindingPointIndex), l.set(be, De));
  }
  function dt() {
    i.disable(i.BLEND), i.disable(i.CULL_FACE), i.disable(i.DEPTH_TEST), i.disable(i.POLYGON_OFFSET_FILL), i.disable(i.SCISSOR_TEST), i.disable(i.STENCIL_TEST), i.disable(i.SAMPLE_ALPHA_TO_COVERAGE), i.blendEquation(i.FUNC_ADD), i.blendFunc(i.ONE, i.ZERO), i.blendFuncSeparate(i.ONE, i.ZERO, i.ONE, i.ZERO), i.blendColor(0, 0, 0, 0), i.colorMask(!0, !0, !0, !0), i.clearColor(0, 0, 0, 0), i.depthMask(!0), i.depthFunc(i.LESS), a.setReversed(!1), i.clearDepth(1), i.stencilMask(4294967295), i.stencilFunc(i.ALWAYS, 0, 4294967295), i.stencilOp(i.KEEP, i.KEEP, i.KEEP), i.clearStencil(0), i.cullFace(i.BACK), i.frontFace(i.CCW), i.polygonOffset(0, 0), i.activeTexture(i.TEXTURE0), i.bindFramebuffer(i.FRAMEBUFFER, null), i.bindFramebuffer(i.DRAW_FRAMEBUFFER, null), i.bindFramebuffer(i.READ_FRAMEBUFFER, null), i.useProgram(null), i.lineWidth(1), i.scissor(0, 0, i.canvas.width, i.canvas.height), i.viewport(0, 0, i.canvas.width, i.canvas.height), u = {}, se = null, ve = {}, h = {}, d = /* @__PURE__ */ new WeakMap(), f = [], p = null, _ = !1, g = null, m = null, x = null, y = null, b = null, T = null, S = null, E = new He(0, 0, 0), v = 0, M = !1, F = null, R = null, I = null, B = null, N = null, me.set(0, 0, i.canvas.width, i.canvas.height), Qe.set(0, 0, i.canvas.width, i.canvas.height), s.reset(), a.reset(), o.reset();
  }
  return {
    buffers: {
      color: s,
      depth: a,
      stencil: o
    },
    enable: Z,
    disable: ue,
    bindFramebuffer: Ie,
    drawBuffers: we,
    useProgram: Re,
    setBlending: mt,
    setMaterial: bt,
    setFlipSided: tt,
    setCullFace: Rt,
    setLineWidth: O,
    setPolygonOffset: fn,
    setScissorTest: Ct,
    activeTexture: Xt,
    bindTexture: Ve,
    unbindTexture: D,
    compressedTexImage2D: w,
    compressedTexImage3D: V,
    texImage2D: Je,
    texImage3D: fe,
    updateUBOMapping: ke,
    uniformBlockBinding: Ce,
    texStorage2D: ye,
    texStorage3D: Ye,
    texSubImage2D: ae,
    texSubImage3D: he,
    compressedTexSubImage2D: ie,
    compressedTexSubImage3D: Ue,
    scissor: ge,
    viewport: Be,
    reset: dt
  };
}
function H1(i, e, t, n, r, s, a) {
  const o = e.has("WEBGL_multisampled_render_to_texture") ? e.get("WEBGL_multisampled_render_to_texture") : null, l = typeof navigator > "u" ? !1 : /OculusBrowser/g.test(navigator.userAgent), c = new de(), u = /* @__PURE__ */ new WeakMap();
  let h;
  const d = /* @__PURE__ */ new WeakMap();
  let f = !1;
  try {
    f = typeof OffscreenCanvas < "u" && new OffscreenCanvas(1, 1).getContext("2d") !== null;
  } catch {
  }
  function p(D, w) {
    return f ? new OffscreenCanvas(D, w) : zc("canvas");
  }
  function _(D, w, V) {
    let ae = 1;
    const he = Ve(D);
    if ((he.width > V || he.height > V) && (ae = V / Math.max(he.width, he.height)), ae < 1)
      if (typeof HTMLImageElement < "u" && D instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && D instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && D instanceof ImageBitmap || typeof VideoFrame < "u" && D instanceof VideoFrame) {
        const ie = Math.floor(ae * he.width), Ue = Math.floor(ae * he.height);
        h === void 0 && (h = p(ie, Ue));
        const ye = w ? p(ie, Ue) : h;
        return ye.width = ie, ye.height = Ue, ye.getContext("2d").drawImage(D, 0, 0, ie, Ue), oe("WebGLRenderer: Texture has been resized from (" + he.width + "x" + he.height + ") to (" + ie + "x" + Ue + ")."), ye;
      } else
        return "data" in D && oe("WebGLRenderer: Image in DataTexture is too big (" + he.width + "x" + he.height + ")."), D;
    return D;
  }
  function g(D) {
    return D.generateMipmaps;
  }
  function m(D) {
    i.generateMipmap(D);
  }
  function x(D) {
    return D.isWebGLCubeRenderTarget ? i.TEXTURE_CUBE_MAP : D.isWebGL3DRenderTarget ? i.TEXTURE_3D : D.isWebGLArrayRenderTarget || D.isCompressedArrayTexture ? i.TEXTURE_2D_ARRAY : i.TEXTURE_2D;
  }
  function y(D, w, V, ae, he = !1) {
    if (D !== null) {
      if (i[D] !== void 0)
        return i[D];
      oe("WebGLRenderer: Attempt to use non-existing WebGL internal format '" + D + "'");
    }
    let ie = w;
    if (w === i.RED && (V === i.FLOAT && (ie = i.R32F), V === i.HALF_FLOAT && (ie = i.R16F), V === i.UNSIGNED_BYTE && (ie = i.R8)), w === i.RED_INTEGER && (V === i.UNSIGNED_BYTE && (ie = i.R8UI), V === i.UNSIGNED_SHORT && (ie = i.R16UI), V === i.UNSIGNED_INT && (ie = i.R32UI), V === i.BYTE && (ie = i.R8I), V === i.SHORT && (ie = i.R16I), V === i.INT && (ie = i.R32I)), w === i.RG && (V === i.FLOAT && (ie = i.RG32F), V === i.HALF_FLOAT && (ie = i.RG16F), V === i.UNSIGNED_BYTE && (ie = i.RG8)), w === i.RG_INTEGER && (V === i.UNSIGNED_BYTE && (ie = i.RG8UI), V === i.UNSIGNED_SHORT && (ie = i.RG16UI), V === i.UNSIGNED_INT && (ie = i.RG32UI), V === i.BYTE && (ie = i.RG8I), V === i.SHORT && (ie = i.RG16I), V === i.INT && (ie = i.RG32I)), w === i.RGB_INTEGER && (V === i.UNSIGNED_BYTE && (ie = i.RGB8UI), V === i.UNSIGNED_SHORT && (ie = i.RGB16UI), V === i.UNSIGNED_INT && (ie = i.RGB32UI), V === i.BYTE && (ie = i.RGB8I), V === i.SHORT && (ie = i.RGB16I), V === i.INT && (ie = i.RGB32I)), w === i.RGBA_INTEGER && (V === i.UNSIGNED_BYTE && (ie = i.RGBA8UI), V === i.UNSIGNED_SHORT && (ie = i.RGBA16UI), V === i.UNSIGNED_INT && (ie = i.RGBA32UI), V === i.BYTE && (ie = i.RGBA8I), V === i.SHORT && (ie = i.RGBA16I), V === i.INT && (ie = i.RGBA32I)), w === i.RGB && (V === i.UNSIGNED_INT_5_9_9_9_REV && (ie = i.RGB9_E5), V === i.UNSIGNED_INT_10F_11F_11F_REV && (ie = i.R11F_G11F_B10F)), w === i.RGBA) {
      const Ue = he ? ll : Ke.getTransfer(ae);
      V === i.FLOAT && (ie = i.RGBA32F), V === i.HALF_FLOAT && (ie = i.RGBA16F), V === i.UNSIGNED_BYTE && (ie = Ue === Te ? i.SRGB8_ALPHA8 : i.RGBA8), V === i.UNSIGNED_SHORT_4_4_4_4 && (ie = i.RGBA4), V === i.UNSIGNED_SHORT_5_5_5_1 && (ie = i.RGB5_A1);
    }
    return (ie === i.R16F || ie === i.R32F || ie === i.RG16F || ie === i.RG32F || ie === i.RGBA16F || ie === i.RGBA32F) && e.get("EXT_color_buffer_float"), ie;
  }
  function b(D, w) {
    let V;
    return D ? w === null || w === Dt || w === Ci ? V = i.DEPTH24_STENCIL8 : w === ln ? V = i.DEPTH32F_STENCIL8 : w === Ji && (V = i.DEPTH24_STENCIL8, oe("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")) : w === null || w === Dt || w === Ci ? V = i.DEPTH_COMPONENT24 : w === ln ? V = i.DEPTH_COMPONENT32F : w === Ji && (V = i.DEPTH_COMPONENT16), V;
  }
  function T(D, w) {
    return g(D) === !0 || D.isFramebufferTexture && D.minFilter !== Tt && D.minFilter !== Ot ? Math.log2(Math.max(w.width, w.height)) + 1 : D.mipmaps !== void 0 && D.mipmaps.length > 0 ? D.mipmaps.length : D.isCompressedTexture && Array.isArray(D.image) ? w.mipmaps.length : 1;
  }
  function S(D) {
    const w = D.target;
    w.removeEventListener("dispose", S), v(w), w.isVideoTexture && u.delete(w);
  }
  function E(D) {
    const w = D.target;
    w.removeEventListener("dispose", E), F(w);
  }
  function v(D) {
    const w = n.get(D);
    if (w.__webglInit === void 0)
      return;
    const V = D.source, ae = d.get(V);
    if (ae) {
      const he = ae[w.__cacheKey];
      he.usedTimes--, he.usedTimes === 0 && M(D), Object.keys(ae).length === 0 && d.delete(V);
    }
    n.remove(D);
  }
  function M(D) {
    const w = n.get(D);
    i.deleteTexture(w.__webglTexture);
    const V = D.source, ae = d.get(V);
    delete ae[w.__cacheKey], a.memory.textures--;
  }
  function F(D) {
    const w = n.get(D);
    if (D.depthTexture && (D.depthTexture.dispose(), n.remove(D.depthTexture)), D.isWebGLCubeRenderTarget)
      for (let ae = 0; ae < 6; ae++) {
        if (Array.isArray(w.__webglFramebuffer[ae]))
          for (let he = 0; he < w.__webglFramebuffer[ae].length; he++)
            i.deleteFramebuffer(w.__webglFramebuffer[ae][he]);
        else
          i.deleteFramebuffer(w.__webglFramebuffer[ae]);
        w.__webglDepthbuffer && i.deleteRenderbuffer(w.__webglDepthbuffer[ae]);
      }
    else {
      if (Array.isArray(w.__webglFramebuffer))
        for (let ae = 0; ae < w.__webglFramebuffer.length; ae++)
          i.deleteFramebuffer(w.__webglFramebuffer[ae]);
      else
        i.deleteFramebuffer(w.__webglFramebuffer);
      if (w.__webglDepthbuffer && i.deleteRenderbuffer(w.__webglDepthbuffer), w.__webglMultisampledFramebuffer && i.deleteFramebuffer(w.__webglMultisampledFramebuffer), w.__webglColorRenderbuffer)
        for (let ae = 0; ae < w.__webglColorRenderbuffer.length; ae++)
          w.__webglColorRenderbuffer[ae] && i.deleteRenderbuffer(w.__webglColorRenderbuffer[ae]);
      w.__webglDepthRenderbuffer && i.deleteRenderbuffer(w.__webglDepthRenderbuffer);
    }
    const V = D.textures;
    for (let ae = 0, he = V.length; ae < he; ae++) {
      const ie = n.get(V[ae]);
      ie.__webglTexture && (i.deleteTexture(ie.__webglTexture), a.memory.textures--), n.remove(V[ae]);
    }
    n.remove(D);
  }
  let R = 0;
  function I() {
    R = 0;
  }
  function B() {
    const D = R;
    return D >= r.maxTextures && oe("WebGLTextures: Trying to use " + D + " texture units while this GPU supports only " + r.maxTextures), R += 1, D;
  }
  function N(D) {
    const w = [];
    return w.push(D.wrapS), w.push(D.wrapT), w.push(D.wrapR || 0), w.push(D.magFilter), w.push(D.minFilter), w.push(D.anisotropy), w.push(D.internalFormat), w.push(D.format), w.push(D.type), w.push(D.generateMipmaps), w.push(D.premultiplyAlpha), w.push(D.flipY), w.push(D.unpackAlignment), w.push(D.colorSpace), w.join();
  }
  function C(D, w) {
    const V = n.get(D);
    if (D.isVideoTexture && Ct(D), D.isRenderTargetTexture === !1 && D.isExternalTexture !== !0 && D.version > 0 && V.__version !== D.version) {
      const ae = D.image;
      if (ae === null)
        oe("WebGLRenderer: Texture marked for update but no image data found.");
      else if (ae.complete === !1)
        oe("WebGLRenderer: Texture marked for update but image is incomplete");
      else {
        z(V, D, w);
        return;
      }
    } else
      D.isExternalTexture && (V.__webglTexture = D.sourceTexture ? D.sourceTexture : null);
    t.bindTexture(i.TEXTURE_2D, V.__webglTexture, i.TEXTURE0 + w);
  }
  function L(D, w) {
    const V = n.get(D);
    if (D.isRenderTargetTexture === !1 && D.version > 0 && V.__version !== D.version) {
      z(V, D, w);
      return;
    } else
      D.isExternalTexture && (V.__webglTexture = D.sourceTexture ? D.sourceTexture : null);
    t.bindTexture(i.TEXTURE_2D_ARRAY, V.__webglTexture, i.TEXTURE0 + w);
  }
  function k(D, w) {
    const V = n.get(D);
    if (D.isRenderTargetTexture === !1 && D.version > 0 && V.__version !== D.version) {
      z(V, D, w);
      return;
    }
    t.bindTexture(i.TEXTURE_3D, V.__webglTexture, i.TEXTURE0 + w);
  }
  function re(D, w) {
    const V = n.get(D);
    if (D.isCubeDepthTexture !== !0 && D.version > 0 && V.__version !== D.version) {
      Z(V, D, w);
      return;
    }
    t.bindTexture(i.TEXTURE_CUBE_MAP, V.__webglTexture, i.TEXTURE0 + w);
  }
  const se = {
    [Ca]: i.REPEAT,
    [fi]: i.CLAMP_TO_EDGE,
    [Na]: i.MIRRORED_REPEAT
  }, ve = {
    [Tt]: i.NEAREST,
    [Um]: i.NEAREST_MIPMAP_NEAREST,
    [ts]: i.NEAREST_MIPMAP_LINEAR,
    [Ot]: i.LINEAR,
    [Po]: i.LINEAR_MIPMAP_NEAREST,
    [pi]: i.LINEAR_MIPMAP_LINEAR
  }, X = {
    [Om]: i.NEVER,
    [Vm]: i.ALWAYS,
    [ld]: i.LESS,
    [Xs]: i.LEQUAL,
    [km]: i.EQUAL,
    [us]: i.GEQUAL,
    [Vc]: i.GREATER,
    [Gm]: i.NOTEQUAL
  };
  function te(D, w) {
    if (w.type === ln && e.has("OES_texture_float_linear") === !1 && (w.magFilter === Ot || w.magFilter === Po || w.magFilter === ts || w.magFilter === pi || w.minFilter === Ot || w.minFilter === Po || w.minFilter === ts || w.minFilter === pi) && oe("WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."), i.texParameteri(D, i.TEXTURE_WRAP_S, se[w.wrapS]), i.texParameteri(D, i.TEXTURE_WRAP_T, se[w.wrapT]), (D === i.TEXTURE_3D || D === i.TEXTURE_2D_ARRAY) && i.texParameteri(D, i.TEXTURE_WRAP_R, se[w.wrapR]), i.texParameteri(D, i.TEXTURE_MAG_FILTER, ve[w.magFilter]), i.texParameteri(D, i.TEXTURE_MIN_FILTER, ve[w.minFilter]), w.compareFunction && (i.texParameteri(D, i.TEXTURE_COMPARE_MODE, i.COMPARE_REF_TO_TEXTURE), i.texParameteri(D, i.TEXTURE_COMPARE_FUNC, X[w.compareFunction])), e.has("EXT_texture_filter_anisotropic") === !0) {
      if (w.magFilter === Tt || w.minFilter !== ts && w.minFilter !== pi || w.type === ln && e.has("OES_texture_float_linear") === !1)
        return;
      if (w.anisotropy > 1 || n.get(w).__currentAnisotropy) {
        const V = e.get("EXT_texture_filter_anisotropic");
        i.texParameterf(D, V.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(w.anisotropy, r.getMaxAnisotropy())), n.get(w).__currentAnisotropy = w.anisotropy;
      }
    }
  }
  function me(D, w) {
    let V = !1;
    D.__webglInit === void 0 && (D.__webglInit = !0, w.addEventListener("dispose", S));
    const ae = w.source;
    let he = d.get(ae);
    he === void 0 && (he = {}, d.set(ae, he));
    const ie = N(w);
    if (ie !== D.__cacheKey) {
      he[ie] === void 0 && (he[ie] = {
        texture: i.createTexture(),
        usedTimes: 0
      }, a.memory.textures++, V = !0), he[ie].usedTimes++;
      const Ue = he[D.__cacheKey];
      Ue !== void 0 && (he[D.__cacheKey].usedTimes--, Ue.usedTimes === 0 && M(w)), D.__cacheKey = ie, D.__webglTexture = he[ie].texture;
    }
    return V;
  }
  function Qe(D, w, V) {
    return Math.floor(Math.floor(D / V) / w);
  }
  function ce(D, w, V, ae) {
    const ie = D.updateRanges;
    if (ie.length === 0)
      t.texSubImage2D(i.TEXTURE_2D, 0, 0, 0, w.width, w.height, V, ae, w.data);
    else {
      ie.sort((fe, ge) => fe.start - ge.start);
      let Ue = 0;
      for (let fe = 1; fe < ie.length; fe++) {
        const ge = ie[Ue], Be = ie[fe], ke = ge.start + ge.count, Ce = Qe(Be.start, w.width, 4), dt = Qe(ge.start, w.width, 4);
        Be.start <= ke + 1 && Ce === dt && Qe(Be.start + Be.count - 1, w.width, 4) === Ce ? ge.count = Math.max(
          ge.count,
          Be.start + Be.count - ge.start
        ) : (++Ue, ie[Ue] = Be);
      }
      ie.length = Ue + 1;
      const ye = i.getParameter(i.UNPACK_ROW_LENGTH), Ye = i.getParameter(i.UNPACK_SKIP_PIXELS), Je = i.getParameter(i.UNPACK_SKIP_ROWS);
      i.pixelStorei(i.UNPACK_ROW_LENGTH, w.width);
      for (let fe = 0, ge = ie.length; fe < ge; fe++) {
        const Be = ie[fe], ke = Math.floor(Be.start / 4), Ce = Math.ceil(Be.count / 4), dt = ke % w.width, G = Math.floor(ke / w.width), be = Ce, _e = 1;
        i.pixelStorei(i.UNPACK_SKIP_PIXELS, dt), i.pixelStorei(i.UNPACK_SKIP_ROWS, G), t.texSubImage2D(i.TEXTURE_2D, 0, dt, G, be, _e, V, ae, w.data);
      }
      D.clearUpdateRanges(), i.pixelStorei(i.UNPACK_ROW_LENGTH, ye), i.pixelStorei(i.UNPACK_SKIP_PIXELS, Ye), i.pixelStorei(i.UNPACK_SKIP_ROWS, Je);
    }
  }
  function z(D, w, V) {
    let ae = i.TEXTURE_2D;
    (w.isDataArrayTexture || w.isCompressedArrayTexture) && (ae = i.TEXTURE_2D_ARRAY), w.isData3DTexture && (ae = i.TEXTURE_3D);
    const he = me(D, w), ie = w.source;
    t.bindTexture(ae, D.__webglTexture, i.TEXTURE0 + V);
    const Ue = n.get(ie);
    if (ie.version !== Ue.__version || he === !0) {
      t.activeTexture(i.TEXTURE0 + V);
      const ye = Ke.getPrimaries(Ke.workingColorSpace), Ye = w.colorSpace === hi ? null : Ke.getPrimaries(w.colorSpace), Je = w.colorSpace === hi || ye === Ye ? i.NONE : i.BROWSER_DEFAULT_WEBGL;
      i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL, w.flipY), i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL, w.premultiplyAlpha), i.pixelStorei(i.UNPACK_ALIGNMENT, w.unpackAlignment), i.pixelStorei(i.UNPACK_COLORSPACE_CONVERSION_WEBGL, Je);
      let fe = _(w.image, !1, r.maxTextureSize);
      fe = Xt(w, fe);
      const ge = s.convert(w.format, w.colorSpace), Be = s.convert(w.type);
      let ke = y(w.internalFormat, ge, Be, w.colorSpace, w.isVideoTexture);
      te(ae, w);
      let Ce;
      const dt = w.mipmaps, G = w.isVideoTexture !== !0, be = Ue.__version === void 0 || he === !0, _e = ie.dataReady, De = T(w, fe);
      if (w.isDepthTexture)
        ke = b(w.format === ii, w.type), be && (G ? t.texStorage2D(i.TEXTURE_2D, 1, ke, fe.width, fe.height) : t.texImage2D(i.TEXTURE_2D, 0, ke, fe.width, fe.height, 0, ge, Be, null));
      else if (w.isDataTexture)
        if (dt.length > 0) {
          G && be && t.texStorage2D(i.TEXTURE_2D, De, ke, dt[0].width, dt[0].height);
          for (let pe = 0, ne = dt.length; pe < ne; pe++)
            Ce = dt[pe], G ? _e && t.texSubImage2D(i.TEXTURE_2D, pe, 0, 0, Ce.width, Ce.height, ge, Be, Ce.data) : t.texImage2D(i.TEXTURE_2D, pe, ke, Ce.width, Ce.height, 0, ge, Be, Ce.data);
          w.generateMipmaps = !1;
        } else
          G ? (be && t.texStorage2D(i.TEXTURE_2D, De, ke, fe.width, fe.height), _e && ce(w, fe, ge, Be)) : t.texImage2D(i.TEXTURE_2D, 0, ke, fe.width, fe.height, 0, ge, Be, fe.data);
      else if (w.isCompressedTexture)
        if (w.isCompressedArrayTexture) {
          G && be && t.texStorage3D(i.TEXTURE_2D_ARRAY, De, ke, dt[0].width, dt[0].height, fe.depth);
          for (let pe = 0, ne = dt.length; pe < ne; pe++)
            if (Ce = dt[pe], w.format !== cn)
              if (ge !== null)
                if (G) {
                  if (_e)
                    if (w.layerUpdates.size > 0) {
                      const Oe = Cp(Ce.width, Ce.height, w.format, w.type);
                      for (const st of w.layerUpdates) {
                        const jt = Ce.data.subarray(
                          st * Oe / Ce.data.BYTES_PER_ELEMENT,
                          (st + 1) * Oe / Ce.data.BYTES_PER_ELEMENT
                        );
                        t.compressedTexSubImage3D(i.TEXTURE_2D_ARRAY, pe, 0, 0, st, Ce.width, Ce.height, 1, ge, jt);
                      }
                      w.clearLayerUpdates();
                    } else
                      t.compressedTexSubImage3D(i.TEXTURE_2D_ARRAY, pe, 0, 0, 0, Ce.width, Ce.height, fe.depth, ge, Ce.data);
                } else
                  t.compressedTexImage3D(i.TEXTURE_2D_ARRAY, pe, ke, Ce.width, Ce.height, fe.depth, 0, Ce.data, 0, 0);
              else
                oe("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()");
            else
              G ? _e && t.texSubImage3D(i.TEXTURE_2D_ARRAY, pe, 0, 0, 0, Ce.width, Ce.height, fe.depth, ge, Be, Ce.data) : t.texImage3D(i.TEXTURE_2D_ARRAY, pe, ke, Ce.width, Ce.height, fe.depth, 0, ge, Be, Ce.data);
        } else {
          G && be && t.texStorage2D(i.TEXTURE_2D, De, ke, dt[0].width, dt[0].height);
          for (let pe = 0, ne = dt.length; pe < ne; pe++)
            Ce = dt[pe], w.format !== cn ? ge !== null ? G ? _e && t.compressedTexSubImage2D(i.TEXTURE_2D, pe, 0, 0, Ce.width, Ce.height, ge, Ce.data) : t.compressedTexImage2D(i.TEXTURE_2D, pe, ke, Ce.width, Ce.height, 0, Ce.data) : oe("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()") : G ? _e && t.texSubImage2D(i.TEXTURE_2D, pe, 0, 0, Ce.width, Ce.height, ge, Be, Ce.data) : t.texImage2D(i.TEXTURE_2D, pe, ke, Ce.width, Ce.height, 0, ge, Be, Ce.data);
        }
      else if (w.isDataArrayTexture)
        if (G) {
          if (be && t.texStorage3D(i.TEXTURE_2D_ARRAY, De, ke, fe.width, fe.height, fe.depth), _e)
            if (w.layerUpdates.size > 0) {
              const pe = Cp(fe.width, fe.height, w.format, w.type);
              for (const ne of w.layerUpdates) {
                const Oe = fe.data.subarray(
                  ne * pe / fe.data.BYTES_PER_ELEMENT,
                  (ne + 1) * pe / fe.data.BYTES_PER_ELEMENT
                );
                t.texSubImage3D(i.TEXTURE_2D_ARRAY, 0, 0, 0, ne, fe.width, fe.height, 1, ge, Be, Oe);
              }
              w.clearLayerUpdates();
            } else
              t.texSubImage3D(i.TEXTURE_2D_ARRAY, 0, 0, 0, 0, fe.width, fe.height, fe.depth, ge, Be, fe.data);
        } else
          t.texImage3D(i.TEXTURE_2D_ARRAY, 0, ke, fe.width, fe.height, fe.depth, 0, ge, Be, fe.data);
      else if (w.isData3DTexture)
        G ? (be && t.texStorage3D(i.TEXTURE_3D, De, ke, fe.width, fe.height, fe.depth), _e && t.texSubImage3D(i.TEXTURE_3D, 0, 0, 0, 0, fe.width, fe.height, fe.depth, ge, Be, fe.data)) : t.texImage3D(i.TEXTURE_3D, 0, ke, fe.width, fe.height, fe.depth, 0, ge, Be, fe.data);
      else if (w.isFramebufferTexture) {
        if (be)
          if (G)
            t.texStorage2D(i.TEXTURE_2D, De, ke, fe.width, fe.height);
          else {
            let pe = fe.width, ne = fe.height;
            for (let Oe = 0; Oe < De; Oe++)
              t.texImage2D(i.TEXTURE_2D, Oe, ke, pe, ne, 0, ge, Be, null), pe >>= 1, ne >>= 1;
          }
      } else if (dt.length > 0) {
        if (G && be) {
          const pe = Ve(dt[0]);
          t.texStorage2D(i.TEXTURE_2D, De, ke, pe.width, pe.height);
        }
        for (let pe = 0, ne = dt.length; pe < ne; pe++)
          Ce = dt[pe], G ? _e && t.texSubImage2D(i.TEXTURE_2D, pe, 0, 0, ge, Be, Ce) : t.texImage2D(i.TEXTURE_2D, pe, ke, ge, Be, Ce);
        w.generateMipmaps = !1;
      } else if (G) {
        if (be) {
          const pe = Ve(fe);
          t.texStorage2D(i.TEXTURE_2D, De, ke, pe.width, pe.height);
        }
        _e && t.texSubImage2D(i.TEXTURE_2D, 0, 0, 0, ge, Be, fe);
      } else
        t.texImage2D(i.TEXTURE_2D, 0, ke, ge, Be, fe);
      g(w) && m(ae), Ue.__version = ie.version, w.onUpdate && w.onUpdate(w);
    }
    D.__version = w.version;
  }
  function Z(D, w, V) {
    if (w.image.length !== 6)
      return;
    const ae = me(D, w), he = w.source;
    t.bindTexture(i.TEXTURE_CUBE_MAP, D.__webglTexture, i.TEXTURE0 + V);
    const ie = n.get(he);
    if (he.version !== ie.__version || ae === !0) {
      t.activeTexture(i.TEXTURE0 + V);
      const Ue = Ke.getPrimaries(Ke.workingColorSpace), ye = w.colorSpace === hi ? null : Ke.getPrimaries(w.colorSpace), Ye = w.colorSpace === hi || Ue === ye ? i.NONE : i.BROWSER_DEFAULT_WEBGL;
      i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL, w.flipY), i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL, w.premultiplyAlpha), i.pixelStorei(i.UNPACK_ALIGNMENT, w.unpackAlignment), i.pixelStorei(i.UNPACK_COLORSPACE_CONVERSION_WEBGL, Ye);
      const Je = w.isCompressedTexture || w.image[0].isCompressedTexture, fe = w.image[0] && w.image[0].isDataTexture, ge = [];
      for (let ne = 0; ne < 6; ne++)
        !Je && !fe ? ge[ne] = _(w.image[ne], !0, r.maxCubemapSize) : ge[ne] = fe ? w.image[ne].image : w.image[ne], ge[ne] = Xt(w, ge[ne]);
      const Be = ge[0], ke = s.convert(w.format, w.colorSpace), Ce = s.convert(w.type), dt = y(w.internalFormat, ke, Ce, w.colorSpace), G = w.isVideoTexture !== !0, be = ie.__version === void 0 || ae === !0, _e = he.dataReady;
      let De = T(w, Be);
      te(i.TEXTURE_CUBE_MAP, w);
      let pe;
      if (Je) {
        G && be && t.texStorage2D(i.TEXTURE_CUBE_MAP, De, dt, Be.width, Be.height);
        for (let ne = 0; ne < 6; ne++) {
          pe = ge[ne].mipmaps;
          for (let Oe = 0; Oe < pe.length; Oe++) {
            const st = pe[Oe];
            w.format !== cn ? ke !== null ? G ? _e && t.compressedTexSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe, 0, 0, st.width, st.height, ke, st.data) : t.compressedTexImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe, dt, st.width, st.height, 0, st.data) : oe("WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()") : G ? _e && t.texSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe, 0, 0, st.width, st.height, ke, Ce, st.data) : t.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe, dt, st.width, st.height, 0, ke, Ce, st.data);
          }
        }
      } else {
        if (pe = w.mipmaps, G && be) {
          pe.length > 0 && De++;
          const ne = Ve(ge[0]);
          t.texStorage2D(i.TEXTURE_CUBE_MAP, De, dt, ne.width, ne.height);
        }
        for (let ne = 0; ne < 6; ne++)
          if (fe) {
            G ? _e && t.texSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, 0, 0, 0, ge[ne].width, ge[ne].height, ke, Ce, ge[ne].data) : t.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, 0, dt, ge[ne].width, ge[ne].height, 0, ke, Ce, ge[ne].data);
            for (let Oe = 0; Oe < pe.length; Oe++) {
              const jt = pe[Oe].image[ne].image;
              G ? _e && t.texSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe + 1, 0, 0, jt.width, jt.height, ke, Ce, jt.data) : t.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe + 1, dt, jt.width, jt.height, 0, ke, Ce, jt.data);
            }
          } else {
            G ? _e && t.texSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, 0, 0, 0, ke, Ce, ge[ne]) : t.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, 0, dt, ke, Ce, ge[ne]);
            for (let Oe = 0; Oe < pe.length; Oe++) {
              const st = pe[Oe];
              G ? _e && t.texSubImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe + 1, 0, 0, ke, Ce, st.image[ne]) : t.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + ne, Oe + 1, dt, ke, Ce, st.image[ne]);
            }
          }
      }
      g(w) && m(i.TEXTURE_CUBE_MAP), ie.__version = he.version, w.onUpdate && w.onUpdate(w);
    }
    D.__version = w.version;
  }
  function ue(D, w, V, ae, he, ie) {
    const Ue = s.convert(V.format, V.colorSpace), ye = s.convert(V.type), Ye = y(V.internalFormat, Ue, ye, V.colorSpace), Je = n.get(w), fe = n.get(V);
    if (fe.__renderTarget = w, !Je.__hasExternalTextures) {
      const ge = Math.max(1, w.width >> ie), Be = Math.max(1, w.height >> ie);
      he === i.TEXTURE_3D || he === i.TEXTURE_2D_ARRAY ? t.texImage3D(he, ie, Ye, ge, Be, w.depth, 0, Ue, ye, null) : t.texImage2D(he, ie, Ye, ge, Be, 0, Ue, ye, null);
    }
    t.bindFramebuffer(i.FRAMEBUFFER, D), fn(w) ? o.framebufferTexture2DMultisampleEXT(i.FRAMEBUFFER, ae, he, fe.__webglTexture, 0, O(w)) : (he === i.TEXTURE_2D || he >= i.TEXTURE_CUBE_MAP_POSITIVE_X && he <= i.TEXTURE_CUBE_MAP_NEGATIVE_Z) && i.framebufferTexture2D(i.FRAMEBUFFER, ae, he, fe.__webglTexture, ie), t.bindFramebuffer(i.FRAMEBUFFER, null);
  }
  function Ie(D, w, V) {
    if (i.bindRenderbuffer(i.RENDERBUFFER, D), w.depthBuffer) {
      const ae = w.depthTexture, he = ae && ae.isDepthTexture ? ae.type : null, ie = b(w.stencilBuffer, he), Ue = w.stencilBuffer ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT;
      fn(w) ? o.renderbufferStorageMultisampleEXT(i.RENDERBUFFER, O(w), ie, w.width, w.height) : V ? i.renderbufferStorageMultisample(i.RENDERBUFFER, O(w), ie, w.width, w.height) : i.renderbufferStorage(i.RENDERBUFFER, ie, w.width, w.height), i.framebufferRenderbuffer(i.FRAMEBUFFER, Ue, i.RENDERBUFFER, D);
    } else {
      const ae = w.textures;
      for (let he = 0; he < ae.length; he++) {
        const ie = ae[he], Ue = s.convert(ie.format, ie.colorSpace), ye = s.convert(ie.type), Ye = y(ie.internalFormat, Ue, ye, ie.colorSpace);
        fn(w) ? o.renderbufferStorageMultisampleEXT(i.RENDERBUFFER, O(w), Ye, w.width, w.height) : V ? i.renderbufferStorageMultisample(i.RENDERBUFFER, O(w), Ye, w.width, w.height) : i.renderbufferStorage(i.RENDERBUFFER, Ye, w.width, w.height);
      }
    }
    i.bindRenderbuffer(i.RENDERBUFFER, null);
  }
  function we(D, w, V) {
    const ae = w.isWebGLCubeRenderTarget === !0;
    if (t.bindFramebuffer(i.FRAMEBUFFER, D), !(w.depthTexture && w.depthTexture.isDepthTexture))
      throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");
    const he = n.get(w.depthTexture);
    if (he.__renderTarget = w, (!he.__webglTexture || w.depthTexture.image.width !== w.width || w.depthTexture.image.height !== w.height) && (w.depthTexture.image.width = w.width, w.depthTexture.image.height = w.height, w.depthTexture.needsUpdate = !0), ae) {
      if (he.__webglInit === void 0 && (he.__webglInit = !0, w.depthTexture.addEventListener("dispose", S)), he.__webglTexture === void 0) {
        he.__webglTexture = i.createTexture(), t.bindTexture(i.TEXTURE_CUBE_MAP, he.__webglTexture), te(i.TEXTURE_CUBE_MAP, w.depthTexture);
        const Je = s.convert(w.depthTexture.format), fe = s.convert(w.depthTexture.type);
        let ge;
        w.depthTexture.format === Un ? ge = i.DEPTH_COMPONENT24 : w.depthTexture.format === ii && (ge = i.DEPTH24_STENCIL8);
        for (let Be = 0; Be < 6; Be++)
          i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X + Be, 0, ge, w.width, w.height, 0, Je, fe, null);
      }
    } else
      C(w.depthTexture, 0);
    const ie = he.__webglTexture, Ue = O(w), ye = ae ? i.TEXTURE_CUBE_MAP_POSITIVE_X + V : i.TEXTURE_2D, Ye = w.depthTexture.format === ii ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT;
    if (w.depthTexture.format === Un)
      fn(w) ? o.framebufferTexture2DMultisampleEXT(i.FRAMEBUFFER, Ye, ye, ie, 0, Ue) : i.framebufferTexture2D(i.FRAMEBUFFER, Ye, ye, ie, 0);
    else if (w.depthTexture.format === ii)
      fn(w) ? o.framebufferTexture2DMultisampleEXT(i.FRAMEBUFFER, Ye, ye, ie, 0, Ue) : i.framebufferTexture2D(i.FRAMEBUFFER, Ye, ye, ie, 0);
    else
      throw new Error("Unknown depthTexture format");
  }
  function Re(D) {
    const w = n.get(D), V = D.isWebGLCubeRenderTarget === !0;
    if (w.__boundDepthTexture !== D.depthTexture) {
      const ae = D.depthTexture;
      if (w.__depthDisposeCallback && w.__depthDisposeCallback(), ae) {
        const he = () => {
          delete w.__boundDepthTexture, delete w.__depthDisposeCallback, ae.removeEventListener("dispose", he);
        };
        ae.addEventListener("dispose", he), w.__depthDisposeCallback = he;
      }
      w.__boundDepthTexture = ae;
    }
    if (D.depthTexture && !w.__autoAllocateDepthBuffer)
      if (V)
        for (let ae = 0; ae < 6; ae++)
          we(w.__webglFramebuffer[ae], D, ae);
      else {
        const ae = D.texture.mipmaps;
        ae && ae.length > 0 ? we(w.__webglFramebuffer[0], D, 0) : we(w.__webglFramebuffer, D, 0);
      }
    else if (V) {
      w.__webglDepthbuffer = [];
      for (let ae = 0; ae < 6; ae++)
        if (t.bindFramebuffer(i.FRAMEBUFFER, w.__webglFramebuffer[ae]), w.__webglDepthbuffer[ae] === void 0)
          w.__webglDepthbuffer[ae] = i.createRenderbuffer(), Ie(w.__webglDepthbuffer[ae], D, !1);
        else {
          const he = D.stencilBuffer ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT, ie = w.__webglDepthbuffer[ae];
          i.bindRenderbuffer(i.RENDERBUFFER, ie), i.framebufferRenderbuffer(i.FRAMEBUFFER, he, i.RENDERBUFFER, ie);
        }
    } else {
      const ae = D.texture.mipmaps;
      if (ae && ae.length > 0 ? t.bindFramebuffer(i.FRAMEBUFFER, w.__webglFramebuffer[0]) : t.bindFramebuffer(i.FRAMEBUFFER, w.__webglFramebuffer), w.__webglDepthbuffer === void 0)
        w.__webglDepthbuffer = i.createRenderbuffer(), Ie(w.__webglDepthbuffer, D, !1);
      else {
        const he = D.stencilBuffer ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT, ie = w.__webglDepthbuffer;
        i.bindRenderbuffer(i.RENDERBUFFER, ie), i.framebufferRenderbuffer(i.FRAMEBUFFER, he, i.RENDERBUFFER, ie);
      }
    }
    t.bindFramebuffer(i.FRAMEBUFFER, null);
  }
  function It(D, w, V) {
    const ae = n.get(D);
    w !== void 0 && ue(ae.__webglFramebuffer, D, D.texture, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, 0), V !== void 0 && Re(D);
  }
  function ut(D) {
    const w = D.texture, V = n.get(D), ae = n.get(w);
    D.addEventListener("dispose", E);
    const he = D.textures, ie = D.isWebGLCubeRenderTarget === !0, Ue = he.length > 1;
    if (Ue || (ae.__webglTexture === void 0 && (ae.__webglTexture = i.createTexture()), ae.__version = w.version, a.memory.textures++), ie) {
      V.__webglFramebuffer = [];
      for (let ye = 0; ye < 6; ye++)
        if (w.mipmaps && w.mipmaps.length > 0) {
          V.__webglFramebuffer[ye] = [];
          for (let Ye = 0; Ye < w.mipmaps.length; Ye++)
            V.__webglFramebuffer[ye][Ye] = i.createFramebuffer();
        } else
          V.__webglFramebuffer[ye] = i.createFramebuffer();
    } else {
      if (w.mipmaps && w.mipmaps.length > 0) {
        V.__webglFramebuffer = [];
        for (let ye = 0; ye < w.mipmaps.length; ye++)
          V.__webglFramebuffer[ye] = i.createFramebuffer();
      } else
        V.__webglFramebuffer = i.createFramebuffer();
      if (Ue)
        for (let ye = 0, Ye = he.length; ye < Ye; ye++) {
          const Je = n.get(he[ye]);
          Je.__webglTexture === void 0 && (Je.__webglTexture = i.createTexture(), a.memory.textures++);
        }
      if (D.samples > 0 && fn(D) === !1) {
        V.__webglMultisampledFramebuffer = i.createFramebuffer(), V.__webglColorRenderbuffer = [], t.bindFramebuffer(i.FRAMEBUFFER, V.__webglMultisampledFramebuffer);
        for (let ye = 0; ye < he.length; ye++) {
          const Ye = he[ye];
          V.__webglColorRenderbuffer[ye] = i.createRenderbuffer(), i.bindRenderbuffer(i.RENDERBUFFER, V.__webglColorRenderbuffer[ye]);
          const Je = s.convert(Ye.format, Ye.colorSpace), fe = s.convert(Ye.type), ge = y(Ye.internalFormat, Je, fe, Ye.colorSpace, D.isXRRenderTarget === !0), Be = O(D);
          i.renderbufferStorageMultisample(i.RENDERBUFFER, Be, ge, D.width, D.height), i.framebufferRenderbuffer(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0 + ye, i.RENDERBUFFER, V.__webglColorRenderbuffer[ye]);
        }
        i.bindRenderbuffer(i.RENDERBUFFER, null), D.depthBuffer && (V.__webglDepthRenderbuffer = i.createRenderbuffer(), Ie(V.__webglDepthRenderbuffer, D, !0)), t.bindFramebuffer(i.FRAMEBUFFER, null);
      }
    }
    if (ie) {
      t.bindTexture(i.TEXTURE_CUBE_MAP, ae.__webglTexture), te(i.TEXTURE_CUBE_MAP, w);
      for (let ye = 0; ye < 6; ye++)
        if (w.mipmaps && w.mipmaps.length > 0)
          for (let Ye = 0; Ye < w.mipmaps.length; Ye++)
            ue(V.__webglFramebuffer[ye][Ye], D, w, i.COLOR_ATTACHMENT0, i.TEXTURE_CUBE_MAP_POSITIVE_X + ye, Ye);
        else
          ue(V.__webglFramebuffer[ye], D, w, i.COLOR_ATTACHMENT0, i.TEXTURE_CUBE_MAP_POSITIVE_X + ye, 0);
      g(w) && m(i.TEXTURE_CUBE_MAP), t.unbindTexture();
    } else if (Ue) {
      for (let ye = 0, Ye = he.length; ye < Ye; ye++) {
        const Je = he[ye], fe = n.get(Je);
        let ge = i.TEXTURE_2D;
        (D.isWebGL3DRenderTarget || D.isWebGLArrayRenderTarget) && (ge = D.isWebGL3DRenderTarget ? i.TEXTURE_3D : i.TEXTURE_2D_ARRAY), t.bindTexture(ge, fe.__webglTexture), te(ge, Je), ue(V.__webglFramebuffer, D, Je, i.COLOR_ATTACHMENT0 + ye, ge, 0), g(Je) && m(ge);
      }
      t.unbindTexture();
    } else {
      let ye = i.TEXTURE_2D;
      if ((D.isWebGL3DRenderTarget || D.isWebGLArrayRenderTarget) && (ye = D.isWebGL3DRenderTarget ? i.TEXTURE_3D : i.TEXTURE_2D_ARRAY), t.bindTexture(ye, ae.__webglTexture), te(ye, w), w.mipmaps && w.mipmaps.length > 0)
        for (let Ye = 0; Ye < w.mipmaps.length; Ye++)
          ue(V.__webglFramebuffer[Ye], D, w, i.COLOR_ATTACHMENT0, ye, Ye);
      else
        ue(V.__webglFramebuffer, D, w, i.COLOR_ATTACHMENT0, ye, 0);
      g(w) && m(ye), t.unbindTexture();
    }
    D.depthBuffer && Re(D);
  }
  function mt(D) {
    const w = D.textures;
    for (let V = 0, ae = w.length; V < ae; V++) {
      const he = w[V];
      if (g(he)) {
        const ie = x(D), Ue = n.get(he).__webglTexture;
        t.bindTexture(ie, Ue), m(ie), t.unbindTexture();
      }
    }
  }
  const bt = [], tt = [];
  function Rt(D) {
    if (D.samples > 0) {
      if (fn(D) === !1) {
        const w = D.textures, V = D.width, ae = D.height;
        let he = i.COLOR_BUFFER_BIT;
        const ie = D.stencilBuffer ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT, Ue = n.get(D), ye = w.length > 1;
        if (ye)
          for (let Je = 0; Je < w.length; Je++)
            t.bindFramebuffer(i.FRAMEBUFFER, Ue.__webglMultisampledFramebuffer), i.framebufferRenderbuffer(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0 + Je, i.RENDERBUFFER, null), t.bindFramebuffer(i.FRAMEBUFFER, Ue.__webglFramebuffer), i.framebufferTexture2D(i.DRAW_FRAMEBUFFER, i.COLOR_ATTACHMENT0 + Je, i.TEXTURE_2D, null, 0);
        t.bindFramebuffer(i.READ_FRAMEBUFFER, Ue.__webglMultisampledFramebuffer);
        const Ye = D.texture.mipmaps;
        Ye && Ye.length > 0 ? t.bindFramebuffer(i.DRAW_FRAMEBUFFER, Ue.__webglFramebuffer[0]) : t.bindFramebuffer(i.DRAW_FRAMEBUFFER, Ue.__webglFramebuffer);
        for (let Je = 0; Je < w.length; Je++) {
          if (D.resolveDepthBuffer && (D.depthBuffer && (he |= i.DEPTH_BUFFER_BIT), D.stencilBuffer && D.resolveStencilBuffer && (he |= i.STENCIL_BUFFER_BIT)), ye) {
            i.framebufferRenderbuffer(i.READ_FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.RENDERBUFFER, Ue.__webglColorRenderbuffer[Je]);
            const fe = n.get(w[Je]).__webglTexture;
            i.framebufferTexture2D(i.DRAW_FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, fe, 0);
          }
          i.blitFramebuffer(0, 0, V, ae, 0, 0, V, ae, he, i.NEAREST), l === !0 && (bt.length = 0, tt.length = 0, bt.push(i.COLOR_ATTACHMENT0 + Je), D.depthBuffer && D.resolveDepthBuffer === !1 && (bt.push(ie), tt.push(ie), i.invalidateFramebuffer(i.DRAW_FRAMEBUFFER, tt)), i.invalidateFramebuffer(i.READ_FRAMEBUFFER, bt));
        }
        if (t.bindFramebuffer(i.READ_FRAMEBUFFER, null), t.bindFramebuffer(i.DRAW_FRAMEBUFFER, null), ye)
          for (let Je = 0; Je < w.length; Je++) {
            t.bindFramebuffer(i.FRAMEBUFFER, Ue.__webglMultisampledFramebuffer), i.framebufferRenderbuffer(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0 + Je, i.RENDERBUFFER, Ue.__webglColorRenderbuffer[Je]);
            const fe = n.get(w[Je]).__webglTexture;
            t.bindFramebuffer(i.FRAMEBUFFER, Ue.__webglFramebuffer), i.framebufferTexture2D(i.DRAW_FRAMEBUFFER, i.COLOR_ATTACHMENT0 + Je, i.TEXTURE_2D, fe, 0);
          }
        t.bindFramebuffer(i.DRAW_FRAMEBUFFER, Ue.__webglMultisampledFramebuffer);
      } else if (D.depthBuffer && D.resolveDepthBuffer === !1 && l) {
        const w = D.stencilBuffer ? i.DEPTH_STENCIL_ATTACHMENT : i.DEPTH_ATTACHMENT;
        i.invalidateFramebuffer(i.DRAW_FRAMEBUFFER, [w]);
      }
    }
  }
  function O(D) {
    return Math.min(r.maxSamples, D.samples);
  }
  function fn(D) {
    const w = n.get(D);
    return D.samples > 0 && e.has("WEBGL_multisampled_render_to_texture") === !0 && w.__useRenderToTexture !== !1;
  }
  function Ct(D) {
    const w = a.render.frame;
    u.get(D) !== w && (u.set(D, w), D.update());
  }
  function Xt(D, w) {
    const V = D.colorSpace, ae = D.format, he = D.type;
    return D.isCompressedTexture === !0 || D.isVideoTexture === !0 || V !== La && V !== hi && (Ke.getTransfer(V) === Te ? (ae !== cn || he !== Zt) && oe("WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.") : le("WebGLTextures: Unsupported texture color space:", V)), w;
  }
  function Ve(D) {
    return typeof HTMLImageElement < "u" && D instanceof HTMLImageElement ? (c.width = D.naturalWidth || D.width, c.height = D.naturalHeight || D.height) : typeof VideoFrame < "u" && D instanceof VideoFrame ? (c.width = D.displayWidth, c.height = D.displayHeight) : (c.width = D.width, c.height = D.height), c;
  }
  this.allocateTextureUnit = B, this.resetTextureUnits = I, this.setTexture2D = C, this.setTexture2DArray = L, this.setTexture3D = k, this.setTextureCube = re, this.rebindTextures = It, this.setupRenderTarget = ut, this.updateRenderTargetMipmap = mt, this.updateMultisampleRenderTarget = Rt, this.setupDepthRenderbuffer = Re, this.setupFrameBufferTexture = ue, this.useMultisampledRTT = fn, this.isReversedDepthBuffer = function() {
    return t.buffers.depth.getReversed();
  };
}
function $1(i, e) {
  function t(n, r = hi) {
    let s;
    const a = Ke.getTransfer(r);
    if (n === Zt)
      return i.UNSIGNED_BYTE;
    if (n === rd)
      return i.UNSIGNED_SHORT_4_4_4_4;
    if (n === sd)
      return i.UNSIGNED_SHORT_5_5_5_1;
    if (n === ad)
      return i.UNSIGNED_INT_5_9_9_9_REV;
    if (n === od)
      return i.UNSIGNED_INT_10F_11F_11F_REV;
    if (n === ba)
      return i.BYTE;
    if (n === Sa)
      return i.SHORT;
    if (n === Ji)
      return i.UNSIGNED_SHORT;
    if (n === wn)
      return i.INT;
    if (n === Dt)
      return i.UNSIGNED_INT;
    if (n === ln)
      return i.FLOAT;
    if (n === nn)
      return i.HALF_FLOAT;
    if (n === Bm)
      return i.ALPHA;
    if (n === Jc)
      return i.RGB;
    if (n === cn)
      return i.RGBA;
    if (n === Un)
      return i.DEPTH_COMPONENT;
    if (n === ii)
      return i.DEPTH_STENCIL;
    if (n === eu)
      return i.RED;
    if (n === _l)
      return i.RED_INTEGER;
    if (n === ri)
      return i.RG;
    if (n === xl)
      return i.RG_INTEGER;
    if (n === vl)
      return i.RGBA_INTEGER;
    if (n === Us || n === Bs || n === Os || n === ks)
      if (a === Te)
        if (s = e.get("WEBGL_compressed_texture_s3tc_srgb"), s !== null) {
          if (n === Us)
            return s.COMPRESSED_SRGB_S3TC_DXT1_EXT;
          if (n === Bs)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
          if (n === Os)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
          if (n === ks)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
        } else
          return null;
      else if (s = e.get("WEBGL_compressed_texture_s3tc"), s !== null) {
        if (n === Us)
          return s.COMPRESSED_RGB_S3TC_DXT1_EXT;
        if (n === Bs)
          return s.COMPRESSED_RGBA_S3TC_DXT1_EXT;
        if (n === Os)
          return s.COMPRESSED_RGBA_S3TC_DXT3_EXT;
        if (n === ks)
          return s.COMPRESSED_RGBA_S3TC_DXT5_EXT;
      } else
        return null;
    if (n === Bc || n === Oc || n === kc || n === Gc)
      if (s = e.get("WEBGL_compressed_texture_pvrtc"), s !== null) {
        if (n === Bc)
          return s.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
        if (n === Oc)
          return s.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
        if (n === kc)
          return s.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
        if (n === Gc)
          return s.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
      } else
        return null;
    if (n === Oo || n === ko || n === Go || n === Vo || n === zo || n === Pa || n === Ho)
      if (s = e.get("WEBGL_compressed_texture_etc"), s !== null) {
        if (n === Oo || n === ko)
          return a === Te ? s.COMPRESSED_SRGB8_ETC2 : s.COMPRESSED_RGB8_ETC2;
        if (n === Go)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : s.COMPRESSED_RGBA8_ETC2_EAC;
        if (n === Vo)
          return s.COMPRESSED_R11_EAC;
        if (n === zo)
          return s.COMPRESSED_SIGNED_R11_EAC;
        if (n === Pa)
          return s.COMPRESSED_RG11_EAC;
        if (n === Ho)
          return s.COMPRESSED_SIGNED_RG11_EAC;
      } else
        return null;
    if (n === $o || n === Wo || n === qo || n === Xo || n === jo || n === Yo || n === Ko || n === Zo || n === Qo || n === Jo || n === el || n === tl || n === nl || n === il)
      if (s = e.get("WEBGL_compressed_texture_astc"), s !== null) {
        if (n === $o)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : s.COMPRESSED_RGBA_ASTC_4x4_KHR;
        if (n === Wo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : s.COMPRESSED_RGBA_ASTC_5x4_KHR;
        if (n === qo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : s.COMPRESSED_RGBA_ASTC_5x5_KHR;
        if (n === Xo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : s.COMPRESSED_RGBA_ASTC_6x5_KHR;
        if (n === jo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : s.COMPRESSED_RGBA_ASTC_6x6_KHR;
        if (n === Yo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : s.COMPRESSED_RGBA_ASTC_8x5_KHR;
        if (n === Ko)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : s.COMPRESSED_RGBA_ASTC_8x6_KHR;
        if (n === Zo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : s.COMPRESSED_RGBA_ASTC_8x8_KHR;
        if (n === Qo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : s.COMPRESSED_RGBA_ASTC_10x5_KHR;
        if (n === Jo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : s.COMPRESSED_RGBA_ASTC_10x6_KHR;
        if (n === el)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : s.COMPRESSED_RGBA_ASTC_10x8_KHR;
        if (n === tl)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : s.COMPRESSED_RGBA_ASTC_10x10_KHR;
        if (n === nl)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : s.COMPRESSED_RGBA_ASTC_12x10_KHR;
        if (n === il)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : s.COMPRESSED_RGBA_ASTC_12x12_KHR;
      } else
        return null;
    if (n === rl || n === Ep || n === wp)
      if (s = e.get("EXT_texture_compression_bptc"), s !== null) {
        if (n === rl)
          return a === Te ? s.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : s.COMPRESSED_RGBA_BPTC_UNORM_EXT;
        if (n === Ep)
          return s.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
        if (n === wp)
          return s.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
      } else
        return null;
    if (n === sl || n === al || n === Da || n === ol)
      if (s = e.get("EXT_texture_compression_rgtc"), s !== null) {
        if (n === sl)
          return s.COMPRESSED_RED_RGTC1_EXT;
        if (n === al)
          return s.COMPRESSED_SIGNED_RED_RGTC1_EXT;
        if (n === Da)
          return s.COMPRESSED_RED_GREEN_RGTC2_EXT;
        if (n === ol)
          return s.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
      } else
        return null;
    return n === Ci ? i.UNSIGNED_INT_24_8 : i[n] !== void 0 ? i[n] : null;
  }
  return { convert: t };
}
const W1 = `
void main() {

	gl_Position = vec4( position, 1.0 );

}`, q1 = `
uniform sampler2DArray depthColor;
uniform float depthWidth;
uniform float depthHeight;

void main() {

	vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight );

	if ( coord.x >= 1.0 ) {

		gl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;

	} else {

		gl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;

	}

}`;
class X1 {
  /**
   * Constructs a new depth sensing module.
   */
  constructor() {
    this.texture = null, this.mesh = null, this.depthNear = 0, this.depthFar = 0;
  }
  /**
   * Inits the depth sensing module
   *
   * @param {XRWebGLDepthInformation} depthData - The XR depth data.
   * @param {XRRenderState} renderState - The XR render state.
   */
  init(e, t) {
    if (this.texture === null) {
      const n = new ry(e.texture);
      (e.depthNear !== t.depthNear || e.depthFar !== t.depthFar) && (this.depthNear = e.depthNear, this.depthFar = e.depthFar), this.texture = n;
    }
  }
  /**
   * Returns a plane mesh that visualizes the depth texture.
   *
   * @param {ArrayCamera} cameraXR - The XR camera.
   * @return {?Mesh} The plane mesh.
   */
  getMesh(e) {
    if (this.texture !== null && this.mesh === null) {
      const t = e.cameras[0].viewport, n = new Vi({
        vertexShader: W1,
        fragmentShader: q1,
        uniforms: {
          depthColor: { value: this.texture },
          depthWidth: { value: t.z },
          depthHeight: { value: t.w }
        }
      });
      this.mesh = new _n(new ru(20, 20), n);
    }
    return this.mesh;
  }
  /**
   * Resets the module
   */
  reset() {
    this.texture = null, this.mesh = null;
  }
  /**
   * Returns a texture representing the depth of the user's environment.
   *
   * @return {?ExternalTexture} The depth texture.
   */
  getDepthTexture() {
    return this.texture;
  }
}
class j1 extends Fr {
  /**
   * Constructs a new WebGL renderer.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGL2RenderingContext} gl - The rendering context.
   */
  constructor(e, t) {
    super();
    const n = this;
    let r = null, s = 1, a = null, o = "local-floor", l = 1, c = null, u = null, h = null, d = null, f = null, p = null;
    const _ = typeof XRWebGLBinding < "u", g = new X1(), m = {}, x = t.getContextAttributes();
    let y = null, b = null;
    const T = [], S = [], E = new de();
    let v = null;
    const M = new An();
    M.viewport = new rt();
    const F = new An();
    F.viewport = new rt();
    const R = [M, F], I = new my();
    let B = null, N = null;
    this.cameraAutoUpdate = !0, this.enabled = !1, this.isPresenting = !1, this.getController = function(z) {
      let Z = T[z];
      return Z === void 0 && (Z = new bh(), T[z] = Z), Z.getTargetRaySpace();
    }, this.getControllerGrip = function(z) {
      let Z = T[z];
      return Z === void 0 && (Z = new bh(), T[z] = Z), Z.getGripSpace();
    }, this.getHand = function(z) {
      let Z = T[z];
      return Z === void 0 && (Z = new bh(), T[z] = Z), Z.getHandSpace();
    };
    function C(z) {
      const Z = S.indexOf(z.inputSource);
      if (Z === -1)
        return;
      const ue = T[Z];
      ue !== void 0 && (ue.update(z.inputSource, z.frame, c || a), ue.dispatchEvent({ type: z.type, data: z.inputSource }));
    }
    function L() {
      r.removeEventListener("select", C), r.removeEventListener("selectstart", C), r.removeEventListener("selectend", C), r.removeEventListener("squeeze", C), r.removeEventListener("squeezestart", C), r.removeEventListener("squeezeend", C), r.removeEventListener("end", L), r.removeEventListener("inputsourceschange", k);
      for (let z = 0; z < T.length; z++) {
        const Z = S[z];
        Z !== null && (S[z] = null, T[z].disconnect(Z));
      }
      B = null, N = null, g.reset();
      for (const z in m)
        delete m[z];
      e.setRenderTarget(y), f = null, d = null, h = null, r = null, b = null, ce.stop(), n.isPresenting = !1, e.setPixelRatio(v), e.setSize(E.width, E.height, !1), n.dispatchEvent({ type: "sessionend" });
    }
    this.setFramebufferScaleFactor = function(z) {
      s = z, n.isPresenting === !0 && oe("WebXRManager: Cannot change framebuffer scale while presenting.");
    }, this.setReferenceSpaceType = function(z) {
      o = z, n.isPresenting === !0 && oe("WebXRManager: Cannot change reference space type while presenting.");
    }, this.getReferenceSpace = function() {
      return c || a;
    }, this.setReferenceSpace = function(z) {
      c = z;
    }, this.getBaseLayer = function() {
      return d !== null ? d : f;
    }, this.getBinding = function() {
      return h === null && _ && (h = new XRWebGLBinding(r, t)), h;
    }, this.getFrame = function() {
      return p;
    }, this.getSession = function() {
      return r;
    }, this.setSession = async function(z) {
      if (r = z, r !== null) {
        if (y = e.getRenderTarget(), r.addEventListener("select", C), r.addEventListener("selectstart", C), r.addEventListener("selectend", C), r.addEventListener("squeeze", C), r.addEventListener("squeezestart", C), r.addEventListener("squeezeend", C), r.addEventListener("end", L), r.addEventListener("inputsourceschange", k), x.xrCompatible !== !0 && await t.makeXRCompatible(), v = e.getPixelRatio(), e.getSize(E), _ && "createProjectionLayer" in XRWebGLBinding.prototype) {
          let ue = null, Ie = null, we = null;
          x.depth && (we = x.stencil ? t.DEPTH24_STENCIL8 : t.DEPTH_COMPONENT24, ue = x.stencil ? ii : Un, Ie = x.stencil ? Ci : Dt);
          const Re = {
            colorFormat: t.RGBA8,
            depthFormat: we,
            scaleFactor: s
          };
          h = this.getBinding(), d = h.createProjectionLayer(Re), r.updateRenderState({ layers: [d] }), e.setPixelRatio(1), e.setSize(d.textureWidth, d.textureHeight, !1), b = new tr(
            d.textureWidth,
            d.textureHeight,
            {
              format: cn,
              type: Zt,
              depthTexture: new oi(d.textureWidth, d.textureHeight, Ie, void 0, void 0, void 0, void 0, void 0, void 0, ue),
              stencilBuffer: x.stencil,
              colorSpace: e.outputColorSpace,
              samples: x.antialias ? 4 : 0,
              resolveDepthBuffer: d.ignoreDepthValues === !1,
              resolveStencilBuffer: d.ignoreDepthValues === !1
            }
          );
        } else {
          const ue = {
            antialias: x.antialias,
            alpha: !0,
            depth: x.depth,
            stencil: x.stencil,
            framebufferScaleFactor: s
          };
          f = new XRWebGLLayer(r, t, ue), r.updateRenderState({ baseLayer: f }), e.setPixelRatio(1), e.setSize(f.framebufferWidth, f.framebufferHeight, !1), b = new tr(
            f.framebufferWidth,
            f.framebufferHeight,
            {
              format: cn,
              type: Zt,
              colorSpace: e.outputColorSpace,
              stencilBuffer: x.stencil,
              resolveDepthBuffer: f.ignoreDepthValues === !1,
              resolveStencilBuffer: f.ignoreDepthValues === !1
            }
          );
        }
        b.isXRRenderTarget = !0, this.setFoveation(l), c = null, a = await r.requestReferenceSpace(o), ce.setContext(r), ce.start(), n.isPresenting = !0, n.dispatchEvent({ type: "sessionstart" });
      }
    }, this.getEnvironmentBlendMode = function() {
      if (r !== null)
        return r.environmentBlendMode;
    }, this.getDepthTexture = function() {
      return g.getDepthTexture();
    };
    function k(z) {
      for (let Z = 0; Z < z.removed.length; Z++) {
        const ue = z.removed[Z], Ie = S.indexOf(ue);
        Ie >= 0 && (S[Ie] = null, T[Ie].disconnect(ue));
      }
      for (let Z = 0; Z < z.added.length; Z++) {
        const ue = z.added[Z];
        let Ie = S.indexOf(ue);
        if (Ie === -1) {
          for (let Re = 0; Re < T.length; Re++)
            if (Re >= S.length) {
              S.push(ue), Ie = Re;
              break;
            } else if (S[Re] === null) {
              S[Re] = ue, Ie = Re;
              break;
            }
          if (Ie === -1)
            break;
        }
        const we = T[Ie];
        we && we.connect(ue);
      }
    }
    const re = new P(), se = new P();
    function ve(z, Z, ue) {
      re.setFromMatrixPosition(Z.matrixWorld), se.setFromMatrixPosition(ue.matrixWorld);
      const Ie = re.distanceTo(se), we = Z.projectionMatrix.elements, Re = ue.projectionMatrix.elements, It = we[14] / (we[10] - 1), ut = we[14] / (we[10] + 1), mt = (we[9] + 1) / we[5], bt = (we[9] - 1) / we[5], tt = (we[8] - 1) / we[0], Rt = (Re[8] + 1) / Re[0], O = It * tt, fn = It * Rt, Ct = Ie / (-tt + Rt), Xt = Ct * -tt;
      if (Z.matrixWorld.decompose(z.position, z.quaternion, z.scale), z.translateX(Xt), z.translateZ(Ct), z.matrixWorld.compose(z.position, z.quaternion, z.scale), z.matrixWorldInverse.copy(z.matrixWorld).invert(), we[10] === -1)
        z.projectionMatrix.copy(Z.projectionMatrix), z.projectionMatrixInverse.copy(Z.projectionMatrixInverse);
      else {
        const Ve = It + Ct, D = ut + Ct, w = O - Xt, V = fn + (Ie - Xt), ae = mt * ut / D * Ve, he = bt * ut / D * Ve;
        z.projectionMatrix.makePerspective(w, V, ae, he, Ve, D), z.projectionMatrixInverse.copy(z.projectionMatrix).invert();
      }
    }
    function X(z, Z) {
      Z === null ? z.matrixWorld.copy(z.matrix) : z.matrixWorld.multiplyMatrices(Z.matrixWorld, z.matrix), z.matrixWorldInverse.copy(z.matrixWorld).invert();
    }
    this.updateCamera = function(z) {
      if (r === null)
        return;
      let Z = z.near, ue = z.far;
      g.texture !== null && (g.depthNear > 0 && (Z = g.depthNear), g.depthFar > 0 && (ue = g.depthFar)), I.near = F.near = M.near = Z, I.far = F.far = M.far = ue, (B !== I.near || N !== I.far) && (r.updateRenderState({
        depthNear: I.near,
        depthFar: I.far
      }), B = I.near, N = I.far), I.layers.mask = z.layers.mask | 6, M.layers.mask = I.layers.mask & -5, F.layers.mask = I.layers.mask & -3;
      const Ie = z.parent, we = I.cameras;
      X(I, Ie);
      for (let Re = 0; Re < we.length; Re++)
        X(we[Re], Ie);
      we.length === 2 ? ve(I, M, F) : I.projectionMatrix.copy(M.projectionMatrix), te(z, I, Ie);
    };
    function te(z, Z, ue) {
      ue === null ? z.matrix.copy(Z.matrixWorld) : (z.matrix.copy(ue.matrixWorld), z.matrix.invert(), z.matrix.multiply(Z.matrixWorld)), z.matrix.decompose(z.position, z.quaternion, z.scale), z.updateMatrixWorld(!0), z.projectionMatrix.copy(Z.projectionMatrix), z.projectionMatrixInverse.copy(Z.projectionMatrixInverse), z.isPerspectiveCamera && (z.fov = Fa * 2 * Math.atan(1 / z.projectionMatrix.elements[5]), z.zoom = 1);
    }
    this.getCamera = function() {
      return I;
    }, this.getFoveation = function() {
      if (!(d === null && f === null))
        return l;
    }, this.setFoveation = function(z) {
      l = z, d !== null && (d.fixedFoveation = z), f !== null && f.fixedFoveation !== void 0 && (f.fixedFoveation = z);
    }, this.hasDepthSensing = function() {
      return g.texture !== null;
    }, this.getDepthSensingMesh = function() {
      return g.getMesh(I);
    }, this.getCameraTexture = function(z) {
      return m[z];
    };
    let me = null;
    function Qe(z, Z) {
      if (u = Z.getViewerPose(c || a), p = Z, u !== null) {
        const ue = u.views;
        f !== null && (e.setRenderTargetFramebuffer(b, f.framebuffer), e.setRenderTarget(b));
        let Ie = !1;
        ue.length !== I.cameras.length && (I.cameras.length = 0, Ie = !0);
        for (let ut = 0; ut < ue.length; ut++) {
          const mt = ue[ut];
          let bt = null;
          if (f !== null)
            bt = f.getViewport(mt);
          else {
            const Rt = h.getViewSubImage(d, mt);
            bt = Rt.viewport, ut === 0 && (e.setRenderTargetTextures(
              b,
              Rt.colorTexture,
              Rt.depthStencilTexture
            ), e.setRenderTarget(b));
          }
          let tt = R[ut];
          tt === void 0 && (tt = new An(), tt.layers.enable(ut), tt.viewport = new rt(), R[ut] = tt), tt.matrix.fromArray(mt.transform.matrix), tt.matrix.decompose(tt.position, tt.quaternion, tt.scale), tt.projectionMatrix.fromArray(mt.projectionMatrix), tt.projectionMatrixInverse.copy(tt.projectionMatrix).invert(), tt.viewport.set(bt.x, bt.y, bt.width, bt.height), ut === 0 && (I.matrix.copy(tt.matrix), I.matrix.decompose(I.position, I.quaternion, I.scale)), Ie === !0 && I.cameras.push(tt);
        }
        const we = r.enabledFeatures;
        if (we && we.includes("depth-sensing") && r.depthUsage == "gpu-optimized" && _) {
          h = n.getBinding();
          const ut = h.getDepthInformation(ue[0]);
          ut && ut.isValid && ut.texture && g.init(ut, r.renderState);
        }
        if (we && we.includes("camera-access") && _) {
          e.state.unbindTexture(), h = n.getBinding();
          for (let ut = 0; ut < ue.length; ut++) {
            const mt = ue[ut].camera;
            if (mt) {
              let bt = m[mt];
              bt || (bt = new ry(), m[mt] = bt);
              const tt = h.getCameraImage(mt);
              bt.sourceTexture = tt;
            }
          }
        }
      }
      for (let ue = 0; ue < T.length; ue++) {
        const Ie = S[ue], we = T[ue];
        Ie !== null && we !== void 0 && we.update(Ie, Z, c || a);
      }
      me && me(z, Z), Z.detectedPlanes && n.dispatchEvent({ type: "planesdetected", data: Z }), p = null;
    }
    const ce = new _y();
    ce.setAnimationLoop(Qe), this.setAnimationLoop = function(z) {
      me = z;
    }, this.dispose = function() {
    };
  }
}
const oa = /* @__PURE__ */ new gi(), Y1 = /* @__PURE__ */ new pt();
function K1(i, e) {
  function t(g, m) {
    g.matrixAutoUpdate === !0 && g.updateMatrix(), m.value.copy(g.matrix);
  }
  function n(g, m) {
    m.color.getRGB(g.fogColor.value, oy(i)), m.isFog ? (g.fogNear.value = m.near, g.fogFar.value = m.far) : m.isFogExp2 && (g.fogDensity.value = m.density);
  }
  function r(g, m, x, y, b) {
    m.isMeshBasicMaterial ? s(g, m) : m.isMeshLambertMaterial ? (s(g, m), m.envMap && (g.envMapIntensity.value = m.envMapIntensity)) : m.isMeshToonMaterial ? (s(g, m), h(g, m)) : m.isMeshPhongMaterial ? (s(g, m), u(g, m), m.envMap && (g.envMapIntensity.value = m.envMapIntensity)) : m.isMeshStandardMaterial ? (s(g, m), d(g, m), m.isMeshPhysicalMaterial && f(g, m, b)) : m.isMeshMatcapMaterial ? (s(g, m), p(g, m)) : m.isMeshDepthMaterial ? s(g, m) : m.isMeshDistanceMaterial ? (s(g, m), _(g, m)) : m.isMeshNormalMaterial ? s(g, m) : m.isLineBasicMaterial ? (a(g, m), m.isLineDashedMaterial && o(g, m)) : m.isPointsMaterial ? l(g, m, x, y) : m.isSpriteMaterial ? c(g, m) : m.isShadowMaterial ? (g.color.value.copy(m.color), g.opacity.value = m.opacity) : m.isShaderMaterial && (m.uniformsNeedUpdate = !1);
  }
  function s(g, m) {
    g.opacity.value = m.opacity, m.color && g.diffuse.value.copy(m.color), m.emissive && g.emissive.value.copy(m.emissive).multiplyScalar(m.emissiveIntensity), m.map && (g.map.value = m.map, t(m.map, g.mapTransform)), m.alphaMap && (g.alphaMap.value = m.alphaMap, t(m.alphaMap, g.alphaMapTransform)), m.bumpMap && (g.bumpMap.value = m.bumpMap, t(m.bumpMap, g.bumpMapTransform), g.bumpScale.value = m.bumpScale, m.side === Ft && (g.bumpScale.value *= -1)), m.normalMap && (g.normalMap.value = m.normalMap, t(m.normalMap, g.normalMapTransform), g.normalScale.value.copy(m.normalScale), m.side === Ft && g.normalScale.value.negate()), m.displacementMap && (g.displacementMap.value = m.displacementMap, t(m.displacementMap, g.displacementMapTransform), g.displacementScale.value = m.displacementScale, g.displacementBias.value = m.displacementBias), m.emissiveMap && (g.emissiveMap.value = m.emissiveMap, t(m.emissiveMap, g.emissiveMapTransform)), m.specularMap && (g.specularMap.value = m.specularMap, t(m.specularMap, g.specularMapTransform)), m.alphaTest > 0 && (g.alphaTest.value = m.alphaTest);
    const x = e.get(m), y = x.envMap, b = x.envMapRotation;
    y && (g.envMap.value = y, oa.copy(b), oa.x *= -1, oa.y *= -1, oa.z *= -1, y.isCubeTexture && y.isRenderTargetTexture === !1 && (oa.y *= -1, oa.z *= -1), g.envMapRotation.value.setFromMatrix4(Y1.makeRotationFromEuler(oa)), g.flipEnvMap.value = y.isCubeTexture && y.isRenderTargetTexture === !1 ? -1 : 1, g.reflectivity.value = m.reflectivity, g.ior.value = m.ior, g.refractionRatio.value = m.refractionRatio), m.lightMap && (g.lightMap.value = m.lightMap, g.lightMapIntensity.value = m.lightMapIntensity, t(m.lightMap, g.lightMapTransform)), m.aoMap && (g.aoMap.value = m.aoMap, g.aoMapIntensity.value = m.aoMapIntensity, t(m.aoMap, g.aoMapTransform));
  }
  function a(g, m) {
    g.diffuse.value.copy(m.color), g.opacity.value = m.opacity, m.map && (g.map.value = m.map, t(m.map, g.mapTransform));
  }
  function o(g, m) {
    g.dashSize.value = m.dashSize, g.totalSize.value = m.dashSize + m.gapSize, g.scale.value = m.scale;
  }
  function l(g, m, x, y) {
    g.diffuse.value.copy(m.color), g.opacity.value = m.opacity, g.size.value = m.size * x, g.scale.value = y * 0.5, m.map && (g.map.value = m.map, t(m.map, g.uvTransform)), m.alphaMap && (g.alphaMap.value = m.alphaMap, t(m.alphaMap, g.alphaMapTransform)), m.alphaTest > 0 && (g.alphaTest.value = m.alphaTest);
  }
  function c(g, m) {
    g.diffuse.value.copy(m.color), g.opacity.value = m.opacity, g.rotation.value = m.rotation, m.map && (g.map.value = m.map, t(m.map, g.mapTransform)), m.alphaMap && (g.alphaMap.value = m.alphaMap, t(m.alphaMap, g.alphaMapTransform)), m.alphaTest > 0 && (g.alphaTest.value = m.alphaTest);
  }
  function u(g, m) {
    g.specular.value.copy(m.specular), g.shininess.value = Math.max(m.shininess, 1e-4);
  }
  function h(g, m) {
    m.gradientMap && (g.gradientMap.value = m.gradientMap);
  }
  function d(g, m) {
    g.metalness.value = m.metalness, m.metalnessMap && (g.metalnessMap.value = m.metalnessMap, t(m.metalnessMap, g.metalnessMapTransform)), g.roughness.value = m.roughness, m.roughnessMap && (g.roughnessMap.value = m.roughnessMap, t(m.roughnessMap, g.roughnessMapTransform)), m.envMap && (g.envMapIntensity.value = m.envMapIntensity);
  }
  function f(g, m, x) {
    g.ior.value = m.ior, m.sheen > 0 && (g.sheenColor.value.copy(m.sheenColor).multiplyScalar(m.sheen), g.sheenRoughness.value = m.sheenRoughness, m.sheenColorMap && (g.sheenColorMap.value = m.sheenColorMap, t(m.sheenColorMap, g.sheenColorMapTransform)), m.sheenRoughnessMap && (g.sheenRoughnessMap.value = m.sheenRoughnessMap, t(m.sheenRoughnessMap, g.sheenRoughnessMapTransform))), m.clearcoat > 0 && (g.clearcoat.value = m.clearcoat, g.clearcoatRoughness.value = m.clearcoatRoughness, m.clearcoatMap && (g.clearcoatMap.value = m.clearcoatMap, t(m.clearcoatMap, g.clearcoatMapTransform)), m.clearcoatRoughnessMap && (g.clearcoatRoughnessMap.value = m.clearcoatRoughnessMap, t(m.clearcoatRoughnessMap, g.clearcoatRoughnessMapTransform)), m.clearcoatNormalMap && (g.clearcoatNormalMap.value = m.clearcoatNormalMap, t(m.clearcoatNormalMap, g.clearcoatNormalMapTransform), g.clearcoatNormalScale.value.copy(m.clearcoatNormalScale), m.side === Ft && g.clearcoatNormalScale.value.negate())), m.dispersion > 0 && (g.dispersion.value = m.dispersion), m.iridescence > 0 && (g.iridescence.value = m.iridescence, g.iridescenceIOR.value = m.iridescenceIOR, g.iridescenceThicknessMinimum.value = m.iridescenceThicknessRange[0], g.iridescenceThicknessMaximum.value = m.iridescenceThicknessRange[1], m.iridescenceMap && (g.iridescenceMap.value = m.iridescenceMap, t(m.iridescenceMap, g.iridescenceMapTransform)), m.iridescenceThicknessMap && (g.iridescenceThicknessMap.value = m.iridescenceThicknessMap, t(m.iridescenceThicknessMap, g.iridescenceThicknessMapTransform))), m.transmission > 0 && (g.transmission.value = m.transmission, g.transmissionSamplerMap.value = x.texture, g.transmissionSamplerSize.value.set(x.width, x.height), m.transmissionMap && (g.transmissionMap.value = m.transmissionMap, t(m.transmissionMap, g.transmissionMapTransform)), g.thickness.value = m.thickness, m.thicknessMap && (g.thicknessMap.value = m.thicknessMap, t(m.thicknessMap, g.thicknessMapTransform)), g.attenuationDistance.value = m.attenuationDistance, g.attenuationColor.value.copy(m.attenuationColor)), m.anisotropy > 0 && (g.anisotropyVector.value.set(m.anisotropy * Math.cos(m.anisotropyRotation), m.anisotropy * Math.sin(m.anisotropyRotation)), m.anisotropyMap && (g.anisotropyMap.value = m.anisotropyMap, t(m.anisotropyMap, g.anisotropyMapTransform))), g.specularIntensity.value = m.specularIntensity, g.specularColor.value.copy(m.specularColor), m.specularColorMap && (g.specularColorMap.value = m.specularColorMap, t(m.specularColorMap, g.specularColorMapTransform)), m.specularIntensityMap && (g.specularIntensityMap.value = m.specularIntensityMap, t(m.specularIntensityMap, g.specularIntensityMapTransform));
  }
  function p(g, m) {
    m.matcap && (g.matcap.value = m.matcap);
  }
  function _(g, m) {
    const x = e.get(m).light;
    g.referencePosition.value.setFromMatrixPosition(x.matrixWorld), g.nearDistance.value = x.shadow.camera.near, g.farDistance.value = x.shadow.camera.far;
  }
  return {
    refreshFogUniforms: n,
    refreshMaterialUniforms: r
  };
}
function Z1(i, e, t, n) {
  let r = {}, s = {}, a = [];
  const o = i.getParameter(i.MAX_UNIFORM_BUFFER_BINDINGS);
  function l(x, y) {
    const b = y.program;
    n.uniformBlockBinding(x, b);
  }
  function c(x, y) {
    let b = r[x.id];
    b === void 0 && (p(x), b = u(x), r[x.id] = b, x.addEventListener("dispose", g));
    const T = y.program;
    n.updateUBOMapping(x, T);
    const S = e.render.frame;
    s[x.id] !== S && (d(x), s[x.id] = S);
  }
  function u(x) {
    const y = h();
    x.__bindingPointIndex = y;
    const b = i.createBuffer(), T = x.__size, S = x.usage;
    return i.bindBuffer(i.UNIFORM_BUFFER, b), i.bufferData(i.UNIFORM_BUFFER, T, S), i.bindBuffer(i.UNIFORM_BUFFER, null), i.bindBufferBase(i.UNIFORM_BUFFER, y, b), b;
  }
  function h() {
    for (let x = 0; x < o; x++)
      if (a.indexOf(x) === -1)
        return a.push(x), x;
    return le("WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached."), 0;
  }
  function d(x) {
    const y = r[x.id], b = x.uniforms, T = x.__cache;
    i.bindBuffer(i.UNIFORM_BUFFER, y);
    for (let S = 0, E = b.length; S < E; S++) {
      const v = Array.isArray(b[S]) ? b[S] : [b[S]];
      for (let M = 0, F = v.length; M < F; M++) {
        const R = v[M];
        if (f(R, S, M, T) === !0) {
          const I = R.__offset, B = Array.isArray(R.value) ? R.value : [R.value];
          let N = 0;
          for (let C = 0; C < B.length; C++) {
            const L = B[C], k = _(L);
            typeof L == "number" || typeof L == "boolean" ? (R.__data[0] = L, i.bufferSubData(i.UNIFORM_BUFFER, I + N, R.__data)) : L.isMatrix3 ? (R.__data[0] = L.elements[0], R.__data[1] = L.elements[1], R.__data[2] = L.elements[2], R.__data[3] = 0, R.__data[4] = L.elements[3], R.__data[5] = L.elements[4], R.__data[6] = L.elements[5], R.__data[7] = 0, R.__data[8] = L.elements[6], R.__data[9] = L.elements[7], R.__data[10] = L.elements[8], R.__data[11] = 0) : (L.toArray(R.__data, N), N += k.storage / Float32Array.BYTES_PER_ELEMENT);
          }
          i.bufferSubData(i.UNIFORM_BUFFER, I, R.__data);
        }
      }
    }
    i.bindBuffer(i.UNIFORM_BUFFER, null);
  }
  function f(x, y, b, T) {
    const S = x.value, E = y + "_" + b;
    if (T[E] === void 0)
      return typeof S == "number" || typeof S == "boolean" ? T[E] = S : T[E] = S.clone(), !0;
    {
      const v = T[E];
      if (typeof S == "number" || typeof S == "boolean") {
        if (v !== S)
          return T[E] = S, !0;
      } else if (v.equals(S) === !1)
        return v.copy(S), !0;
    }
    return !1;
  }
  function p(x) {
    const y = x.uniforms;
    let b = 0;
    const T = 16;
    for (let E = 0, v = y.length; E < v; E++) {
      const M = Array.isArray(y[E]) ? y[E] : [y[E]];
      for (let F = 0, R = M.length; F < R; F++) {
        const I = M[F], B = Array.isArray(I.value) ? I.value : [I.value];
        for (let N = 0, C = B.length; N < C; N++) {
          const L = B[N], k = _(L), re = b % T, se = re % k.boundary, ve = re + se;
          b += se, ve !== 0 && T - ve < k.storage && (b += T - ve), I.__data = new Float32Array(k.storage / Float32Array.BYTES_PER_ELEMENT), I.__offset = b, b += k.storage;
        }
      }
    }
    const S = b % T;
    return S > 0 && (b += T - S), x.__size = b, x.__cache = {}, this;
  }
  function _(x) {
    const y = {
      boundary: 0,
      // bytes
      storage: 0
      // bytes
    };
    return typeof x == "number" || typeof x == "boolean" ? (y.boundary = 4, y.storage = 4) : x.isVector2 ? (y.boundary = 8, y.storage = 8) : x.isVector3 || x.isColor ? (y.boundary = 16, y.storage = 12) : x.isVector4 ? (y.boundary = 16, y.storage = 16) : x.isMatrix3 ? (y.boundary = 48, y.storage = 48) : x.isMatrix4 ? (y.boundary = 64, y.storage = 64) : x.isTexture ? oe("WebGLRenderer: Texture samplers can not be part of an uniforms group.") : oe("WebGLRenderer: Unsupported uniform value type.", x), y;
  }
  function g(x) {
    const y = x.target;
    y.removeEventListener("dispose", g);
    const b = a.indexOf(y.__bindingPointIndex);
    a.splice(b, 1), i.deleteBuffer(r[y.id]), delete r[y.id], delete s[y.id];
  }
  function m() {
    for (const x in r)
      i.deleteBuffer(r[x]);
    a = [], r = {}, s = {};
  }
  return {
    bind: l,
    update: c,
    dispose: m
  };
}
const Q1 = new Uint16Array([
  12469,
  15057,
  12620,
  14925,
  13266,
  14620,
  13807,
  14376,
  14323,
  13990,
  14545,
  13625,
  14713,
  13328,
  14840,
  12882,
  14931,
  12528,
  14996,
  12233,
  15039,
  11829,
  15066,
  11525,
  15080,
  11295,
  15085,
  10976,
  15082,
  10705,
  15073,
  10495,
  13880,
  14564,
  13898,
  14542,
  13977,
  14430,
  14158,
  14124,
  14393,
  13732,
  14556,
  13410,
  14702,
  12996,
  14814,
  12596,
  14891,
  12291,
  14937,
  11834,
  14957,
  11489,
  14958,
  11194,
  14943,
  10803,
  14921,
  10506,
  14893,
  10278,
  14858,
  9960,
  14484,
  14039,
  14487,
  14025,
  14499,
  13941,
  14524,
  13740,
  14574,
  13468,
  14654,
  13106,
  14743,
  12678,
  14818,
  12344,
  14867,
  11893,
  14889,
  11509,
  14893,
  11180,
  14881,
  10751,
  14852,
  10428,
  14812,
  10128,
  14765,
  9754,
  14712,
  9466,
  14764,
  13480,
  14764,
  13475,
  14766,
  13440,
  14766,
  13347,
  14769,
  13070,
  14786,
  12713,
  14816,
  12387,
  14844,
  11957,
  14860,
  11549,
  14868,
  11215,
  14855,
  10751,
  14825,
  10403,
  14782,
  10044,
  14729,
  9651,
  14666,
  9352,
  14599,
  9029,
  14967,
  12835,
  14966,
  12831,
  14963,
  12804,
  14954,
  12723,
  14936,
  12564,
  14917,
  12347,
  14900,
  11958,
  14886,
  11569,
  14878,
  11247,
  14859,
  10765,
  14828,
  10401,
  14784,
  10011,
  14727,
  9600,
  14660,
  9289,
  14586,
  8893,
  14508,
  8533,
  15111,
  12234,
  15110,
  12234,
  15104,
  12216,
  15092,
  12156,
  15067,
  12010,
  15028,
  11776,
  14981,
  11500,
  14942,
  11205,
  14902,
  10752,
  14861,
  10393,
  14812,
  9991,
  14752,
  9570,
  14682,
  9252,
  14603,
  8808,
  14519,
  8445,
  14431,
  8145,
  15209,
  11449,
  15208,
  11451,
  15202,
  11451,
  15190,
  11438,
  15163,
  11384,
  15117,
  11274,
  15055,
  10979,
  14994,
  10648,
  14932,
  10343,
  14871,
  9936,
  14803,
  9532,
  14729,
  9218,
  14645,
  8742,
  14556,
  8381,
  14461,
  8020,
  14365,
  7603,
  15273,
  10603,
  15272,
  10607,
  15267,
  10619,
  15256,
  10631,
  15231,
  10614,
  15182,
  10535,
  15118,
  10389,
  15042,
  10167,
  14963,
  9787,
  14883,
  9447,
  14800,
  9115,
  14710,
  8665,
  14615,
  8318,
  14514,
  7911,
  14411,
  7507,
  14279,
  7198,
  15314,
  9675,
  15313,
  9683,
  15309,
  9712,
  15298,
  9759,
  15277,
  9797,
  15229,
  9773,
  15166,
  9668,
  15084,
  9487,
  14995,
  9274,
  14898,
  8910,
  14800,
  8539,
  14697,
  8234,
  14590,
  7790,
  14479,
  7409,
  14367,
  7067,
  14178,
  6621,
  15337,
  8619,
  15337,
  8631,
  15333,
  8677,
  15325,
  8769,
  15305,
  8871,
  15264,
  8940,
  15202,
  8909,
  15119,
  8775,
  15022,
  8565,
  14916,
  8328,
  14804,
  8009,
  14688,
  7614,
  14569,
  7287,
  14448,
  6888,
  14321,
  6483,
  14088,
  6171,
  15350,
  7402,
  15350,
  7419,
  15347,
  7480,
  15340,
  7613,
  15322,
  7804,
  15287,
  7973,
  15229,
  8057,
  15148,
  8012,
  15046,
  7846,
  14933,
  7611,
  14810,
  7357,
  14682,
  7069,
  14552,
  6656,
  14421,
  6316,
  14251,
  5948,
  14007,
  5528,
  15356,
  5942,
  15356,
  5977,
  15353,
  6119,
  15348,
  6294,
  15332,
  6551,
  15302,
  6824,
  15249,
  7044,
  15171,
  7122,
  15070,
  7050,
  14949,
  6861,
  14818,
  6611,
  14679,
  6349,
  14538,
  6067,
  14398,
  5651,
  14189,
  5311,
  13935,
  4958,
  15359,
  4123,
  15359,
  4153,
  15356,
  4296,
  15353,
  4646,
  15338,
  5160,
  15311,
  5508,
  15263,
  5829,
  15188,
  6042,
  15088,
  6094,
  14966,
  6001,
  14826,
  5796,
  14678,
  5543,
  14527,
  5287,
  14377,
  4985,
  14133,
  4586,
  13869,
  4257,
  15360,
  1563,
  15360,
  1642,
  15358,
  2076,
  15354,
  2636,
  15341,
  3350,
  15317,
  4019,
  15273,
  4429,
  15203,
  4732,
  15105,
  4911,
  14981,
  4932,
  14836,
  4818,
  14679,
  4621,
  14517,
  4386,
  14359,
  4156,
  14083,
  3795,
  13808,
  3437,
  15360,
  122,
  15360,
  137,
  15358,
  285,
  15355,
  636,
  15344,
  1274,
  15322,
  2177,
  15281,
  2765,
  15215,
  3223,
  15120,
  3451,
  14995,
  3569,
  14846,
  3567,
  14681,
  3466,
  14511,
  3305,
  14344,
  3121,
  14037,
  2800,
  13753,
  2467,
  15360,
  0,
  15360,
  1,
  15359,
  21,
  15355,
  89,
  15346,
  253,
  15325,
  479,
  15287,
  796,
  15225,
  1148,
  15133,
  1492,
  15008,
  1749,
  14856,
  1882,
  14685,
  1886,
  14506,
  1783,
  14324,
  1608,
  13996,
  1398,
  13702,
  1183
]);
let or = null;
function J1() {
  return or === null && (or = new Zm(Q1, 16, 16, ri, nn), or.name = "DFG_LUT", or.minFilter = Ot, or.magFilter = Ot, or.wrapS = fi, or.wrapT = fi, or.generateMipmaps = !1, or.needsUpdate = !0), or;
}
class eN {
  /**
   * Constructs a new WebGL renderer.
   *
   * @param {WebGLRenderer~Options} [parameters] - The configuration parameter.
   */
  constructor(e = {}) {
    const {
      canvas: t = Zv(),
      context: n = null,
      depth: r = !0,
      stencil: s = !1,
      alpha: a = !1,
      antialias: o = !1,
      premultipliedAlpha: l = !0,
      preserveDrawingBuffer: c = !1,
      powerPreference: u = "default",
      failIfMajorPerformanceCaveat: h = !1,
      reversedDepthBuffer: d = !1,
      outputBufferType: f = Zt
    } = e;
    this.isWebGLRenderer = !0;
    let p;
    if (n !== null) {
      if (typeof WebGLRenderingContext < "u" && n instanceof WebGLRenderingContext)
        throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163.");
      p = n.getContextAttributes().alpha;
    } else
      p = a;
    const _ = f, g = /* @__PURE__ */ new Set([
      vl,
      xl,
      _l
    ]), m = /* @__PURE__ */ new Set([
      Zt,
      Dt,
      Ji,
      Ci,
      rd,
      sd
    ]), x = new Uint32Array(4), y = new Int32Array(4);
    let b = null, T = null;
    const S = [], E = [];
    let v = null;
    this.domElement = t, this.debug = {
      /**
       * Enables error checking and reporting when shader programs are being compiled.
       * @type {boolean}
       */
      checkShaderErrors: !0,
      /**
       * Callback for custom error reporting.
       * @type {?Function}
       */
      onShaderError: null
    }, this.autoClear = !0, this.autoClearColor = !0, this.autoClearDepth = !0, this.autoClearStencil = !0, this.sortObjects = !0, this.clippingPlanes = [], this.localClippingEnabled = !1, this.toneMapping = In, this.toneMappingExposure = 1, this.transmissionResolutionScale = 1;
    const M = this;
    let F = !1;
    this._outputColorSpace = Jn;
    let R = 0, I = 0, B = null, N = -1, C = null;
    const L = new rt(), k = new rt();
    let re = null;
    const se = new He(0);
    let ve = 0, X = t.width, te = t.height, me = 1, Qe = null, ce = null;
    const z = new rt(0, 0, X, te), Z = new rt(0, 0, X, te);
    let ue = !1;
    const Ie = new nu();
    let we = !1, Re = !1;
    const It = new pt(), ut = new P(), mt = new rt(), bt = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: !0 };
    let tt = !1;
    function Rt() {
      return B === null ? me : 1;
    }
    let O = n;
    function fn(A, H) {
      return t.getContext(A, H);
    }
    try {
      const A = {
        alpha: !0,
        depth: r,
        stencil: s,
        antialias: o,
        premultipliedAlpha: l,
        preserveDrawingBuffer: c,
        powerPreference: u,
        failIfMajorPerformanceCaveat: h
      };
      if ("setAttribute" in t && t.setAttribute("data-engine", `three.js r${za}`), t.addEventListener("webglcontextlost", Oe, !1), t.addEventListener("webglcontextrestored", st, !1), t.addEventListener("webglcontextcreationerror", jt, !1), O === null) {
        const H = "webgl2";
        if (O = fn(H, A), O === null)
          throw fn(H) ? new Error("Error creating WebGL context with your selected attributes.") : new Error("Error creating WebGL context.");
      }
    } catch (A) {
      throw le("WebGLRenderer: " + A.message), A;
    }
    let Ct, Xt, Ve, D, w, V, ae, he, ie, Ue, ye, Ye, Je, fe, ge, Be, ke, Ce, dt, G, be, _e, De;
    function pe() {
      Ct = new eC(O), Ct.init(), be = new $1(O, Ct), Xt = new qR(O, Ct, e, be), Ve = new z1(O, Ct), Xt.reversedDepthBuffer && d && Ve.buffers.depth.setReversed(!0), D = new iC(O), w = new R1(), V = new H1(O, Ct, Ve, w, Xt, be, D), ae = new JR(M), he = new lw(O), _e = new $R(O, he), ie = new tC(O, he, D, _e), Ue = new sC(O, ie, he, _e, D), Ce = new rC(O, Xt, V), ge = new XR(w), ye = new A1(M, ae, Ct, Xt, _e, ge), Ye = new K1(M, w), Je = new N1(), fe = new U1(Ct), ke = new HR(M, ae, Ve, Ue, p, l), Be = new V1(M, Ue, Xt), De = new Z1(O, D, Xt, Ve), dt = new WR(O, Ct, D), G = new nC(O, Ct, D), D.programs = ye.programs, M.capabilities = Xt, M.extensions = Ct, M.properties = w, M.renderLists = Je, M.shadowMap = Be, M.state = Ve, M.info = D;
    }
    pe(), _ !== Zt && (v = new oC(_, t.width, t.height, r, s));
    const ne = new j1(M, O);
    this.xr = ne, this.getContext = function() {
      return O;
    }, this.getContextAttributes = function() {
      return O.getContextAttributes();
    }, this.forceContextLoss = function() {
      const A = Ct.get("WEBGL_lose_context");
      A && A.loseContext();
    }, this.forceContextRestore = function() {
      const A = Ct.get("WEBGL_lose_context");
      A && A.restoreContext();
    }, this.getPixelRatio = function() {
      return me;
    }, this.setPixelRatio = function(A) {
      A !== void 0 && (me = A, this.setSize(X, te, !1));
    }, this.getSize = function(A) {
      return A.set(X, te);
    }, this.setSize = function(A, H, j = !0) {
      if (ne.isPresenting) {
        oe("WebGLRenderer: Can't change size while VR device is presenting.");
        return;
      }
      X = A, te = H, t.width = Math.floor(A * me), t.height = Math.floor(H * me), j === !0 && (t.style.width = A + "px", t.style.height = H + "px"), v !== null && v.setSize(t.width, t.height), this.setViewport(0, 0, A, H);
    }, this.getDrawingBufferSize = function(A) {
      return A.set(X * me, te * me).floor();
    }, this.setDrawingBufferSize = function(A, H, j) {
      X = A, te = H, me = j, t.width = Math.floor(A * j), t.height = Math.floor(H * j), this.setViewport(0, 0, A, H);
    }, this.setEffects = function(A) {
      if (_ === Zt) {
        console.error("THREE.WebGLRenderer: setEffects() requires outputBufferType set to HalfFloatType or FloatType.");
        return;
      }
      if (A) {
        for (let H = 0; H < A.length; H++)
          if (A[H].isOutputPass === !0) {
            console.warn("THREE.WebGLRenderer: OutputPass is not needed in setEffects(). Tone mapping and color space conversion are applied automatically.");
            break;
          }
      }
      v.setEffects(A || []);
    }, this.getCurrentViewport = function(A) {
      return A.copy(L);
    }, this.getViewport = function(A) {
      return A.copy(z);
    }, this.setViewport = function(A, H, j, q) {
      A.isVector4 ? z.set(A.x, A.y, A.z, A.w) : z.set(A, H, j, q), Ve.viewport(L.copy(z).multiplyScalar(me).round());
    }, this.getScissor = function(A) {
      return A.copy(Z);
    }, this.setScissor = function(A, H, j, q) {
      A.isVector4 ? Z.set(A.x, A.y, A.z, A.w) : Z.set(A, H, j, q), Ve.scissor(k.copy(Z).multiplyScalar(me).round());
    }, this.getScissorTest = function() {
      return ue;
    }, this.setScissorTest = function(A) {
      Ve.setScissorTest(ue = A);
    }, this.setOpaqueSort = function(A) {
      Qe = A;
    }, this.setTransparentSort = function(A) {
      ce = A;
    }, this.getClearColor = function(A) {
      return A.copy(ke.getClearColor());
    }, this.setClearColor = function() {
      ke.setClearColor(...arguments);
    }, this.getClearAlpha = function() {
      return ke.getClearAlpha();
    }, this.setClearAlpha = function() {
      ke.setClearAlpha(...arguments);
    }, this.clear = function(A = !0, H = !0, j = !0) {
      let q = 0;
      if (A) {
        let W = !1;
        if (B !== null) {
          const Me = B.texture.format;
          W = g.has(Me);
        }
        if (W) {
          const Me = B.texture.type, Ne = m.has(Me), Ee = ke.getClearColor(), Ge = ke.getClearAlpha(), We = Ee.r, ot = Ee.g, ft = Ee.b;
          Ne ? (x[0] = We, x[1] = ot, x[2] = ft, x[3] = Ge, O.clearBufferuiv(O.COLOR, 0, x)) : (y[0] = We, y[1] = ot, y[2] = ft, y[3] = Ge, O.clearBufferiv(O.COLOR, 0, y));
        } else
          q |= O.COLOR_BUFFER_BIT;
      }
      H && (q |= O.DEPTH_BUFFER_BIT), j && (q |= O.STENCIL_BUFFER_BIT, this.state.buffers.stencil.setMask(4294967295)), q !== 0 && O.clear(q);
    }, this.clearColor = function() {
      this.clear(!0, !1, !1);
    }, this.clearDepth = function() {
      this.clear(!1, !0, !1);
    }, this.clearStencil = function() {
      this.clear(!1, !1, !0);
    }, this.dispose = function() {
      t.removeEventListener("webglcontextlost", Oe, !1), t.removeEventListener("webglcontextrestored", st, !1), t.removeEventListener("webglcontextcreationerror", jt, !1), ke.dispose(), Je.dispose(), fe.dispose(), w.dispose(), ae.dispose(), Ue.dispose(), _e.dispose(), De.dispose(), ye.dispose(), ne.dispose(), ne.removeEventListener("sessionstart", e_), ne.removeEventListener("sessionend", t_), ea.stop();
    };
    function Oe(A) {
      A.preventDefault(), Hc("WebGLRenderer: Context Lost."), F = !0;
    }
    function st() {
      Hc("WebGLRenderer: Context Restored."), F = !1;
      const A = D.autoReset, H = Be.enabled, j = Be.autoUpdate, q = Be.needsUpdate, W = Be.type;
      pe(), D.autoReset = A, Be.enabled = H, Be.autoUpdate = j, Be.needsUpdate = q, Be.type = W;
    }
    function jt(A) {
      le("WebGLRenderer: A WebGL context could not be created. Reason: ", A.statusMessage);
    }
    function Ut(A) {
      const H = A.target;
      H.removeEventListener("dispose", Ut), Br(H);
    }
    function Br(A) {
      Or(A), w.remove(A);
    }
    function Or(A) {
      const H = w.get(A).programs;
      H !== void 0 && (H.forEach(function(j) {
        ye.releaseProgram(j);
      }), A.isShaderMaterial && ye.releaseShaderCache(A));
    }
    this.renderBufferDirect = function(A, H, j, q, W, Me) {
      H === null && (H = bt);
      const Ne = W.isMesh && W.matrixWorld.determinant() < 0, Ee = eM(A, H, j, q, W);
      Ve.setMaterial(q, Ne);
      let Ge = j.index, We = 1;
      if (q.wireframe === !0) {
        if (Ge = ie.getWireframeAttribute(j), Ge === void 0)
          return;
        We = 2;
      }
      const ot = j.drawRange, ft = j.attributes.position;
      let qe = ot.start * We, kt = (ot.start + ot.count) * We;
      Me !== null && (qe = Math.max(qe, Me.start * We), kt = Math.min(kt, (Me.start + Me.count) * We)), Ge !== null ? (qe = Math.max(qe, 0), kt = Math.min(kt, Ge.count)) : ft != null && (qe = Math.max(qe, 0), kt = Math.min(kt, ft.count));
      const un = kt - qe;
      if (un < 0 || un === 1 / 0)
        return;
      _e.setup(W, q, Ee, j, Ge);
      let on, Gt = dt;
      if (Ge !== null && (on = he.get(Ge), Gt = G, Gt.setIndex(on)), W.isMesh)
        q.wireframe === !0 ? (Ve.setLineWidth(q.wireframeLinewidth * Rt()), Gt.setMode(O.LINES)) : Gt.setMode(O.TRIANGLES);
      else if (W.isLine) {
        let Vn = q.linewidth;
        Vn === void 0 && (Vn = 1), Ve.setLineWidth(Vn * Rt()), W.isLineSegments ? Gt.setMode(O.LINES) : W.isLineLoop ? Gt.setMode(O.LINE_LOOP) : Gt.setMode(O.LINE_STRIP);
      } else
        W.isPoints ? Gt.setMode(O.POINTS) : W.isSprite && Gt.setMode(O.TRIANGLES);
      if (W.isBatchedMesh)
        if (W._multiDrawInstances !== null)
          Pt("WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."), Gt.renderMultiDrawInstances(W._multiDrawStarts, W._multiDrawCounts, W._multiDrawCount, W._multiDrawInstances);
        else if (Ct.get("WEBGL_multi_draw"))
          Gt.renderMultiDraw(W._multiDrawStarts, W._multiDrawCounts, W._multiDrawCount);
        else {
          const Vn = W._multiDrawStarts, ze = W._multiDrawCounts, yi = W._multiDrawCount, St = Ge ? he.get(Ge).bytesPerElement : 1, $i = w.get(q).currentProgram.getUniforms();
          for (let ir = 0; ir < yi; ir++)
            $i.setValue(O, "_gl_DrawID", ir), Gt.render(Vn[ir] / St, ze[ir]);
        }
      else if (W.isInstancedMesh)
        Gt.renderInstances(qe, un, W.count);
      else if (j.isInstancedBufferGeometry) {
        const Vn = j._maxInstanceCount !== void 0 ? j._maxInstanceCount : 1 / 0, ze = Math.min(j.instanceCount, Vn);
        Gt.renderInstances(qe, un, ze);
      } else
        Gt.render(qe, un);
    };
    function Jg(A, H, j) {
      A.transparent === !0 && A.side === Rn && A.forceSinglePass === !1 ? (A.side = Ft, A.needsUpdate = !0, pu(A, H, j), A.side = ai, A.needsUpdate = !0, pu(A, H, j), A.side = Rn) : pu(A, H, j);
    }
    this.compile = function(A, H, j = null) {
      j === null && (j = A), T = fe.get(j), T.init(H), E.push(T), j.traverseVisible(function(W) {
        W.isLight && W.layers.test(H.layers) && (T.pushLight(W), W.castShadow && T.pushShadow(W));
      }), A !== j && A.traverseVisible(function(W) {
        W.isLight && W.layers.test(H.layers) && (T.pushLight(W), W.castShadow && T.pushShadow(W));
      }), T.setupLights();
      const q = /* @__PURE__ */ new Set();
      return A.traverse(function(W) {
        if (!(W.isMesh || W.isPoints || W.isLine || W.isSprite))
          return;
        const Me = W.material;
        if (Me)
          if (Array.isArray(Me))
            for (let Ne = 0; Ne < Me.length; Ne++) {
              const Ee = Me[Ne];
              Jg(Ee, j, W), q.add(Ee);
            }
          else
            Jg(Me, j, W), q.add(Me);
      }), T = E.pop(), q;
    }, this.compileAsync = function(A, H, j = null) {
      const q = this.compile(A, H, j);
      return new Promise((W) => {
        function Me() {
          if (q.forEach(function(Ne) {
            w.get(Ne).currentProgram.isReady() && q.delete(Ne);
          }), q.size === 0) {
            W(A);
            return;
          }
          setTimeout(Me, 10);
        }
        Ct.get("KHR_parallel_shader_compile") !== null ? Me() : setTimeout(Me, 10);
      });
    };
    let Ud = null;
    function JT(A) {
      Ud && Ud(A);
    }
    function e_() {
      ea.stop();
    }
    function t_() {
      ea.start();
    }
    const ea = new _y();
    ea.setAnimationLoop(JT), typeof self < "u" && ea.setContext(self), this.setAnimationLoop = function(A) {
      Ud = A, ne.setAnimationLoop(A), A === null ? ea.stop() : ea.start();
    }, ne.addEventListener("sessionstart", e_), ne.addEventListener("sessionend", t_), this.render = function(A, H) {
      if (H !== void 0 && H.isCamera !== !0) {
        le("WebGLRenderer.render: camera is not an instance of THREE.Camera.");
        return;
      }
      if (F === !0)
        return;
      const j = ne.enabled === !0 && ne.isPresenting === !0, q = v !== null && (B === null || j) && v.begin(M, B);
      if (A.matrixWorldAutoUpdate === !0 && A.updateMatrixWorld(), H.parent === null && H.matrixWorldAutoUpdate === !0 && H.updateMatrixWorld(), ne.enabled === !0 && ne.isPresenting === !0 && (v === null || v.isCompositing() === !1) && (ne.cameraAutoUpdate === !0 && ne.updateCamera(H), H = ne.getCamera()), A.isScene === !0 && A.onBeforeRender(M, A, H, B), T = fe.get(A, E.length), T.init(H), E.push(T), It.multiplyMatrices(H.projectionMatrix, H.matrixWorldInverse), Ie.setFromProjectionMatrix(It, si, H.reversedDepth), Re = this.localClippingEnabled, we = ge.init(this.clippingPlanes, Re), b = Je.get(A, S.length), b.init(), S.push(b), ne.enabled === !0 && ne.isPresenting === !0) {
        const Ne = M.xr.getDepthSensingMesh();
        Ne !== null && Bd(Ne, H, -1 / 0, M.sortObjects);
      }
      Bd(A, H, 0, M.sortObjects), b.finish(), M.sortObjects === !0 && b.sort(Qe, ce), tt = ne.enabled === !1 || ne.isPresenting === !1 || ne.hasDepthSensing() === !1, tt && ke.addToRenderList(b, A), this.info.render.frame++, we === !0 && ge.beginShadows();
      const W = T.state.shadowsArray;
      if (Be.render(W, A, H), we === !0 && ge.endShadows(), this.info.autoReset === !0 && this.info.reset(), (q && v.hasRenderPass()) === !1) {
        const Ne = b.opaque, Ee = b.transmissive;
        if (T.setupLights(), H.isArrayCamera) {
          const Ge = H.cameras;
          if (Ee.length > 0)
            for (let We = 0, ot = Ge.length; We < ot; We++) {
              const ft = Ge[We];
              i_(Ne, Ee, A, ft);
            }
          tt && ke.render(A);
          for (let We = 0, ot = Ge.length; We < ot; We++) {
            const ft = Ge[We];
            n_(b, A, ft, ft.viewport);
          }
        } else
          Ee.length > 0 && i_(Ne, Ee, A, H), tt && ke.render(A), n_(b, A, H);
      }
      B !== null && I === 0 && (V.updateMultisampleRenderTarget(B), V.updateRenderTargetMipmap(B)), q && v.end(M), A.isScene === !0 && A.onAfterRender(M, A, H), _e.resetDefaultState(), N = -1, C = null, E.pop(), E.length > 0 ? (T = E[E.length - 1], we === !0 && ge.setGlobalState(M.clippingPlanes, T.state.camera)) : T = null, S.pop(), S.length > 0 ? b = S[S.length - 1] : b = null;
    };
    function Bd(A, H, j, q) {
      if (A.visible === !1)
        return;
      if (A.layers.test(H.layers)) {
        if (A.isGroup)
          j = A.renderOrder;
        else if (A.isLOD)
          A.autoUpdate === !0 && A.update(H);
        else if (A.isLight)
          T.pushLight(A), A.castShadow && T.pushShadow(A);
        else if (A.isSprite) {
          if (!A.frustumCulled || Ie.intersectsSprite(A)) {
            q && mt.setFromMatrixPosition(A.matrixWorld).applyMatrix4(It);
            const Ne = Ue.update(A), Ee = A.material;
            Ee.visible && b.push(A, Ne, Ee, j, mt.z, null);
          }
        } else if ((A.isMesh || A.isLine || A.isPoints) && (!A.frustumCulled || Ie.intersectsObject(A))) {
          const Ne = Ue.update(A), Ee = A.material;
          if (q && (A.boundingSphere !== void 0 ? (A.boundingSphere === null && A.computeBoundingSphere(), mt.copy(A.boundingSphere.center)) : (Ne.boundingSphere === null && Ne.computeBoundingSphere(), mt.copy(Ne.boundingSphere.center)), mt.applyMatrix4(A.matrixWorld).applyMatrix4(It)), Array.isArray(Ee)) {
            const Ge = Ne.groups;
            for (let We = 0, ot = Ge.length; We < ot; We++) {
              const ft = Ge[We], qe = Ee[ft.materialIndex];
              qe && qe.visible && b.push(A, Ne, qe, j, mt.z, ft);
            }
          } else
            Ee.visible && b.push(A, Ne, Ee, j, mt.z, null);
        }
      }
      const Me = A.children;
      for (let Ne = 0, Ee = Me.length; Ne < Ee; Ne++)
        Bd(Me[Ne], H, j, q);
    }
    function n_(A, H, j, q) {
      const { opaque: W, transmissive: Me, transparent: Ne } = A;
      T.setupLightsView(j), we === !0 && ge.setGlobalState(M.clippingPlanes, j), q && Ve.viewport(L.copy(q)), W.length > 0 && fu(W, H, j), Me.length > 0 && fu(Me, H, j), Ne.length > 0 && fu(Ne, H, j), Ve.buffers.depth.setTest(!0), Ve.buffers.depth.setMask(!0), Ve.buffers.color.setMask(!0), Ve.setPolygonOffset(!1);
    }
    function i_(A, H, j, q) {
      if ((j.isScene === !0 ? j.overrideMaterial : null) !== null)
        return;
      if (T.state.transmissionRenderTarget[q.id] === void 0) {
        const qe = Ct.has("EXT_color_buffer_half_float") || Ct.has("EXT_color_buffer_float");
        T.state.transmissionRenderTarget[q.id] = new tr(1, 1, {
          generateMipmaps: !0,
          type: qe ? nn : Zt,
          minFilter: pi,
          samples: Math.max(4, Xt.samples),
          // to avoid feedback loops, the transmission render target requires a resolve, see #26177
          stencilBuffer: s,
          resolveDepthBuffer: !1,
          resolveStencilBuffer: !1,
          colorSpace: Ke.workingColorSpace
        });
      }
      const Me = T.state.transmissionRenderTarget[q.id], Ne = q.viewport || L;
      Me.setSize(Ne.z * M.transmissionResolutionScale, Ne.w * M.transmissionResolutionScale);
      const Ee = M.getRenderTarget(), Ge = M.getActiveCubeFace(), We = M.getActiveMipmapLevel();
      M.setRenderTarget(Me), M.getClearColor(se), ve = M.getClearAlpha(), ve < 1 && M.setClearColor(16777215, 0.5), M.clear(), tt && ke.render(j);
      const ot = M.toneMapping;
      M.toneMapping = In;
      const ft = q.viewport;
      if (q.viewport !== void 0 && (q.viewport = void 0), T.setupLightsView(q), we === !0 && ge.setGlobalState(M.clippingPlanes, q), fu(A, j, q), V.updateMultisampleRenderTarget(Me), V.updateRenderTargetMipmap(Me), Ct.has("WEBGL_multisampled_render_to_texture") === !1) {
        let qe = !1;
        for (let kt = 0, un = H.length; kt < un; kt++) {
          const on = H[kt], { object: Gt, geometry: Vn, material: ze, group: yi } = on;
          if (ze.side === Rn && Gt.layers.test(q.layers)) {
            const St = ze.side;
            ze.side = Ft, ze.needsUpdate = !0, r_(Gt, j, q, Vn, ze, yi), ze.side = St, ze.needsUpdate = !0, qe = !0;
          }
        }
        qe === !0 && (V.updateMultisampleRenderTarget(Me), V.updateRenderTargetMipmap(Me));
      }
      M.setRenderTarget(Ee, Ge, We), M.setClearColor(se, ve), ft !== void 0 && (q.viewport = ft), M.toneMapping = ot;
    }
    function fu(A, H, j) {
      const q = H.isScene === !0 ? H.overrideMaterial : null;
      for (let W = 0, Me = A.length; W < Me; W++) {
        const Ne = A[W], { object: Ee, geometry: Ge, group: We } = Ne;
        let ot = Ne.material;
        ot.allowOverride === !0 && q !== null && (ot = q), Ee.layers.test(j.layers) && r_(Ee, H, j, Ge, ot, We);
      }
    }
    function r_(A, H, j, q, W, Me) {
      A.onBeforeRender(M, H, j, q, W, Me), A.modelViewMatrix.multiplyMatrices(j.matrixWorldInverse, A.matrixWorld), A.normalMatrix.getNormalMatrix(A.modelViewMatrix), W.onBeforeRender(M, H, j, q, A, Me), W.transparent === !0 && W.side === Rn && W.forceSinglePass === !1 ? (W.side = Ft, W.needsUpdate = !0, M.renderBufferDirect(j, H, q, W, A, Me), W.side = ai, W.needsUpdate = !0, M.renderBufferDirect(j, H, q, W, A, Me), W.side = Rn) : M.renderBufferDirect(j, H, q, W, A, Me), A.onAfterRender(M, H, j, q, W, Me);
    }
    function pu(A, H, j) {
      H.isScene !== !0 && (H = bt);
      const q = w.get(A), W = T.state.lights, Me = T.state.shadowsArray, Ne = W.state.version, Ee = ye.getParameters(A, W.state, Me, H, j), Ge = ye.getProgramCacheKey(Ee);
      let We = q.programs;
      q.environment = A.isMeshStandardMaterial || A.isMeshLambertMaterial || A.isMeshPhongMaterial ? H.environment : null, q.fog = H.fog;
      const ot = A.isMeshStandardMaterial || A.isMeshLambertMaterial && !A.envMap || A.isMeshPhongMaterial && !A.envMap;
      q.envMap = ae.get(A.envMap || q.environment, ot), q.envMapRotation = q.environment !== null && A.envMap === null ? H.environmentRotation : A.envMapRotation, We === void 0 && (A.addEventListener("dispose", Ut), We = /* @__PURE__ */ new Map(), q.programs = We);
      let ft = We.get(Ge);
      if (ft !== void 0) {
        if (q.currentProgram === ft && q.lightsStateVersion === Ne)
          return a_(A, Ee), ft;
      } else
        Ee.uniforms = ye.getUniforms(A), A.onBeforeCompile(Ee, M), ft = ye.acquireProgram(Ee, Ge), We.set(Ge, ft), q.uniforms = Ee.uniforms;
      const qe = q.uniforms;
      return (!A.isShaderMaterial && !A.isRawShaderMaterial || A.clipping === !0) && (qe.clippingPlanes = ge.uniform), a_(A, Ee), q.needsLights = nM(A), q.lightsStateVersion = Ne, q.needsLights && (qe.ambientLightColor.value = W.state.ambient, qe.lightProbe.value = W.state.probe, qe.directionalLights.value = W.state.directional, qe.directionalLightShadows.value = W.state.directionalShadow, qe.spotLights.value = W.state.spot, qe.spotLightShadows.value = W.state.spotShadow, qe.rectAreaLights.value = W.state.rectArea, qe.ltc_1.value = W.state.rectAreaLTC1, qe.ltc_2.value = W.state.rectAreaLTC2, qe.pointLights.value = W.state.point, qe.pointLightShadows.value = W.state.pointShadow, qe.hemisphereLights.value = W.state.hemi, qe.directionalShadowMatrix.value = W.state.directionalShadowMatrix, qe.spotLightMatrix.value = W.state.spotLightMatrix, qe.spotLightMap.value = W.state.spotLightMap, qe.pointShadowMatrix.value = W.state.pointShadowMatrix), q.currentProgram = ft, q.uniformsList = null, ft;
    }
    function s_(A) {
      if (A.uniformsList === null) {
        const H = A.currentProgram.getUniforms();
        A.uniformsList = Sh.seqWithValue(H.seq, A.uniforms);
      }
      return A.uniformsList;
    }
    function a_(A, H) {
      const j = w.get(A);
      j.outputColorSpace = H.outputColorSpace, j.batching = H.batching, j.batchingColor = H.batchingColor, j.instancing = H.instancing, j.instancingColor = H.instancingColor, j.instancingMorph = H.instancingMorph, j.skinning = H.skinning, j.morphTargets = H.morphTargets, j.morphNormals = H.morphNormals, j.morphColors = H.morphColors, j.morphTargetsCount = H.morphTargetsCount, j.numClippingPlanes = H.numClippingPlanes, j.numIntersection = H.numClipIntersection, j.vertexAlphas = H.vertexAlphas, j.vertexTangents = H.vertexTangents, j.toneMapping = H.toneMapping;
    }
    function eM(A, H, j, q, W) {
      H.isScene !== !0 && (H = bt), V.resetTextureUnits();
      const Me = H.fog, Ne = q.isMeshStandardMaterial || q.isMeshLambertMaterial || q.isMeshPhongMaterial ? H.environment : null, Ee = B === null ? M.outputColorSpace : B.isXRRenderTarget === !0 ? B.texture.colorSpace : La, Ge = q.isMeshStandardMaterial || q.isMeshLambertMaterial && !q.envMap || q.isMeshPhongMaterial && !q.envMap, We = ae.get(q.envMap || Ne, Ge), ot = q.vertexColors === !0 && !!j.attributes.color && j.attributes.color.itemSize === 4, ft = !!j.attributes.tangent && (!!q.normalMap || q.anisotropy > 0), qe = !!j.morphAttributes.position, kt = !!j.morphAttributes.normal, un = !!j.morphAttributes.color;
      let on = In;
      q.toneMapped && (B === null || B.isXRRenderTarget === !0) && (on = M.toneMapping);
      const Gt = j.morphAttributes.position || j.morphAttributes.normal || j.morphAttributes.color, Vn = Gt !== void 0 ? Gt.length : 0, ze = w.get(q), yi = T.state.lights;
      if (we === !0 && (Re === !0 || A !== C)) {
        const Tn = A === C && q.id === N;
        ge.setState(q, A, Tn);
      }
      let St = !1;
      q.version === ze.__version ? (ze.needsLights && ze.lightsStateVersion !== yi.state.version || ze.outputColorSpace !== Ee || W.isBatchedMesh && ze.batching === !1 || !W.isBatchedMesh && ze.batching === !0 || W.isBatchedMesh && ze.batchingColor === !0 && W.colorTexture === null || W.isBatchedMesh && ze.batchingColor === !1 && W.colorTexture !== null || W.isInstancedMesh && ze.instancing === !1 || !W.isInstancedMesh && ze.instancing === !0 || W.isSkinnedMesh && ze.skinning === !1 || !W.isSkinnedMesh && ze.skinning === !0 || W.isInstancedMesh && ze.instancingColor === !0 && W.instanceColor === null || W.isInstancedMesh && ze.instancingColor === !1 && W.instanceColor !== null || W.isInstancedMesh && ze.instancingMorph === !0 && W.morphTexture === null || W.isInstancedMesh && ze.instancingMorph === !1 && W.morphTexture !== null || ze.envMap !== We || q.fog === !0 && ze.fog !== Me || ze.numClippingPlanes !== void 0 && (ze.numClippingPlanes !== ge.numPlanes || ze.numIntersection !== ge.numIntersection) || ze.vertexAlphas !== ot || ze.vertexTangents !== ft || ze.morphTargets !== qe || ze.morphNormals !== kt || ze.morphColors !== un || ze.toneMapping !== on || ze.morphTargetsCount !== Vn) && (St = !0) : (St = !0, ze.__version = q.version);
      let $i = ze.currentProgram;
      St === !0 && ($i = pu(q, H, W));
      let ir = !1, ta = !1, Ya = !1;
      const zt = $i.getUniforms(), Dn = ze.uniforms;
      if (Ve.useProgram($i.program) && (ir = !0, ta = !0, Ya = !0), q.id !== N && (N = q.id, ta = !0), ir || C !== A) {
        Ve.buffers.depth.getReversed() && A.reversedDepth !== !0 && (A._reversedDepth = !0, A.updateProjectionMatrix()), zt.setValue(O, "projectionMatrix", A.projectionMatrix), zt.setValue(O, "viewMatrix", A.matrixWorldInverse);
        const ms = zt.map.cameraPosition;
        ms !== void 0 && ms.setValue(O, ut.setFromMatrixPosition(A.matrixWorld)), Xt.logarithmicDepthBuffer && zt.setValue(
          O,
          "logDepthBufFC",
          2 / (Math.log(A.far + 1) / Math.LN2)
        ), (q.isMeshPhongMaterial || q.isMeshToonMaterial || q.isMeshLambertMaterial || q.isMeshBasicMaterial || q.isMeshStandardMaterial || q.isShaderMaterial) && zt.setValue(O, "isOrthographic", A.isOrthographicCamera === !0), C !== A && (C = A, ta = !0, Ya = !0);
      }
      if (ze.needsLights && (yi.state.directionalShadowMap.length > 0 && zt.setValue(O, "directionalShadowMap", yi.state.directionalShadowMap, V), yi.state.spotShadowMap.length > 0 && zt.setValue(O, "spotShadowMap", yi.state.spotShadowMap, V), yi.state.pointShadowMap.length > 0 && zt.setValue(O, "pointShadowMap", yi.state.pointShadowMap, V)), W.isSkinnedMesh) {
        zt.setOptional(O, W, "bindMatrix"), zt.setOptional(O, W, "bindMatrixInverse");
        const Tn = W.skeleton;
        Tn && (Tn.boneTexture === null && Tn.computeBoneTexture(), zt.setValue(O, "boneTexture", Tn.boneTexture, V));
      }
      W.isBatchedMesh && (zt.setOptional(O, W, "batchingTexture"), zt.setValue(O, "batchingTexture", W._matricesTexture, V), zt.setOptional(O, W, "batchingIdTexture"), zt.setValue(O, "batchingIdTexture", W._indirectTexture, V), zt.setOptional(O, W, "batchingColorTexture"), W._colorsTexture !== null && zt.setValue(O, "batchingColorTexture", W._colorsTexture, V));
      const ps = j.morphAttributes;
      if ((ps.position !== void 0 || ps.normal !== void 0 || ps.color !== void 0) && Ce.update(W, j, $i), (ta || ze.receiveShadow !== W.receiveShadow) && (ze.receiveShadow = W.receiveShadow, zt.setValue(O, "receiveShadow", W.receiveShadow)), (q.isMeshStandardMaterial || q.isMeshLambertMaterial || q.isMeshPhongMaterial) && q.envMap === null && H.environment !== null && (Dn.envMapIntensity.value = H.environmentIntensity), Dn.dfgLUT !== void 0 && (Dn.dfgLUT.value = J1()), ta && (zt.setValue(O, "toneMappingExposure", M.toneMappingExposure), ze.needsLights && tM(Dn, Ya), Me && q.fog === !0 && Ye.refreshFogUniforms(Dn, Me), Ye.refreshMaterialUniforms(Dn, q, me, te, T.state.transmissionRenderTarget[A.id]), Sh.upload(O, s_(ze), Dn, V)), q.isShaderMaterial && q.uniformsNeedUpdate === !0 && (Sh.upload(O, s_(ze), Dn, V), q.uniformsNeedUpdate = !1), q.isSpriteMaterial && zt.setValue(O, "center", W.center), zt.setValue(O, "modelViewMatrix", W.modelViewMatrix), zt.setValue(O, "normalMatrix", W.normalMatrix), zt.setValue(O, "modelMatrix", W.matrixWorld), q.isShaderMaterial || q.isRawShaderMaterial) {
        const Tn = q.uniformsGroups;
        for (let ms = 0, Ka = Tn.length; ms < Ka; ms++) {
          const o_ = Tn[ms];
          De.update(o_, $i), De.bind(o_, $i);
        }
      }
      return $i;
    }
    function tM(A, H) {
      A.ambientLightColor.needsUpdate = H, A.lightProbe.needsUpdate = H, A.directionalLights.needsUpdate = H, A.directionalLightShadows.needsUpdate = H, A.pointLights.needsUpdate = H, A.pointLightShadows.needsUpdate = H, A.spotLights.needsUpdate = H, A.spotLightShadows.needsUpdate = H, A.rectAreaLights.needsUpdate = H, A.hemisphereLights.needsUpdate = H;
    }
    function nM(A) {
      return A.isMeshLambertMaterial || A.isMeshToonMaterial || A.isMeshPhongMaterial || A.isMeshStandardMaterial || A.isShadowMaterial || A.isShaderMaterial && A.lights === !0;
    }
    this.getActiveCubeFace = function() {
      return R;
    }, this.getActiveMipmapLevel = function() {
      return I;
    }, this.getRenderTarget = function() {
      return B;
    }, this.setRenderTargetTextures = function(A, H, j) {
      const q = w.get(A);
      q.__autoAllocateDepthBuffer = A.resolveDepthBuffer === !1, q.__autoAllocateDepthBuffer === !1 && (q.__useRenderToTexture = !1), w.get(A.texture).__webglTexture = H, w.get(A.depthTexture).__webglTexture = q.__autoAllocateDepthBuffer ? void 0 : j, q.__hasExternalTextures = !0;
    }, this.setRenderTargetFramebuffer = function(A, H) {
      const j = w.get(A);
      j.__webglFramebuffer = H, j.__useDefaultFramebuffer = H === void 0;
    };
    const iM = O.createFramebuffer();
    this.setRenderTarget = function(A, H = 0, j = 0) {
      B = A, R = H, I = j;
      let q = null, W = !1, Me = !1;
      if (A) {
        const Ee = w.get(A);
        if (Ee.__useDefaultFramebuffer !== void 0) {
          Ve.bindFramebuffer(O.FRAMEBUFFER, Ee.__webglFramebuffer), L.copy(A.viewport), k.copy(A.scissor), re = A.scissorTest, Ve.viewport(L), Ve.scissor(k), Ve.setScissorTest(re), N = -1;
          return;
        } else if (Ee.__webglFramebuffer === void 0)
          V.setupRenderTarget(A);
        else if (Ee.__hasExternalTextures)
          V.rebindTextures(A, w.get(A.texture).__webglTexture, w.get(A.depthTexture).__webglTexture);
        else if (A.depthBuffer) {
          const ot = A.depthTexture;
          if (Ee.__boundDepthTexture !== ot) {
            if (ot !== null && w.has(ot) && (A.width !== ot.image.width || A.height !== ot.image.height))
              throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.");
            V.setupDepthRenderbuffer(A);
          }
        }
        const Ge = A.texture;
        (Ge.isData3DTexture || Ge.isDataArrayTexture || Ge.isCompressedArrayTexture) && (Me = !0);
        const We = w.get(A).__webglFramebuffer;
        A.isWebGLCubeRenderTarget ? (Array.isArray(We[H]) ? q = We[H][j] : q = We[H], W = !0) : A.samples > 0 && V.useMultisampledRTT(A) === !1 ? q = w.get(A).__webglMultisampledFramebuffer : Array.isArray(We) ? q = We[j] : q = We, L.copy(A.viewport), k.copy(A.scissor), re = A.scissorTest;
      } else
        L.copy(z).multiplyScalar(me).floor(), k.copy(Z).multiplyScalar(me).floor(), re = ue;
      if (j !== 0 && (q = iM), Ve.bindFramebuffer(O.FRAMEBUFFER, q) && Ve.drawBuffers(A, q), Ve.viewport(L), Ve.scissor(k), Ve.setScissorTest(re), W) {
        const Ee = w.get(A.texture);
        O.framebufferTexture2D(O.FRAMEBUFFER, O.COLOR_ATTACHMENT0, O.TEXTURE_CUBE_MAP_POSITIVE_X + H, Ee.__webglTexture, j);
      } else if (Me) {
        const Ee = H;
        for (let Ge = 0; Ge < A.textures.length; Ge++) {
          const We = w.get(A.textures[Ge]);
          O.framebufferTextureLayer(O.FRAMEBUFFER, O.COLOR_ATTACHMENT0 + Ge, We.__webglTexture, j, Ee);
        }
      } else if (A !== null && j !== 0) {
        const Ee = w.get(A.texture);
        O.framebufferTexture2D(O.FRAMEBUFFER, O.COLOR_ATTACHMENT0, O.TEXTURE_2D, Ee.__webglTexture, j);
      }
      N = -1;
    }, this.readRenderTargetPixels = function(A, H, j, q, W, Me, Ne, Ee = 0) {
      if (!(A && A.isWebGLRenderTarget)) {
        le("WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");
        return;
      }
      let Ge = w.get(A).__webglFramebuffer;
      if (A.isWebGLCubeRenderTarget && Ne !== void 0 && (Ge = Ge[Ne]), Ge) {
        Ve.bindFramebuffer(O.FRAMEBUFFER, Ge);
        try {
          const We = A.textures[Ee], ot = We.format, ft = We.type;
          if (A.textures.length > 1 && O.readBuffer(O.COLOR_ATTACHMENT0 + Ee), !Xt.textureFormatReadable(ot)) {
            le("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");
            return;
          }
          if (!Xt.textureTypeReadable(ft)) {
            le("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");
            return;
          }
          H >= 0 && H <= A.width - q && j >= 0 && j <= A.height - W && O.readPixels(H, j, q, W, be.convert(ot), be.convert(ft), Me);
        } finally {
          const We = B !== null ? w.get(B).__webglFramebuffer : null;
          Ve.bindFramebuffer(O.FRAMEBUFFER, We);
        }
      }
    }, this.readRenderTargetPixelsAsync = async function(A, H, j, q, W, Me, Ne, Ee = 0) {
      if (!(A && A.isWebGLRenderTarget))
        throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");
      let Ge = w.get(A).__webglFramebuffer;
      if (A.isWebGLCubeRenderTarget && Ne !== void 0 && (Ge = Ge[Ne]), Ge)
        if (H >= 0 && H <= A.width - q && j >= 0 && j <= A.height - W) {
          Ve.bindFramebuffer(O.FRAMEBUFFER, Ge);
          const We = A.textures[Ee], ot = We.format, ft = We.type;
          if (A.textures.length > 1 && O.readBuffer(O.COLOR_ATTACHMENT0 + Ee), !Xt.textureFormatReadable(ot))
            throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");
          if (!Xt.textureTypeReadable(ft))
            throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");
          const qe = O.createBuffer();
          O.bindBuffer(O.PIXEL_PACK_BUFFER, qe), O.bufferData(O.PIXEL_PACK_BUFFER, Me.byteLength, O.STREAM_READ), O.readPixels(H, j, q, W, be.convert(ot), be.convert(ft), 0);
          const kt = B !== null ? w.get(B).__webglFramebuffer : null;
          Ve.bindFramebuffer(O.FRAMEBUFFER, kt);
          const un = O.fenceSync(O.SYNC_GPU_COMMANDS_COMPLETE, 0);
          return O.flush(), await CM(O, un, 4), O.bindBuffer(O.PIXEL_PACK_BUFFER, qe), O.getBufferSubData(O.PIXEL_PACK_BUFFER, 0, Me), O.deleteBuffer(qe), O.deleteSync(un), Me;
        } else
          throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.");
    }, this.copyFramebufferToTexture = function(A, H = null, j = 0) {
      const q = Math.pow(2, -j), W = Math.floor(A.image.width * q), Me = Math.floor(A.image.height * q), Ne = H !== null ? H.x : 0, Ee = H !== null ? H.y : 0;
      V.setTexture2D(A, 0), O.copyTexSubImage2D(O.TEXTURE_2D, j, 0, 0, Ne, Ee, W, Me), Ve.unbindTexture();
    };
    const rM = O.createFramebuffer(), sM = O.createFramebuffer();
    this.copyTextureToTexture = function(A, H, j = null, q = null, W = 0, Me = 0) {
      let Ne, Ee, Ge, We, ot, ft, qe, kt, un;
      const on = A.isCompressedTexture ? A.mipmaps[Me] : A.image;
      if (j !== null)
        Ne = j.max.x - j.min.x, Ee = j.max.y - j.min.y, Ge = j.isBox3 ? j.max.z - j.min.z : 1, We = j.min.x, ot = j.min.y, ft = j.isBox3 ? j.min.z : 0;
      else {
        const Dn = Math.pow(2, -W);
        Ne = Math.floor(on.width * Dn), Ee = Math.floor(on.height * Dn), A.isDataArrayTexture ? Ge = on.depth : A.isData3DTexture ? Ge = Math.floor(on.depth * Dn) : Ge = 1, We = 0, ot = 0, ft = 0;
      }
      q !== null ? (qe = q.x, kt = q.y, un = q.z) : (qe = 0, kt = 0, un = 0);
      const Gt = be.convert(H.format), Vn = be.convert(H.type);
      let ze;
      H.isData3DTexture ? (V.setTexture3D(H, 0), ze = O.TEXTURE_3D) : H.isDataArrayTexture || H.isCompressedArrayTexture ? (V.setTexture2DArray(H, 0), ze = O.TEXTURE_2D_ARRAY) : (V.setTexture2D(H, 0), ze = O.TEXTURE_2D), O.pixelStorei(O.UNPACK_FLIP_Y_WEBGL, H.flipY), O.pixelStorei(O.UNPACK_PREMULTIPLY_ALPHA_WEBGL, H.premultiplyAlpha), O.pixelStorei(O.UNPACK_ALIGNMENT, H.unpackAlignment);
      const yi = O.getParameter(O.UNPACK_ROW_LENGTH), St = O.getParameter(O.UNPACK_IMAGE_HEIGHT), $i = O.getParameter(O.UNPACK_SKIP_PIXELS), ir = O.getParameter(O.UNPACK_SKIP_ROWS), ta = O.getParameter(O.UNPACK_SKIP_IMAGES);
      O.pixelStorei(O.UNPACK_ROW_LENGTH, on.width), O.pixelStorei(O.UNPACK_IMAGE_HEIGHT, on.height), O.pixelStorei(O.UNPACK_SKIP_PIXELS, We), O.pixelStorei(O.UNPACK_SKIP_ROWS, ot), O.pixelStorei(O.UNPACK_SKIP_IMAGES, ft);
      const Ya = A.isDataArrayTexture || A.isData3DTexture, zt = H.isDataArrayTexture || H.isData3DTexture;
      if (A.isDepthTexture) {
        const Dn = w.get(A), ps = w.get(H), Tn = w.get(Dn.__renderTarget), ms = w.get(ps.__renderTarget);
        Ve.bindFramebuffer(O.READ_FRAMEBUFFER, Tn.__webglFramebuffer), Ve.bindFramebuffer(O.DRAW_FRAMEBUFFER, ms.__webglFramebuffer);
        for (let Ka = 0; Ka < Ge; Ka++)
          Ya && (O.framebufferTextureLayer(O.READ_FRAMEBUFFER, O.COLOR_ATTACHMENT0, w.get(A).__webglTexture, W, ft + Ka), O.framebufferTextureLayer(O.DRAW_FRAMEBUFFER, O.COLOR_ATTACHMENT0, w.get(H).__webglTexture, Me, un + Ka)), O.blitFramebuffer(We, ot, Ne, Ee, qe, kt, Ne, Ee, O.DEPTH_BUFFER_BIT, O.NEAREST);
        Ve.bindFramebuffer(O.READ_FRAMEBUFFER, null), Ve.bindFramebuffer(O.DRAW_FRAMEBUFFER, null);
      } else if (W !== 0 || A.isRenderTargetTexture || w.has(A)) {
        const Dn = w.get(A), ps = w.get(H);
        Ve.bindFramebuffer(O.READ_FRAMEBUFFER, rM), Ve.bindFramebuffer(O.DRAW_FRAMEBUFFER, sM);
        for (let Tn = 0; Tn < Ge; Tn++)
          Ya ? O.framebufferTextureLayer(O.READ_FRAMEBUFFER, O.COLOR_ATTACHMENT0, Dn.__webglTexture, W, ft + Tn) : O.framebufferTexture2D(O.READ_FRAMEBUFFER, O.COLOR_ATTACHMENT0, O.TEXTURE_2D, Dn.__webglTexture, W), zt ? O.framebufferTextureLayer(O.DRAW_FRAMEBUFFER, O.COLOR_ATTACHMENT0, ps.__webglTexture, Me, un + Tn) : O.framebufferTexture2D(O.DRAW_FRAMEBUFFER, O.COLOR_ATTACHMENT0, O.TEXTURE_2D, ps.__webglTexture, Me), W !== 0 ? O.blitFramebuffer(We, ot, Ne, Ee, qe, kt, Ne, Ee, O.COLOR_BUFFER_BIT, O.NEAREST) : zt ? O.copyTexSubImage3D(ze, Me, qe, kt, un + Tn, We, ot, Ne, Ee) : O.copyTexSubImage2D(ze, Me, qe, kt, We, ot, Ne, Ee);
        Ve.bindFramebuffer(O.READ_FRAMEBUFFER, null), Ve.bindFramebuffer(O.DRAW_FRAMEBUFFER, null);
      } else
        zt ? A.isDataTexture || A.isData3DTexture ? O.texSubImage3D(ze, Me, qe, kt, un, Ne, Ee, Ge, Gt, Vn, on.data) : H.isCompressedArrayTexture ? O.compressedTexSubImage3D(ze, Me, qe, kt, un, Ne, Ee, Ge, Gt, on.data) : O.texSubImage3D(ze, Me, qe, kt, un, Ne, Ee, Ge, Gt, Vn, on) : A.isDataTexture ? O.texSubImage2D(O.TEXTURE_2D, Me, qe, kt, Ne, Ee, Gt, Vn, on.data) : A.isCompressedTexture ? O.compressedTexSubImage2D(O.TEXTURE_2D, Me, qe, kt, on.width, on.height, Gt, on.data) : O.texSubImage2D(O.TEXTURE_2D, Me, qe, kt, Ne, Ee, Gt, Vn, on);
      O.pixelStorei(O.UNPACK_ROW_LENGTH, yi), O.pixelStorei(O.UNPACK_IMAGE_HEIGHT, St), O.pixelStorei(O.UNPACK_SKIP_PIXELS, $i), O.pixelStorei(O.UNPACK_SKIP_ROWS, ir), O.pixelStorei(O.UNPACK_SKIP_IMAGES, ta), Me === 0 && H.generateMipmaps && O.generateMipmap(ze), Ve.unbindTexture();
    }, this.initRenderTarget = function(A) {
      w.get(A).__webglFramebuffer === void 0 && V.setupRenderTarget(A);
    }, this.initTexture = function(A) {
      A.isCubeTexture ? V.setTextureCube(A, 0) : A.isData3DTexture ? V.setTexture3D(A, 0) : A.isDataArrayTexture || A.isCompressedArrayTexture ? V.setTexture2DArray(A, 0) : V.setTexture2D(A, 0), Ve.unbindTexture();
    }, this.resetState = function() {
      R = 0, I = 0, B = null, Ve.reset(), _e.reset();
    }, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this }));
  }
  /**
   * Defines the coordinate system of the renderer.
   *
   * In `WebGLRenderer`, the value is always `WebGLCoordinateSystem`.
   *
   * @type {WebGLCoordinateSystem|WebGPUCoordinateSystem}
   * @default WebGLCoordinateSystem
   * @readonly
   */
  get coordinateSystem() {
    return si;
  }
  /**
   * Defines the output color space of the renderer.
   *
   * @type {SRGBColorSpace|LinearSRGBColorSpace}
   * @default SRGBColorSpace
   */
  get outputColorSpace() {
    return this._outputColorSpace;
  }
  set outputColorSpace(e) {
    this._outputColorSpace = e;
    const t = this.getContext();
    t.drawingBufferColorSpace = Ke._getDrawingBufferColorSpace(e), t.unpackColorSpace = Ke._getUnpackColorSpace();
  }
}
const Lo = new Zi(), Zr = new de(), Ty = new P(), vf = new de(), Th = new de(), Bh = new P(), Dp = new P(), My = new pt(), Ey = new P(), wy = new P();
let qn = null, fr = null;
const Qr = [], Gs = {
  NONE: -1,
  PAN: 0,
  ROTATE: 1
};
class tN extends dd {
  /**
   * Constructs a new controls instance.
   *
   * @param {Array<Object3D>} objects - An array of draggable 3D objects.
   * @param {Camera} camera - The camera of the rendered scene.
   * @param {?HTMLElement} [domElement=null] - The HTML DOM element used for event listeners.
   */
  constructor(e, t, n = null) {
    super(t, n), this.objects = e, this.recursive = !0, this.transformGroup = !1, this.rotateSpeed = 1, this.raycaster = new gy(), this.mouseButtons = { LEFT: Fn.PAN, MIDDLE: Fn.PAN, RIGHT: Fn.ROTATE }, this.touches = { ONE: es.PAN }, this._onPointerMove = nN.bind(this), this._onPointerDown = iN.bind(this), this._onPointerCancel = rN.bind(this), this._onContextMenu = sN.bind(this), n !== null && this.connect(n);
  }
  connect(e) {
    super.connect(e), this.domElement.addEventListener("pointermove", this._onPointerMove), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointerup", this._onPointerCancel), this.domElement.addEventListener("pointerleave", this._onPointerCancel), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.style.touchAction = "none";
  }
  disconnect() {
    this.domElement.removeEventListener("pointermove", this._onPointerMove), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointerup", this._onPointerCancel), this.domElement.removeEventListener("pointerleave", this._onPointerCancel), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.domElement.style.touchAction = "auto", this.domElement.style.cursor = "";
  }
  dispose() {
    this.disconnect();
  }
  _updatePointer(e) {
    const t = this.domElement.getBoundingClientRect();
    Zr.x = (e.clientX - t.left) / t.width * 2 - 1, Zr.y = -(e.clientY - t.top) / t.height * 2 + 1;
  }
  _updateState(e) {
    let t;
    if (e.pointerType === "touch")
      t = this.touches.ONE;
    else
      switch (e.button) {
        case 0:
          t = this.mouseButtons.LEFT;
          break;
        case 1:
          t = this.mouseButtons.MIDDLE;
          break;
        case 2:
          t = this.mouseButtons.RIGHT;
          break;
        default:
          t = null;
      }
    switch (t) {
      case Fn.PAN:
      case es.PAN:
        this.state = Gs.PAN;
        break;
      case Fn.ROTATE:
      case es.ROTATE:
        this.state = Gs.ROTATE;
        break;
      default:
        this.state = Gs.NONE;
    }
  }
}
function nN(i) {
  const e = this.object, t = this.domElement, n = this.raycaster;
  if (this.enabled !== !1) {
    if (this._updatePointer(i), n.setFromCamera(Zr, e), qn)
      this.state === Gs.PAN ? n.ray.intersectPlane(Lo, Bh) && (qn.position.copy(Bh.sub(Ty).applyMatrix4(My)), this.dispatchEvent({ type: "drag", object: qn })) : this.state === Gs.ROTATE && (vf.subVectors(Zr, Th).multiplyScalar(this.rotateSpeed), qn.rotateOnWorldAxis(Ey, vf.x), qn.rotateOnWorldAxis(wy.normalize(), -vf.y), this.dispatchEvent({ type: "drag", object: qn })), Th.copy(Zr);
    else if (i.pointerType === "mouse" || i.pointerType === "pen")
      if (Qr.length = 0, n.setFromCamera(Zr, e), n.intersectObjects(this.objects, this.recursive, Qr), Qr.length > 0) {
        const r = Qr[0].object;
        Lo.setFromNormalAndCoplanarPoint(e.getWorldDirection(Lo.normal), Dp.setFromMatrixPosition(r.matrixWorld)), fr !== r && fr !== null && (this.dispatchEvent({ type: "hoveroff", object: fr }), t.style.cursor = "auto", fr = null), fr !== r && (this.dispatchEvent({ type: "hoveron", object: r }), t.style.cursor = "pointer", fr = r);
      } else
        fr !== null && (this.dispatchEvent({ type: "hoveroff", object: fr }), t.style.cursor = "auto", fr = null);
    Th.copy(Zr);
  }
}
function iN(i) {
  const e = this.object, t = this.domElement, n = this.raycaster;
  this.enabled !== !1 && (this._updatePointer(i), this._updateState(i), Qr.length = 0, n.setFromCamera(Zr, e), n.intersectObjects(this.objects, this.recursive, Qr), Qr.length > 0 && (this.transformGroup === !0 ? qn = Ay(Qr[0].object) : qn = Qr[0].object, Lo.setFromNormalAndCoplanarPoint(e.getWorldDirection(Lo.normal), Dp.setFromMatrixPosition(qn.matrixWorld)), n.ray.intersectPlane(Lo, Bh) && (this.state === Gs.PAN ? (My.copy(qn.parent.matrixWorld).invert(), Ty.copy(Bh).sub(Dp.setFromMatrixPosition(qn.matrixWorld)), t.style.cursor = "move", this.dispatchEvent({ type: "dragstart", object: qn })) : this.state === Gs.ROTATE && (Ey.set(0, 1, 0).applyQuaternion(e.quaternion).normalize(), wy.set(1, 0, 0).applyQuaternion(e.quaternion).normalize(), t.style.cursor = "move", this.dispatchEvent({ type: "dragstart", object: qn })))), Th.copy(Zr));
}
function rN() {
  this.enabled !== !1 && (qn && (this.dispatchEvent({ type: "dragend", object: qn }), qn = null), this.domElement.style.cursor = fr ? "pointer" : "auto", this.state = Gs.NONE);
}
function sN(i) {
  this.enabled !== !1 && i.preventDefault();
}
function Ay(i, e = null) {
  return i.isGroup && (e = i), i.parent === null ? e : Ay(i.parent, e);
}
function aN(i, e, t) {
  var n, r = 1;
  i == null && (i = 0), e == null && (e = 0), t == null && (t = 0);
  function s() {
    var a, o = n.length, l, c = 0, u = 0, h = 0;
    for (a = 0; a < o; ++a)
      l = n[a], c += l.x || 0, u += l.y || 0, h += l.z || 0;
    for (c = (c / o - i) * r, u = (u / o - e) * r, h = (h / o - t) * r, a = 0; a < o; ++a)
      l = n[a], c && (l.x -= c), u && (l.y -= u), h && (l.z -= h);
  }
  return s.initialize = function(a) {
    n = a;
  }, s.x = function(a) {
    return arguments.length ? (i = +a, s) : i;
  }, s.y = function(a) {
    return arguments.length ? (e = +a, s) : e;
  }, s.z = function(a) {
    return arguments.length ? (t = +a, s) : t;
  }, s.strength = function(a) {
    return arguments.length ? (r = +a, s) : r;
  }, s;
}
function oN(i) {
  const e = +this._x.call(null, i);
  return Ry(this.cover(e), e, i);
}
function Ry(i, e, t) {
  if (isNaN(e))
    return i;
  var n, r = i._root, s = { data: t }, a = i._x0, o = i._x1, l, c, u, h, d;
  if (!r)
    return i._root = s, i;
  for (; r.length; )
    if ((u = e >= (l = (a + o) / 2)) ? a = l : o = l, n = r, !(r = r[h = +u]))
      return n[h] = s, i;
  if (c = +i._x.call(null, r.data), e === c)
    return s.next = r, n ? n[h] = s : i._root = s, i;
  do
    n = n ? n[h] = new Array(2) : i._root = new Array(2), (u = e >= (l = (a + o) / 2)) ? a = l : o = l;
  while ((h = +u) == (d = +(c >= l)));
  return n[d] = r, n[h] = s, i;
}
function lN(i) {
  Array.isArray(i) || (i = Array.from(i));
  const e = i.length, t = new Float64Array(e);
  let n = 1 / 0, r = -1 / 0;
  for (let s = 0, a; s < e; ++s)
    isNaN(a = +this._x.call(null, i[s])) || (t[s] = a, a < n && (n = a), a > r && (r = a));
  if (n > r)
    return this;
  this.cover(n).cover(r);
  for (let s = 0; s < e; ++s)
    Ry(this, t[s], i[s]);
  return this;
}
function cN(i) {
  if (isNaN(i = +i))
    return this;
  var e = this._x0, t = this._x1;
  if (isNaN(e))
    t = (e = Math.floor(i)) + 1;
  else {
    for (var n = t - e || 1, r = this._root, s, a; e > i || i >= t; )
      switch (a = +(i < e), s = new Array(2), s[a] = r, r = s, n *= 2, a) {
        case 0:
          t = e + n;
          break;
        case 1:
          e = t - n;
          break;
      }
    this._root && this._root.length && (this._root = r);
  }
  return this._x0 = e, this._x1 = t, this;
}
function uN() {
  var i = [];
  return this.visit(function(e) {
    if (!e.length)
      do
        i.push(e.data);
      while (e = e.next);
  }), i;
}
function hN(i) {
  return arguments.length ? this.cover(+i[0][0]).cover(+i[1][0]) : isNaN(this._x0) ? void 0 : [[this._x0], [this._x1]];
}
function os(i, e, t) {
  this.node = i, this.x0 = e, this.x1 = t;
}
function dN(i, e) {
  var t, n = this._x0, r, s, a = this._x1, o = [], l = this._root, c, u;
  for (l && o.push(new os(l, n, a)), e == null ? e = 1 / 0 : (n = i - e, a = i + e); c = o.pop(); )
    if (!(!(l = c.node) || (r = c.x0) > a || (s = c.x1) < n))
      if (l.length) {
        var h = (r + s) / 2;
        o.push(
          new os(l[1], h, s),
          new os(l[0], r, h)
        ), (u = +(i >= h)) && (c = o[o.length - 1], o[o.length - 1] = o[o.length - 1 - u], o[o.length - 1 - u] = c);
      } else {
        var d = Math.abs(i - +this._x.call(null, l.data));
        d < e && (e = d, n = i - d, a = i + d, t = l.data);
      }
  return t;
}
function fN(i) {
  if (isNaN(l = +this._x.call(null, i)))
    return this;
  var e, t = this._root, n, r, s, a = this._x0, o = this._x1, l, c, u, h, d;
  if (!t)
    return this;
  if (t.length)
    for (; ; ) {
      if ((u = l >= (c = (a + o) / 2)) ? a = c : o = c, e = t, !(t = t[h = +u]))
        return this;
      if (!t.length)
        break;
      e[h + 1 & 1] && (n = e, d = h);
    }
  for (; t.data !== i; )
    if (r = t, !(t = t.next))
      return this;
  return (s = t.next) && delete t.next, r ? (s ? r.next = s : delete r.next, this) : e ? (s ? e[h] = s : delete e[h], (t = e[0] || e[1]) && t === (e[1] || e[0]) && !t.length && (n ? n[d] = t : this._root = t), this) : (this._root = s, this);
}
function pN(i) {
  for (var e = 0, t = i.length; e < t; ++e)
    this.remove(i[e]);
  return this;
}
function mN() {
  return this._root;
}
function gN() {
  var i = 0;
  return this.visit(function(e) {
    if (!e.length)
      do
        ++i;
      while (e = e.next);
  }), i;
}
function _N(i) {
  var e = [], t, n = this._root, r, s, a;
  for (n && e.push(new os(n, this._x0, this._x1)); t = e.pop(); )
    if (!i(n = t.node, s = t.x0, a = t.x1) && n.length) {
      var o = (s + a) / 2;
      (r = n[1]) && e.push(new os(r, o, a)), (r = n[0]) && e.push(new os(r, s, o));
    }
  return this;
}
function xN(i) {
  var e = [], t = [], n;
  for (this._root && e.push(new os(this._root, this._x0, this._x1)); n = e.pop(); ) {
    var r = n.node;
    if (r.length) {
      var s, a = n.x0, o = n.x1, l = (a + o) / 2;
      (s = r[0]) && e.push(new os(s, a, l)), (s = r[1]) && e.push(new os(s, l, o));
    }
    t.push(n);
  }
  for (; n = t.pop(); )
    i(n.node, n.x0, n.x1);
  return this;
}
function vN(i) {
  return i[0];
}
function yN(i) {
  return arguments.length ? (this._x = i, this) : this._x;
}
function Cy(i, e) {
  var t = new ag(e ?? vN, NaN, NaN);
  return i == null ? t : t.addAll(i);
}
function ag(i, e, t) {
  this._x = i, this._x0 = e, this._x1 = t, this._root = void 0;
}
function s0(i) {
  for (var e = { data: i.data }, t = e; i = i.next; )
    t = t.next = { data: i.data };
  return e;
}
var vi = Cy.prototype = ag.prototype;
vi.copy = function() {
  var i = new ag(this._x, this._x0, this._x1), e = this._root, t, n;
  if (!e)
    return i;
  if (!e.length)
    return i._root = s0(e), i;
  for (t = [{ source: e, target: i._root = new Array(2) }]; e = t.pop(); )
    for (var r = 0; r < 2; ++r)
      (n = e.source[r]) && (n.length ? t.push({ source: n, target: e.target[r] = new Array(2) }) : e.target[r] = s0(n));
  return i;
};
vi.add = oN;
vi.addAll = lN;
vi.cover = cN;
vi.data = uN;
vi.extent = hN;
vi.find = dN;
vi.remove = fN;
vi.removeAll = pN;
vi.root = mN;
vi.size = gN;
vi.visit = _N;
vi.visitAfter = xN;
vi.x = yN;
function bN(i) {
  const e = +this._x.call(null, i), t = +this._y.call(null, i);
  return Ny(this.cover(e, t), e, t, i);
}
function Ny(i, e, t, n) {
  if (isNaN(e) || isNaN(t))
    return i;
  var r, s = i._root, a = { data: n }, o = i._x0, l = i._y0, c = i._x1, u = i._y1, h, d, f, p, _, g, m, x;
  if (!s)
    return i._root = a, i;
  for (; s.length; )
    if ((_ = e >= (h = (o + c) / 2)) ? o = h : c = h, (g = t >= (d = (l + u) / 2)) ? l = d : u = d, r = s, !(s = s[m = g << 1 | _]))
      return r[m] = a, i;
  if (f = +i._x.call(null, s.data), p = +i._y.call(null, s.data), e === f && t === p)
    return a.next = s, r ? r[m] = a : i._root = a, i;
  do
    r = r ? r[m] = new Array(4) : i._root = new Array(4), (_ = e >= (h = (o + c) / 2)) ? o = h : c = h, (g = t >= (d = (l + u) / 2)) ? l = d : u = d;
  while ((m = g << 1 | _) === (x = (p >= d) << 1 | f >= h));
  return r[x] = s, r[m] = a, i;
}
function SN(i) {
  var e, t, n = i.length, r, s, a = new Array(n), o = new Array(n), l = 1 / 0, c = 1 / 0, u = -1 / 0, h = -1 / 0;
  for (t = 0; t < n; ++t)
    isNaN(r = +this._x.call(null, e = i[t])) || isNaN(s = +this._y.call(null, e)) || (a[t] = r, o[t] = s, r < l && (l = r), r > u && (u = r), s < c && (c = s), s > h && (h = s));
  if (l > u || c > h)
    return this;
  for (this.cover(l, c).cover(u, h), t = 0; t < n; ++t)
    Ny(this, a[t], o[t], i[t]);
  return this;
}
function TN(i, e) {
  if (isNaN(i = +i) || isNaN(e = +e))
    return this;
  var t = this._x0, n = this._y0, r = this._x1, s = this._y1;
  if (isNaN(t))
    r = (t = Math.floor(i)) + 1, s = (n = Math.floor(e)) + 1;
  else {
    for (var a = r - t || 1, o = this._root, l, c; t > i || i >= r || n > e || e >= s; )
      switch (c = (e < n) << 1 | i < t, l = new Array(4), l[c] = o, o = l, a *= 2, c) {
        case 0:
          r = t + a, s = n + a;
          break;
        case 1:
          t = r - a, s = n + a;
          break;
        case 2:
          r = t + a, n = s - a;
          break;
        case 3:
          t = r - a, n = s - a;
          break;
      }
    this._root && this._root.length && (this._root = o);
  }
  return this._x0 = t, this._y0 = n, this._x1 = r, this._y1 = s, this;
}
function MN() {
  var i = [];
  return this.visit(function(e) {
    if (!e.length)
      do
        i.push(e.data);
      while (e = e.next);
  }), i;
}
function EN(i) {
  return arguments.length ? this.cover(+i[0][0], +i[0][1]).cover(+i[1][0], +i[1][1]) : isNaN(this._x0) ? void 0 : [[this._x0, this._y0], [this._x1, this._y1]];
}
function ni(i, e, t, n, r) {
  this.node = i, this.x0 = e, this.y0 = t, this.x1 = n, this.y1 = r;
}
function wN(i, e, t) {
  var n, r = this._x0, s = this._y0, a, o, l, c, u = this._x1, h = this._y1, d = [], f = this._root, p, _;
  for (f && d.push(new ni(f, r, s, u, h)), t == null ? t = 1 / 0 : (r = i - t, s = e - t, u = i + t, h = e + t, t *= t); p = d.pop(); )
    if (!(!(f = p.node) || (a = p.x0) > u || (o = p.y0) > h || (l = p.x1) < r || (c = p.y1) < s))
      if (f.length) {
        var g = (a + l) / 2, m = (o + c) / 2;
        d.push(
          new ni(f[3], g, m, l, c),
          new ni(f[2], a, m, g, c),
          new ni(f[1], g, o, l, m),
          new ni(f[0], a, o, g, m)
        ), (_ = (e >= m) << 1 | i >= g) && (p = d[d.length - 1], d[d.length - 1] = d[d.length - 1 - _], d[d.length - 1 - _] = p);
      } else {
        var x = i - +this._x.call(null, f.data), y = e - +this._y.call(null, f.data), b = x * x + y * y;
        if (b < t) {
          var T = Math.sqrt(t = b);
          r = i - T, s = e - T, u = i + T, h = e + T, n = f.data;
        }
      }
  return n;
}
function AN(i) {
  if (isNaN(u = +this._x.call(null, i)) || isNaN(h = +this._y.call(null, i)))
    return this;
  var e, t = this._root, n, r, s, a = this._x0, o = this._y0, l = this._x1, c = this._y1, u, h, d, f, p, _, g, m;
  if (!t)
    return this;
  if (t.length)
    for (; ; ) {
      if ((p = u >= (d = (a + l) / 2)) ? a = d : l = d, (_ = h >= (f = (o + c) / 2)) ? o = f : c = f, e = t, !(t = t[g = _ << 1 | p]))
        return this;
      if (!t.length)
        break;
      (e[g + 1 & 3] || e[g + 2 & 3] || e[g + 3 & 3]) && (n = e, m = g);
    }
  for (; t.data !== i; )
    if (r = t, !(t = t.next))
      return this;
  return (s = t.next) && delete t.next, r ? (s ? r.next = s : delete r.next, this) : e ? (s ? e[g] = s : delete e[g], (t = e[0] || e[1] || e[2] || e[3]) && t === (e[3] || e[2] || e[1] || e[0]) && !t.length && (n ? n[m] = t : this._root = t), this) : (this._root = s, this);
}
function RN(i) {
  for (var e = 0, t = i.length; e < t; ++e)
    this.remove(i[e]);
  return this;
}
function CN() {
  return this._root;
}
function NN() {
  var i = 0;
  return this.visit(function(e) {
    if (!e.length)
      do
        ++i;
      while (e = e.next);
  }), i;
}
function PN(i) {
  var e = [], t, n = this._root, r, s, a, o, l;
  for (n && e.push(new ni(n, this._x0, this._y0, this._x1, this._y1)); t = e.pop(); )
    if (!i(n = t.node, s = t.x0, a = t.y0, o = t.x1, l = t.y1) && n.length) {
      var c = (s + o) / 2, u = (a + l) / 2;
      (r = n[3]) && e.push(new ni(r, c, u, o, l)), (r = n[2]) && e.push(new ni(r, s, u, c, l)), (r = n[1]) && e.push(new ni(r, c, a, o, u)), (r = n[0]) && e.push(new ni(r, s, a, c, u));
    }
  return this;
}
function DN(i) {
  var e = [], t = [], n;
  for (this._root && e.push(new ni(this._root, this._x0, this._y0, this._x1, this._y1)); n = e.pop(); ) {
    var r = n.node;
    if (r.length) {
      var s, a = n.x0, o = n.y0, l = n.x1, c = n.y1, u = (a + l) / 2, h = (o + c) / 2;
      (s = r[0]) && e.push(new ni(s, a, o, u, h)), (s = r[1]) && e.push(new ni(s, u, o, l, h)), (s = r[2]) && e.push(new ni(s, a, h, u, c)), (s = r[3]) && e.push(new ni(s, u, h, l, c));
    }
    t.push(n);
  }
  for (; n = t.pop(); )
    i(n.node, n.x0, n.y0, n.x1, n.y1);
  return this;
}
function LN(i) {
  return i[0];
}
function FN(i) {
  return arguments.length ? (this._x = i, this) : this._x;
}
function IN(i) {
  return i[1];
}
function UN(i) {
  return arguments.length ? (this._y = i, this) : this._y;
}
function Py(i, e, t) {
  var n = new og(e ?? LN, t ?? IN, NaN, NaN, NaN, NaN);
  return i == null ? n : n.addAll(i);
}
function og(i, e, t, n, r, s) {
  this._x = i, this._y = e, this._x0 = t, this._y0 = n, this._x1 = r, this._y1 = s, this._root = void 0;
}
function a0(i) {
  for (var e = { data: i.data }, t = e; i = i.next; )
    t = t.next = { data: i.data };
  return e;
}
var li = Py.prototype = og.prototype;
li.copy = function() {
  var i = new og(this._x, this._y, this._x0, this._y0, this._x1, this._y1), e = this._root, t, n;
  if (!e)
    return i;
  if (!e.length)
    return i._root = a0(e), i;
  for (t = [{ source: e, target: i._root = new Array(4) }]; e = t.pop(); )
    for (var r = 0; r < 4; ++r)
      (n = e.source[r]) && (n.length ? t.push({ source: n, target: e.target[r] = new Array(4) }) : e.target[r] = a0(n));
  return i;
};
li.add = bN;
li.addAll = SN;
li.cover = TN;
li.data = MN;
li.extent = EN;
li.find = wN;
li.remove = AN;
li.removeAll = RN;
li.root = CN;
li.size = NN;
li.visit = PN;
li.visitAfter = DN;
li.x = FN;
li.y = UN;
function BN(i) {
  const e = +this._x.call(null, i), t = +this._y.call(null, i), n = +this._z.call(null, i);
  return Dy(this.cover(e, t, n), e, t, n, i);
}
function Dy(i, e, t, n, r) {
  if (isNaN(e) || isNaN(t) || isNaN(n))
    return i;
  var s, a = i._root, o = { data: r }, l = i._x0, c = i._y0, u = i._z0, h = i._x1, d = i._y1, f = i._z1, p, _, g, m, x, y, b, T, S, E, v;
  if (!a)
    return i._root = o, i;
  for (; a.length; )
    if ((b = e >= (p = (l + h) / 2)) ? l = p : h = p, (T = t >= (_ = (c + d) / 2)) ? c = _ : d = _, (S = n >= (g = (u + f) / 2)) ? u = g : f = g, s = a, !(a = a[E = S << 2 | T << 1 | b]))
      return s[E] = o, i;
  if (m = +i._x.call(null, a.data), x = +i._y.call(null, a.data), y = +i._z.call(null, a.data), e === m && t === x && n === y)
    return o.next = a, s ? s[E] = o : i._root = o, i;
  do
    s = s ? s[E] = new Array(8) : i._root = new Array(8), (b = e >= (p = (l + h) / 2)) ? l = p : h = p, (T = t >= (_ = (c + d) / 2)) ? c = _ : d = _, (S = n >= (g = (u + f) / 2)) ? u = g : f = g;
  while ((E = S << 2 | T << 1 | b) === (v = (y >= g) << 2 | (x >= _) << 1 | m >= p));
  return s[v] = a, s[E] = o, i;
}
function ON(i) {
  Array.isArray(i) || (i = Array.from(i));
  const e = i.length, t = new Float64Array(e), n = new Float64Array(e), r = new Float64Array(e);
  let s = 1 / 0, a = 1 / 0, o = 1 / 0, l = -1 / 0, c = -1 / 0, u = -1 / 0;
  for (let h = 0, d, f, p, _; h < e; ++h)
    isNaN(f = +this._x.call(null, d = i[h])) || isNaN(p = +this._y.call(null, d)) || isNaN(_ = +this._z.call(null, d)) || (t[h] = f, n[h] = p, r[h] = _, f < s && (s = f), f > l && (l = f), p < a && (a = p), p > c && (c = p), _ < o && (o = _), _ > u && (u = _));
  if (s > l || a > c || o > u)
    return this;
  this.cover(s, a, o).cover(l, c, u);
  for (let h = 0; h < e; ++h)
    Dy(this, t[h], n[h], r[h], i[h]);
  return this;
}
function kN(i, e, t) {
  if (isNaN(i = +i) || isNaN(e = +e) || isNaN(t = +t))
    return this;
  var n = this._x0, r = this._y0, s = this._z0, a = this._x1, o = this._y1, l = this._z1;
  if (isNaN(n))
    a = (n = Math.floor(i)) + 1, o = (r = Math.floor(e)) + 1, l = (s = Math.floor(t)) + 1;
  else {
    for (var c = a - n || 1, u = this._root, h, d; n > i || i >= a || r > e || e >= o || s > t || t >= l; )
      switch (d = (t < s) << 2 | (e < r) << 1 | i < n, h = new Array(8), h[d] = u, u = h, c *= 2, d) {
        case 0:
          a = n + c, o = r + c, l = s + c;
          break;
        case 1:
          n = a - c, o = r + c, l = s + c;
          break;
        case 2:
          a = n + c, r = o - c, l = s + c;
          break;
        case 3:
          n = a - c, r = o - c, l = s + c;
          break;
        case 4:
          a = n + c, o = r + c, s = l - c;
          break;
        case 5:
          n = a - c, o = r + c, s = l - c;
          break;
        case 6:
          a = n + c, r = o - c, s = l - c;
          break;
        case 7:
          n = a - c, r = o - c, s = l - c;
          break;
      }
    this._root && this._root.length && (this._root = u);
  }
  return this._x0 = n, this._y0 = r, this._z0 = s, this._x1 = a, this._y1 = o, this._z1 = l, this;
}
function GN() {
  var i = [];
  return this.visit(function(e) {
    if (!e.length)
      do
        i.push(e.data);
      while (e = e.next);
  }), i;
}
function VN(i) {
  return arguments.length ? this.cover(+i[0][0], +i[0][1], +i[0][2]).cover(+i[1][0], +i[1][1], +i[1][2]) : isNaN(this._x0) ? void 0 : [[this._x0, this._y0, this._z0], [this._x1, this._y1, this._z1]];
}
function Wt(i, e, t, n, r, s, a) {
  this.node = i, this.x0 = e, this.y0 = t, this.z0 = n, this.x1 = r, this.y1 = s, this.z1 = a;
}
function zN(i, e, t, n) {
  var r, s = this._x0, a = this._y0, o = this._z0, l, c, u, h, d, f, p = this._x1, _ = this._y1, g = this._z1, m = [], x = this._root, y, b;
  for (x && m.push(new Wt(x, s, a, o, p, _, g)), n == null ? n = 1 / 0 : (s = i - n, a = e - n, o = t - n, p = i + n, _ = e + n, g = t + n, n *= n); y = m.pop(); )
    if (!(!(x = y.node) || (l = y.x0) > p || (c = y.y0) > _ || (u = y.z0) > g || (h = y.x1) < s || (d = y.y1) < a || (f = y.z1) < o))
      if (x.length) {
        var T = (l + h) / 2, S = (c + d) / 2, E = (u + f) / 2;
        m.push(
          new Wt(x[7], T, S, E, h, d, f),
          new Wt(x[6], l, S, E, T, d, f),
          new Wt(x[5], T, c, E, h, S, f),
          new Wt(x[4], l, c, E, T, S, f),
          new Wt(x[3], T, S, u, h, d, E),
          new Wt(x[2], l, S, u, T, d, E),
          new Wt(x[1], T, c, u, h, S, E),
          new Wt(x[0], l, c, u, T, S, E)
        ), (b = (t >= E) << 2 | (e >= S) << 1 | i >= T) && (y = m[m.length - 1], m[m.length - 1] = m[m.length - 1 - b], m[m.length - 1 - b] = y);
      } else {
        var v = i - +this._x.call(null, x.data), M = e - +this._y.call(null, x.data), F = t - +this._z.call(null, x.data), R = v * v + M * M + F * F;
        if (R < n) {
          var I = Math.sqrt(n = R);
          s = i - I, a = e - I, o = t - I, p = i + I, _ = e + I, g = t + I, r = x.data;
        }
      }
  return r;
}
const HN = (i, e, t, n, r, s) => Math.sqrt((i - n) ** 2 + (e - r) ** 2 + (t - s) ** 2);
function $N(i, e, t, n) {
  const r = [], s = i - n, a = e - n, o = t - n, l = i + n, c = e + n, u = t + n;
  return this.visit((h, d, f, p, _, g, m) => {
    if (!h.length)
      do {
        const x = h.data;
        HN(i, e, t, this._x(x), this._y(x), this._z(x)) <= n && r.push(x);
      } while (h = h.next);
    return d > l || f > c || p > u || _ < s || g < a || m < o;
  }), r;
}
function WN(i) {
  if (isNaN(d = +this._x.call(null, i)) || isNaN(f = +this._y.call(null, i)) || isNaN(p = +this._z.call(null, i)))
    return this;
  var e, t = this._root, n, r, s, a = this._x0, o = this._y0, l = this._z0, c = this._x1, u = this._y1, h = this._z1, d, f, p, _, g, m, x, y, b, T, S;
  if (!t)
    return this;
  if (t.length)
    for (; ; ) {
      if ((x = d >= (_ = (a + c) / 2)) ? a = _ : c = _, (y = f >= (g = (o + u) / 2)) ? o = g : u = g, (b = p >= (m = (l + h) / 2)) ? l = m : h = m, e = t, !(t = t[T = b << 2 | y << 1 | x]))
        return this;
      if (!t.length)
        break;
      (e[T + 1 & 7] || e[T + 2 & 7] || e[T + 3 & 7] || e[T + 4 & 7] || e[T + 5 & 7] || e[T + 6 & 7] || e[T + 7 & 7]) && (n = e, S = T);
    }
  for (; t.data !== i; )
    if (r = t, !(t = t.next))
      return this;
  return (s = t.next) && delete t.next, r ? (s ? r.next = s : delete r.next, this) : e ? (s ? e[T] = s : delete e[T], (t = e[0] || e[1] || e[2] || e[3] || e[4] || e[5] || e[6] || e[7]) && t === (e[7] || e[6] || e[5] || e[4] || e[3] || e[2] || e[1] || e[0]) && !t.length && (n ? n[S] = t : this._root = t), this) : (this._root = s, this);
}
function qN(i) {
  for (var e = 0, t = i.length; e < t; ++e)
    this.remove(i[e]);
  return this;
}
function XN() {
  return this._root;
}
function jN() {
  var i = 0;
  return this.visit(function(e) {
    if (!e.length)
      do
        ++i;
      while (e = e.next);
  }), i;
}
function YN(i) {
  var e = [], t, n = this._root, r, s, a, o, l, c, u;
  for (n && e.push(new Wt(n, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1)); t = e.pop(); )
    if (!i(n = t.node, s = t.x0, a = t.y0, o = t.z0, l = t.x1, c = t.y1, u = t.z1) && n.length) {
      var h = (s + l) / 2, d = (a + c) / 2, f = (o + u) / 2;
      (r = n[7]) && e.push(new Wt(r, h, d, f, l, c, u)), (r = n[6]) && e.push(new Wt(r, s, d, f, h, c, u)), (r = n[5]) && e.push(new Wt(r, h, a, f, l, d, u)), (r = n[4]) && e.push(new Wt(r, s, a, f, h, d, u)), (r = n[3]) && e.push(new Wt(r, h, d, o, l, c, f)), (r = n[2]) && e.push(new Wt(r, s, d, o, h, c, f)), (r = n[1]) && e.push(new Wt(r, h, a, o, l, d, f)), (r = n[0]) && e.push(new Wt(r, s, a, o, h, d, f));
    }
  return this;
}
function KN(i) {
  var e = [], t = [], n;
  for (this._root && e.push(new Wt(this._root, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1)); n = e.pop(); ) {
    var r = n.node;
    if (r.length) {
      var s, a = n.x0, o = n.y0, l = n.z0, c = n.x1, u = n.y1, h = n.z1, d = (a + c) / 2, f = (o + u) / 2, p = (l + h) / 2;
      (s = r[0]) && e.push(new Wt(s, a, o, l, d, f, p)), (s = r[1]) && e.push(new Wt(s, d, o, l, c, f, p)), (s = r[2]) && e.push(new Wt(s, a, f, l, d, u, p)), (s = r[3]) && e.push(new Wt(s, d, f, l, c, u, p)), (s = r[4]) && e.push(new Wt(s, a, o, p, d, f, h)), (s = r[5]) && e.push(new Wt(s, d, o, p, c, f, h)), (s = r[6]) && e.push(new Wt(s, a, f, p, d, u, h)), (s = r[7]) && e.push(new Wt(s, d, f, p, c, u, h));
    }
    t.push(n);
  }
  for (; n = t.pop(); )
    i(n.node, n.x0, n.y0, n.z0, n.x1, n.y1, n.z1);
  return this;
}
function ZN(i) {
  return i[0];
}
function QN(i) {
  return arguments.length ? (this._x = i, this) : this._x;
}
function JN(i) {
  return i[1];
}
function eP(i) {
  return arguments.length ? (this._y = i, this) : this._y;
}
function tP(i) {
  return i[2];
}
function nP(i) {
  return arguments.length ? (this._z = i, this) : this._z;
}
function Ly(i, e, t, n) {
  var r = new lg(e ?? ZN, t ?? JN, n ?? tP, NaN, NaN, NaN, NaN, NaN, NaN);
  return i == null ? r : r.addAll(i);
}
function lg(i, e, t, n, r, s, a, o, l) {
  this._x = i, this._y = e, this._z = t, this._x0 = n, this._y0 = r, this._z0 = s, this._x1 = a, this._y1 = o, this._z1 = l, this._root = void 0;
}
function o0(i) {
  for (var e = { data: i.data }, t = e; i = i.next; )
    t = t.next = { data: i.data };
  return e;
}
var Gn = Ly.prototype = lg.prototype;
Gn.copy = function() {
  var i = new lg(this._x, this._y, this._z, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1), e = this._root, t, n;
  if (!e)
    return i;
  if (!e.length)
    return i._root = o0(e), i;
  for (t = [{ source: e, target: i._root = new Array(8) }]; e = t.pop(); )
    for (var r = 0; r < 8; ++r)
      (n = e.source[r]) && (n.length ? t.push({ source: n, target: e.target[r] = new Array(8) }) : e.target[r] = o0(n));
  return i;
};
Gn.add = BN;
Gn.addAll = ON;
Gn.cover = kN;
Gn.data = GN;
Gn.extent = VN;
Gn.find = zN;
Gn.findAllWithinRadius = $N;
Gn.remove = WN;
Gn.removeAll = qN;
Gn.root = XN;
Gn.size = jN;
Gn.visit = YN;
Gn.visitAfter = KN;
Gn.x = QN;
Gn.y = eP;
Gn.z = nP;
function ns(i) {
  return function() {
    return i;
  };
}
function Yr(i) {
  return (i() - 0.5) * 1e-6;
}
function iP(i) {
  return i.index;
}
function l0(i, e) {
  var t = i.get(e);
  if (!t)
    throw new Error("node not found: " + e);
  return t;
}
function rP(i) {
  var e = iP, t = d, n, r = ns(30), s, a, o, l, c, u, h = 1;
  i == null && (i = []);
  function d(m) {
    return 1 / Math.min(l[m.source.index], l[m.target.index]);
  }
  function f(m) {
    for (var x = 0, y = i.length; x < h; ++x)
      for (var b = 0, T, S, E, v = 0, M = 0, F = 0, R, I; b < y; ++b)
        T = i[b], S = T.source, E = T.target, v = E.x + E.vx - S.x - S.vx || Yr(u), o > 1 && (M = E.y + E.vy - S.y - S.vy || Yr(u)), o > 2 && (F = E.z + E.vz - S.z - S.vz || Yr(u)), R = Math.sqrt(v * v + M * M + F * F), R = (R - s[b]) / R * m * n[b], v *= R, M *= R, F *= R, E.vx -= v * (I = c[b]), o > 1 && (E.vy -= M * I), o > 2 && (E.vz -= F * I), S.vx += v * (I = 1 - I), o > 1 && (S.vy += M * I), o > 2 && (S.vz += F * I);
  }
  function p() {
    if (a) {
      var m, x = a.length, y = i.length, b = new Map(a.map((S, E) => [e(S, E, a), S])), T;
      for (m = 0, l = new Array(x); m < y; ++m)
        T = i[m], T.index = m, typeof T.source != "object" && (T.source = l0(b, T.source)), typeof T.target != "object" && (T.target = l0(b, T.target)), l[T.source.index] = (l[T.source.index] || 0) + 1, l[T.target.index] = (l[T.target.index] || 0) + 1;
      for (m = 0, c = new Array(y); m < y; ++m)
        T = i[m], c[m] = l[T.source.index] / (l[T.source.index] + l[T.target.index]);
      n = new Array(y), _(), s = new Array(y), g();
    }
  }
  function _() {
    if (a)
      for (var m = 0, x = i.length; m < x; ++m)
        n[m] = +t(i[m], m, i);
  }
  function g() {
    if (a)
      for (var m = 0, x = i.length; m < x; ++m)
        s[m] = +r(i[m], m, i);
  }
  return f.initialize = function(m, ...x) {
    a = m, u = x.find((y) => typeof y == "function") || Math.random, o = x.find((y) => [1, 2, 3].includes(y)) || 2, p();
  }, f.links = function(m) {
    return arguments.length ? (i = m, p(), f) : i;
  }, f.id = function(m) {
    return arguments.length ? (e = m, f) : e;
  }, f.iterations = function(m) {
    return arguments.length ? (h = +m, f) : h;
  }, f.strength = function(m) {
    return arguments.length ? (t = typeof m == "function" ? m : ns(+m), _(), f) : t;
  }, f.distance = function(m) {
    return arguments.length ? (r = typeof m == "function" ? m : ns(+m), g(), f) : r;
  }, f;
}
var sP = { value: () => {
} };
function Fy() {
  for (var i = 0, e = arguments.length, t = {}, n; i < e; ++i) {
    if (!(n = arguments[i] + "") || n in t || /[\s.]/.test(n))
      throw new Error("illegal type: " + n);
    t[n] = [];
  }
  return new Mh(t);
}
function Mh(i) {
  this._ = i;
}
function aP(i, e) {
  return i.trim().split(/^|\s+/).map(function(t) {
    var n = "", r = t.indexOf(".");
    if (r >= 0 && (n = t.slice(r + 1), t = t.slice(0, r)), t && !e.hasOwnProperty(t))
      throw new Error("unknown type: " + t);
    return { type: t, name: n };
  });
}
Mh.prototype = Fy.prototype = {
  constructor: Mh,
  on: function(i, e) {
    var t = this._, n = aP(i + "", t), r, s = -1, a = n.length;
    if (arguments.length < 2) {
      for (; ++s < a; )
        if ((r = (i = n[s]).type) && (r = oP(t[r], i.name)))
          return r;
      return;
    }
    if (e != null && typeof e != "function")
      throw new Error("invalid callback: " + e);
    for (; ++s < a; )
      if (r = (i = n[s]).type)
        t[r] = c0(t[r], i.name, e);
      else if (e == null)
        for (r in t)
          t[r] = c0(t[r], i.name, null);
    return this;
  },
  copy: function() {
    var i = {}, e = this._;
    for (var t in e)
      i[t] = e[t].slice();
    return new Mh(i);
  },
  call: function(i, e) {
    if ((r = arguments.length - 2) > 0)
      for (var t = new Array(r), n = 0, r, s; n < r; ++n)
        t[n] = arguments[n + 2];
    if (!this._.hasOwnProperty(i))
      throw new Error("unknown type: " + i);
    for (s = this._[i], n = 0, r = s.length; n < r; ++n)
      s[n].value.apply(e, t);
  },
  apply: function(i, e, t) {
    if (!this._.hasOwnProperty(i))
      throw new Error("unknown type: " + i);
    for (var n = this._[i], r = 0, s = n.length; r < s; ++r)
      n[r].value.apply(e, t);
  }
};
function oP(i, e) {
  for (var t = 0, n = i.length, r; t < n; ++t)
    if ((r = i[t]).name === e)
      return r.value;
}
function c0(i, e, t) {
  for (var n = 0, r = i.length; n < r; ++n)
    if (i[n].name === e) {
      i[n] = sP, i = i.slice(0, n).concat(i.slice(n + 1));
      break;
    }
  return t != null && i.push({ name: e, value: t }), i;
}
var hl = 0, ac = 0, Vl = 0, Iy = 1e3, Oh, oc, kh = 0, Ia = 0, md = 0, $c = typeof performance == "object" && performance.now ? performance : Date, Uy = typeof window == "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(i) {
  setTimeout(i, 17);
};
function By() {
  return Ia || (Uy(lP), Ia = $c.now() + md);
}
function lP() {
  Ia = 0;
}
function Lp() {
  this._call = this._time = this._next = null;
}
Lp.prototype = Oy.prototype = {
  constructor: Lp,
  restart: function(i, e, t) {
    if (typeof i != "function")
      throw new TypeError("callback is not a function");
    t = (t == null ? By() : +t) + (e == null ? 0 : +e), !this._next && oc !== this && (oc ? oc._next = this : Oh = this, oc = this), this._call = i, this._time = t, Fp();
  },
  stop: function() {
    this._call && (this._call = null, this._time = 1 / 0, Fp());
  }
};
function Oy(i, e, t) {
  var n = new Lp();
  return n.restart(i, e, t), n;
}
function cP() {
  By(), ++hl;
  for (var i = Oh, e; i; )
    (e = Ia - i._time) >= 0 && i._call.call(void 0, e), i = i._next;
  --hl;
}
function u0() {
  Ia = (kh = $c.now()) + md, hl = ac = 0;
  try {
    cP();
  } finally {
    hl = 0, hP(), Ia = 0;
  }
}
function uP() {
  var i = $c.now(), e = i - kh;
  e > Iy && (md -= e, kh = i);
}
function hP() {
  for (var i, e = Oh, t, n = 1 / 0; e; )
    e._call ? (n > e._time && (n = e._time), i = e, e = e._next) : (t = e._next, e._next = null, e = i ? i._next = t : Oh = t);
  oc = i, Fp(n);
}
function Fp(i) {
  if (!hl) {
    ac && (ac = clearTimeout(ac));
    var e = i - Ia;
    e > 24 ? (i < 1 / 0 && (ac = setTimeout(u0, i - $c.now() - md)), Vl && (Vl = clearInterval(Vl))) : (Vl || (kh = $c.now(), Vl = setInterval(uP, Iy)), hl = 1, Uy(u0));
  }
}
const dP = 1664525, fP = 1013904223, h0 = 4294967296;
function pP() {
  let i = 1;
  return () => (i = (dP * i + fP) % h0) / h0;
}
var d0 = 3;
function yf(i) {
  return i.x;
}
function f0(i) {
  return i.y;
}
function mP(i) {
  return i.z;
}
var gP = 10, _P = Math.PI * (3 - Math.sqrt(5)), xP = Math.PI * 20 / (9 + Math.sqrt(221));
function vP(i, e) {
  e = e || 2;
  var t = Math.min(d0, Math.max(1, Math.round(e))), n, r = 1, s = 1e-3, a = 1 - Math.pow(s, 1 / 300), o = 0, l = 0.6, c = /* @__PURE__ */ new Map(), u = Oy(f), h = Fy("tick", "end"), d = pP();
  i == null && (i = []);
  function f() {
    p(), h.call("tick", n), r < s && (u.stop(), h.call("end", n));
  }
  function p(m) {
    var x, y = i.length, b;
    m === void 0 && (m = 1);
    for (var T = 0; T < m; ++T)
      for (r += (o - r) * a, c.forEach(function(S) {
        S(r);
      }), x = 0; x < y; ++x)
        b = i[x], b.fx == null ? b.x += b.vx *= l : (b.x = b.fx, b.vx = 0), t > 1 && (b.fy == null ? b.y += b.vy *= l : (b.y = b.fy, b.vy = 0)), t > 2 && (b.fz == null ? b.z += b.vz *= l : (b.z = b.fz, b.vz = 0));
    return n;
  }
  function _() {
    for (var m = 0, x = i.length, y; m < x; ++m) {
      if (y = i[m], y.index = m, y.fx != null && (y.x = y.fx), y.fy != null && (y.y = y.fy), y.fz != null && (y.z = y.fz), isNaN(y.x) || t > 1 && isNaN(y.y) || t > 2 && isNaN(y.z)) {
        var b = gP * (t > 2 ? Math.cbrt(0.5 + m) : t > 1 ? Math.sqrt(0.5 + m) : m), T = m * _P, S = m * xP;
        t === 1 ? y.x = b : t === 2 ? (y.x = b * Math.cos(T), y.y = b * Math.sin(T)) : (y.x = b * Math.sin(T) * Math.cos(S), y.y = b * Math.cos(T), y.z = b * Math.sin(T) * Math.sin(S));
      }
      (isNaN(y.vx) || t > 1 && isNaN(y.vy) || t > 2 && isNaN(y.vz)) && (y.vx = 0, t > 1 && (y.vy = 0), t > 2 && (y.vz = 0));
    }
  }
  function g(m) {
    return m.initialize && m.initialize(i, d, t), m;
  }
  return _(), n = {
    tick: p,
    restart: function() {
      return u.restart(f), n;
    },
    stop: function() {
      return u.stop(), n;
    },
    numDimensions: function(m) {
      return arguments.length ? (t = Math.min(d0, Math.max(1, Math.round(m))), c.forEach(g), n) : t;
    },
    nodes: function(m) {
      return arguments.length ? (i = m, _(), c.forEach(g), n) : i;
    },
    alpha: function(m) {
      return arguments.length ? (r = +m, n) : r;
    },
    alphaMin: function(m) {
      return arguments.length ? (s = +m, n) : s;
    },
    alphaDecay: function(m) {
      return arguments.length ? (a = +m, n) : +a;
    },
    alphaTarget: function(m) {
      return arguments.length ? (o = +m, n) : o;
    },
    velocityDecay: function(m) {
      return arguments.length ? (l = 1 - m, n) : 1 - l;
    },
    randomSource: function(m) {
      return arguments.length ? (d = m, c.forEach(g), n) : d;
    },
    force: function(m, x) {
      return arguments.length > 1 ? (x == null ? c.delete(m) : c.set(m, g(x)), n) : c.get(m);
    },
    find: function() {
      var m = Array.prototype.slice.call(arguments), x = m.shift() || 0, y = (t > 1 ? m.shift() : null) || 0, b = (t > 2 ? m.shift() : null) || 0, T = m.shift() || 1 / 0, S = 0, E = i.length, v, M, F, R, I, B;
      for (T *= T, S = 0; S < E; ++S)
        I = i[S], v = x - I.x, M = y - (I.y || 0), F = b - (I.z || 0), R = v * v + M * M + F * F, R < T && (B = I, T = R);
      return B;
    },
    on: function(m, x) {
      return arguments.length > 1 ? (h.on(m, x), n) : h.on(m);
    }
  };
}
function yP() {
  var i, e, t, n, r, s = ns(-30), a, o = 1, l = 1 / 0, c = 0.81;
  function u(p) {
    var _, g = i.length, m = (e === 1 ? Cy(i, yf) : e === 2 ? Py(i, yf, f0) : e === 3 ? Ly(i, yf, f0, mP) : null).visitAfter(d);
    for (r = p, _ = 0; _ < g; ++_)
      t = i[_], m.visit(f);
  }
  function h() {
    if (i) {
      var p, _ = i.length, g;
      for (a = new Array(_), p = 0; p < _; ++p)
        g = i[p], a[g.index] = +s(g, p, i);
    }
  }
  function d(p) {
    var _ = 0, g, m, x = 0, y, b, T, S, E = p.length;
    if (E) {
      for (y = b = T = S = 0; S < E; ++S)
        (g = p[S]) && (m = Math.abs(g.value)) && (_ += g.value, x += m, y += m * (g.x || 0), b += m * (g.y || 0), T += m * (g.z || 0));
      _ *= Math.sqrt(4 / E), p.x = y / x, e > 1 && (p.y = b / x), e > 2 && (p.z = T / x);
    } else {
      g = p, g.x = g.data.x, e > 1 && (g.y = g.data.y), e > 2 && (g.z = g.data.z);
      do
        _ += a[g.data.index];
      while (g = g.next);
    }
    p.value = _;
  }
  function f(p, _, g, m, x) {
    if (!p.value)
      return !0;
    var y = [g, m, x][e - 1], b = p.x - t.x, T = e > 1 ? p.y - t.y : 0, S = e > 2 ? p.z - t.z : 0, E = y - _, v = b * b + T * T + S * S;
    if (E * E / c < v)
      return v < l && (b === 0 && (b = Yr(n), v += b * b), e > 1 && T === 0 && (T = Yr(n), v += T * T), e > 2 && S === 0 && (S = Yr(n), v += S * S), v < o && (v = Math.sqrt(o * v)), t.vx += b * p.value * r / v, e > 1 && (t.vy += T * p.value * r / v), e > 2 && (t.vz += S * p.value * r / v)), !0;
    if (p.length || v >= l)
      return;
    (p.data !== t || p.next) && (b === 0 && (b = Yr(n), v += b * b), e > 1 && T === 0 && (T = Yr(n), v += T * T), e > 2 && S === 0 && (S = Yr(n), v += S * S), v < o && (v = Math.sqrt(o * v)));
    do
      p.data !== t && (E = a[p.data.index] * r / v, t.vx += b * E, e > 1 && (t.vy += T * E), e > 2 && (t.vz += S * E));
    while (p = p.next);
  }
  return u.initialize = function(p, ..._) {
    i = p, n = _.find((g) => typeof g == "function") || Math.random, e = _.find((g) => [1, 2, 3].includes(g)) || 2, h();
  }, u.strength = function(p) {
    return arguments.length ? (s = typeof p == "function" ? p : ns(+p), h(), u) : s;
  }, u.distanceMin = function(p) {
    return arguments.length ? (o = p * p, u) : Math.sqrt(o);
  }, u.distanceMax = function(p) {
    return arguments.length ? (l = p * p, u) : Math.sqrt(l);
  }, u.theta = function(p) {
    return arguments.length ? (c = p * p, u) : Math.sqrt(c);
  }, u;
}
function bP(i, e, t, n) {
  var r, s, a = ns(0.1), o, l;
  typeof i != "function" && (i = ns(+i)), e == null && (e = 0), t == null && (t = 0), n == null && (n = 0);
  function c(h) {
    for (var d = 0, f = r.length; d < f; ++d) {
      var p = r[d], _ = p.x - e || 1e-6, g = (p.y || 0) - t || 1e-6, m = (p.z || 0) - n || 1e-6, x = Math.sqrt(_ * _ + g * g + m * m), y = (l[d] - x) * o[d] * h / x;
      p.vx += _ * y, s > 1 && (p.vy += g * y), s > 2 && (p.vz += m * y);
    }
  }
  function u() {
    if (r) {
      var h, d = r.length;
      for (o = new Array(d), l = new Array(d), h = 0; h < d; ++h)
        l[h] = +i(r[h], h, r), o[h] = isNaN(l[h]) ? 0 : +a(r[h], h, r);
    }
  }
  return c.initialize = function(h, ...d) {
    r = h, s = d.find((f) => [1, 2, 3].includes(f)) || 2, u();
  }, c.strength = function(h) {
    return arguments.length ? (a = typeof h == "function" ? h : ns(+h), u(), c) : a;
  }, c.radius = function(h) {
    return arguments.length ? (i = typeof h == "function" ? h : ns(+h), u(), c) : i;
  }, c.x = function(h) {
    return arguments.length ? (e = +h, c) : e;
  }, c.y = function(h) {
    return arguments.length ? (t = +h, c) : t;
  }, c.z = function(h) {
    return arguments.length ? (n = +h, c) : n;
  }, c;
}
function SP(i) {
  MP(i);
  const e = TP(i);
  return i.on = e.on, i.off = e.off, i.fire = e.fire, i;
}
function TP(i) {
  let e = /* @__PURE__ */ Object.create(null);
  return { on: function(t, n, r) {
    if (typeof n != "function")
      throw new Error("callback is expected to be a function");
    let s = e[t];
    return s || (s = e[t] = []), s.push({ callback: n, ctx: r }), i;
  }, off: function(t, n) {
    if (typeof t > "u")
      return e = /* @__PURE__ */ Object.create(null), i;
    if (e[t])
      if (typeof n != "function")
        delete e[t];
      else {
        const r = e[t];
        for (let s = 0; s < r.length; ++s)
          r[s].callback === n && r.splice(s, 1);
      }
    return i;
  }, fire: function(t) {
    const n = e[t];
    if (!n)
      return i;
    let r;
    arguments.length > 1 && (r = Array.prototype.slice.call(arguments, 1));
    for (let s = 0; s < n.length; ++s) {
      const a = n[s];
      a.callback.apply(a.ctx, r);
    }
    return i;
  } };
}
function MP(i) {
  if (!i)
    throw new Error("Eventify cannot use falsy object as events subject");
  const e = ["on", "fire", "off"];
  for (let t = 0; t < e.length; ++t)
    if (i.hasOwnProperty(e[t]))
      throw new Error("Subject cannot be eventified, since it already has property '" + e[t] + "'");
}
var cg = SP;
const EP = /* @__PURE__ */ kv(cg);
function wP(i) {
  if (i = i || {}, "uniqueLinkId" in i && (console.warn(
    "ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\nUse `multigraph` option instead\n",
    `
`,
    `Note: there is also change in default behavior: From now on each graph
is considered to be not a multigraph by default (each edge is unique).`
  ), i.multigraph = i.uniqueLinkId), i.multigraph === void 0 && (i.multigraph = !1), typeof Map != "function")
    throw new Error("ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph");
  var e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map(), n = {}, r = 0, s = i.multigraph ? b : y, a = [], o = k, l = k, c = k, u = k, h = {
    /**
     * Sometimes duck typing could be slow. Giving clients a hint about data structure
     * via explicit version number here:
     */
    version: 20,
    /**
     * Adds node to the graph. If node with given id already exists in the graph
     * its data is extended with whatever comes in 'data' argument.
     *
     * @param nodeId the node's identifier. A string or number is preferred.
     * @param [data] additional data for the node being added. If node already
     *   exists its data object is augmented with the new one.
     *
     * @return {node} The newly added node or node with given id if it already exists.
     */
    addNode: _,
    /**
     * Adds a link to the graph. The function always create a new
     * link between two nodes. If one of the nodes does not exists
     * a new node is created.
     *
     * @param fromId link start node id;
     * @param toId link end node id;
     * @param [data] additional data to be set on the new link;
     *
     * @return {link} The newly created link
     */
    addLink: x,
    /**
     * Removes link from the graph. If link does not exist does nothing.
     *
     * @param link - object returned by addLink() or getLinks() methods.
     *
     * @returns true if link was removed; false otherwise.
     */
    removeLink: v,
    /**
     * Removes node with given id from the graph. If node does not exist in the graph
     * does nothing.
     *
     * @param nodeId node's identifier passed to addNode() function.
     *
     * @returns true if node was removed; false otherwise.
     */
    removeNode: m,
    /**
     * Gets node with given identifier. If node does not exist undefined value is returned.
     *
     * @param nodeId requested node identifier;
     *
     * @return {node} in with requested identifier or undefined if no such node exists.
     */
    getNode: g,
    /**
     * Gets number of nodes in this graph.
     *
     * @return number of nodes in the graph.
     */
    getNodeCount: T,
    /**
     * Gets total number of links in the graph.
     */
    getLinkCount: S,
    /**
     * Synonym for `getLinkCount()`
     */
    getEdgeCount: S,
    /**
     * Synonym for `getLinkCount()`
     */
    getLinksCount: S,
    /**
     * Synonym for `getNodeCount()`
     */
    getNodesCount: T,
    /**
     * Gets all links (inbound and outbound) from the node with given id.
     * If node with given id is not found null is returned.
     *
     * @param nodeId requested node identifier.
     *
     * @return Set of links from and to requested node if such node exists;
     *   otherwise null is returned.
     */
    getLinks: E,
    /**
     * Invokes callback on each node of the graph.
     *
     * @param {Function(node)} callback Function to be invoked. The function
     *   is passed one argument: visited node.
     */
    forEachNode: ve,
    /**
     * Invokes callback on every linked (adjacent) node to the given one.
     *
     * @param nodeId Identifier of the requested node.
     * @param {Function(node, link)} callback Function to be called on all linked nodes.
     *   The function is passed two parameters: adjacent node and link object itself.
     * @param oriented if true graph treated as oriented.
     */
    forEachLinkedNode: N,
    /**
     * Enumerates all links in the graph
     *
     * @param {Function(link)} callback Function to be called on all links in the graph.
     *   The function is passed one parameter: graph's link object.
     *
     * Link object contains at least the following fields:
     *  fromId - node id where link starts;
     *  toId - node id where link ends,
     *  data - additional data passed to graph.addLink() method.
     */
    forEachLink: B,
    /**
     * Suspend all notifications about graph changes until
     * endUpdate is called.
     */
    beginUpdate: c,
    /**
     * Resumes all notifications about graph changes and fires
     * graph 'changed' event in case there are any pending changes.
     */
    endUpdate: u,
    /**
     * Removes all nodes and links from the graph.
     */
    clear: I,
    /**
     * Detects whether there is a link between two nodes.
     * Operation complexity is O(n) where n - number of links of a node.
     * NOTE: this function is synonym for getLink()
     *
     * @returns link if there is one. null otherwise.
     */
    hasLink: F,
    /**
     * Detects whether there is a node with given id
     * 
     * Operation complexity is O(1)
     * NOTE: this function is synonym for getNode()
     *
     * @returns node if there is one; Falsy value otherwise.
     */
    hasNode: g,
    /**
     * Gets an edge between two nodes.
     * Operation complexity is O(n) where n - number of links of a node.
     *
     * @param {string} fromId link start identifier
     * @param {string} toId link end identifier
     *
     * @returns link if there is one; undefined otherwise.
     */
    getLink: F,
    /**
     * Gets a link by its id.
     *
     * @param {string} linkId link identifier
     *
     * @returns link if there is one; undefined otherwise.
     */
    getLinkById: R
  };
  return EP(h), d(), h;
  function d() {
    var X = h.on;
    h.on = te;
    function te() {
      return h.beginUpdate = c = re, h.endUpdate = u = se, o = f, l = p, h.on = X, X.apply(h, arguments);
    }
  }
  function f(X, te) {
    a.push({
      link: X,
      changeType: te
    });
  }
  function p(X, te) {
    a.push({
      node: X,
      changeType: te
    });
  }
  function _(X, te) {
    if (X === void 0)
      throw new Error("Invalid node identifier");
    c();
    var me = g(X);
    return me ? (me.data = te, l(me, "update")) : (me = new AP(X, te), l(me, "add")), e.set(X, me), u(), me;
  }
  function g(X) {
    return e.get(X);
  }
  function m(X) {
    var te = g(X);
    if (!te)
      return !1;
    c();
    var me = te.links;
    return me && (me.forEach(M), te.links = null), e.delete(X), l(te, "remove"), u(), !0;
  }
  function x(X, te, me) {
    c();
    var Qe = g(X) || _(X), ce = g(te) || _(te), z = s(X, te, me), Z = t.has(z.id);
    return t.set(z.id, z), p0(Qe, z), X !== te && p0(ce, z), o(z, Z ? "update" : "add"), u(), z;
  }
  function y(X, te, me) {
    var Qe = Gu(X, te), ce = t.get(Qe);
    return ce ? (ce.data = me, ce) : new m0(X, te, me, Qe);
  }
  function b(X, te, me) {
    var Qe = Gu(X, te), ce = n.hasOwnProperty(Qe);
    if (ce || F(X, te)) {
      ce || (n[Qe] = 0);
      var z = "@" + ++n[Qe];
      Qe = Gu(X + z, te + z);
    }
    return new m0(X, te, me, Qe);
  }
  function T() {
    return e.size;
  }
  function S() {
    return t.size;
  }
  function E(X) {
    var te = g(X);
    return te ? te.links : null;
  }
  function v(X, te) {
    return te !== void 0 && (X = F(X, te)), M(X);
  }
  function M(X) {
    if (!X || !t.get(X.id))
      return !1;
    c(), t.delete(X.id);
    var te = g(X.fromId), me = g(X.toId);
    return te && te.links.delete(X), me && me.links.delete(X), o(X, "remove"), u(), !0;
  }
  function F(X, te) {
    if (!(X === void 0 || te === void 0))
      return t.get(Gu(X, te));
  }
  function R(X) {
    if (X !== void 0)
      return t.get(X);
  }
  function I() {
    c(), ve(function(X) {
      m(X.id);
    }), u();
  }
  function B(X) {
    if (typeof X == "function")
      for (var te = t.values(), me = te.next(); !me.done; ) {
        if (X(me.value))
          return !0;
        me = te.next();
      }
  }
  function N(X, te, me) {
    var Qe = g(X);
    if (Qe && Qe.links && typeof te == "function")
      return me ? L(Qe.links, X, te) : C(Qe.links, X, te);
  }
  function C(X, te, me) {
    for (var Qe, ce = X.values(), z = ce.next(); !z.done; ) {
      var Z = z.value, ue = Z.fromId === te ? Z.toId : Z.fromId;
      if (Qe = me(e.get(ue), Z), Qe)
        return !0;
      z = ce.next();
    }
  }
  function L(X, te, me) {
    for (var Qe, ce = X.values(), z = ce.next(); !z.done; ) {
      var Z = z.value;
      if (Z.fromId === te && (Qe = me(e.get(Z.toId), Z), Qe))
        return !0;
      z = ce.next();
    }
  }
  function k() {
  }
  function re() {
    r += 1;
  }
  function se() {
    r -= 1, r === 0 && a.length > 0 && (h.fire("changed", a), a.length = 0);
  }
  function ve(X) {
    if (typeof X != "function")
      throw new Error("Function is expected to iterate over graph nodes. You passed " + X);
    for (var te = e.values(), me = te.next(); !me.done; ) {
      if (X(me.value))
        return !0;
      me = te.next();
    }
  }
}
function AP(i, e) {
  this.id = i, this.links = null, this.data = e;
}
function p0(i, e) {
  i.links ? i.links.add(e) : i.links = /* @__PURE__ */ new Set([e]);
}
function m0(i, e, t, n) {
  this.fromId = i, this.toId = e, this.data = t, this.id = n;
}
function Gu(i, e) {
  return i.toString() + "👉 " + e.toString();
}
var ug = { exports: {} }, au = { exports: {} }, ky = function(e) {
  return e === 0 ? "x" : e === 1 ? "y" : e === 2 ? "z" : "c" + (e + 1);
};
const RP = ky;
var Tl = function(e) {
  return t;
  function t(n, r) {
    let s = r && r.indent || 0, a = r && r.join !== void 0 ? r.join : `
`, o = Array(s + 1).join(" "), l = [];
    for (let c = 0; c < e; ++c) {
      let u = RP(c), h = c === 0 ? "" : o;
      l.push(h + n.replace(/{var}/g, u));
    }
    return l.join(a);
  }
};
const Gy = Tl;
au.exports = CP;
au.exports.generateCreateBodyFunctionBody = Vy;
au.exports.getVectorCode = Hy;
au.exports.getBodyCode = zy;
function CP(i, e) {
  let t = Vy(i, e), { Body: n } = new Function(t)();
  return n;
}
function Vy(i, e) {
  return `
${Hy(i, e)}
${zy(i)}
return {Body: Body, Vector: Vector};
`;
}
function zy(i) {
  let e = Gy(i), t = e("{var}", { join: ", " });
  return `
function Body(${t}) {
  this.isPinned = false;
  this.pos = new Vector(${t});
  this.force = new Vector();
  this.velocity = new Vector();
  this.mass = 1;

  this.springCount = 0;
  this.springLength = 0;
}

Body.prototype.reset = function() {
  this.force.reset();
  this.springCount = 0;
  this.springLength = 0;
}

Body.prototype.setPosition = function (${t}) {
  ${e("this.pos.{var} = {var} || 0;", { indent: 2 })}
};`;
}
function Hy(i, e) {
  let t = Gy(i), n = "";
  return e && (n = `${t(`
   var v{var};
Object.defineProperty(this, '{var}', {
  set: function(v) { 
    if (!Number.isFinite(v)) throw new Error('Cannot set non-numbers to {var}');
    v{var} = v; 
  },
  get: function() { return v{var}; }
});`)}`), `function Vector(${t("{var}", { join: ", " })}) {
  ${n}
    if (typeof arguments[0] === 'object') {
      // could be another vector
      let v = arguments[0];
      ${t('if (!Number.isFinite(v.{var})) throw new Error("Expected value is not a finite number at Vector constructor ({var})");', { indent: 4 })}
      ${t("this.{var} = v.{var};", { indent: 4 })}
    } else {
      ${t('this.{var} = typeof {var} === "number" ? {var} : 0;', { indent: 4 })}
    }
  }
  
  Vector.prototype.reset = function () {
    ${t("this.{var} = ", { join: "" })}0;
  };`;
}
var NP = au.exports, Ys = { exports: {} };
const hg = Tl, Ss = ky;
Ys.exports = PP;
Ys.exports.generateQuadTreeFunctionBody = $y;
Ys.exports.getInsertStackCode = Yy;
Ys.exports.getQuadNodeCode = jy;
Ys.exports.isSamePosition = Wy;
Ys.exports.getChildBodyCode = Xy;
Ys.exports.setChildBodyCode = qy;
function PP(i) {
  let e = $y(i);
  return new Function(e)();
}
function $y(i) {
  let e = hg(i), t = Math.pow(2, i);
  return `
${Yy()}
${jy(i)}
${Wy(i)}
${Xy(i)}
${qy(i)}

function createQuadTree(options, random) {
  options = options || {};
  options.gravity = typeof options.gravity === 'number' ? options.gravity : -1;
  options.theta = typeof options.theta === 'number' ? options.theta : 0.8;

  var gravity = options.gravity;
  var updateQueue = [];
  var insertStack = new InsertStack();
  var theta = options.theta;

  var nodesCache = [];
  var currentInCache = 0;
  var root = newNode();

  return {
    insertBodies: insertBodies,

    /**
     * Gets root node if it is present
     */
    getRoot: function() {
      return root;
    },

    updateBodyForce: update,

    options: function(newOptions) {
      if (newOptions) {
        if (typeof newOptions.gravity === 'number') {
          gravity = newOptions.gravity;
        }
        if (typeof newOptions.theta === 'number') {
          theta = newOptions.theta;
        }

        return this;
      }

      return {
        gravity: gravity,
        theta: theta
      };
    }
  };

  function newNode() {
    // To avoid pressure on GC we reuse nodes.
    var node = nodesCache[currentInCache];
    if (node) {
${a("      node.")}
      node.body = null;
      node.mass = ${e("node.mass_{var} = ", { join: "" })}0;
      ${e("node.min_{var} = node.max_{var} = ", { join: "" })}0;
    } else {
      node = new QuadNode();
      nodesCache[currentInCache] = node;
    }

    ++currentInCache;
    return node;
  }

  function update(sourceBody) {
    var queue = updateQueue;
    var v;
    ${e("var d{var};", { indent: 4 })}
    var r; 
    ${e("var f{var} = 0;", { indent: 4 })}
    var queueLength = 1;
    var shiftIdx = 0;
    var pushIdx = 1;

    queue[0] = root;

    while (queueLength) {
      var node = queue[shiftIdx];
      var body = node.body;

      queueLength -= 1;
      shiftIdx += 1;
      var differentBody = (body !== sourceBody);
      if (body && differentBody) {
        // If the current node is a leaf node (and it is not source body),
        // calculate the force exerted by the current node on body, and add this
        // amount to body's net force.
        ${e("d{var} = body.pos.{var} - sourceBody.pos.{var};", { indent: 8 })}
        r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});

        if (r === 0) {
          // Poor man's protection against zero distance.
          ${e("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 10 })}
          r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});
        }

        // This is standard gravitation force calculation but we divide
        // by r^3 to save two operations when normalizing force vector.
        v = gravity * body.mass * sourceBody.mass / (r * r * r);
        ${e("f{var} += v * d{var};", { indent: 8 })}
      } else if (differentBody) {
        // Otherwise, calculate the ratio s / r,  where s is the width of the region
        // represented by the internal node, and r is the distance between the body
        // and the node's center-of-mass
        ${e("d{var} = node.mass_{var} / node.mass - sourceBody.pos.{var};", { indent: 8 })}
        r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});

        if (r === 0) {
          // Sorry about code duplication. I don't want to create many functions
          // right away. Just want to see performance first.
          ${e("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 10 })}
          r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});
        }
        // If s / r < θ, treat this internal node as a single body, and calculate the
        // force it exerts on sourceBody, and add this amount to sourceBody's net force.
        if ((node.max_${Ss(0)} - node.min_${Ss(0)}) / r < theta) {
          // in the if statement above we consider node's width only
          // because the region was made into square during tree creation.
          // Thus there is no difference between using width or height.
          v = gravity * node.mass * sourceBody.mass / (r * r * r);
          ${e("f{var} += v * d{var};", { indent: 10 })}
        } else {
          // Otherwise, run the procedure recursively on each of the current node's children.

          // I intentionally unfolded this loop, to save several CPU cycles.
${s()}
        }
      }
    }

    ${e("sourceBody.force.{var} += f{var};", { indent: 4 })}
  }

  function insertBodies(bodies) {
    ${e("var {var}min = Number.MAX_VALUE;", { indent: 4 })}
    ${e("var {var}max = Number.MIN_VALUE;", { indent: 4 })}
    var i = bodies.length;

    // To reduce quad tree depth we are looking for exact bounding box of all particles.
    while (i--) {
      var pos = bodies[i].pos;
      ${e("if (pos.{var} < {var}min) {var}min = pos.{var};", { indent: 6 })}
      ${e("if (pos.{var} > {var}max) {var}max = pos.{var};", { indent: 6 })}
    }

    // Makes the bounds square.
    var maxSideLength = -Infinity;
    ${e("if ({var}max - {var}min > maxSideLength) maxSideLength = {var}max - {var}min ;", { indent: 4 })}

    currentInCache = 0;
    root = newNode();
    ${e("root.min_{var} = {var}min;", { indent: 4 })}
    ${e("root.max_{var} = {var}min + maxSideLength;", { indent: 4 })}

    i = bodies.length - 1;
    if (i >= 0) {
      root.body = bodies[i];
    }
    while (i--) {
      insert(bodies[i], root);
    }
  }

  function insert(newBody) {
    insertStack.reset();
    insertStack.push(root, newBody);

    while (!insertStack.isEmpty()) {
      var stackItem = insertStack.pop();
      var node = stackItem.node;
      var body = stackItem.body;

      if (!node.body) {
        // This is internal node. Update the total mass of the node and center-of-mass.
        ${e("var {var} = body.pos.{var};", { indent: 8 })}
        node.mass += body.mass;
        ${e("node.mass_{var} += body.mass * {var};", { indent: 8 })}

        // Recursively insert the body in the appropriate quadrant.
        // But first find the appropriate quadrant.
        var quadIdx = 0; // Assume we are in the 0's quad.
        ${e("var min_{var} = node.min_{var};", { indent: 8 })}
        ${e("var max_{var} = (min_{var} + node.max_{var}) / 2;", { indent: 8 })}

${r(8)}

        var child = getChild(node, quadIdx);

        if (!child) {
          // The node is internal but this quadrant is not taken. Add
          // subnode to it.
          child = newNode();
          ${e("child.min_{var} = min_{var};", { indent: 10 })}
          ${e("child.max_{var} = max_{var};", { indent: 10 })}
          child.body = body;

          setChild(node, quadIdx, child);
        } else {
          // continue searching in this quadrant.
          insertStack.push(child, body);
        }
      } else {
        // We are trying to add to the leaf node.
        // We have to convert current leaf into internal node
        // and continue adding two nodes.
        var oldBody = node.body;
        node.body = null; // internal nodes do not cary bodies

        if (isSamePosition(oldBody.pos, body.pos)) {
          // Prevent infinite subdivision by bumping one node
          // anywhere in this quadrant
          var retriesCount = 3;
          do {
            var offset = random.nextDouble();
            ${e("var d{var} = (node.max_{var} - node.min_{var}) * offset;", { indent: 12 })}

            ${e("oldBody.pos.{var} = node.min_{var} + d{var};", { indent: 12 })}
            retriesCount -= 1;
            // Make sure we don't bump it out of the box. If we do, next iteration should fix it
          } while (retriesCount > 0 && isSamePosition(oldBody.pos, body.pos));

          if (retriesCount === 0 && isSamePosition(oldBody.pos, body.pos)) {
            // This is very bad, we ran out of precision.
            // if we do not return from the method we'll get into
            // infinite loop here. So we sacrifice correctness of layout, and keep the app running
            // Next layout iteration should get larger bounding box in the first step and fix this
            return;
          }
        }
        // Next iteration should subdivide node further.
        insertStack.push(node, oldBody);
        insertStack.push(node, body);
      }
    }
  }
}
return createQuadTree;

`;
  function r(o) {
    let l = [], c = Array(o + 1).join(" ");
    for (let u = 0; u < i; ++u)
      l.push(c + `if (${Ss(u)} > max_${Ss(u)}) {`), l.push(c + `  quadIdx = quadIdx + ${Math.pow(2, u)};`), l.push(c + `  min_${Ss(u)} = max_${Ss(u)};`), l.push(c + `  max_${Ss(u)} = node.max_${Ss(u)};`), l.push(c + "}");
    return l.join(`
`);
  }
  function s() {
    let o = Array(11).join(" "), l = [];
    for (let c = 0; c < t; ++c)
      l.push(o + `if (node.quad${c}) {`), l.push(o + `  queue[pushIdx] = node.quad${c};`), l.push(o + "  queueLength += 1;"), l.push(o + "  pushIdx += 1;"), l.push(o + "}");
    return l.join(`
`);
  }
  function a(o) {
    let l = [];
    for (let c = 0; c < t; ++c)
      l.push(`${o}quad${c} = null;`);
    return l.join(`
`);
  }
}
function Wy(i) {
  let e = hg(i);
  return `
  function isSamePosition(point1, point2) {
    ${e("var d{var} = Math.abs(point1.{var} - point2.{var});", { indent: 2 })}
  
    return ${e("d{var} < 1e-8", { join: " && " })};
  }  
`;
}
function qy(i) {
  var e = Math.pow(2, i);
  return `
function setChild(node, idx, child) {
  ${t()}
}`;
  function t() {
    let n = [];
    for (let r = 0; r < e; ++r) {
      let s = r === 0 ? "  " : "  else ";
      n.push(`${s}if (idx === ${r}) node.quad${r} = child;`);
    }
    return n.join(`
`);
  }
}
function Xy(i) {
  return `function getChild(node, idx) {
${e()}
  return null;
}`;
  function e() {
    let t = [], n = Math.pow(2, i);
    for (let r = 0; r < n; ++r)
      t.push(`  if (idx === ${r}) return node.quad${r};`);
    return t.join(`
`);
  }
}
function jy(i) {
  let e = hg(i), t = Math.pow(2, i);
  var n = `
function QuadNode() {
  // body stored inside this node. In quad tree only leaf nodes (by construction)
  // contain bodies:
  this.body = null;

  // Child nodes are stored in quads. Each quad is presented by number:
  // 0 | 1
  // -----
  // 2 | 3
${r("  this.")}

  // Total mass of current node
  this.mass = 0;

  // Center of mass coordinates
  ${e("this.mass_{var} = 0;", { indent: 2 })}

  // bounding box coordinates
  ${e("this.min_{var} = 0;", { indent: 2 })}
  ${e("this.max_{var} = 0;", { indent: 2 })}
}
`;
  return n;
  function r(s) {
    let a = [];
    for (let o = 0; o < t; ++o)
      a.push(`${s}quad${o} = null;`);
    return a.join(`
`);
  }
}
function Yy() {
  return `
/**
 * Our implementation of QuadTree is non-recursive to avoid GC hit
 * This data structure represent stack of elements
 * which we are trying to insert into quad tree.
 */
function InsertStack () {
    this.stack = [];
    this.popIdx = 0;
}

InsertStack.prototype = {
    isEmpty: function() {
        return this.popIdx === 0;
    },
    push: function (node, body) {
        var item = this.stack[this.popIdx];
        if (!item) {
            // we are trying to avoid memory pressure: create new element
            // only when absolutely necessary
            this.stack[this.popIdx] = new InsertStackElement(node, body);
        } else {
            item.node = node;
            item.body = body;
        }
        ++this.popIdx;
    },
    pop: function () {
        if (this.popIdx > 0) {
            return this.stack[--this.popIdx];
        }
    },
    reset: function () {
        this.popIdx = 0;
    }
};

function InsertStackElement(node, body) {
    this.node = node; // QuadTree node
    this.body = body; // physical body which needs to be inserted to node
}
`;
}
var DP = Ys.exports, dg = { exports: {} };
dg.exports = FP;
dg.exports.generateFunctionBody = Ky;
const LP = Tl;
function FP(i) {
  let e = Ky(i);
  return new Function("bodies", "settings", "random", e);
}
function Ky(i) {
  let e = LP(i);
  return `
  var boundingBox = {
    ${e("min_{var}: 0, max_{var}: 0,", { indent: 4 })}
  };

  return {
    box: boundingBox,

    update: updateBoundingBox,

    reset: resetBoundingBox,

    getBestNewPosition: function (neighbors) {
      var ${e("base_{var} = 0", { join: ", " })};

      if (neighbors.length) {
        for (var i = 0; i < neighbors.length; ++i) {
          let neighborPos = neighbors[i].pos;
          ${e("base_{var} += neighborPos.{var};", { indent: 10 })}
        }

        ${e("base_{var} /= neighbors.length;", { indent: 8 })}
      } else {
        ${e("base_{var} = (boundingBox.min_{var} + boundingBox.max_{var}) / 2;", { indent: 8 })}
      }

      var springLength = settings.springLength;
      return {
        ${e("{var}: base_{var} + (random.nextDouble() - 0.5) * springLength,", { indent: 8 })}
      };
    }
  };

  function updateBoundingBox() {
    var i = bodies.length;
    if (i === 0) return; // No bodies - no borders.

    ${e("var max_{var} = -Infinity;", { indent: 4 })}
    ${e("var min_{var} = Infinity;", { indent: 4 })}

    while(i--) {
      // this is O(n), it could be done faster with quadtree, if we check the root node bounds
      var bodyPos = bodies[i].pos;
      ${e("if (bodyPos.{var} < min_{var}) min_{var} = bodyPos.{var};", { indent: 6 })}
      ${e("if (bodyPos.{var} > max_{var}) max_{var} = bodyPos.{var};", { indent: 6 })}
    }

    ${e("boundingBox.min_{var} = min_{var};", { indent: 4 })}
    ${e("boundingBox.max_{var} = max_{var};", { indent: 4 })}
  }

  function resetBoundingBox() {
    ${e("boundingBox.min_{var} = boundingBox.max_{var} = 0;", { indent: 4 })}
  }
`;
}
var IP = dg.exports, fg = { exports: {} };
const UP = Tl;
fg.exports = BP;
fg.exports.generateCreateDragForceFunctionBody = Zy;
function BP(i) {
  let e = Zy(i);
  return new Function("options", e);
}
function Zy(i) {
  return `
  if (!Number.isFinite(options.dragCoefficient)) throw new Error('dragCoefficient is not a finite number');

  return {
    update: function(body) {
      ${UP(i)("body.force.{var} -= options.dragCoefficient * body.velocity.{var};", { indent: 6 })}
    }
  };
`;
}
var OP = fg.exports, pg = { exports: {} };
const kP = Tl;
pg.exports = GP;
pg.exports.generateCreateSpringForceFunctionBody = Qy;
function GP(i) {
  let e = Qy(i);
  return new Function("options", "random", e);
}
function Qy(i) {
  let e = kP(i);
  return `
  if (!Number.isFinite(options.springCoefficient)) throw new Error('Spring coefficient is not a number');
  if (!Number.isFinite(options.springLength)) throw new Error('Spring length is not a number');

  return {
    /**
     * Updates forces acting on a spring
     */
    update: function (spring) {
      var body1 = spring.from;
      var body2 = spring.to;
      var length = spring.length < 0 ? options.springLength : spring.length;
      ${e("var d{var} = body2.pos.{var} - body1.pos.{var};", { indent: 6 })}
      var r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});

      if (r === 0) {
        ${e("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 8 })}
        r = Math.sqrt(${e("d{var} * d{var}", { join: " + " })});
      }

      var d = r - length;
      var coefficient = ((spring.coefficient > 0) ? spring.coefficient : options.springCoefficient) * d / r;

      ${e("body1.force.{var} += coefficient * d{var}", { indent: 6 })};
      body1.springCount += 1;
      body1.springLength += r;

      ${e("body2.force.{var} -= coefficient * d{var}", { indent: 6 })};
      body2.springCount += 1;
      body2.springLength += r;
    }
  };
`;
}
var VP = pg.exports, mg = { exports: {} };
const zP = Tl;
mg.exports = HP;
mg.exports.generateIntegratorFunctionBody = Jy;
function HP(i) {
  let e = Jy(i);
  return new Function("bodies", "timeStep", "adaptiveTimeStepWeight", e);
}
function Jy(i) {
  let e = zP(i);
  return `
  var length = bodies.length;
  if (length === 0) return 0;

  ${e("var d{var} = 0, t{var} = 0;", { indent: 2 })}

  for (var i = 0; i < length; ++i) {
    var body = bodies[i];
    if (body.isPinned) continue;

    if (adaptiveTimeStepWeight && body.springCount) {
      timeStep = (adaptiveTimeStepWeight * body.springLength/body.springCount);
    }

    var coeff = timeStep / body.mass;

    ${e("body.velocity.{var} += coeff * body.force.{var};", { indent: 4 })}
    ${e("var v{var} = body.velocity.{var};", { indent: 4 })}
    var v = Math.sqrt(${e("v{var} * v{var}", { join: " + " })});

    if (v > 1) {
      // We normalize it so that we move within timeStep range. 
      // for the case when v <= 1 - we let velocity to fade out.
      ${e("body.velocity.{var} = v{var} / v;", { indent: 6 })}
    }

    ${e("d{var} = timeStep * body.velocity.{var};", { indent: 4 })}

    ${e("body.pos.{var} += d{var};", { indent: 4 })}

    ${e("t{var} += Math.abs(d{var});", { indent: 4 })}
  }

  return (${e("t{var} * t{var}", { join: " + " })})/length;
`;
}
var $P = mg.exports, bf, g0;
function WP() {
  if (g0)
    return bf;
  g0 = 1, bf = i;
  function i(e, t, n, r) {
    this.from = e, this.to = t, this.length = n, this.coefficient = r;
  }
  return bf;
}
var Sf, _0;
function qP() {
  if (_0)
    return Sf;
  _0 = 1, Sf = i;
  function i(e, t) {
    var n;
    if (e || (e = {}), t) {
      for (n in t)
        if (t.hasOwnProperty(n)) {
          var r = e.hasOwnProperty(n), s = typeof t[n], a = !r || typeof e[n] !== s;
          a ? e[n] = t[n] : s === "object" && (e[n] = i(e[n], t[n]));
        }
    }
    return e;
  }
  return Sf;
}
var zl = { exports: {} }, x0;
function XP() {
  if (x0)
    return zl.exports;
  x0 = 1, zl.exports = i, zl.exports.random = i, zl.exports.randomIterator = o;
  function i(l) {
    var c = typeof l == "number" ? l : +/* @__PURE__ */ new Date();
    return new e(c);
  }
  function e(l) {
    this.seed = l;
  }
  e.prototype.next = a, e.prototype.nextDouble = s, e.prototype.uniform = s, e.prototype.gaussian = t, e.prototype.random = s;
  function t() {
    var l, c, u;
    do
      c = this.nextDouble() * 2 - 1, u = this.nextDouble() * 2 - 1, l = c * c + u * u;
    while (l >= 1 || l === 0);
    return c * Math.sqrt(-2 * Math.log(l) / l);
  }
  e.prototype.levy = n;
  function n() {
    var l = 1.5, c = Math.pow(
      r(1 + l) * Math.sin(Math.PI * l / 2) / (r((1 + l) / 2) * l * Math.pow(2, (l - 1) / 2)),
      1 / l
    );
    return this.gaussian() * c / Math.pow(Math.abs(this.gaussian()), 1 / l);
  }
  function r(l) {
    return Math.sqrt(2 * Math.PI / l) * Math.pow(1 / Math.E * (l + 1 / (12 * l - 1 / (10 * l))), l);
  }
  function s() {
    var l = this.seed;
    return l = l + 2127912214 + (l << 12) & 4294967295, l = (l ^ 3345072700 ^ l >>> 19) & 4294967295, l = l + 374761393 + (l << 5) & 4294967295, l = (l + 3550635116 ^ l << 9) & 4294967295, l = l + 4251993797 + (l << 3) & 4294967295, l = (l ^ 3042594569 ^ l >>> 16) & 4294967295, this.seed = l, (l & 268435455) / 268435456;
  }
  function a(l) {
    return Math.floor(this.nextDouble() * l);
  }
  function o(l, c) {
    var u = c || i();
    if (typeof u.next != "function")
      throw new Error("customRandom does not match expected API: next() function is missing");
    return {
      /**
       * Visits every single element of a collection once, in a random order.
       * Note: collection is modified in place.
       */
      forEach: d,
      /**
       * Shuffles array randomly, in place.
       */
      shuffle: h
    };
    function h() {
      var f, p, _;
      for (f = l.length - 1; f > 0; --f)
        p = u.next(f + 1), _ = l[p], l[p] = l[f], l[f] = _;
      return l;
    }
    function d(f) {
      var p, _, g;
      for (p = l.length - 1; p > 0; --p)
        _ = u.next(p + 1), g = l[_], l[_] = l[p], l[p] = g, f(g);
      l.length && f(l[0]);
    }
  }
  return zl.exports;
}
var eb = eD, jP = NP, YP = DP, KP = IP, ZP = OP, QP = VP, JP = $P, v0 = {};
function eD(i) {
  var e = WP(), t = qP(), n = cg;
  if (i) {
    if (i.springCoeff !== void 0)
      throw new Error("springCoeff was renamed to springCoefficient");
    if (i.dragCoeff !== void 0)
      throw new Error("dragCoeff was renamed to dragCoefficient");
  }
  i = t(i, {
    /**
     * Ideal length for links (springs in physical model).
     */
    springLength: 10,
    /**
     * Hook's law coefficient. 1 - solid spring.
     */
    springCoefficient: 0.8,
    /**
     * Coulomb's law coefficient. It's used to repel nodes thus should be negative
     * if you make it positive nodes start attract each other :).
     */
    gravity: -12,
    /**
     * Theta coefficient from Barnes Hut simulation. Ranged between (0, 1).
     * The closer it's to 1 the more nodes algorithm will have to go through.
     * Setting it to one makes Barnes Hut simulation no different from
     * brute-force forces calculation (each node is considered).
     */
    theta: 0.8,
    /**
     * Drag force coefficient. Used to slow down system, thus should be less than 1.
     * The closer it is to 0 the less tight system will be.
     */
    dragCoefficient: 0.9,
    // TODO: Need to rename this to something better. E.g. `dragCoefficient`
    /**
     * Default time step (dt) for forces integration
     */
    timeStep: 0.5,
    /**
     * Adaptive time step uses average spring length to compute actual time step:
     * See: https://twitter.com/anvaka/status/1293067160755957760
     */
    adaptiveTimeStepWeight: 0,
    /**
     * This parameter defines number of dimensions of the space where simulation
     * is performed. 
     */
    dimensions: 2,
    /**
     * In debug mode more checks are performed, this will help you catch errors
     * quickly, however for production build it is recommended to turn off this flag
     * to speed up computation.
     */
    debug: !1
  });
  var r = v0[i.dimensions];
  if (!r) {
    var s = i.dimensions;
    r = {
      Body: jP(s, i.debug),
      createQuadTree: YP(s),
      createBounds: KP(s),
      createDragForce: ZP(s),
      createSpringForce: QP(s),
      integrate: JP(s)
    }, v0[s] = r;
  }
  var a = r.Body, o = r.createQuadTree, l = r.createBounds, c = r.createDragForce, u = r.createSpringForce, h = r.integrate, d = (C) => new a(C), f = XP().random(42), p = [], _ = [], g = o(i, f), m = l(p, i, f), x = u(i, f), y = c(i), b = 0, T = [], S = /* @__PURE__ */ new Map(), E = 0;
  F("nbody", B), F("spring", N);
  var v = {
    /**
     * Array of bodies, registered with current simulator
     *
     * Note: To add new body, use addBody() method. This property is only
     * exposed for testing/performance purposes.
     */
    bodies: p,
    quadTree: g,
    /**
     * Array of springs, registered with current simulator
     *
     * Note: To add new spring, use addSpring() method. This property is only
     * exposed for testing/performance purposes.
     */
    springs: _,
    /**
     * Returns settings with which current simulator was initialized
     */
    settings: i,
    /**
     * Adds a new force to simulation
     */
    addForce: F,
    /**
     * Removes a force from the simulation.
     */
    removeForce: R,
    /**
     * Returns a map of all registered forces.
     */
    getForces: I,
    /**
     * Performs one step of force simulation.
     *
     * @returns {boolean} true if system is considered stable; False otherwise.
     */
    step: function() {
      for (var C = 0; C < T.length; ++C)
        T[C](E);
      var L = h(p, i.timeStep, i.adaptiveTimeStepWeight);
      return E += 1, L;
    },
    /**
     * Adds body to the system
     *
     * @param {ngraph.physics.primitives.Body} body physical body
     *
     * @returns {ngraph.physics.primitives.Body} added body
     */
    addBody: function(C) {
      if (!C)
        throw new Error("Body is required");
      return p.push(C), C;
    },
    /**
     * Adds body to the system at given position
     *
     * @param {Object} pos position of a body
     *
     * @returns {ngraph.physics.primitives.Body} added body
     */
    addBodyAt: function(C) {
      if (!C)
        throw new Error("Body position is required");
      var L = d(C);
      return p.push(L), L;
    },
    /**
     * Removes body from the system
     *
     * @param {ngraph.physics.primitives.Body} body to remove
     *
     * @returns {Boolean} true if body found and removed. falsy otherwise;
     */
    removeBody: function(C) {
      if (C) {
        var L = p.indexOf(C);
        if (!(L < 0))
          return p.splice(L, 1), p.length === 0 && m.reset(), !0;
      }
    },
    /**
     * Adds a spring to this simulation.
     *
     * @returns {Object} - a handle for a spring. If you want to later remove
     * spring pass it to removeSpring() method.
     */
    addSpring: function(C, L, k, re) {
      if (!C || !L)
        throw new Error("Cannot add null spring to force simulator");
      typeof k != "number" && (k = -1);
      var se = new e(C, L, k, re >= 0 ? re : -1);
      return _.push(se), se;
    },
    /**
     * Returns amount of movement performed on last step() call
     */
    getTotalMovement: function() {
      return b;
    },
    /**
     * Removes spring from the system
     *
     * @param {Object} spring to remove. Spring is an object returned by addSpring
     *
     * @returns {Boolean} true if spring found and removed. falsy otherwise;
     */
    removeSpring: function(C) {
      if (C) {
        var L = _.indexOf(C);
        if (L > -1)
          return _.splice(L, 1), !0;
      }
    },
    getBestNewBodyPosition: function(C) {
      return m.getBestNewPosition(C);
    },
    /**
     * Returns bounding box which covers all bodies
     */
    getBBox: M,
    getBoundingBox: M,
    invalidateBBox: function() {
      console.warn("invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call");
    },
    // TODO: Move the force specific stuff to force
    gravity: function(C) {
      return C !== void 0 ? (i.gravity = C, g.options({ gravity: C }), this) : i.gravity;
    },
    theta: function(C) {
      return C !== void 0 ? (i.theta = C, g.options({ theta: C }), this) : i.theta;
    },
    /**
     * Returns pseudo-random number generator instance.
     */
    random: f
  };
  return tD(i, v), n(v), v;
  function M() {
    return m.update(), m.box;
  }
  function F(C, L) {
    if (S.has(C))
      throw new Error("Force " + C + " is already added");
    S.set(C, L), T.push(L);
  }
  function R(C) {
    var L = T.indexOf(S.get(C));
    L < 0 || (T.splice(L, 1), S.delete(C));
  }
  function I() {
    return S;
  }
  function B() {
    if (p.length !== 0) {
      g.insertBodies(p);
      for (var C = p.length; C--; ) {
        var L = p[C];
        L.isPinned || (L.reset(), g.updateBodyForce(L), y.update(L));
      }
    }
  }
  function N() {
    for (var C = _.length; C--; )
      x.update(_[C]);
  }
}
function tD(i, e) {
  for (var t in i)
    nD(i, e, t);
}
function nD(i, e, t) {
  if (i.hasOwnProperty(t) && typeof e[t] != "function") {
    var n = Number.isFinite(i[t]);
    n ? e[t] = function(r) {
      if (r !== void 0) {
        if (!Number.isFinite(r))
          throw new Error("Value of " + t + " should be a valid number.");
        return i[t] = r, e;
      }
      return i[t];
    } : e[t] = function(r) {
      return r !== void 0 ? (i[t] = r, e) : i[t];
    };
  }
}
ug.exports = rD;
ug.exports.simulator = eb;
var iD = cg;
function rD(i, e) {
  if (!i)
    throw new Error("Graph structure cannot be undefined");
  var t = e && e.createSimulator || eb, n = t(e);
  if (Array.isArray(e))
    throw new Error("Physics settings is expected to be an object");
  var r = i.version > 19 ? B : I;
  e && typeof e.nodeMass == "function" && (r = e.nodeMass);
  var s = /* @__PURE__ */ new Map(), a = {}, o = 0, l = n.settings.springTransform || sD;
  y(), g();
  var c = !1, u = {
    /**
     * Performs one step of iterative layout algorithm
     *
     * @returns {boolean} true if the system should be considered stable; False otherwise.
     * The system is stable if no further call to `step()` can improve the layout.
     */
    step: function() {
      if (o === 0)
        return h(!0), !0;
      var N = n.step();
      u.lastMove = N, u.fire("step");
      var C = N / o, L = C <= 0.01;
      return h(L), L;
    },
    /**
     * For a given `nodeId` returns position
     */
    getNodePosition: function(N) {
      return R(N).pos;
    },
    /**
     * Sets position of a node to a given coordinates
     * @param {string} nodeId node identifier
     * @param {number} x position of a node
     * @param {number} y position of a node
     * @param {number=} z position of node (only if applicable to body)
     */
    setNodePosition: function(N) {
      var C = R(N);
      C.setPosition.apply(C, Array.prototype.slice.call(arguments, 1));
    },
    /**
     * @returns {Object} Link position by link id
     * @returns {Object.from} {x, y} coordinates of link start
     * @returns {Object.to} {x, y} coordinates of link end
     */
    getLinkPosition: function(N) {
      var C = a[N];
      if (C)
        return {
          from: C.from.pos,
          to: C.to.pos
        };
    },
    /**
     * @returns {Object} area required to fit in the graph. Object contains
     * `x1`, `y1` - top left coordinates
     * `x2`, `y2` - bottom right coordinates
     */
    getGraphRect: function() {
      return n.getBBox();
    },
    /**
     * Iterates over each body in the layout simulator and performs a callback(body, nodeId)
     */
    forEachBody: d,
    /*
     * Requests layout algorithm to pin/unpin node to its current position
     * Pinned nodes should not be affected by layout algorithm and always
     * remain at their position
     */
    pinNode: function(N, C) {
      var L = R(N.id);
      L.isPinned = !!C;
    },
    /**
     * Checks whether given graph's node is currently pinned
     */
    isNodePinned: function(N) {
      return R(N.id).isPinned;
    },
    /**
     * Request to release all resources
     */
    dispose: function() {
      i.off("changed", x), u.fire("disposed");
    },
    /**
     * Gets physical body for a given node id. If node is not found undefined
     * value is returned.
     */
    getBody: _,
    /**
     * Gets spring for a given edge.
     *
     * @param {string} linkId link identifer. If two arguments are passed then
     * this argument is treated as formNodeId
     * @param {string=} toId when defined this parameter denotes head of the link
     * and first argument is treated as tail of the link (fromId)
     */
    getSpring: p,
    /**
     * Returns length of cumulative force vector. The closer this to zero - the more stable the system is
     */
    getForceVectorLength: f,
    /**
     * [Read only] Gets current physics simulator
     */
    simulator: n,
    /**
     * Gets the graph that was used for layout
     */
    graph: i,
    /**
     * Gets amount of movement performed during last step operation
     */
    lastMove: 0
  };
  return iD(u), u;
  function h(N) {
    c !== N && (c = N, m(N));
  }
  function d(N) {
    s.forEach(N);
  }
  function f() {
    var N = 0, C = 0;
    return d(function(L) {
      N += Math.abs(L.force.x), C += Math.abs(L.force.y);
    }), Math.sqrt(N * N + C * C);
  }
  function p(N, C) {
    var L;
    if (C === void 0)
      typeof N != "object" ? L = N : L = N.id;
    else {
      var k = i.hasLink(N, C);
      if (!k)
        return;
      L = k.id;
    }
    return a[L];
  }
  function _(N) {
    return s.get(N);
  }
  function g() {
    i.on("changed", x);
  }
  function m(N) {
    u.fire("stable", N);
  }
  function x(N) {
    for (var C = 0; C < N.length; ++C) {
      var L = N[C];
      L.changeType === "add" ? (L.node && b(L.node.id), L.link && S(L.link)) : L.changeType === "remove" && (L.node && T(L.node), L.link && E(L.link));
    }
    o = i.getNodesCount();
  }
  function y() {
    o = 0, i.forEachNode(function(N) {
      b(N.id), o += 1;
    }), i.forEachLink(S);
  }
  function b(N) {
    var C = s.get(N);
    if (!C) {
      var L = i.getNode(N);
      if (!L)
        throw new Error("initBody() was called with unknown node id");
      var k = L.position;
      if (!k) {
        var re = v(L);
        k = n.getBestNewBodyPosition(re);
      }
      C = n.addBodyAt(k), C.id = N, s.set(N, C), M(N), F(L) && (C.isPinned = !0);
    }
  }
  function T(N) {
    var C = N.id, L = s.get(C);
    L && (s.delete(C), n.removeBody(L));
  }
  function S(N) {
    M(N.fromId), M(N.toId);
    var C = s.get(N.fromId), L = s.get(N.toId), k = n.addSpring(C, L, N.length);
    l(N, k), a[N.id] = k;
  }
  function E(N) {
    var C = a[N.id];
    if (C) {
      var L = i.getNode(N.fromId), k = i.getNode(N.toId);
      L && M(L.id), k && M(k.id), delete a[N.id], n.removeSpring(C);
    }
  }
  function v(N) {
    var C = [];
    if (!N.links)
      return C;
    for (var L = Math.min(N.links.length, 2), k = 0; k < L; ++k) {
      var re = N.links[k], se = re.fromId !== N.id ? s.get(re.fromId) : s.get(re.toId);
      se && se.pos && C.push(se);
    }
    return C;
  }
  function M(N) {
    var C = s.get(N);
    if (C.mass = r(N), Number.isNaN(C.mass))
      throw new Error("Node mass should be a number");
  }
  function F(N) {
    return N && (N.isPinned || N.data && N.data.isPinned);
  }
  function R(N) {
    var C = s.get(N);
    return C || (b(N), C = s.get(N)), C;
  }
  function I(N) {
    var C = i.getLinks(N);
    return C ? 1 + C.length / 3 : 1;
  }
  function B(N) {
    var C = i.getLinks(N);
    return C ? 1 + C.size / 3 : 1;
  }
}
function sD() {
}
var aD = ug.exports;
const oD = /* @__PURE__ */ kv(aD);
function Ip(i) {
  var e = typeof i;
  return i != null && (e == "object" || e == "function");
}
var lD = typeof global == "object" && global && global.Object === Object && global, cD = typeof self == "object" && self && self.Object === Object && self, tb = lD || cD || Function("return this")(), Tf = function() {
  return tb.Date.now();
}, uD = /\s/;
function hD(i) {
  for (var e = i.length; e-- && uD.test(i.charAt(e)); )
    ;
  return e;
}
var dD = /^\s+/;
function fD(i) {
  return i && i.slice(0, hD(i) + 1).replace(dD, "");
}
var Gh = tb.Symbol, nb = Object.prototype, pD = nb.hasOwnProperty, mD = nb.toString, Hl = Gh ? Gh.toStringTag : void 0;
function gD(i) {
  var e = pD.call(i, Hl), t = i[Hl];
  try {
    i[Hl] = void 0;
    var n = !0;
  } catch {
  }
  var r = mD.call(i);
  return n && (e ? i[Hl] = t : delete i[Hl]), r;
}
var _D = Object.prototype, xD = _D.toString;
function vD(i) {
  return xD.call(i);
}
var yD = "[object Null]", bD = "[object Undefined]", y0 = Gh ? Gh.toStringTag : void 0;
function SD(i) {
  return i == null ? i === void 0 ? bD : yD : y0 && y0 in Object(i) ? gD(i) : vD(i);
}
function TD(i) {
  return i != null && typeof i == "object";
}
var MD = "[object Symbol]";
function ED(i) {
  return typeof i == "symbol" || TD(i) && SD(i) == MD;
}
var b0 = NaN, wD = /^[-+]0x[0-9a-f]+$/i, AD = /^0b[01]+$/i, RD = /^0o[0-7]+$/i, CD = parseInt;
function S0(i) {
  if (typeof i == "number")
    return i;
  if (ED(i))
    return b0;
  if (Ip(i)) {
    var e = typeof i.valueOf == "function" ? i.valueOf() : i;
    i = Ip(e) ? e + "" : e;
  }
  if (typeof i != "string")
    return i === 0 ? i : +i;
  i = fD(i);
  var t = AD.test(i);
  return t || RD.test(i) ? CD(i.slice(2), t ? 2 : 8) : wD.test(i) ? b0 : +i;
}
var ND = "Expected a function", PD = Math.max, DD = Math.min;
function LD(i, e, t) {
  var n, r, s, a, o, l, c = 0, u = !1, h = !1, d = !0;
  if (typeof i != "function")
    throw new TypeError(ND);
  e = S0(e) || 0, Ip(t) && (u = !!t.leading, h = "maxWait" in t, s = h ? PD(S0(t.maxWait) || 0, e) : s, d = "trailing" in t ? !!t.trailing : d);
  function f(S) {
    var E = n, v = r;
    return n = r = void 0, c = S, a = i.apply(v, E), a;
  }
  function p(S) {
    return c = S, o = setTimeout(m, e), u ? f(S) : a;
  }
  function _(S) {
    var E = S - l, v = S - c, M = e - E;
    return h ? DD(M, s - v) : M;
  }
  function g(S) {
    var E = S - l, v = S - c;
    return l === void 0 || E >= e || E < 0 || h && v >= s;
  }
  function m() {
    var S = Tf();
    if (g(S))
      return x(S);
    o = setTimeout(m, _(S));
  }
  function x(S) {
    return o = void 0, d && n ? f(S) : (n = r = void 0, a);
  }
  function y() {
    o !== void 0 && clearTimeout(o), c = 0, n = l = r = o = void 0;
  }
  function b() {
    return o === void 0 ? a : x(Tf());
  }
  function T() {
    var S = Tf(), E = g(S);
    if (n = arguments, r = this, l = S, E) {
      if (o === void 0)
        return p(l);
      if (h)
        return clearTimeout(o), o = setTimeout(m, e), f(l);
    }
    return o === void 0 && (o = setTimeout(m, e)), a;
  }
  return T.cancel = y, T.flush = b, T;
}
function T0(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function FD(i) {
  if (Array.isArray(i))
    return i;
}
function ID(i, e) {
  if (!(i instanceof e))
    throw new TypeError("Cannot call a class as a function");
}
function UD(i, e, t) {
  return Object.defineProperty(i, "prototype", {
    writable: !1
  }), i;
}
function BD(i, e) {
  var t = i == null ? null : typeof Symbol < "u" && i[Symbol.iterator] || i["@@iterator"];
  if (t != null) {
    var n, r, s, a, o = [], l = !0, c = !1;
    try {
      if (s = (t = t.call(i)).next, e !== 0)
        for (; !(l = (n = s.call(t)).done) && (o.push(n.value), o.length !== e); l = !0)
          ;
    } catch (u) {
      c = !0, r = u;
    } finally {
      try {
        if (!l && t.return != null && (a = t.return(), Object(a) !== a))
          return;
      } finally {
        if (c)
          throw r;
      }
    }
    return o;
  }
}
function OD() {
  throw new TypeError(`Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function kD(i, e) {
  return FD(i) || BD(i, e) || GD(i, e) || OD();
}
function GD(i, e) {
  if (i) {
    if (typeof i == "string")
      return T0(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? T0(i, e) : void 0;
  }
}
var VD = /* @__PURE__ */ UD(function i(e, t) {
  var n = t.default, r = n === void 0 ? null : n, s = t.triggerUpdate, a = s === void 0 ? !0 : s, o = t.onChange, l = o === void 0 ? function(c, u) {
  } : o;
  ID(this, i), this.name = e, this.defaultVal = r, this.triggerUpdate = a, this.onChange = l;
});
function gd(i) {
  var e = i.stateInit, t = e === void 0 ? function() {
    return {};
  } : e, n = i.props, r = n === void 0 ? {} : n, s = i.methods, a = s === void 0 ? {} : s, o = i.aliases, l = o === void 0 ? {} : o, c = i.init, u = c === void 0 ? function() {
  } : c, h = i.update, d = h === void 0 ? function() {
  } : h, f = Object.keys(r).map(function(p) {
    return new VD(p, r[p]);
  });
  return function p() {
    for (var _ = arguments.length, g = new Array(_), m = 0; m < _; m++)
      g[m] = arguments[m];
    var x = !!(this instanceof p && this.constructor), y = x ? g.shift() : void 0, b = g[0], T = b === void 0 ? {} : b, S = Object.assign(
      {},
      t instanceof Function ? t(T) : t,
      // Support plain objects for backwards compatibility
      {
        initialised: !1
      }
    ), E = {};
    function v(R) {
      return M(R, T), F(), v;
    }
    var M = function(I, B) {
      u.call(v, I, S, B), S.initialised = !0;
    }, F = LD(function() {
      S.initialised && (d.call(v, S, E), E = {});
    }, 1);
    return f.forEach(function(R) {
      v[R.name] = I(R);
      function I(B) {
        var N = B.name, C = B.triggerUpdate, L = C === void 0 ? !1 : C, k = B.onChange, re = k === void 0 ? function(X, te) {
        } : k, se = B.defaultVal, ve = se === void 0 ? null : se;
        return function(X) {
          var te = S[N];
          if (!arguments.length)
            return te;
          var me = X === void 0 ? ve : X;
          return S[N] = me, re.call(v, me, S, te), !E.hasOwnProperty(N) && (E[N] = te), L && F(), v;
        };
      }
    }), Object.keys(a).forEach(function(R) {
      v[R] = function() {
        for (var I, B = arguments.length, N = new Array(B), C = 0; C < B; C++)
          N[C] = arguments[C];
        return (I = a[R]).call.apply(I, [v, S].concat(N));
      };
    }), Object.entries(l).forEach(function(R) {
      var I = kD(R, 2), B = I[0], N = I[1];
      return v[B] = v[N];
    }), v.resetProps = function() {
      return f.forEach(function(R) {
        v[R.name](R.defaultVal);
      }), v;
    }, v.resetProps(), S._rerender = F, x && y && v(y), v;
  };
}
var xt = function(i) {
  return typeof i == "function" ? i : typeof i == "string" ? function(e) {
    return e[i];
  } : function(e) {
    return i;
  };
};
class M0 extends Map {
  constructor(e, t = $D) {
    if (super(), Object.defineProperties(this, { _intern: { value: /* @__PURE__ */ new Map() }, _key: { value: t } }), e != null)
      for (const [n, r] of e)
        this.set(n, r);
  }
  get(e) {
    return super.get(E0(this, e));
  }
  has(e) {
    return super.has(E0(this, e));
  }
  set(e, t) {
    return super.set(zD(this, e), t);
  }
  delete(e) {
    return super.delete(HD(this, e));
  }
}
function E0({ _intern: i, _key: e }, t) {
  const n = e(t);
  return i.has(n) ? i.get(n) : t;
}
function zD({ _intern: i, _key: e }, t) {
  const n = e(t);
  return i.has(n) ? i.get(n) : (i.set(n, t), t);
}
function HD({ _intern: i, _key: e }, t) {
  const n = e(t);
  return i.has(n) && (t = i.get(n), i.delete(n)), t;
}
function $D(i) {
  return i !== null && typeof i == "object" ? i.valueOf() : i;
}
function WD(i, e) {
  let t;
  if (e === void 0)
    for (const n of i)
      n != null && (t < n || t === void 0 && n >= n) && (t = n);
  else {
    let n = -1;
    for (let r of i)
      (r = e(r, ++n, i)) != null && (t < r || t === void 0 && r >= r) && (t = r);
  }
  return t;
}
function qD(i, e) {
  let t;
  if (e === void 0)
    for (const n of i)
      n != null && (t > n || t === void 0 && n >= n) && (t = n);
  else {
    let n = -1;
    for (let r of i)
      (r = e(r, ++n, i)) != null && (t > r || t === void 0 && r >= r) && (t = r);
  }
  return t;
}
function Up(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function XD(i) {
  if (Array.isArray(i))
    return i;
}
function jD(i) {
  if (Array.isArray(i))
    return Up(i);
}
function ib(i, e, t) {
  if (typeof i == "function" ? i === e : i.has(e))
    return arguments.length < 3 ? e : t;
  throw new TypeError("Private element is not present on this object");
}
function YD(i, e) {
  if (e.has(i))
    throw new TypeError("Cannot initialize the same private elements twice on an object");
}
function KD(i, e) {
  if (!(i instanceof e))
    throw new TypeError("Cannot call a class as a function");
}
function $n(i, e) {
  return i.get(ib(i, e));
}
function ho(i, e, t) {
  YD(i, e), e.set(i, t);
}
function Vu(i, e, t) {
  return i.set(ib(i, e), t), t;
}
function ZD(i, e) {
  for (var t = 0; t < e.length; t++) {
    var n = e[t];
    n.enumerable = n.enumerable || !1, n.configurable = !0, "value" in n && (n.writable = !0), Object.defineProperty(i, aL(n.key), n);
  }
}
function QD(i, e, t) {
  return e && ZD(i.prototype, e), Object.defineProperty(i, "prototype", {
    writable: !1
  }), i;
}
function JD(i) {
  if (typeof Symbol < "u" && i[Symbol.iterator] != null || i["@@iterator"] != null)
    return Array.from(i);
}
function eL(i, e) {
  var t = i == null ? null : typeof Symbol < "u" && i[Symbol.iterator] || i["@@iterator"];
  if (t != null) {
    var n, r, s, a, o = [], l = !0, c = !1;
    try {
      if (s = (t = t.call(i)).next, e !== 0)
        for (; !(l = (n = s.call(t)).done) && (o.push(n.value), o.length !== e); l = !0)
          ;
    } catch (u) {
      c = !0, r = u;
    } finally {
      try {
        if (!l && t.return != null && (a = t.return(), Object(a) !== a))
          return;
      } finally {
        if (c)
          throw r;
      }
    }
    return o;
  }
}
function tL() {
  throw new TypeError(`Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function nL() {
  throw new TypeError(`Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function iL(i, e) {
  return XD(i) || eL(i, e) || rb(i, e) || tL();
}
function rL(i) {
  return jD(i) || JD(i) || rb(i) || nL();
}
function sL(i, e) {
  if (typeof i != "object" || !i)
    return i;
  var t = i[Symbol.toPrimitive];
  if (t !== void 0) {
    var n = t.call(i, e);
    if (typeof n != "object")
      return n;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return String(i);
}
function aL(i) {
  var e = sL(i, "string");
  return typeof e == "symbol" ? e : e + "";
}
function rb(i, e) {
  if (i) {
    if (typeof i == "string")
      return Up(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? Up(i, e) : void 0;
  }
}
var fo = /* @__PURE__ */ new WeakMap(), $l = /* @__PURE__ */ new WeakMap(), po = /* @__PURE__ */ new WeakMap(), Mf = /* @__PURE__ */ new WeakMap(), Ef = /* @__PURE__ */ new WeakMap(), wf = /* @__PURE__ */ new WeakMap(), oL = /* @__PURE__ */ function() {
  function i() {
    KD(this, i), ho(this, fo, /* @__PURE__ */ new Map()), ho(this, $l, /* @__PURE__ */ new Map()), ho(this, po, function(e) {
      return e;
    }), ho(this, Mf, function() {
      return {};
    }), ho(this, Ef, function() {
    }), ho(this, wf, function() {
    });
  }
  return QD(i, [{
    key: "getObj",
    value: function(t) {
      return $n(fo, this).get($n(po, this).call(this, t));
    }
  }, {
    key: "getData",
    value: function(t) {
      return $n($l, this).get(t);
    }
  }, {
    key: "entries",
    value: function() {
      return rL($n($l, this).entries()).map(function(t) {
        var n = iL(t, 2), r = n[0], s = n[1];
        return [s, r];
      });
    }
  }, {
    key: "id",
    value: function(t) {
      return Vu(po, this, xt(t)), this;
    }
  }, {
    key: "onCreateObj",
    value: function(t) {
      return Vu(Mf, this, t), this;
    }
  }, {
    key: "onUpdateObj",
    value: function(t) {
      return Vu(Ef, this, t), this;
    }
  }, {
    key: "onRemoveObj",
    value: function(t) {
      return Vu(wf, this, t), this;
    }
  }, {
    key: "digest",
    value: function(t) {
      var n = this;
      t.filter(function(s) {
        return !$n(fo, n).has($n(po, n).call(n, s));
      }).forEach(function(s) {
        var a = $n(Mf, n).call(n, s);
        $n(fo, n).set($n(po, n).call(n, s), a), $n($l, n).set(a, s);
      });
      var r = new Map(t.map(function(s) {
        return [$n(po, n).call(n, s), s];
      }));
      return $n(fo, this).forEach(function(s, a) {
        r.has(a) ? $n(Ef, n).call(n, s, r.get(a)) : ($n(wf, n).call(n, s, a), $n(fo, n).delete(a), $n($l, n).delete(s));
      }), this;
    }
  }, {
    key: "clear",
    value: function() {
      return this.digest([]), this;
    }
  }]);
}();
function lL(i, e) {
  switch (arguments.length) {
    case 0:
      break;
    case 1:
      this.range(i);
      break;
    default:
      this.range(e).domain(i);
      break;
  }
  return this;
}
const w0 = Symbol("implicit");
function sb() {
  var i = new M0(), e = [], t = [], n = w0;
  function r(s) {
    let a = i.get(s);
    if (a === void 0) {
      if (n !== w0)
        return n;
      i.set(s, a = e.push(s) - 1);
    }
    return t[a % t.length];
  }
  return r.domain = function(s) {
    if (!arguments.length)
      return e.slice();
    e = [], i = new M0();
    for (const a of s)
      i.has(a) || i.set(a, e.push(a) - 1);
    return r;
  }, r.range = function(s) {
    return arguments.length ? (t = Array.from(s), r) : t.slice();
  }, r.unknown = function(s) {
    return arguments.length ? (n = s, r) : n;
  }, r.copy = function() {
    return sb(e, t).unknown(n);
  }, lL.apply(r, arguments), r;
}
function cL(i) {
  for (var e = i.length / 6 | 0, t = new Array(e), n = 0; n < e; )
    t[n] = "#" + i.slice(n * 6, ++n * 6);
  return t;
}
const uL = cL("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928");
function Vh(i) {
  "@babel/helpers - typeof";
  return Vh = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
    return typeof e;
  } : function(e) {
    return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
  }, Vh(i);
}
var hL = /^\s+/, dL = /\s+$/;
function $e(i, e) {
  if (i = i || "", e = e || {}, i instanceof $e)
    return i;
  if (!(this instanceof $e))
    return new $e(i, e);
  var t = fL(i);
  this._originalInput = i, this._r = t.r, this._g = t.g, this._b = t.b, this._a = t.a, this._roundA = Math.round(100 * this._a) / 100, this._format = e.format || t.format, this._gradientType = e.gradientType, this._r < 1 && (this._r = Math.round(this._r)), this._g < 1 && (this._g = Math.round(this._g)), this._b < 1 && (this._b = Math.round(this._b)), this._ok = t.ok;
}
$e.prototype = {
  isDark: function() {
    return this.getBrightness() < 128;
  },
  isLight: function() {
    return !this.isDark();
  },
  isValid: function() {
    return this._ok;
  },
  getOriginalInput: function() {
    return this._originalInput;
  },
  getFormat: function() {
    return this._format;
  },
  getAlpha: function() {
    return this._a;
  },
  getBrightness: function() {
    var e = this.toRgb();
    return (e.r * 299 + e.g * 587 + e.b * 114) / 1e3;
  },
  getLuminance: function() {
    var e = this.toRgb(), t, n, r, s, a, o;
    return t = e.r / 255, n = e.g / 255, r = e.b / 255, t <= 0.03928 ? s = t / 12.92 : s = Math.pow((t + 0.055) / 1.055, 2.4), n <= 0.03928 ? a = n / 12.92 : a = Math.pow((n + 0.055) / 1.055, 2.4), r <= 0.03928 ? o = r / 12.92 : o = Math.pow((r + 0.055) / 1.055, 2.4), 0.2126 * s + 0.7152 * a + 0.0722 * o;
  },
  setAlpha: function(e) {
    return this._a = ab(e), this._roundA = Math.round(100 * this._a) / 100, this;
  },
  toHsv: function() {
    var e = R0(this._r, this._g, this._b);
    return {
      h: e.h * 360,
      s: e.s,
      v: e.v,
      a: this._a
    };
  },
  toHsvString: function() {
    var e = R0(this._r, this._g, this._b), t = Math.round(e.h * 360), n = Math.round(e.s * 100), r = Math.round(e.v * 100);
    return this._a == 1 ? "hsv(" + t + ", " + n + "%, " + r + "%)" : "hsva(" + t + ", " + n + "%, " + r + "%, " + this._roundA + ")";
  },
  toHsl: function() {
    var e = A0(this._r, this._g, this._b);
    return {
      h: e.h * 360,
      s: e.s,
      l: e.l,
      a: this._a
    };
  },
  toHslString: function() {
    var e = A0(this._r, this._g, this._b), t = Math.round(e.h * 360), n = Math.round(e.s * 100), r = Math.round(e.l * 100);
    return this._a == 1 ? "hsl(" + t + ", " + n + "%, " + r + "%)" : "hsla(" + t + ", " + n + "%, " + r + "%, " + this._roundA + ")";
  },
  toHex: function(e) {
    return C0(this._r, this._g, this._b, e);
  },
  toHexString: function(e) {
    return "#" + this.toHex(e);
  },
  toHex8: function(e) {
    return _L(this._r, this._g, this._b, this._a, e);
  },
  toHex8String: function(e) {
    return "#" + this.toHex8(e);
  },
  toRgb: function() {
    return {
      r: Math.round(this._r),
      g: Math.round(this._g),
      b: Math.round(this._b),
      a: this._a
    };
  },
  toRgbString: function() {
    return this._a == 1 ? "rgb(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ")" : "rgba(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ", " + this._roundA + ")";
  },
  toPercentageRgb: function() {
    return {
      r: Math.round(tn(this._r, 255) * 100) + "%",
      g: Math.round(tn(this._g, 255) * 100) + "%",
      b: Math.round(tn(this._b, 255) * 100) + "%",
      a: this._a
    };
  },
  toPercentageRgbString: function() {
    return this._a == 1 ? "rgb(" + Math.round(tn(this._r, 255) * 100) + "%, " + Math.round(tn(this._g, 255) * 100) + "%, " + Math.round(tn(this._b, 255) * 100) + "%)" : "rgba(" + Math.round(tn(this._r, 255) * 100) + "%, " + Math.round(tn(this._g, 255) * 100) + "%, " + Math.round(tn(this._b, 255) * 100) + "%, " + this._roundA + ")";
  },
  toName: function() {
    return this._a === 0 ? "transparent" : this._a < 1 ? !1 : CL[C0(this._r, this._g, this._b, !0)] || !1;
  },
  toFilter: function(e) {
    var t = "#" + N0(this._r, this._g, this._b, this._a), n = t, r = this._gradientType ? "GradientType = 1, " : "";
    if (e) {
      var s = $e(e);
      n = "#" + N0(s._r, s._g, s._b, s._a);
    }
    return "progid:DXImageTransform.Microsoft.gradient(" + r + "startColorstr=" + t + ",endColorstr=" + n + ")";
  },
  toString: function(e) {
    var t = !!e;
    e = e || this._format;
    var n = !1, r = this._a < 1 && this._a >= 0, s = !t && r && (e === "hex" || e === "hex6" || e === "hex3" || e === "hex4" || e === "hex8" || e === "name");
    return s ? e === "name" && this._a === 0 ? this.toName() : this.toRgbString() : (e === "rgb" && (n = this.toRgbString()), e === "prgb" && (n = this.toPercentageRgbString()), (e === "hex" || e === "hex6") && (n = this.toHexString()), e === "hex3" && (n = this.toHexString(!0)), e === "hex4" && (n = this.toHex8String(!0)), e === "hex8" && (n = this.toHex8String()), e === "name" && (n = this.toName()), e === "hsl" && (n = this.toHslString()), e === "hsv" && (n = this.toHsvString()), n || this.toHexString());
  },
  clone: function() {
    return $e(this.toString());
  },
  _applyModification: function(e, t) {
    var n = e.apply(null, [this].concat([].slice.call(t)));
    return this._r = n._r, this._g = n._g, this._b = n._b, this.setAlpha(n._a), this;
  },
  lighten: function() {
    return this._applyModification(bL, arguments);
  },
  brighten: function() {
    return this._applyModification(SL, arguments);
  },
  darken: function() {
    return this._applyModification(TL, arguments);
  },
  desaturate: function() {
    return this._applyModification(xL, arguments);
  },
  saturate: function() {
    return this._applyModification(vL, arguments);
  },
  greyscale: function() {
    return this._applyModification(yL, arguments);
  },
  spin: function() {
    return this._applyModification(ML, arguments);
  },
  _applyCombination: function(e, t) {
    return e.apply(null, [this].concat([].slice.call(t)));
  },
  analogous: function() {
    return this._applyCombination(AL, arguments);
  },
  complement: function() {
    return this._applyCombination(EL, arguments);
  },
  monochromatic: function() {
    return this._applyCombination(RL, arguments);
  },
  splitcomplement: function() {
    return this._applyCombination(wL, arguments);
  },
  // Disabled until https://github.com/bgrins/TinyColor/issues/254
  // polyad: function (number) {
  //   return this._applyCombination(polyad, [number]);
  // },
  triad: function() {
    return this._applyCombination(P0, [3]);
  },
  tetrad: function() {
    return this._applyCombination(P0, [4]);
  }
};
$e.fromRatio = function(i, e) {
  if (Vh(i) == "object") {
    var t = {};
    for (var n in i)
      i.hasOwnProperty(n) && (n === "a" ? t[n] = i[n] : t[n] = lc(i[n]));
    i = t;
  }
  return $e(i, e);
};
function fL(i) {
  var e = {
    r: 0,
    g: 0,
    b: 0
  }, t = 1, n = null, r = null, s = null, a = !1, o = !1;
  return typeof i == "string" && (i = LL(i)), Vh(i) == "object" && ($r(i.r) && $r(i.g) && $r(i.b) ? (e = pL(i.r, i.g, i.b), a = !0, o = String(i.r).substr(-1) === "%" ? "prgb" : "rgb") : $r(i.h) && $r(i.s) && $r(i.v) ? (n = lc(i.s), r = lc(i.v), e = gL(i.h, n, r), a = !0, o = "hsv") : $r(i.h) && $r(i.s) && $r(i.l) && (n = lc(i.s), s = lc(i.l), e = mL(i.h, n, s), a = !0, o = "hsl"), i.hasOwnProperty("a") && (t = i.a)), t = ab(t), {
    ok: a,
    format: i.format || o,
    r: Math.min(255, Math.max(e.r, 0)),
    g: Math.min(255, Math.max(e.g, 0)),
    b: Math.min(255, Math.max(e.b, 0)),
    a: t
  };
}
function pL(i, e, t) {
  return {
    r: tn(i, 255) * 255,
    g: tn(e, 255) * 255,
    b: tn(t, 255) * 255
  };
}
function A0(i, e, t) {
  i = tn(i, 255), e = tn(e, 255), t = tn(t, 255);
  var n = Math.max(i, e, t), r = Math.min(i, e, t), s, a, o = (n + r) / 2;
  if (n == r)
    s = a = 0;
  else {
    var l = n - r;
    switch (a = o > 0.5 ? l / (2 - n - r) : l / (n + r), n) {
      case i:
        s = (e - t) / l + (e < t ? 6 : 0);
        break;
      case e:
        s = (t - i) / l + 2;
        break;
      case t:
        s = (i - e) / l + 4;
        break;
    }
    s /= 6;
  }
  return {
    h: s,
    s: a,
    l: o
  };
}
function mL(i, e, t) {
  var n, r, s;
  i = tn(i, 360), e = tn(e, 100), t = tn(t, 100);
  function a(c, u, h) {
    return h < 0 && (h += 1), h > 1 && (h -= 1), h < 1 / 6 ? c + (u - c) * 6 * h : h < 1 / 2 ? u : h < 2 / 3 ? c + (u - c) * (2 / 3 - h) * 6 : c;
  }
  if (e === 0)
    n = r = s = t;
  else {
    var o = t < 0.5 ? t * (1 + e) : t + e - t * e, l = 2 * t - o;
    n = a(l, o, i + 1 / 3), r = a(l, o, i), s = a(l, o, i - 1 / 3);
  }
  return {
    r: n * 255,
    g: r * 255,
    b: s * 255
  };
}
function R0(i, e, t) {
  i = tn(i, 255), e = tn(e, 255), t = tn(t, 255);
  var n = Math.max(i, e, t), r = Math.min(i, e, t), s, a, o = n, l = n - r;
  if (a = n === 0 ? 0 : l / n, n == r)
    s = 0;
  else {
    switch (n) {
      case i:
        s = (e - t) / l + (e < t ? 6 : 0);
        break;
      case e:
        s = (t - i) / l + 2;
        break;
      case t:
        s = (i - e) / l + 4;
        break;
    }
    s /= 6;
  }
  return {
    h: s,
    s: a,
    v: o
  };
}
function gL(i, e, t) {
  i = tn(i, 360) * 6, e = tn(e, 100), t = tn(t, 100);
  var n = Math.floor(i), r = i - n, s = t * (1 - e), a = t * (1 - r * e), o = t * (1 - (1 - r) * e), l = n % 6, c = [t, a, s, s, o, t][l], u = [o, t, t, a, s, s][l], h = [s, s, o, t, t, a][l];
  return {
    r: c * 255,
    g: u * 255,
    b: h * 255
  };
}
function C0(i, e, t, n) {
  var r = [er(Math.round(i).toString(16)), er(Math.round(e).toString(16)), er(Math.round(t).toString(16))];
  return n && r[0].charAt(0) == r[0].charAt(1) && r[1].charAt(0) == r[1].charAt(1) && r[2].charAt(0) == r[2].charAt(1) ? r[0].charAt(0) + r[1].charAt(0) + r[2].charAt(0) : r.join("");
}
function _L(i, e, t, n, r) {
  var s = [er(Math.round(i).toString(16)), er(Math.round(e).toString(16)), er(Math.round(t).toString(16)), er(ob(n))];
  return r && s[0].charAt(0) == s[0].charAt(1) && s[1].charAt(0) == s[1].charAt(1) && s[2].charAt(0) == s[2].charAt(1) && s[3].charAt(0) == s[3].charAt(1) ? s[0].charAt(0) + s[1].charAt(0) + s[2].charAt(0) + s[3].charAt(0) : s.join("");
}
function N0(i, e, t, n) {
  var r = [er(ob(n)), er(Math.round(i).toString(16)), er(Math.round(e).toString(16)), er(Math.round(t).toString(16))];
  return r.join("");
}
$e.equals = function(i, e) {
  return !i || !e ? !1 : $e(i).toRgbString() == $e(e).toRgbString();
};
$e.random = function() {
  return $e.fromRatio({
    r: Math.random(),
    g: Math.random(),
    b: Math.random()
  });
};
function xL(i, e) {
  e = e === 0 ? 0 : e || 10;
  var t = $e(i).toHsl();
  return t.s -= e / 100, t.s = _d(t.s), $e(t);
}
function vL(i, e) {
  e = e === 0 ? 0 : e || 10;
  var t = $e(i).toHsl();
  return t.s += e / 100, t.s = _d(t.s), $e(t);
}
function yL(i) {
  return $e(i).desaturate(100);
}
function bL(i, e) {
  e = e === 0 ? 0 : e || 10;
  var t = $e(i).toHsl();
  return t.l += e / 100, t.l = _d(t.l), $e(t);
}
function SL(i, e) {
  e = e === 0 ? 0 : e || 10;
  var t = $e(i).toRgb();
  return t.r = Math.max(0, Math.min(255, t.r - Math.round(255 * -(e / 100)))), t.g = Math.max(0, Math.min(255, t.g - Math.round(255 * -(e / 100)))), t.b = Math.max(0, Math.min(255, t.b - Math.round(255 * -(e / 100)))), $e(t);
}
function TL(i, e) {
  e = e === 0 ? 0 : e || 10;
  var t = $e(i).toHsl();
  return t.l -= e / 100, t.l = _d(t.l), $e(t);
}
function ML(i, e) {
  var t = $e(i).toHsl(), n = (t.h + e) % 360;
  return t.h = n < 0 ? 360 + n : n, $e(t);
}
function EL(i) {
  var e = $e(i).toHsl();
  return e.h = (e.h + 180) % 360, $e(e);
}
function P0(i, e) {
  if (isNaN(e) || e <= 0)
    throw new Error("Argument to polyad must be a positive number");
  for (var t = $e(i).toHsl(), n = [$e(i)], r = 360 / e, s = 1; s < e; s++)
    n.push($e({
      h: (t.h + s * r) % 360,
      s: t.s,
      l: t.l
    }));
  return n;
}
function wL(i) {
  var e = $e(i).toHsl(), t = e.h;
  return [$e(i), $e({
    h: (t + 72) % 360,
    s: e.s,
    l: e.l
  }), $e({
    h: (t + 216) % 360,
    s: e.s,
    l: e.l
  })];
}
function AL(i, e, t) {
  e = e || 6, t = t || 30;
  var n = $e(i).toHsl(), r = 360 / t, s = [$e(i)];
  for (n.h = (n.h - (r * e >> 1) + 720) % 360; --e; )
    n.h = (n.h + r) % 360, s.push($e(n));
  return s;
}
function RL(i, e) {
  e = e || 6;
  for (var t = $e(i).toHsv(), n = t.h, r = t.s, s = t.v, a = [], o = 1 / e; e--; )
    a.push($e({
      h: n,
      s: r,
      v: s
    })), s = (s + o) % 1;
  return a;
}
$e.mix = function(i, e, t) {
  t = t === 0 ? 0 : t || 50;
  var n = $e(i).toRgb(), r = $e(e).toRgb(), s = t / 100, a = {
    r: (r.r - n.r) * s + n.r,
    g: (r.g - n.g) * s + n.g,
    b: (r.b - n.b) * s + n.b,
    a: (r.a - n.a) * s + n.a
  };
  return $e(a);
};
$e.readability = function(i, e) {
  var t = $e(i), n = $e(e);
  return (Math.max(t.getLuminance(), n.getLuminance()) + 0.05) / (Math.min(t.getLuminance(), n.getLuminance()) + 0.05);
};
$e.isReadable = function(i, e, t) {
  var n = $e.readability(i, e), r, s;
  switch (s = !1, r = FL(t), r.level + r.size) {
    case "AAsmall":
    case "AAAlarge":
      s = n >= 4.5;
      break;
    case "AAlarge":
      s = n >= 3;
      break;
    case "AAAsmall":
      s = n >= 7;
      break;
  }
  return s;
};
$e.mostReadable = function(i, e, t) {
  var n = null, r = 0, s, a, o, l;
  t = t || {}, a = t.includeFallbackColors, o = t.level, l = t.size;
  for (var c = 0; c < e.length; c++)
    s = $e.readability(i, e[c]), s > r && (r = s, n = $e(e[c]));
  return $e.isReadable(i, n, {
    level: o,
    size: l
  }) || !a ? n : (t.includeFallbackColors = !1, $e.mostReadable(i, ["#fff", "#000"], t));
};
var Bp = $e.names = {
  aliceblue: "f0f8ff",
  antiquewhite: "faebd7",
  aqua: "0ff",
  aquamarine: "7fffd4",
  azure: "f0ffff",
  beige: "f5f5dc",
  bisque: "ffe4c4",
  black: "000",
  blanchedalmond: "ffebcd",
  blue: "00f",
  blueviolet: "8a2be2",
  brown: "a52a2a",
  burlywood: "deb887",
  burntsienna: "ea7e5d",
  cadetblue: "5f9ea0",
  chartreuse: "7fff00",
  chocolate: "d2691e",
  coral: "ff7f50",
  cornflowerblue: "6495ed",
  cornsilk: "fff8dc",
  crimson: "dc143c",
  cyan: "0ff",
  darkblue: "00008b",
  darkcyan: "008b8b",
  darkgoldenrod: "b8860b",
  darkgray: "a9a9a9",
  darkgreen: "006400",
  darkgrey: "a9a9a9",
  darkkhaki: "bdb76b",
  darkmagenta: "8b008b",
  darkolivegreen: "556b2f",
  darkorange: "ff8c00",
  darkorchid: "9932cc",
  darkred: "8b0000",
  darksalmon: "e9967a",
  darkseagreen: "8fbc8f",
  darkslateblue: "483d8b",
  darkslategray: "2f4f4f",
  darkslategrey: "2f4f4f",
  darkturquoise: "00ced1",
  darkviolet: "9400d3",
  deeppink: "ff1493",
  deepskyblue: "00bfff",
  dimgray: "696969",
  dimgrey: "696969",
  dodgerblue: "1e90ff",
  firebrick: "b22222",
  floralwhite: "fffaf0",
  forestgreen: "228b22",
  fuchsia: "f0f",
  gainsboro: "dcdcdc",
  ghostwhite: "f8f8ff",
  gold: "ffd700",
  goldenrod: "daa520",
  gray: "808080",
  green: "008000",
  greenyellow: "adff2f",
  grey: "808080",
  honeydew: "f0fff0",
  hotpink: "ff69b4",
  indianred: "cd5c5c",
  indigo: "4b0082",
  ivory: "fffff0",
  khaki: "f0e68c",
  lavender: "e6e6fa",
  lavenderblush: "fff0f5",
  lawngreen: "7cfc00",
  lemonchiffon: "fffacd",
  lightblue: "add8e6",
  lightcoral: "f08080",
  lightcyan: "e0ffff",
  lightgoldenrodyellow: "fafad2",
  lightgray: "d3d3d3",
  lightgreen: "90ee90",
  lightgrey: "d3d3d3",
  lightpink: "ffb6c1",
  lightsalmon: "ffa07a",
  lightseagreen: "20b2aa",
  lightskyblue: "87cefa",
  lightslategray: "789",
  lightslategrey: "789",
  lightsteelblue: "b0c4de",
  lightyellow: "ffffe0",
  lime: "0f0",
  limegreen: "32cd32",
  linen: "faf0e6",
  magenta: "f0f",
  maroon: "800000",
  mediumaquamarine: "66cdaa",
  mediumblue: "0000cd",
  mediumorchid: "ba55d3",
  mediumpurple: "9370db",
  mediumseagreen: "3cb371",
  mediumslateblue: "7b68ee",
  mediumspringgreen: "00fa9a",
  mediumturquoise: "48d1cc",
  mediumvioletred: "c71585",
  midnightblue: "191970",
  mintcream: "f5fffa",
  mistyrose: "ffe4e1",
  moccasin: "ffe4b5",
  navajowhite: "ffdead",
  navy: "000080",
  oldlace: "fdf5e6",
  olive: "808000",
  olivedrab: "6b8e23",
  orange: "ffa500",
  orangered: "ff4500",
  orchid: "da70d6",
  palegoldenrod: "eee8aa",
  palegreen: "98fb98",
  paleturquoise: "afeeee",
  palevioletred: "db7093",
  papayawhip: "ffefd5",
  peachpuff: "ffdab9",
  peru: "cd853f",
  pink: "ffc0cb",
  plum: "dda0dd",
  powderblue: "b0e0e6",
  purple: "800080",
  rebeccapurple: "663399",
  red: "f00",
  rosybrown: "bc8f8f",
  royalblue: "4169e1",
  saddlebrown: "8b4513",
  salmon: "fa8072",
  sandybrown: "f4a460",
  seagreen: "2e8b57",
  seashell: "fff5ee",
  sienna: "a0522d",
  silver: "c0c0c0",
  skyblue: "87ceeb",
  slateblue: "6a5acd",
  slategray: "708090",
  slategrey: "708090",
  snow: "fffafa",
  springgreen: "00ff7f",
  steelblue: "4682b4",
  tan: "d2b48c",
  teal: "008080",
  thistle: "d8bfd8",
  tomato: "ff6347",
  turquoise: "40e0d0",
  violet: "ee82ee",
  wheat: "f5deb3",
  white: "fff",
  whitesmoke: "f5f5f5",
  yellow: "ff0",
  yellowgreen: "9acd32"
}, CL = $e.hexNames = NL(Bp);
function NL(i) {
  var e = {};
  for (var t in i)
    i.hasOwnProperty(t) && (e[i[t]] = t);
  return e;
}
function ab(i) {
  return i = parseFloat(i), (isNaN(i) || i < 0 || i > 1) && (i = 1), i;
}
function tn(i, e) {
  PL(i) && (i = "100%");
  var t = DL(i);
  return i = Math.min(e, Math.max(0, parseFloat(i))), t && (i = parseInt(i * e, 10) / 100), Math.abs(i - e) < 1e-6 ? 1 : i % e / parseFloat(e);
}
function _d(i) {
  return Math.min(1, Math.max(0, i));
}
function Ei(i) {
  return parseInt(i, 16);
}
function PL(i) {
  return typeof i == "string" && i.indexOf(".") != -1 && parseFloat(i) === 1;
}
function DL(i) {
  return typeof i == "string" && i.indexOf("%") != -1;
}
function er(i) {
  return i.length == 1 ? "0" + i : "" + i;
}
function lc(i) {
  return i <= 1 && (i = i * 100 + "%"), i;
}
function ob(i) {
  return Math.round(parseFloat(i) * 255).toString(16);
}
function D0(i) {
  return Ei(i) / 255;
}
var Yi = function() {
  var i = "[-\\+]?\\d+%?", e = "[-\\+]?\\d*\\.\\d+%?", t = "(?:" + e + ")|(?:" + i + ")", n = "[\\s|\\(]+(" + t + ")[,|\\s]+(" + t + ")[,|\\s]+(" + t + ")\\s*\\)?", r = "[\\s|\\(]+(" + t + ")[,|\\s]+(" + t + ")[,|\\s]+(" + t + ")[,|\\s]+(" + t + ")\\s*\\)?";
  return {
    CSS_UNIT: new RegExp(t),
    rgb: new RegExp("rgb" + n),
    rgba: new RegExp("rgba" + r),
    hsl: new RegExp("hsl" + n),
    hsla: new RegExp("hsla" + r),
    hsv: new RegExp("hsv" + n),
    hsva: new RegExp("hsva" + r),
    hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
    hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
    hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
    hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
  };
}();
function $r(i) {
  return !!Yi.CSS_UNIT.exec(i);
}
function LL(i) {
  i = i.replace(hL, "").replace(dL, "").toLowerCase();
  var e = !1;
  if (Bp[i])
    i = Bp[i], e = !0;
  else if (i == "transparent")
    return {
      r: 0,
      g: 0,
      b: 0,
      a: 0,
      format: "name"
    };
  var t;
  return (t = Yi.rgb.exec(i)) ? {
    r: t[1],
    g: t[2],
    b: t[3]
  } : (t = Yi.rgba.exec(i)) ? {
    r: t[1],
    g: t[2],
    b: t[3],
    a: t[4]
  } : (t = Yi.hsl.exec(i)) ? {
    h: t[1],
    s: t[2],
    l: t[3]
  } : (t = Yi.hsla.exec(i)) ? {
    h: t[1],
    s: t[2],
    l: t[3],
    a: t[4]
  } : (t = Yi.hsv.exec(i)) ? {
    h: t[1],
    s: t[2],
    v: t[3]
  } : (t = Yi.hsva.exec(i)) ? {
    h: t[1],
    s: t[2],
    v: t[3],
    a: t[4]
  } : (t = Yi.hex8.exec(i)) ? {
    r: Ei(t[1]),
    g: Ei(t[2]),
    b: Ei(t[3]),
    a: D0(t[4]),
    format: e ? "name" : "hex8"
  } : (t = Yi.hex6.exec(i)) ? {
    r: Ei(t[1]),
    g: Ei(t[2]),
    b: Ei(t[3]),
    format: e ? "name" : "hex"
  } : (t = Yi.hex4.exec(i)) ? {
    r: Ei(t[1] + "" + t[1]),
    g: Ei(t[2] + "" + t[2]),
    b: Ei(t[3] + "" + t[3]),
    a: D0(t[4] + "" + t[4]),
    format: e ? "name" : "hex8"
  } : (t = Yi.hex3.exec(i)) ? {
    r: Ei(t[1] + "" + t[1]),
    g: Ei(t[2] + "" + t[2]),
    b: Ei(t[3] + "" + t[3]),
    format: e ? "name" : "hex"
  } : !1;
}
function FL(i) {
  var e, t;
  return i = i || {
    level: "AA",
    size: "small"
  }, e = (i.level || "AA").toUpperCase(), t = (i.size || "small").toLowerCase(), e !== "AA" && e !== "AAA" && (e = "AA"), t !== "small" && t !== "large" && (t = "small"), {
    level: e,
    size: t
  };
}
function Op(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function IL(i) {
  if (Array.isArray(i))
    return i;
}
function UL(i) {
  if (Array.isArray(i))
    return Op(i);
}
function lb(i, e, t) {
  if (typeof i == "function" ? i === e : i.has(e))
    return arguments.length < 3 ? e : t;
  throw new TypeError("Private element is not present on this object");
}
function BL(i) {
  if (i === void 0)
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  return i;
}
function cb(i, e, t) {
  return e = dl(e), WL(i, gg() ? Reflect.construct(e, t || [], dl(i).constructor) : e.apply(i, t));
}
function OL(i, e) {
  if (e.has(i))
    throw new TypeError("Cannot initialize the same private elements twice on an object");
}
function ub(i, e) {
  if (!(i instanceof e))
    throw new TypeError("Cannot call a class as a function");
}
function Af(i, e) {
  return i.get(lb(i, e));
}
function L0(i, e, t) {
  OL(i, e), e.set(i, t);
}
function F0(i, e, t) {
  return i.set(lb(i, e), t), t;
}
function hb(i, e, t) {
  if (gg())
    return Reflect.construct.apply(null, arguments);
  var n = [null];
  n.push.apply(n, e);
  var r = new (i.bind.apply(i, n))();
  return r;
}
function kL(i, e) {
  for (var t = 0; t < e.length; t++) {
    var n = e[t];
    n.enumerable = n.enumerable || !1, n.configurable = !0, "value" in n && (n.writable = !0), Object.defineProperty(i, pb(n.key), n);
  }
}
function db(i, e, t) {
  return e && kL(i.prototype, e), Object.defineProperty(i, "prototype", {
    writable: !1
  }), i;
}
function xd(i, e, t) {
  return (e = pb(e)) in i ? Object.defineProperty(i, e, {
    value: t,
    enumerable: !0,
    configurable: !0,
    writable: !0
  }) : i[e] = t, i;
}
function kp() {
  return kp = typeof Reflect < "u" && Reflect.get ? Reflect.get.bind() : function(i, e, t) {
    var n = qL(i, e);
    if (n) {
      var r = Object.getOwnPropertyDescriptor(n, e);
      return r.get ? r.get.call(arguments.length < 3 ? i : t) : r.value;
    }
  }, kp.apply(null, arguments);
}
function dl(i) {
  return dl = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e) {
    return e.__proto__ || Object.getPrototypeOf(e);
  }, dl(i);
}
function fb(i, e) {
  if (typeof e != "function" && e !== null)
    throw new TypeError("Super expression must either be null or a function");
  i.prototype = Object.create(e && e.prototype, {
    constructor: {
      value: i,
      writable: !0,
      configurable: !0
    }
  }), Object.defineProperty(i, "prototype", {
    writable: !1
  }), e && Gp(i, e);
}
function gg() {
  try {
    var i = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {
    }));
  } catch {
  }
  return (gg = function() {
    return !!i;
  })();
}
function GL(i) {
  if (typeof Symbol < "u" && i[Symbol.iterator] != null || i["@@iterator"] != null)
    return Array.from(i);
}
function VL(i, e) {
  var t = i == null ? null : typeof Symbol < "u" && i[Symbol.iterator] || i["@@iterator"];
  if (t != null) {
    var n, r, s, a, o = [], l = !0, c = !1;
    try {
      if (s = (t = t.call(i)).next, e !== 0)
        for (; !(l = (n = s.call(t)).done) && (o.push(n.value), o.length !== e); l = !0)
          ;
    } catch (u) {
      c = !0, r = u;
    } finally {
      try {
        if (!l && t.return != null && (a = t.return(), Object(a) !== a))
          return;
      } finally {
        if (c)
          throw r;
      }
    }
    return o;
  }
}
function zL() {
  throw new TypeError(`Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function HL() {
  throw new TypeError(`Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function I0(i, e) {
  var t = Object.keys(i);
  if (Object.getOwnPropertySymbols) {
    var n = Object.getOwnPropertySymbols(i);
    e && (n = n.filter(function(r) {
      return Object.getOwnPropertyDescriptor(i, r).enumerable;
    })), t.push.apply(t, n);
  }
  return t;
}
function $L(i) {
  for (var e = 1; e < arguments.length; e++) {
    var t = arguments[e] != null ? arguments[e] : {};
    e % 2 ? I0(Object(t), !0).forEach(function(n) {
      xd(i, n, t[n]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(i, Object.getOwnPropertyDescriptors(t)) : I0(Object(t)).forEach(function(n) {
      Object.defineProperty(i, n, Object.getOwnPropertyDescriptor(t, n));
    });
  }
  return i;
}
function WL(i, e) {
  if (e && (typeof e == "object" || typeof e == "function"))
    return e;
  if (e !== void 0)
    throw new TypeError("Derived constructors may only return object or undefined");
  return BL(i);
}
function Gp(i, e) {
  return Gp = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t, n) {
    return t.__proto__ = n, t;
  }, Gp(i, e);
}
function _c(i, e) {
  return IL(i) || VL(i, e) || mb(i, e) || zL();
}
function qL(i, e) {
  for (; !{}.hasOwnProperty.call(i, e) && (i = dl(i)) !== null; )
    ;
  return i;
}
function Rf(i, e, t, n) {
  var r = kp(dl(i.prototype), e, t);
  return typeof r == "function" ? function(s) {
    return r.apply(t, s);
  } : r;
}
function Ki(i) {
  return UL(i) || GL(i) || mb(i) || HL();
}
function XL(i, e) {
  if (typeof i != "object" || !i)
    return i;
  var t = i[Symbol.toPrimitive];
  if (t !== void 0) {
    var n = t.call(i, e);
    if (typeof n != "object")
      return n;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (e === "string" ? String : Number)(i);
}
function pb(i) {
  var e = XL(i, "string");
  return typeof e == "symbol" ? e : e + "";
}
function Vp(i) {
  "@babel/helpers - typeof";
  return Vp = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
    return typeof e;
  } : function(e) {
    return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
  }, Vp(i);
}
function mb(i, e) {
  if (i) {
    if (typeof i == "string")
      return Op(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? Op(i, e) : void 0;
  }
}
var gb = function(e) {
  e instanceof Array ? e.forEach(gb) : (e.map && e.map.dispose(), e.dispose());
}, _b = function(e) {
  e.geometry && e.geometry.dispose(), e.material && gb(e.material), e.texture && e.texture.dispose(), e.children && e.children.forEach(_b);
}, zp = function(e) {
  for (; e.children.length; ) {
    var t = e.children[0];
    e.remove(t), _b(t);
  }
}, Cf = /* @__PURE__ */ new WeakMap(), zu = /* @__PURE__ */ new WeakMap(), Wl = /* @__PURE__ */ function(i) {
  function e(t) {
    var n, r = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, s = r.dataBindAttr, a = s === void 0 ? "__data" : s, o = r.objBindAttr, l = o === void 0 ? "__threeObj" : o;
    return ub(this, e), n = cb(this, e), xd(n, "scene", void 0), L0(n, Cf, void 0), L0(n, zu, void 0), n.scene = t, F0(Cf, n, a), F0(zu, n, l), n.onRemoveObj(function() {
    }), n;
  }
  return fb(e, i), db(e, [{
    key: "onCreateObj",
    value: function(n) {
      var r = this;
      return Rf(e, "onCreateObj", this)([function(s) {
        var a = n(s);
        return s[Af(zu, r)] = a, a[Af(Cf, r)] = s, r.scene.add(a), a;
      }]), this;
    }
  }, {
    key: "onRemoveObj",
    value: function(n) {
      var r = this;
      return Rf(e, "onRemoveObj", this)([function(s, a) {
        var o = Rf(e, "getData", r)([s]);
        n(s, a), r.scene.remove(s), zp(s), delete o[Af(zu, r)];
      }]), this;
    }
  }]);
}(oL), ql = function(e) {
  return isNaN(e) ? parseInt($e(e).toHex(), 16) : e;
}, Nf = function(e) {
  return isNaN(e) ? $e(e).getAlpha() : 1;
}, jL = sb(uL);
function U0(i, e, t) {
  !e || typeof t != "string" || i.filter(function(n) {
    return !n[t];
  }).forEach(function(n) {
    n[t] = jL(e(n));
  });
}
function YL(i, e) {
  var t = i.nodes, n = i.links, r = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, s = r.nodeFilter, a = s === void 0 ? function() {
    return !0;
  } : s, o = r.onLoopError, l = o === void 0 ? function(f) {
    throw "Invalid DAG structure! Found cycle in node path: ".concat(f.join(" -> "), ".");
  } : o, c = {};
  t.forEach(function(f) {
    return c[e(f)] = {
      data: f,
      out: [],
      depth: -1,
      skip: !a(f)
    };
  }), n.forEach(function(f) {
    var p = f.source, _ = f.target, g = b(p), m = b(_);
    if (!c.hasOwnProperty(g))
      throw "Missing source node with id: ".concat(g);
    if (!c.hasOwnProperty(m))
      throw "Missing target node with id: ".concat(m);
    var x = c[g], y = c[m];
    x.out.push(y);
    function b(T) {
      return Vp(T) === "object" ? e(T) : T;
    }
  });
  var u = [];
  d(Object.values(c));
  var h = Object.assign.apply(Object, [{}].concat(Ki(Object.entries(c).filter(function(f) {
    var p = _c(f, 2), _ = p[1];
    return !_.skip;
  }).map(function(f) {
    var p = _c(f, 2), _ = p[0], g = p[1];
    return xd({}, _, g.depth);
  }))));
  return h;
  function d(f) {
    for (var p = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [], _ = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 0, g = function() {
      var b = f[m];
      if (p.indexOf(b) !== -1) {
        var T = [].concat(Ki(p.slice(p.indexOf(b))), [b]).map(function(S) {
          return e(S.data);
        });
        return u.some(function(S) {
          return S.length === T.length && S.every(function(E, v) {
            return E === T[v];
          });
        }) || (u.push(T), l(T)), 1;
      }
      _ > b.depth && (b.depth = _, d(b.out, [].concat(Ki(p), [b]), _ + (b.skip ? 0 : 1)));
    }, m = 0, x = f.length; m < x; m++)
      g();
  }
}
var Ze = window.THREE ? window.THREE : {
  Group: Mo,
  Mesh: _n,
  MeshLambertMaterial: uy,
  Color: He,
  BufferGeometry: Pn,
  BufferAttribute: Bn,
  Matrix4: pt,
  Vector3: P,
  SphereGeometry: su,
  CylinderGeometry: iu,
  TubeGeometry: ng,
  ConeGeometry: Jm,
  Line: mE,
  LineBasicMaterial: ud,
  QuadraticBezierCurve3: tg,
  CubicBezierCurve3: ay,
  Box3: Ha
}, B0 = {
  graph: wP,
  forcelayout: oD
}, KL = 2, Pf = new Ze.BufferGeometry().setAttribute ? "setAttribute" : "addAttribute", Hu = new Ze.BufferGeometry().applyMatrix4 ? "applyMatrix4" : "applyMatrix", ZL = gd({
  props: {
    jsonUrl: {
      onChange: function(e, t) {
        var n = this;
        e && !t.fetchingJson && (t.fetchingJson = !0, t.onLoading(), fetch(e).then(function(r) {
          return r.json();
        }).then(function(r) {
          t.fetchingJson = !1, t.onFinishLoading(r), n.graphData(r);
        }));
      },
      triggerUpdate: !1
    },
    graphData: {
      default: {
        nodes: [],
        links: []
      },
      onChange: function(e, t) {
        t.engineRunning = !1;
      }
    },
    numDimensions: {
      default: 3,
      onChange: function(e, t) {
        var n = t.d3ForceLayout.force("charge");
        n && n.strength(e > 2 ? -60 : -30), e < 3 && r(t.graphData.nodes, "z"), e < 2 && r(t.graphData.nodes, "y");
        function r(s, a) {
          s.forEach(function(o) {
            delete o[a], delete o["v".concat(a)];
          });
        }
      }
    },
    dagMode: {
      onChange: function(e, t) {
        !e && t.forceEngine === "d3" && (t.graphData.nodes || []).forEach(function(n) {
          return n.fx = n.fy = n.fz = void 0;
        });
      }
    },
    dagLevelDistance: {},
    dagNodeFilter: {
      default: function(e) {
        return !0;
      }
    },
    onDagError: {
      triggerUpdate: !1
    },
    nodeRelSize: {
      default: 4
    },
    // volume per val unit
    nodeId: {
      default: "id"
    },
    nodeVal: {
      default: "val"
    },
    nodeResolution: {
      default: 8
    },
    // how many slice segments in the sphere's circumference
    nodeColor: {
      default: "color"
    },
    nodeAutoColorBy: {},
    nodeOpacity: {
      default: 0.75
    },
    nodeVisibility: {
      default: !0
    },
    nodeThreeObject: {},
    nodeThreeObjectExtend: {
      default: !1
    },
    nodePositionUpdate: {
      triggerUpdate: !1
    },
    // custom function to call for updating the node's position. Signature: (threeObj, { x, y, z}, node). If the function returns a truthy value, the regular node position update will not run.
    linkSource: {
      default: "source"
    },
    linkTarget: {
      default: "target"
    },
    linkVisibility: {
      default: !0
    },
    linkColor: {
      default: "color"
    },
    linkAutoColorBy: {},
    linkOpacity: {
      default: 0.2
    },
    linkWidth: {},
    // Rounded to nearest decimal. For falsy values use dimensionless line with 1px regardless of distance.
    linkResolution: {
      default: 6
    },
    // how many radial segments in each line tube's geometry
    linkCurvature: {
      default: 0,
      triggerUpdate: !1
    },
    // line curvature radius (0: straight, 1: semi-circle)
    linkCurveRotation: {
      default: 0,
      triggerUpdate: !1
    },
    // line curve rotation along the line axis (0: interection with XY plane, PI: upside down)
    linkMaterial: {},
    linkThreeObject: {},
    linkThreeObjectExtend: {
      default: !1
    },
    linkPositionUpdate: {
      triggerUpdate: !1
    },
    // custom function to call for updating the link's position. Signature: (threeObj, { start: { x, y, z},  end: { x, y, z }}, link). If the function returns a truthy value, the regular link position update will not run.
    linkDirectionalArrowLength: {
      default: 0
    },
    linkDirectionalArrowColor: {},
    linkDirectionalArrowRelPos: {
      default: 0.5,
      triggerUpdate: !1
    },
    // value between 0<>1 indicating the relative pos along the (exposed) line
    linkDirectionalArrowResolution: {
      default: 8
    },
    // how many slice segments in the arrow's conic circumference
    linkDirectionalParticles: {
      default: 0
    },
    // animate photons travelling in the link direction
    linkDirectionalParticleSpeed: {
      default: 0.01,
      triggerUpdate: !1
    },
    // in link length ratio per frame
    linkDirectionalParticleOffset: {
      default: 0,
      triggerUpdate: !1
    },
    // starting position offset along the link's length, like a pre-delay. Values between [0, 1]
    linkDirectionalParticleWidth: {
      default: 0.5
    },
    linkDirectionalParticleColor: {},
    linkDirectionalParticleResolution: {
      default: 4
    },
    // how many slice segments in the particle sphere's circumference
    linkDirectionalParticleThreeObject: {},
    forceEngine: {
      default: "d3"
    },
    // d3 or ngraph
    d3AlphaMin: {
      default: 0
    },
    d3AlphaDecay: {
      default: 0.0228,
      triggerUpdate: !1,
      onChange: function(e, t) {
        t.d3ForceLayout.alphaDecay(e);
      }
    },
    d3AlphaTarget: {
      default: 0,
      triggerUpdate: !1,
      onChange: function(e, t) {
        t.d3ForceLayout.alphaTarget(e);
      }
    },
    d3VelocityDecay: {
      default: 0.4,
      triggerUpdate: !1,
      onChange: function(e, t) {
        t.d3ForceLayout.velocityDecay(e);
      }
    },
    ngraphPhysics: {
      default: {
        // defaults from https://github.com/anvaka/ngraph.physics.simulator/blob/master/index.js
        timeStep: 20,
        gravity: -1.2,
        theta: 0.8,
        springLength: 30,
        springCoefficient: 8e-4,
        dragCoefficient: 0.02
      }
    },
    warmupTicks: {
      default: 0,
      triggerUpdate: !1
    },
    // how many times to tick the force engine at init before starting to render
    cooldownTicks: {
      default: 1 / 0,
      triggerUpdate: !1
    },
    cooldownTime: {
      default: 15e3,
      triggerUpdate: !1
    },
    // ms
    onLoading: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onFinishLoading: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onUpdate: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onFinishUpdate: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onEngineTick: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onEngineStop: {
      default: function() {
      },
      triggerUpdate: !1
    }
  },
  methods: {
    refresh: function(e) {
      return e._flushObjects = !0, e._rerender(), this;
    },
    // Expose d3 forces for external manipulation
    d3Force: function(e, t, n) {
      return n === void 0 ? e.d3ForceLayout.force(t) : (e.d3ForceLayout.force(t, n), this);
    },
    d3ReheatSimulation: function(e) {
      return e.d3ForceLayout.alpha(1), this.resetCountdown(), this;
    },
    // reset cooldown state
    resetCountdown: function(e) {
      return e.cntTicks = 0, e.startTickTime = /* @__PURE__ */ new Date(), e.engineRunning = !0, this;
    },
    tickFrame: function(e) {
      var t = e.forceEngine !== "ngraph";
      return e.engineRunning && n(), r(), s(), this;
      function n() {
        ++e.cntTicks > e.cooldownTicks || /* @__PURE__ */ new Date() - e.startTickTime > e.cooldownTime || t && e.d3AlphaMin > 0 && e.d3ForceLayout.alpha() < e.d3AlphaMin ? (e.engineRunning = !1, e.onEngineStop()) : (e.layout[t ? "tick" : "step"](), e.onEngineTick());
        var a = xt(e.nodeThreeObjectExtend);
        e.nodeDataMapper.entries().forEach(function(d) {
          var f = _c(d, 2), p = f[0], _ = f[1];
          if (_) {
            var g = t ? p : e.layout.getNodePosition(p[e.nodeId]), m = a(p);
            (!e.nodePositionUpdate || !e.nodePositionUpdate(m ? _.children[0] : _, {
              x: g.x,
              y: g.y,
              z: g.z
            }, p) || m) && (_.position.x = g.x, _.position.y = g.y || 0, _.position.z = g.z || 0);
          }
        });
        var o = xt(e.linkWidth), l = xt(e.linkCurvature), c = xt(e.linkCurveRotation), u = xt(e.linkThreeObjectExtend);
        e.linkDataMapper.entries().forEach(function(d) {
          var f = _c(d, 2), p = f[0], _ = f[1];
          if (_) {
            var g = t ? p : e.layout.getLinkPosition(e.layout.graph.getLink(p.source, p.target).id), m = g[t ? "source" : "from"], x = g[t ? "target" : "to"];
            if (!(!m || !x || !m.hasOwnProperty("x") || !x.hasOwnProperty("x"))) {
              h(p);
              var y = u(p);
              if (!(e.linkPositionUpdate && e.linkPositionUpdate(
                y ? _.children[1] : _,
                // pass child custom object if extending the default
                {
                  start: {
                    x: m.x,
                    y: m.y,
                    z: m.z
                  },
                  end: {
                    x: x.x,
                    y: x.y,
                    z: x.z
                  }
                },
                p
              ) && !y)) {
                var b = 30, T = p.__curve, S = _.children.length ? _.children[0] : _;
                if (S.type === "Line") {
                  if (T) {
                    var v = T.getPoints(b);
                    S.geometry.getAttribute("position").array.length !== v.length * 3 && S.geometry[Pf]("position", new Ze.BufferAttribute(new Float32Array(v.length * 3), 3)), S.geometry.setFromPoints(v);
                  } else {
                    var E = S.geometry.getAttribute("position");
                    (!E || !E.array || E.array.length !== 6) && S.geometry[Pf]("position", E = new Ze.BufferAttribute(new Float32Array(2 * 3), 3)), E.array[0] = m.x, E.array[1] = m.y || 0, E.array[2] = m.z || 0, E.array[3] = x.x, E.array[4] = x.y || 0, E.array[5] = x.z || 0, E.needsUpdate = !0;
                  }
                  S.geometry.computeBoundingSphere();
                } else if (S.type === "Mesh")
                  if (T) {
                    S.geometry.type.match(/^Tube(Buffer)?Geometry$/) || (S.position.set(0, 0, 0), S.rotation.set(0, 0, 0), S.scale.set(1, 1, 1));
                    var C = Math.ceil(o(p) * 10) / 10, L = C / 2, k = new Ze.TubeGeometry(T, b, L, e.linkResolution, !1);
                    S.geometry.dispose(), S.geometry = k;
                  } else {
                    if (!S.geometry.type.match(/^Cylinder(Buffer)?Geometry$/)) {
                      var M = Math.ceil(o(p) * 10) / 10, F = M / 2, R = new Ze.CylinderGeometry(F, F, 1, e.linkResolution, 1, !1);
                      R[Hu](new Ze.Matrix4().makeTranslation(0, 1 / 2, 0)), R[Hu](new Ze.Matrix4().makeRotationX(Math.PI / 2)), S.geometry.dispose(), S.geometry = R;
                    }
                    var I = new Ze.Vector3(m.x, m.y || 0, m.z || 0), B = new Ze.Vector3(x.x, x.y || 0, x.z || 0), N = I.distanceTo(B);
                    S.position.x = I.x, S.position.y = I.y, S.position.z = I.z, S.scale.z = N, S.parent.localToWorld(B), S.lookAt(B);
                  }
              }
            }
          }
        });
        function h(d) {
          var f = t ? d : e.layout.getLinkPosition(e.layout.graph.getLink(d.source, d.target).id), p = f[t ? "source" : "from"], _ = f[t ? "target" : "to"];
          if (!(!p || !_ || !p.hasOwnProperty("x") || !_.hasOwnProperty("x"))) {
            var g = l(d);
            if (!g)
              d.__curve = null;
            else {
              var m = new Ze.Vector3(p.x, p.y || 0, p.z || 0), x = new Ze.Vector3(_.x, _.y || 0, _.z || 0), y = m.distanceTo(x), b, T = c(d);
              if (y > 0) {
                var S = _.x - p.x, E = _.y - p.y || 0, v = new Ze.Vector3().subVectors(x, m), M = v.clone().multiplyScalar(g).cross(S !== 0 || E !== 0 ? new Ze.Vector3(0, 0, 1) : new Ze.Vector3(0, 1, 0)).applyAxisAngle(v.normalize(), T).add(new Ze.Vector3().addVectors(m, x).divideScalar(2));
                b = new Ze.QuadraticBezierCurve3(m, M, x);
              } else {
                var F = g * 70, R = -T, I = R + Math.PI / 2;
                b = new Ze.CubicBezierCurve3(m, new Ze.Vector3(F * Math.cos(I), F * Math.sin(I), 0).add(m), new Ze.Vector3(F * Math.cos(R), F * Math.sin(R), 0).add(m), x);
              }
              d.__curve = b;
            }
          }
        }
      }
      function r() {
        var a = xt(e.linkDirectionalArrowRelPos), o = xt(e.linkDirectionalArrowLength), l = xt(e.nodeVal);
        e.arrowDataMapper.entries().forEach(function(c) {
          var u = _c(c, 2), h = u[0], d = u[1];
          if (d) {
            var f = t ? h : e.layout.getLinkPosition(e.layout.graph.getLink(h.source, h.target).id), p = f[t ? "source" : "from"], _ = f[t ? "target" : "to"];
            if (!(!p || !_ || !p.hasOwnProperty("x") || !_.hasOwnProperty("x"))) {
              var g = Math.cbrt(Math.max(0, l(p) || 1)) * e.nodeRelSize, m = Math.cbrt(Math.max(0, l(_) || 1)) * e.nodeRelSize, x = o(h), y = a(h), b = h.__curve ? function(F) {
                return h.__curve.getPoint(F);
              } : function(F) {
                var R = function(B, N, C, L) {
                  return N[B] + (C[B] - N[B]) * L || 0;
                };
                return {
                  x: R("x", p, _, F),
                  y: R("y", p, _, F),
                  z: R("z", p, _, F)
                };
              }, T = h.__curve ? h.__curve.getLength() : Math.sqrt(["x", "y", "z"].map(function(F) {
                return Math.pow((_[F] || 0) - (p[F] || 0), 2);
              }).reduce(function(F, R) {
                return F + R;
              }, 0)), S = g + x + (T - g - m - x) * y, E = b(S / T), v = b((S - x) / T);
              ["x", "y", "z"].forEach(function(F) {
                return d.position[F] = v[F];
              });
              var M = hb(Ze.Vector3, Ki(["x", "y", "z"].map(function(F) {
                return E[F];
              })));
              d.parent.localToWorld(M), d.lookAt(M);
            }
          }
        });
      }
      function s() {
        var a = xt(e.linkDirectionalParticleSpeed), o = xt(e.linkDirectionalParticleOffset);
        e.graphData.links.forEach(function(l) {
          var c = e.particlesDataMapper.getObj(l), u = c && c.children, h = l.__singleHopPhotonsObj && l.__singleHopPhotonsObj.children;
          if (!((!h || !h.length) && (!u || !u.length))) {
            var d = t ? l : e.layout.getLinkPosition(e.layout.graph.getLink(l.source, l.target).id), f = d[t ? "source" : "from"], p = d[t ? "target" : "to"];
            if (!(!f || !p || !f.hasOwnProperty("x") || !p.hasOwnProperty("x"))) {
              var _ = a(l), g = Math.abs(o(l)), m = l.__curve ? function(y) {
                return l.__curve.getPoint(y);
              } : function(y) {
                var b = function(S, E, v, M) {
                  return E[S] + (v[S] - E[S]) * M || 0;
                };
                return {
                  x: b("x", f, p, y),
                  y: b("y", f, p, y),
                  z: b("z", f, p, y)
                };
              }, x = [].concat(Ki(u || []), Ki(h || []));
              x.forEach(function(y, b) {
                var T = y.parent.__linkThreeObjType === "singleHopPhotons";
                if (y.hasOwnProperty("__progressRatio") || (y.__progressRatio = T ? 0 : (b + g) / u.length), y.__progressRatio += _, y.__progressRatio >= 1)
                  if (!T)
                    y.__progressRatio = y.__progressRatio % 1;
                  else {
                    y.parent.remove(y), zp(y);
                    return;
                  }
                var S = y.__progressRatio, E = m(S);
                y.geometry.type !== "SphereGeometry" && y.lookAt(E.x, E.y, E.z), ["x", "y", "z"].forEach(function(v) {
                  return y.position[v] = E[v];
                });
              });
            }
          }
        });
      }
    },
    emitParticle: function(e, t) {
      if (t && e.graphData.links.includes(t)) {
        if (!t.__singleHopPhotonsObj) {
          var n = new Ze.Group();
          n.__linkThreeObjType = "singleHopPhotons", t.__singleHopPhotonsObj = n, e.graphScene.add(n);
        }
        var r = xt(e.linkDirectionalParticleThreeObject)(t);
        if (r && e.linkDirectionalParticleThreeObject === r && (r = r.clone()), !r) {
          var s = xt(e.linkDirectionalParticleWidth), a = Math.ceil(s(t) * 10) / 10 / 2, o = e.linkDirectionalParticleResolution, l = new Ze.SphereGeometry(a, o, o), c = xt(e.linkColor), u = xt(e.linkDirectionalParticleColor), h = u(t) || c(t) || "#f0f0f0", d = new Ze.Color(ql(h)), f = e.linkOpacity * 3, p = new Ze.MeshLambertMaterial({
            color: d,
            transparent: !0,
            opacity: f
          });
          r = new Ze.Mesh(l, p);
        }
        t.__singleHopPhotonsObj.add(r);
      }
      return this;
    },
    getGraphBbox: function(e) {
      var t = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : function() {
        return !0;
      };
      if (!e.initialised)
        return null;
      var n = function r(s) {
        var a = [];
        if (s.geometry) {
          s.geometry.computeBoundingBox();
          var o = new Ze.Box3();
          o.copy(s.geometry.boundingBox).applyMatrix4(s.matrixWorld), a.push(o);
        }
        return a.concat.apply(a, Ki((s.children || []).filter(
          function(l) {
            return !l.hasOwnProperty("__graphObjType") || l.__graphObjType === "node" && t(l.__data);
          }
          // exclude filtered out nodes
        ).map(r)));
      }(e.graphScene);
      return n.length ? Object.assign.apply(Object, Ki(["x", "y", "z"].map(function(r) {
        return xd({}, r, [qD(n, function(s) {
          return s.min[r];
        }), WD(n, function(s) {
          return s.max[r];
        })]);
      }))) : null;
    }
  },
  stateInit: function() {
    return {
      d3ForceLayout: vP().force("link", rP()).force("charge", yP()).force("center", aN()).force("dagRadial", null).stop(),
      engineRunning: !1
    };
  },
  init: function(e, t) {
    t.graphScene = e, t.nodeDataMapper = new Wl(e, {
      objBindAttr: "__threeObj"
    }), t.linkDataMapper = new Wl(e, {
      objBindAttr: "__lineObj"
    }), t.arrowDataMapper = new Wl(e, {
      objBindAttr: "__arrowObj"
    }), t.particlesDataMapper = new Wl(e, {
      objBindAttr: "__photonsObj"
    });
  },
  update: function(e, t) {
    var n = function(z) {
      return z.some(function(Z) {
        return t.hasOwnProperty(Z);
      });
    };
    if (e.engineRunning = !1, typeof e.onUpdate == "function" && e.onUpdate(), e.nodeAutoColorBy !== null && n(["nodeAutoColorBy", "graphData", "nodeColor"]) && U0(e.graphData.nodes, xt(e.nodeAutoColorBy), e.nodeColor), e.linkAutoColorBy !== null && n(["linkAutoColorBy", "graphData", "linkColor"]) && U0(e.graphData.links, xt(e.linkAutoColorBy), e.linkColor), e._flushObjects || n(["graphData", "nodeThreeObject", "nodeThreeObjectExtend", "nodeVal", "nodeColor", "nodeVisibility", "nodeRelSize", "nodeResolution", "nodeOpacity"])) {
      var r = xt(e.nodeThreeObject), s = xt(e.nodeThreeObjectExtend), a = xt(e.nodeVal), o = xt(e.nodeColor), l = xt(e.nodeVisibility), c = {}, u = {};
      (e._flushObjects || n([
        // recreate objects if any of these props have changed
        "nodeThreeObject",
        "nodeThreeObjectExtend"
      ])) && e.nodeDataMapper.clear(), e.nodeDataMapper.onCreateObj(function(ce) {
        var z = r(ce), Z = s(ce);
        z && e.nodeThreeObject === z && (z = z.clone());
        var ue;
        return z && !Z ? ue = z : (ue = new Ze.Mesh(), ue.__graphDefaultObj = !0, z && Z && ue.add(z)), ue.__graphObjType = "node", ue;
      }).onUpdateObj(function(ce, z) {
        if (ce.__graphDefaultObj) {
          var Z = a(z) || 1, ue = Math.cbrt(Z) * e.nodeRelSize, Ie = e.nodeResolution;
          (!ce.geometry.type.match(/^Sphere(Buffer)?Geometry$/) || ce.geometry.parameters.radius !== ue || ce.geometry.parameters.widthSegments !== Ie) && (c.hasOwnProperty(Z) || (c[Z] = new Ze.SphereGeometry(ue, Ie, Ie)), ce.geometry.dispose(), ce.geometry = c[Z]);
          var we = o(z), Re = new Ze.Color(ql(we || "#ffffaa")), It = e.nodeOpacity * Nf(we);
          (ce.material.type !== "MeshLambertMaterial" || !ce.material.color.equals(Re) || ce.material.opacity !== It) && (u.hasOwnProperty(we) || (u[we] = new Ze.MeshLambertMaterial({
            color: Re,
            transparent: !0,
            opacity: It
          })), ce.material.dispose(), ce.material = u[we]);
        }
      }).digest(e.graphData.nodes.filter(l));
    }
    if (e._flushObjects || n(["graphData", "linkThreeObject", "linkThreeObjectExtend", "linkMaterial", "linkColor", "linkWidth", "linkVisibility", "linkResolution", "linkOpacity", "linkDirectionalArrowLength", "linkDirectionalArrowColor", "linkDirectionalArrowResolution", "linkDirectionalParticles", "linkDirectionalParticleWidth", "linkDirectionalParticleColor", "linkDirectionalParticleResolution", "linkDirectionalParticleThreeObject"])) {
      var h = xt(e.linkThreeObject), d = xt(e.linkThreeObjectExtend), f = xt(e.linkMaterial), p = xt(e.linkVisibility), _ = xt(e.linkColor), g = xt(e.linkWidth), m = {}, x = {}, y = {}, b = e.graphData.links.filter(p);
      if ((e._flushObjects || n([
        // recreate objects if any of these props have changed
        "linkThreeObject",
        "linkThreeObjectExtend",
        "linkWidth"
      ])) && e.linkDataMapper.clear(), e.linkDataMapper.onRemoveObj(function(ce) {
        var z = ce.__data && ce.__data.__singleHopPhotonsObj;
        z && (z.parent.remove(z), zp(z), delete ce.__data.__singleHopPhotonsObj);
      }).onCreateObj(function(ce) {
        var z = h(ce), Z = d(ce);
        z && e.linkThreeObject === z && (z = z.clone());
        var ue;
        if (!z || Z) {
          var Ie = !!g(ce);
          if (Ie)
            ue = new Ze.Mesh();
          else {
            var we = new Ze.BufferGeometry();
            we[Pf]("position", new Ze.BufferAttribute(new Float32Array(2 * 3), 3)), ue = new Ze.Line(we);
          }
        }
        var Re;
        return z ? Z ? (Re = new Ze.Group(), Re.__graphDefaultObj = !0, Re.add(ue), Re.add(z)) : Re = z : (Re = ue, Re.__graphDefaultObj = !0), Re.renderOrder = 10, Re.__graphObjType = "link", Re;
      }).onUpdateObj(function(ce, z) {
        if (ce.__graphDefaultObj) {
          var Z = ce.children.length ? ce.children[0] : ce, ue = Math.ceil(g(z) * 10) / 10, Ie = !!ue;
          if (Ie) {
            var we = ue / 2, Re = e.linkResolution;
            if (!Z.geometry.type.match(/^Cylinder(Buffer)?Geometry$/) || Z.geometry.parameters.radiusTop !== we || Z.geometry.parameters.radialSegments !== Re) {
              if (!m.hasOwnProperty(ue)) {
                var It = new Ze.CylinderGeometry(we, we, 1, Re, 1, !1);
                It[Hu](new Ze.Matrix4().makeTranslation(0, 1 / 2, 0)), It[Hu](new Ze.Matrix4().makeRotationX(Math.PI / 2)), m[ue] = It;
              }
              Z.geometry.dispose(), Z.geometry = m[ue];
            }
          }
          var ut = f(z);
          if (ut)
            Z.material = ut;
          else {
            var mt = _(z), bt = new Ze.Color(ql(mt || "#f0f0f0")), tt = e.linkOpacity * Nf(mt), Rt = Ie ? "MeshLambertMaterial" : "LineBasicMaterial";
            if (Z.material.type !== Rt || !Z.material.color.equals(bt) || Z.material.opacity !== tt) {
              var O = Ie ? x : y;
              O.hasOwnProperty(mt) || (O[mt] = new Ze[Rt]({
                color: bt,
                transparent: tt < 1,
                opacity: tt,
                depthWrite: tt >= 1
                // Prevent transparency issues
              })), Z.material.dispose(), Z.material = O[mt];
            }
          }
        }
      }).digest(b), e.linkDirectionalArrowLength || t.hasOwnProperty("linkDirectionalArrowLength")) {
        var T = xt(e.linkDirectionalArrowLength), S = xt(e.linkDirectionalArrowColor);
        e.arrowDataMapper.onCreateObj(function() {
          var ce = new Ze.Mesh(void 0, new Ze.MeshLambertMaterial({
            transparent: !0
          }));
          return ce.__linkThreeObjType = "arrow", ce;
        }).onUpdateObj(function(ce, z) {
          var Z = T(z), ue = e.linkDirectionalArrowResolution;
          if (!ce.geometry.type.match(/^Cone(Buffer)?Geometry$/) || ce.geometry.parameters.height !== Z || ce.geometry.parameters.radialSegments !== ue) {
            var Ie = new Ze.ConeGeometry(Z * 0.25, Z, ue);
            Ie.translate(0, Z / 2, 0), Ie.rotateX(Math.PI / 2), ce.geometry.dispose(), ce.geometry = Ie;
          }
          var we = S(z) || _(z) || "#f0f0f0";
          ce.material.color = new Ze.Color(ql(we)), ce.material.opacity = e.linkOpacity * 3 * Nf(we);
        }).digest(b.filter(T));
      }
      if (e.linkDirectionalParticles || t.hasOwnProperty("linkDirectionalParticles")) {
        var E = xt(e.linkDirectionalParticles), v = xt(e.linkDirectionalParticleWidth), M = xt(e.linkDirectionalParticleColor), F = xt(e.linkDirectionalParticleThreeObject), R = {}, I = {};
        e.particlesDataMapper.onCreateObj(function() {
          var ce = new Ze.Group();
          return ce.__linkThreeObjType = "photons", ce.__photonDataMapper = new Wl(ce), ce;
        }).onUpdateObj(function(ce, z) {
          var Z = !!ce.children.length && ce.children[0], ue = F(z), Ie, we;
          if (ue)
            Ie = ue.geometry, we = ue.material;
          else {
            var Re = Math.ceil(v(z) * 10) / 10 / 2, It = e.linkDirectionalParticleResolution;
            Z && Z.geometry.parameters.radius === Re && Z.geometry.parameters.widthSegments === It ? Ie = Z.geometry : (I.hasOwnProperty(Re) || (I[Re] = new Ze.SphereGeometry(Re, It, It)), Ie = I[Re]);
            var ut = M(z) || _(z) || "#f0f0f0", mt = new Ze.Color(ql(ut)), bt = e.linkOpacity * 3;
            Z && Z.material.color.equals(mt) && Z.material.opacity === bt ? we = Z.material : (R.hasOwnProperty(ut) || (R[ut] = new Ze.MeshLambertMaterial({
              color: mt,
              transparent: !0,
              opacity: bt
            })), we = R[ut]);
          }
          Z && (Z.geometry !== Ie && Z.geometry.dispose(), Z.material !== we && Z.material.dispose());
          var tt = Math.round(Math.abs(E(z)));
          ce.__photonDataMapper.id(function(Rt) {
            return Rt.idx;
          }).onCreateObj(function() {
            return new Ze.Mesh(Ie, we);
          }).onUpdateObj(function(Rt) {
            Rt.geometry = Ie, Rt.material = we;
          }).digest(Ki(new Array(tt)).map(function(Rt, O) {
            return {
              idx: O
            };
          }));
        }).digest(b.filter(E));
      }
    }
    if (e._flushObjects = !1, n(["graphData", "nodeId", "linkSource", "linkTarget", "numDimensions", "forceEngine", "dagMode", "dagNodeFilter", "dagLevelDistance"])) {
      e.engineRunning = !1, e.graphData.links.forEach(function(ce) {
        ce.source = ce[e.linkSource], ce.target = ce[e.linkTarget];
      });
      var B = e.forceEngine !== "ngraph", N;
      if (B) {
        (N = e.d3ForceLayout).stop().alpha(1).numDimensions(e.numDimensions).nodes(e.graphData.nodes);
        var C = e.d3ForceLayout.force("link");
        C && C.id(function(ce) {
          return ce[e.nodeId];
        }).links(e.graphData.links);
        var L = e.dagMode && YL(e.graphData, function(ce) {
          return ce[e.nodeId];
        }, {
          nodeFilter: e.dagNodeFilter,
          onLoopError: e.onDagError || void 0
        }), k = Math.max.apply(Math, Ki(Object.values(L || []))), re = e.dagLevelDistance || e.graphData.nodes.length / (k || 1) * KL * (["radialin", "radialout"].indexOf(e.dagMode) !== -1 ? 0.7 : 1);
        if (["lr", "rl", "td", "bu", "zin", "zout"].includes(t.dagMode)) {
          var se = ["lr", "rl"].includes(t.dagMode) ? "fx" : ["td", "bu"].includes(t.dagMode) ? "fy" : "fz";
          e.graphData.nodes.filter(e.dagNodeFilter).forEach(function(ce) {
            return delete ce[se];
          });
        }
        if (["lr", "rl", "td", "bu", "zin", "zout"].includes(e.dagMode)) {
          var ve = ["rl", "td", "zout"].includes(e.dagMode), X = function(z) {
            return (L[z[e.nodeId]] - k / 2) * re * (ve ? -1 : 1);
          }, te = ["lr", "rl"].includes(e.dagMode) ? "fx" : ["td", "bu"].includes(e.dagMode) ? "fy" : "fz";
          e.graphData.nodes.filter(e.dagNodeFilter).forEach(function(ce) {
            return ce[te] = X(ce);
          });
        }
        e.d3ForceLayout.force("dagRadial", ["radialin", "radialout"].indexOf(e.dagMode) !== -1 ? bP(function(ce) {
          var z = L[ce[e.nodeId]] || -1;
          return (e.dagMode === "radialin" ? k - z : z) * re;
        }).strength(function(ce) {
          return e.dagNodeFilter(ce) ? 1 : 0;
        }) : null);
      } else {
        var me = B0.graph();
        e.graphData.nodes.forEach(function(ce) {
          me.addNode(ce[e.nodeId]);
        }), e.graphData.links.forEach(function(ce) {
          me.addLink(ce.source, ce.target);
        }), N = B0.forcelayout(me, $L({
          dimensions: e.numDimensions
        }, e.ngraphPhysics)), N.graph = me;
      }
      for (var Qe = 0; Qe < e.warmupTicks && !(B && e.d3AlphaMin > 0 && e.d3ForceLayout.alpha() < e.d3AlphaMin); Qe++)
        N[B ? "tick" : "step"]();
      e.layout = N, this.resetCountdown();
    }
    e.engineRunning = !0, e.onFinishUpdate();
  }
});
function QL(i) {
  var e = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Object, t = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : !1, n = /* @__PURE__ */ function(r) {
    function s() {
      var a;
      ub(this, s);
      for (var o = arguments.length, l = new Array(o), c = 0; c < o; c++)
        l[c] = arguments[c];
      return a = cb(this, s, [].concat(l)), a.__kapsuleInstance = hb(i, [].concat(Ki(t ? [a] : []), l)), a;
    }
    return fb(s, r), db(s);
  }(e);
  return Object.keys(i()).forEach(function(r) {
    return n.prototype[r] = function() {
      var s, a = (s = this.__kapsuleInstance)[r].apply(s, arguments);
      return a === this.__kapsuleInstance ? this : a;
    };
  }), n;
}
var JL = window.THREE ? window.THREE : {
  Group: Mo
}, xb = QL(ZL, JL.Group, !0);
/**
 * @license
 * Copyright 2010-2026 Three.js Authors
 * SPDX-License-Identifier: MIT
 */
const e2 = [
  "alphaMap",
  "alphaTest",
  "anisotropy",
  "anisotropyMap",
  "anisotropyRotation",
  "aoMap",
  "aoMapIntensity",
  "attenuationColor",
  "attenuationDistance",
  "bumpMap",
  "clearcoat",
  "clearcoatMap",
  "clearcoatNormalMap",
  "clearcoatNormalScale",
  "clearcoatRoughness",
  "color",
  "dispersion",
  "displacementMap",
  "emissive",
  "emissiveIntensity",
  "emissiveMap",
  "envMap",
  "envMapIntensity",
  "gradientMap",
  "ior",
  "iridescence",
  "iridescenceIOR",
  "iridescenceMap",
  "iridescenceThicknessMap",
  "lightMap",
  "lightMapIntensity",
  "map",
  "matcap",
  "metalness",
  "metalnessMap",
  "normalMap",
  "normalScale",
  "opacity",
  "roughness",
  "roughnessMap",
  "sheen",
  "sheenColor",
  "sheenColorMap",
  "sheenRoughnessMap",
  "shininess",
  "specular",
  "specularColor",
  "specularColorMap",
  "specularIntensity",
  "specularIntensityMap",
  "specularMap",
  "thickness",
  "transmission",
  "transmissionMap"
], Df = /* @__PURE__ */ new WeakMap();
class t2 {
  /**
   * Constructs a new node material observer.
   *
   * @param {NodeBuilder} builder - The node builder.
   */
  constructor(e) {
    this.renderObjects = /* @__PURE__ */ new WeakMap(), this.hasNode = this.containsNode(e), this.hasAnimation = e.object.isSkinnedMesh === !0, this.refreshUniforms = e2, this.renderId = 0;
  }
  /**
   * Returns `true` if the given render object is verified for the first time of this observer.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the given render object is verified for the first time of this observer.
   */
  firstInitialization(e) {
    return this.renderObjects.has(e) === !1 ? (this.getRenderObjectData(e), !0) : !1;
  }
  /**
   * Returns `true` if the current rendering produces motion vectors.
   *
   * @param {Renderer} renderer - The renderer.
   * @return {boolean} Whether the current rendering produces motion vectors or not.
   */
  needsVelocity(e) {
    const t = e.getMRT();
    return t !== null && t.has("velocity");
  }
  /**
   * Returns monitoring data for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {Object} The monitoring data.
   */
  getRenderObjectData(e) {
    let t = this.renderObjects.get(e);
    if (t === void 0) {
      const { geometry: n, material: r, object: s } = e;
      if (t = {
        material: this.getMaterialData(r),
        geometry: {
          id: n.id,
          attributes: this.getAttributesData(n.attributes),
          indexId: n.index ? n.index.id : null,
          indexVersion: n.index ? n.index.version : null,
          drawRange: { start: n.drawRange.start, count: n.drawRange.count }
        },
        worldMatrix: s.matrixWorld.clone()
      }, s.center && (t.center = s.center.clone()), s.morphTargetInfluences && (t.morphTargetInfluences = s.morphTargetInfluences.slice()), e.bundle !== null && (t.version = e.bundle.version), t.material.transmission > 0) {
        const { width: a, height: o } = e.context;
        t.bufferWidth = a, t.bufferHeight = o;
      }
      t.lights = this.getLightsData(e.lightsNode.getLights()), this.renderObjects.set(e, t);
    }
    return t;
  }
  /**
   * Returns an attribute data structure holding the attributes versions for
   * monitoring.
   *
   * @param {Object} attributes - The geometry attributes.
   * @return {Object} An object for monitoring the versions of attributes.
   */
  getAttributesData(e) {
    const t = {};
    for (const n in e) {
      const r = e[n];
      t[n] = {
        id: r.id,
        version: r.version
      };
    }
    return t;
  }
  /**
   * Returns `true` if the node builder's material uses
   * node properties.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {boolean} Whether the node builder's material uses node properties or not.
   */
  containsNode(e) {
    const t = e.material;
    for (const n in t)
      if (t[n] && t[n].isNode)
        return !0;
    return !!(e.context.modelViewMatrix || e.context.modelNormalViewMatrix || e.context.getAO || e.context.getShadow);
  }
  /**
   * Returns a material data structure holding the material property values for
   * monitoring.
   *
   * @param {Material} material - The material.
   * @return {Object} An object for monitoring material properties.
   */
  getMaterialData(e) {
    const t = {};
    for (const n of this.refreshUniforms) {
      const r = e[n];
      r != null && (typeof r == "object" && r.clone !== void 0 ? r.isTexture === !0 ? t[n] = { id: r.id, version: r.version } : t[n] = r.clone() : t[n] = r);
    }
    return t;
  }
  /**
   * Returns `true` if the given render object has not changed its state.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {Array<Light>} lightsData - The current material lights.
   * @return {boolean} Whether the given render object has changed its state or not.
   */
  equals(e, t) {
    const { object: n, material: r, geometry: s } = e, a = this.getRenderObjectData(e);
    if (a.worldMatrix.equals(n.matrixWorld) !== !0)
      return a.worldMatrix.copy(n.matrixWorld), !1;
    const o = a.material;
    for (const x in o) {
      const y = o[x], b = r[x];
      if (y.equals !== void 0) {
        if (y.equals(b) === !1)
          return y.copy(b), !1;
      } else if (b.isTexture === !0) {
        if (y.id !== b.id || y.version !== b.version)
          return y.id = b.id, y.version = b.version, !1;
      } else if (y !== b)
        return o[x] = b, !1;
    }
    if (o.transmission > 0) {
      const { width: x, height: y } = e.context;
      if (a.bufferWidth !== x || a.bufferHeight !== y)
        return a.bufferWidth = x, a.bufferHeight = y, !1;
    }
    const l = a.geometry, c = s.attributes, u = l.attributes, h = Object.keys(u), d = Object.keys(c);
    if (l.id !== s.id)
      return l.id = s.id, !1;
    if (h.length !== d.length)
      return a.geometry.attributes = this.getAttributesData(c), !1;
    for (const x of h) {
      const y = u[x], b = c[x];
      if (b === void 0)
        return delete u[x], !1;
      if (y.id !== b.id || y.version !== b.version)
        return y.id = b.id, y.version = b.version, !1;
    }
    const f = s.index, p = l.indexId, _ = l.indexVersion, g = f ? f.id : null, m = f ? f.version : null;
    if (p !== g || _ !== m)
      return l.indexId = g, l.indexVersion = m, !1;
    if (l.drawRange.start !== s.drawRange.start || l.drawRange.count !== s.drawRange.count)
      return l.drawRange.start = s.drawRange.start, l.drawRange.count = s.drawRange.count, !1;
    if (a.morphTargetInfluences) {
      let x = !1;
      for (let y = 0; y < a.morphTargetInfluences.length; y++)
        a.morphTargetInfluences[y] !== n.morphTargetInfluences[y] && (a.morphTargetInfluences[y] = n.morphTargetInfluences[y], x = !0);
      if (x)
        return !1;
    }
    if (a.lights) {
      for (let x = 0; x < t.length; x++)
        if (a.lights[x].map !== t[x].map)
          return !1;
    }
    return a.center && a.center.equals(n.center) === !1 ? (a.center.copy(n.center), !0) : (e.bundle !== null && (a.version = e.bundle.version), !0);
  }
  /**
   * Returns the lights data for the given material lights.
   *
   * @param {Array<Light>} materialLights - The material lights.
   * @return {Array<Object>} The lights data for the given material lights.
   */
  getLightsData(e) {
    const t = [];
    for (const n of e)
      n.isSpotLight === !0 && n.map !== null && t.push({ map: n.map.version });
    return t;
  }
  /**
   * Returns the lights for the given lights node and render ID.
   *
   * @param {LightsNode} lightsNode - The lights node.
   * @param {number} renderId - The render ID.
   * @return {Array<Object>} The lights for the given lights node and render ID.
   */
  getLights(e, t) {
    if (Df.has(e)) {
      const r = Df.get(e);
      if (r.renderId === t)
        return r.lightsData;
    }
    const n = this.getLightsData(e.getLights());
    return Df.set(e, { renderId: t, lightsData: n }), n;
  }
  /**
   * Checks if the given render object requires a refresh.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {NodeFrame} nodeFrame - The current node frame.
   * @return {boolean} Whether the given render object requires a refresh or not.
   */
  needsRefresh(e, t) {
    if (this.hasNode || this.hasAnimation || this.firstInitialization(e) || this.needsVelocity(t.renderer))
      return !0;
    const { renderId: n } = t;
    if (this.renderId !== n)
      return this.renderId = n, !0;
    const r = e.object.static === !0, s = e.bundle !== null && e.bundle.static === !0 && this.getRenderObjectData(e).version === e.bundle.version;
    if (r || s)
      return !1;
    const a = this.getLights(e.lightsNode, n);
    return this.equals(e, a) !== !0;
  }
}
const n2 = [
  /^StackTrace\.js$/,
  /^TSLCore\.js$/,
  /^.*Node\.js$/,
  /^three\.webgpu.*\.js$/
];
function i2(i) {
  const e = /(?:at\s+(.+?)\s+\()?(?:(.+?)@)?([^@\s()]+):(\d+):(\d+)/;
  return i.split(`
`).map((t) => {
    const n = t.match(e);
    if (!n)
      return null;
    const r = n[1] || n[2] || "", s = n[3].split("?")[0], a = parseInt(n[4], 10), o = parseInt(n[5], 10), l = s.split("/").pop();
    return {
      fn: r,
      file: l,
      line: a,
      column: o
    };
  }).filter((t) => t && !n2.some((n) => n.test(t.file)));
}
class Yn {
  /**
   * Creates a StackTrace instance by capturing and filtering the current stack trace.
   *
   * @param {Error|string|null} stackMessage - An optional stack trace to use instead of capturing a new one.
   */
  constructor(e = null) {
    this.isStackTrace = !0, this.stack = i2(e || new Error().stack);
  }
  /**
   * Returns a formatted location string of the top stack frame.
   *
   * @returns {string} The formatted stack trace message.
   */
  getLocation() {
    if (this.stack.length === 0)
      return "[Unknown location]";
    const e = this.stack[0], t = e.fn;
    return `${t ? `"${t}()" at ` : ""}"${e.file}:${e.line}"`;
  }
  /**
   * Returns the full error message including the stack trace.
   *
   * @param {string} message - The error message.
   * @returns {string} The full error message with stack trace.
   */
  getError(e) {
    if (this.stack.length === 0)
      return e;
    const t = this.stack.map((n) => {
      const r = `${n.file}:${n.line}:${n.column}`;
      return n.fn ? `    at ${n.fn} (${r})` : `    at ${r}`;
    }).join(`
`);
    return `${e}
${t}`;
  }
}
function _g(i, e = 0) {
  let t = 3735928559 ^ e, n = 1103547991 ^ e;
  if (i instanceof Array)
    for (let r = 0, s; r < i.length; r++)
      s = i[r], t = Math.imul(t ^ s, 2654435761), n = Math.imul(n ^ s, 1597334677);
  else
    for (let r = 0, s; r < i.length; r++)
      s = i.charCodeAt(r), t = Math.imul(t ^ s, 2654435761), n = Math.imul(n ^ s, 1597334677);
  return t = Math.imul(t ^ t >>> 16, 2246822507), t ^= Math.imul(n ^ n >>> 13, 3266489909), n = Math.imul(n ^ n >>> 16, 2246822507), n ^= Math.imul(t ^ t >>> 13, 3266489909), 4294967296 * (2097151 & n) + (t >>> 0);
}
const Ml = (i) => _g(i), ou = (i) => _g(i), xc = (...i) => _g(i), r2 = /* @__PURE__ */ new Map([
  [1, "float"],
  [2, "vec2"],
  [3, "vec3"],
  [4, "vec4"],
  [9, "mat3"],
  [16, "mat4"]
]), O0 = /* @__PURE__ */ new WeakMap();
function vb(i) {
  return r2.get(i);
}
function zh(i) {
  if (i == null)
    return null;
  const e = typeof i;
  return i.isNode === !0 ? "node" : e === "number" ? "float" : e === "boolean" ? "bool" : e === "string" ? "string" : e === "function" ? "shader" : i.isVector2 === !0 ? "vec2" : i.isVector3 === !0 ? "vec3" : i.isVector4 === !0 ? "vec4" : i.isMatrix2 === !0 ? "mat2" : i.isMatrix3 === !0 ? "mat3" : i.isMatrix4 === !0 ? "mat4" : i.isColor === !0 ? "color" : i instanceof ArrayBuffer ? "ArrayBuffer" : null;
}
function xg(i, ...e) {
  const t = i ? i.slice(-4) : void 0;
  return e.length === 1 && (t === "vec2" ? e = [e[0], e[0]] : t === "vec3" ? e = [e[0], e[0], e[0]] : t === "vec4" && (e = [e[0], e[0], e[0], e[0]])), i === "color" ? new He(...e) : t === "vec2" ? new de(...e) : t === "vec3" ? new P(...e) : t === "vec4" ? new rt(...e) : t === "mat2" ? new hd(...e) : t === "mat3" ? new nt(...e) : t === "mat4" ? new pt(...e) : i === "bool" ? e[0] || !1 : i === "float" || i === "int" || i === "uint" ? e[0] || 0 : i === "string" ? e[0] || "" : i === "ArrayBuffer" ? a2(e[0]) : null;
}
function yb(i) {
  let e = O0.get(i);
  return e === void 0 && (e = {}, O0.set(i, e)), e;
}
function s2(i) {
  let e = "";
  const t = new Uint8Array(i);
  for (let n = 0; n < t.length; n++)
    e += String.fromCharCode(t[n]);
  return btoa(e);
}
function a2(i) {
  return Uint8Array.from(atob(i), (e) => e.charCodeAt(0)).buffer;
}
const $u = {
  VERTEX: "vertex",
  FRAGMENT: "fragment"
}, it = {
  NONE: "none",
  FRAME: "frame",
  RENDER: "render",
  OBJECT: "object"
}, Bi = {
  READ_ONLY: "readOnly",
  WRITE_ONLY: "writeOnly",
  READ_WRITE: "readWrite"
}, o2 = ["fragment", "vertex"], k0 = ["setup", "analyze", "generate"], G0 = [...o2, "compute"], El = ["x", "y", "z", "w"], l2 = {
  analyze: "setup",
  generate: "analyze"
};
let c2 = 0;
class Fe extends Fr {
  static get type() {
    return "Node";
  }
  /**
   * Constructs a new node.
   *
   * @param {?string} nodeType - The node type.
   */
  constructor(e = null) {
    super(), this.nodeType = e, this.updateType = it.NONE, this.updateBeforeType = it.NONE, this.updateAfterType = it.NONE, this.uuid = Fh.generateUUID(), this.version = 0, this.name = "", this.global = !1, this.parents = !1, this.isNode = !0, this._beforeNodes = null, this._cacheKey = null, this._cacheKeyVersion = 0, Object.defineProperty(this, "id", { value: c2++ }), this.stackTrace = null, Fe.captureStackTrace === !0 && (this.stackTrace = new Yn());
  }
  /**
   * Set this property to `true` when the node should be regenerated.
   *
   * @type {boolean}
   * @default false
   * @param {boolean} value
   */
  set needsUpdate(e) {
    e === !0 && this.version++;
  }
  /**
   * The type of the class. The value is usually the constructor name.
   *
   * @type {string}
  	 * @readonly
   */
  get type() {
    return this.constructor.type;
  }
  /**
   * Convenient method for defining {@link Node#update}.
   *
   * @param {Function} callback - The update method.
   * @param {string} updateType - The update type.
   * @return {Node} A reference to this node.
   */
  onUpdate(e, t) {
    return this.updateType = t, this.update = e.bind(this), this;
  }
  /**
   * Convenient method for defining {@link Node#update}. Similar to {@link Node#onUpdate}, but
   * this method automatically sets the update type to `FRAME`.
   *
   * @param {Function} callback - The update method.
   * @return {Node} A reference to this node.
   */
  onFrameUpdate(e) {
    return this.onUpdate(e, it.FRAME);
  }
  /**
   * Convenient method for defining {@link Node#update}. Similar to {@link Node#onUpdate}, but
   * this method automatically sets the update type to `RENDER`.
   *
   * @param {Function} callback - The update method.
   * @return {Node} A reference to this node.
   */
  onRenderUpdate(e) {
    return this.onUpdate(e, it.RENDER);
  }
  /**
   * Convenient method for defining {@link Node#update}. Similar to {@link Node#onUpdate}, but
   * this method automatically sets the update type to `OBJECT`.
   *
   * @param {Function} callback - The update method.
   * @return {Node} A reference to this node.
   */
  onObjectUpdate(e) {
    return this.onUpdate(e, it.OBJECT);
  }
  /**
   * Convenient method for defining {@link Node#updateReference}.
   *
   * @param {Function} callback - The update method.
   * @return {Node} A reference to this node.
   */
  onReference(e) {
    return this.updateReference = e.bind(this), this;
  }
  /**
   * Nodes might refer to other objects like materials. This method allows to dynamically update the reference
   * to such objects based on a given state (e.g. the current node frame or builder).
   *
   * @param {any} state - This method can be invocated in different contexts so `state` can refer to any object type.
   * @return {any} The updated reference.
   */
  updateReference() {
    return this;
  }
  /**
   * By default this method returns the value of the {@link Node#global} flag. This method
   * can be overwritten in derived classes if an analytical way is required to determine the
   * global cache referring to the current shader-stage.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {boolean} Whether this node is global or not.
   */
  isGlobal() {
    return this.global;
  }
  /**
   * Generator function that can be used to iterate over the child nodes.
   *
   * @generator
   * @yields {Node} A child node.
   */
  *getChildren() {
    for (const { childNode: e } of this._getChildren())
      yield e;
  }
  /**
   * Calling this method dispatches the `dispose` event. This event can be used
   * to register event listeners for clean up tasks.
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
  /**
   * Callback for {@link Node#traverse}.
   *
   * @callback traverseCallback
   * @param {Node} node - The current node.
   */
  /**
   * Can be used to traverse through the node's hierarchy.
   *
   * @param {traverseCallback} callback - A callback that is executed per node.
   */
  traverse(e) {
    e(this);
    for (const t of this.getChildren())
      t.traverse(e);
  }
  /**
   * Returns the child nodes of this node.
   *
   * @private
   * @param {Set<Node>} [ignores=new Set()] - A set of nodes to ignore during the search to avoid circular references.
   * @returns {Array<Object>} An array of objects describing the child nodes.
   */
  _getChildren(e = /* @__PURE__ */ new Set()) {
    const t = [];
    e.add(this);
    for (const n of Object.getOwnPropertyNames(this)) {
      const r = this[n];
      if (!(n.startsWith("_") === !0 || e.has(r))) {
        if (Array.isArray(r) === !0)
          for (let s = 0; s < r.length; s++) {
            const a = r[s];
            a && a.isNode === !0 && t.push({ property: n, index: s, childNode: a });
          }
        else if (r && r.isNode === !0)
          t.push({ property: n, childNode: r });
        else if (r && Object.getPrototypeOf(r) === Object.prototype)
          for (const s in r) {
            if (s.startsWith("_") === !0)
              continue;
            const a = r[s];
            a && a.isNode === !0 && t.push({ property: n, index: s, childNode: a });
          }
      }
    }
    return t;
  }
  /**
   * Returns the cache key for this node.
   *
   * @param {boolean} [force=false] - When set to `true`, a recomputation of the cache key is forced.
   * @param {Set<Node>} [ignores=null] - A set of nodes to ignore during the computation of the cache key.
   * @return {number} The cache key of the node.
   */
  getCacheKey(e = !1, t = null) {
    if (e = e || this.version !== this._cacheKeyVersion, e === !0 || this._cacheKey === null) {
      t === null && (t = /* @__PURE__ */ new Set());
      const n = [];
      for (const { property: r, childNode: s } of this._getChildren(t))
        n.push(Ml(r.slice(0, -4)), s.getCacheKey(e, t));
      this._cacheKey = xc(ou(n), this.customCacheKey()), this._cacheKeyVersion = this.version;
    }
    return this._cacheKey;
  }
  /**
   * Generate a custom cache key for this node.
   *
   * @return {number} The cache key of the node.
   */
  customCacheKey() {
    return this.id;
  }
  /**
   * Returns the references to this node which is by default `this`.
   *
   * @return {Node} A reference to this node.
   */
  getScope() {
    return this;
  }
  /**
   * Returns the hash of the node which is used to identify the node. By default it's
   * the {@link Node#uuid} however derived node classes might have to overwrite this method
   * depending on their implementation.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The hash.
   */
  getHash() {
    return this.uuid;
  }
  /**
   * Returns the update type of {@link Node#update}.
   *
   * @return {NodeUpdateType} The update type.
   */
  getUpdateType() {
    return this.updateType;
  }
  /**
   * Returns the update type of {@link Node#updateBefore}.
   *
   * @return {NodeUpdateType} The update type.
   */
  getUpdateBeforeType() {
    return this.updateBeforeType;
  }
  /**
   * Returns the update type of {@link Node#updateAfter}.
   *
   * @return {NodeUpdateType} The update type.
   */
  getUpdateAfterType() {
    return this.updateAfterType;
  }
  /**
   * Certain types are composed of multiple elements. For example a `vec3`
   * is composed of three `float` values. This method returns the type of
   * these elements.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The type of the node.
   */
  getElementType(e) {
    const t = this.getNodeType(e);
    return e.getElementType(t);
  }
  /**
   * Returns the node member type for the given name.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The name of the member.
   * @return {string} The type of the node.
   */
  getMemberType() {
    return "void";
  }
  /**
   * Returns the node's type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The type of the node.
   */
  getNodeType(e) {
    const t = e.getNodeProperties(this);
    return t.outputNode ? t.outputNode.getNodeType(e) : this.nodeType;
  }
  /**
   * This method is used during the build process of a node and ensures
   * equal nodes are not built multiple times but just once. For example if
   * `attribute( 'uv' )` is used multiple times by the user, the build
   * process makes sure to process just the first node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node} The shared node if possible. Otherwise `this` is returned.
   */
  getShared(e) {
    const t = this.getHash(e);
    return e.getNodeFromHash(t) || this;
  }
  /**
   * Returns the number of elements in the node array.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?number} The number of elements in the node array.
   */
  getArrayCount() {
    return null;
  }
  /**
   * Represents the setup stage which is the first step of the build process, see {@link Node#build} method.
   * This method is often overwritten in derived modules to prepare the node which is used as a node's output/result.
   * If an output node is prepared, then it must be returned in the `return` statement of the derived module's setup function.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?Node} The output node.
   */
  setup(e) {
    const t = e.getNodeProperties(this);
    let n = 0;
    for (const r of this.getChildren())
      t["node" + n++] = r;
    return t.outputNode || null;
  }
  /**
   * Represents the analyze stage which is the second step of the build process, see {@link Node#build} method.
   * This stage analyzes the node hierarchy and ensures descendent nodes are built.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {?Node} output - The target output node.
   */
  analyze(e, t = null) {
    const n = e.increaseUsage(this);
    if (this.parents === !0) {
      const r = e.getDataFromNode(this, "any");
      r.stages = r.stages || {}, r.stages[e.shaderStage] = r.stages[e.shaderStage] || [], r.stages[e.shaderStage].push(t);
    }
    if (n === 1) {
      const r = e.getNodeProperties(this);
      for (const s of Object.values(r))
        s && s.isNode === !0 && s.build(e, this);
    }
  }
  /**
   * Represents the generate stage which is the third step of the build process, see {@link Node#build} method.
   * This state builds the output node and returns the resulting shader string.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {?string} [output] - Can be used to define the output type.
   * @return {?string} The generated shader string.
   */
  generate(e, t) {
    const { outputNode: n } = e.getNodeProperties(this);
    if (n && n.isNode === !0)
      return n.build(e, t);
  }
  /**
   * The method can be implemented to update the node's internal state before it is used to render an object.
   * The {@link Node#updateBeforeType} property defines how often the update is executed.
   *
   * @abstract
   * @param {NodeFrame} frame - A reference to the current node frame.
   * @return {?boolean} An optional bool that indicates whether the implementation actually performed an update or not (e.g. due to caching).
   */
  updateBefore() {
    oe("Abstract function.");
  }
  /**
   * The method can be implemented to update the node's internal state after it was used to render an object.
   * The {@link Node#updateAfterType} property defines how often the update is executed.
   *
   * @abstract
   * @param {NodeFrame} frame - A reference to the current node frame.
   * @return {?boolean} An optional bool that indicates whether the implementation actually performed an update or not (e.g. due to caching).
   */
  updateAfter() {
    oe("Abstract function.");
  }
  /**
   * The method can be implemented to update the node's internal state when it is used to render an object.
   * The {@link Node#updateType} property defines how often the update is executed.
   *
   * @abstract
   * @param {NodeFrame} frame - A reference to the current node frame.
   * @return {?boolean} An optional bool that indicates whether the implementation actually performed an update or not (e.g. due to caching).
   */
  update() {
    oe("Abstract function.");
  }
  before(e) {
    return this._beforeNodes === null && (this._beforeNodes = []), this._beforeNodes.push(e), this;
  }
  /**
   * This method performs the build of a node. The behavior and return value depend on the current build stage:
   * - **setup**: Prepares the node and its children for the build process. This process can also create new nodes. Returns the node itself or a variant.
   * - **analyze**: Analyzes the node hierarchy for optimizations in the code generation stage. Returns `null`.
   * - **generate**: Generates the shader code for the node. Returns the generated shader string.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {?(string|Node)} [output=null] - Can be used to define the output type.
   * @return {?(Node|string)} The result of the build process, depending on the build stage.
   */
  build(e, t = null) {
    const n = this.getShared(e);
    if (this !== n)
      return n.build(e, t);
    if (this._beforeNodes !== null) {
      const l = this._beforeNodes;
      this._beforeNodes = null;
      for (const c of l)
        c.build(e, t);
      this._beforeNodes = l;
    }
    const r = e.getDataFromNode(this);
    r.buildStages = r.buildStages || {}, r.buildStages[e.buildStage] = !0;
    const s = l2[e.buildStage];
    if (s && r.buildStages[s] !== !0) {
      const l = e.getBuildStage();
      e.setBuildStage(s), this.build(e), e.setBuildStage(l);
    }
    e.addChain(this);
    let a = null;
    const o = e.getBuildStage();
    if (o === "setup") {
      e.addNode(this), this.updateReference(e);
      const l = e.getNodeProperties(this);
      if (l.initialized !== !0) {
        l.initialized = !0, l.outputNode = this.setup(e) || l.outputNode || null;
        for (const c of Object.values(l))
          if (c && c.isNode === !0) {
            if (c.parents === !0) {
              const u = e.getNodeProperties(c);
              u.parents = u.parents || [], u.parents.push(this);
            }
            c.build(e);
          }
        e.addSequentialNode(this);
      }
      a = l.outputNode;
    } else if (o === "analyze")
      this.analyze(e, t);
    else if (o === "generate") {
      if (this.generate.length < 2) {
        const c = this.getNodeType(e), u = e.getDataFromNode(this);
        a = u.snippet, a === void 0 ? u.generated === void 0 ? (u.generated = !0, a = this.generate(e) || "", u.snippet = a) : (oe("Node: Recursion detected.", this), a = "/* Recursion detected. */") : u.flowCodes !== void 0 && e.context.nodeBlock !== void 0 && e.addFlowCodeHierarchy(this, e.context.nodeBlock), a = e.format(a, c, t);
      } else
        a = this.generate(e, t) || "";
      a === "" && t !== null && t !== "void" && t !== "OutputType" && (le(`TSL: Invalid generated code, expected a "${t}".`), a = e.generateConst(t));
    }
    return e.removeChain(this), a;
  }
  /**
   * Returns the child nodes as a JSON object.
   *
   * @return {Generator<Object>} An iterable list of serialized child objects as JSON.
   */
  getSerializeChildren() {
    return this._getChildren();
  }
  /**
   * Serializes the node to JSON.
   *
   * @param {Object} json - The output JSON object.
   */
  serialize(e) {
    const t = this.getSerializeChildren(), n = {};
    for (const { property: r, index: s, childNode: a } of t)
      s !== void 0 ? (n[r] === void 0 && (n[r] = Number.isInteger(s) ? [] : {}), n[r][s] = a.toJSON(e.meta).uuid) : n[r] = a.toJSON(e.meta).uuid;
    Object.keys(n).length > 0 && (e.inputNodes = n);
  }
  /**
   * Deserializes the node from the given JSON.
   *
   * @param {Object} json - The JSON object.
   */
  deserialize(e) {
    if (e.inputNodes !== void 0) {
      const t = e.meta.nodes;
      for (const n in e.inputNodes)
        if (Array.isArray(e.inputNodes[n])) {
          const r = [];
          for (const s of e.inputNodes[n])
            r.push(t[s]);
          this[n] = r;
        } else if (typeof e.inputNodes[n] == "object") {
          const r = {};
          for (const s in e.inputNodes[n]) {
            const a = e.inputNodes[n][s];
            r[s] = t[a];
          }
          this[n] = r;
        } else {
          const r = e.inputNodes[n];
          this[n] = t[r];
        }
    }
  }
  /**
   * Serializes the node into the three.js JSON Object/Scene format.
   *
   * @param {?Object} meta - An optional JSON object that already holds serialized data from other scene objects.
   * @return {Object} The serialized node.
   */
  toJSON(e) {
    const { uuid: t, type: n } = this, r = e === void 0 || typeof e == "string";
    r && (e = {
      textures: {},
      images: {},
      nodes: {}
    });
    let s = e.nodes[t];
    s === void 0 && (s = {
      uuid: t,
      type: n,
      meta: e,
      metadata: {
        version: 4.7,
        type: "Node",
        generator: "Node.toJSON"
      }
    }, r !== !0 && (e.nodes[s.uuid] = s), this.serialize(s), delete s.meta);
    function a(o) {
      const l = [];
      for (const c in o) {
        const u = o[c];
        delete u.metadata, l.push(u);
      }
      return l;
    }
    if (r) {
      const o = a(e.textures), l = a(e.images), c = a(e.nodes);
      o.length > 0 && (s.textures = o), l.length > 0 && (s.images = l), c.length > 0 && (s.nodes = c);
    }
    return s;
  }
}
Fe.captureStackTrace = !1;
class wl extends Fe {
  // @TODO: If extending from TempNode it breaks webgpu_compute
  static get type() {
    return "ArrayElementNode";
  }
  /**
   * Constructs an array element node.
   *
   * @param {Node} node - The array-like node.
   * @param {Node} indexNode - The index node that defines the element access.
   */
  constructor(e, t) {
    super(), this.node = e, this.indexNode = t, this.isArrayElementNode = !0;
  }
  /**
   * This method is overwritten since the node type is inferred from the array-like node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.node.getElementType(e);
  }
  /**
   * This method is overwritten since the member type is inferred from the array-like node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The member name.
   * @return {string} The member type.
   */
  getMemberType(e, t) {
    return this.node.getMemberType(e, t);
  }
  generate(e) {
    const t = this.indexNode.getNodeType(e), n = this.node.build(e), r = this.indexNode.build(e, !e.isVector(t) && e.isInteger(t) ? t : "uint");
    return `${n}[ ${r} ]`;
  }
}
class bb extends Fe {
  static get type() {
    return "ConvertNode";
  }
  /**
   * Constructs a new convert node.
   *
   * @param {Node} node - The node which type should be converted.
   * @param {string} convertTo - The target node type. Multiple types can be defined by separating them with a `|` sign.
   */
  constructor(e, t) {
    super(), this.node = e, this.convertTo = t;
  }
  /**
   * This method is overwritten since the implementation tries to infer the best
   * matching type from the {@link ConvertNode#convertTo} property.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    const t = this.node.getNodeType(e);
    let n = null;
    for (const r of this.convertTo.split("|"))
      (n === null || e.getTypeLength(t) === e.getTypeLength(r)) && (n = r);
    return n;
  }
  serialize(e) {
    super.serialize(e), e.convertTo = this.convertTo;
  }
  deserialize(e) {
    super.deserialize(e), this.convertTo = e.convertTo;
  }
  generate(e, t) {
    const n = this.node, r = this.getNodeType(e), s = n.build(e, r);
    return e.format(s, r, t);
  }
}
class xn extends Fe {
  static get type() {
    return "TempNode";
  }
  /**
   * Constructs a temp node.
   *
   * @param {?string} nodeType - The node type.
   */
  constructor(e = null) {
    super(e), this.isTempNode = !0;
  }
  /**
   * Whether this node is used more than once in context of other nodes.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @return {boolean} A flag that indicates if there is more than one dependency to other nodes.
   */
  hasDependencies(e) {
    return e.getDataFromNode(this).usageCount > 1;
  }
  build(e, t) {
    if (e.getBuildStage() === "generate") {
      const r = e.getVectorType(this.getNodeType(e, t)), s = e.getDataFromNode(this);
      if (s.propertyName !== void 0)
        return e.format(s.propertyName, r, t);
      if (r !== "void" && t !== "void" && this.hasDependencies(e)) {
        const a = super.build(e, r), o = e.getVarFromNode(this, null, r), l = e.getPropertyName(o);
        return e.addLineFlowCode(`${l} = ${a}`, this), s.snippet = a, s.propertyName = l, e.format(s.propertyName, r, t);
      }
    }
    return super.build(e, t);
  }
}
class u2 extends xn {
  static get type() {
    return "JoinNode";
  }
  /**
   * Constructs a new join node.
   *
   * @param {Array<Node>} nodes - An array of nodes that should be joined.
   * @param {?string} [nodeType=null] - The node type.
   */
  constructor(e = [], t = null) {
    super(t), this.nodes = e;
  }
  /**
   * This method is overwritten since the node type must be inferred from the
   * joined data length if not explicitly defined.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.nodeType !== null ? e.getVectorType(this.nodeType) : e.getTypeFromLength(this.nodes.reduce((t, n) => t + e.getTypeLength(n.getNodeType(e)), 0));
  }
  generate(e, t) {
    const n = this.getNodeType(e), r = e.getTypeLength(n), s = this.nodes, a = e.getComponentType(n), o = [];
    let l = 0;
    for (const u of s) {
      if (l >= r) {
        le(`TSL: Length of parameters exceeds maximum length of function '${n}()' type.`, this.stackTrace);
        break;
      }
      let h = u.getNodeType(e), d = e.getTypeLength(h), f;
      if (l + d > r && (le(`TSL: Length of '${n}()' data exceeds maximum length of output type.`, this.stackTrace), d = r - l, h = e.getTypeFromLength(d)), l += d, f = u.build(e, h), e.getComponentType(h) !== a) {
        const _ = e.getTypeFromLength(d, a);
        f = e.format(f, h, _);
      }
      o.push(f);
    }
    const c = `${e.getType(n)}( ${o.join(", ")} )`;
    return e.format(c, n, t);
  }
}
const h2 = El.join("");
class d2 extends Fe {
  static get type() {
    return "SplitNode";
  }
  /**
   * Constructs a new split node.
   *
   * @param {Node} node - The node that should be accessed.
   * @param {string} [components='x'] - The components that should be accessed.
   */
  constructor(e, t = "x") {
    super(), this.node = e, this.components = t, this.isSplitNode = !0;
  }
  /**
   * Returns the vector length which is computed based on the requested components.
   *
   * @return {number} The vector length.
   */
  getVectorLength() {
    let e = this.components.length;
    for (const t of this.components)
      e = Math.max(El.indexOf(t) + 1, e);
    return e;
  }
  /**
   * Returns the component type of the node's type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The component type.
   */
  getComponentType(e) {
    return e.getComponentType(this.node.getNodeType(e));
  }
  /**
   * This method is overwritten since the node type is inferred from requested components.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return e.getTypeFromLength(this.components.length, this.getComponentType(e));
  }
  /**
   * Returns the scope of the node.
   *
   * @return {Node} The scope of the node.
   */
  getScope() {
    return this.node.getScope();
  }
  generate(e, t) {
    const n = this.node, r = e.getTypeLength(n.getNodeType(e));
    let s = null;
    if (r > 1) {
      let a = null;
      this.getVectorLength() >= r && (a = e.getTypeFromLength(this.getVectorLength(), this.getComponentType(e)));
      const l = n.build(e, a);
      this.components.length === r && this.components === h2.slice(0, this.components.length) ? s = e.format(l, a, t) : s = e.format(`${l}.${this.components}`, this.getNodeType(e), t);
    } else
      s = n.build(e, t);
    return s;
  }
  serialize(e) {
    super.serialize(e), e.components = this.components;
  }
  deserialize(e) {
    super.deserialize(e), this.components = e.components;
  }
}
class f2 extends xn {
  static get type() {
    return "SetNode";
  }
  /**
   * Constructs a new set node.
   *
   * @param {Node} sourceNode - The node that should be updated.
   * @param {string} components - The components that should be updated.
   * @param {Node} targetNode - The value node.
   */
  constructor(e, t, n) {
    super(), this.sourceNode = e, this.components = t, this.targetNode = n;
  }
  /**
   * This method is overwritten since the node type is inferred from {@link SetNode#sourceNode}.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.sourceNode.getNodeType(e);
  }
  generate(e) {
    const { sourceNode: t, components: n, targetNode: r } = this, s = this.getNodeType(e), a = e.getComponentType(r.getNodeType(e)), o = e.getTypeFromLength(n.length, a), l = r.build(e, o), c = t.build(e, s), u = e.getTypeLength(s), h = [];
    for (let d = 0; d < u; d++) {
      const f = El[d];
      f === n[0] ? (h.push(l), d += n.length - 1) : h.push(c + "." + f);
    }
    return `${e.getType(s)}( ${h.join(", ")} )`;
  }
}
class p2 extends xn {
  static get type() {
    return "FlipNode";
  }
  /**
   * Constructs a new flip node.
   *
   * @param {Node} sourceNode - The node which component(s) should be flipped.
   * @param {string} components - The components that should be flipped e.g. `'x'` or `'xy'`.
   */
  constructor(e, t) {
    super(), this.sourceNode = e, this.components = t;
  }
  /**
   * This method is overwritten since the node type is inferred from the source node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.sourceNode.getNodeType(e);
  }
  generate(e) {
    const { components: t, sourceNode: n } = this, r = this.getNodeType(e), s = n.build(e), a = e.getVarFromNode(this), o = e.getPropertyName(a);
    e.addLineFlowCode(o + " = " + s, this);
    const l = e.getTypeLength(r), c = [];
    let u = 0;
    for (let h = 0; h < l; h++) {
      const d = El[h];
      d === t[u] ? (c.push("1.0 - " + (o + "." + d)), u++) : c.push(o + "." + d);
    }
    return `${e.getType(r)}( ${c.join(", ")} )`;
  }
}
class vg extends Fe {
  static get type() {
    return "InputNode";
  }
  /**
   * Constructs a new input node.
   *
   * @param {any} value - The value of this node. This can be any JS primitive, functions, array buffers or even three.js objects (vector, matrices, colors).
   * @param {?string} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
   */
  constructor(e, t = null) {
    super(t), this.isInputNode = !0, this.value = e, this.precision = null;
  }
  getNodeType() {
    return this.nodeType === null ? zh(this.value) : this.nodeType;
  }
  /**
   * Returns the input type of the node which is by default the node type. Derived modules
   * might overwrite this method and use a fixed type or compute one analytically.
   *
   * A typical example for different input and node types are textures. The input type of a
   * normal RGBA texture is `texture` whereas its node type is `vec4`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType(e) {
    return this.getNodeType(e);
  }
  /**
   * Sets the precision to the given value. The method can be
   * overwritten in derived classes if the final precision must be computed
   * analytically.
   *
   * @param {('low'|'medium'|'high')} precision - The precision of the input value in the shader.
   * @return {InputNode} A reference to this node.
   */
  setPrecision(e) {
    return this.precision = e, this;
  }
  serialize(e) {
    super.serialize(e), e.value = this.value, this.value && this.value.toArray && (e.value = this.value.toArray()), e.valueType = zh(this.value), e.nodeType = this.nodeType, e.valueType === "ArrayBuffer" && (e.value = s2(e.value)), e.precision = this.precision;
  }
  deserialize(e) {
    super.deserialize(e), this.nodeType = e.nodeType, this.value = Array.isArray(e.value) ? xg(e.valueType, ...e.value) : e.value, this.precision = e.precision || null, this.value && this.value.fromArray && (this.value = this.value.fromArray(e.value));
  }
  generate() {
    oe("Abstract function.");
  }
}
const V0 = /float|u?int/;
class Ir extends vg {
  static get type() {
    return "ConstNode";
  }
  /**
   * Constructs a new input node.
   *
   * @param {any} value - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color).
   * @param {?string} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
   */
  constructor(e, t = null) {
    super(e, t), this.isConstNode = !0;
  }
  /**
   * Generates the shader string of the value with the current node builder.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated value as a shader string.
   */
  generateConst(e) {
    return e.generateConst(this.getNodeType(e), this.value);
  }
  generate(e, t) {
    const n = this.getNodeType(e);
    return V0.test(n) && V0.test(t) ? e.generateConst(t, this.value) : e.format(this.generateConst(e), n, t);
  }
}
class m2 extends Fe {
  static get type() {
    return "MemberNode";
  }
  /**
   * Constructs a member node.
   *
   * @param {Node} structNode - The struct node.
   * @param {string} property - The property name.
   */
  constructor(e, t) {
    super(), this.structNode = e, this.property = t, this.isMemberNode = !0;
  }
  hasMember(e) {
    return this.structNode.isMemberNode && this.structNode.hasMember(e) === !1 ? !1 : this.structNode.getMemberType(e, this.property) !== "void";
  }
  getNodeType(e) {
    return this.hasMember(e) === !1 ? "float" : this.structNode.getMemberType(e, this.property);
  }
  getMemberType(e, t) {
    if (this.hasMember(e) === !1)
      return "float";
    const n = this.getNodeType(e);
    return e.getStructTypeNode(n).getMemberType(e, t);
  }
  generate(e) {
    if (this.hasMember(e) === !1) {
      oe(`TSL: Member "${this.property}" does not exist in struct.`, this.stackTrace);
      const n = this.getNodeType(e);
      return e.generateConst(n);
    }
    return this.structNode.build(e) + "." + this.property;
  }
}
let Ua = null;
const Hp = /* @__PURE__ */ new Map();
function Q(i, e) {
  if (Hp.has(i)) {
    oe(`TSL: Redefinition of method chaining '${i}'.`);
    return;
  }
  if (typeof e != "function")
    throw new Error(`THREE.TSL: Node element ${i} is not a function`);
  Hp.set(i, e), i !== "assign" && (Fe.prototype[i] = function(...t) {
    return this.isStackNode ? this.addToStack(e(...t)) : e(this, ...t);
  }, Fe.prototype[i + "Assign"] = function(...t) {
    return this.isStackNode ? this.assign(t[0], e(...t)) : this.assign(e(this, ...t));
  });
}
const g2 = (i) => i.replace(/r|s/g, "x").replace(/g|t/g, "y").replace(/b|p/g, "z").replace(/a|q/g, "w"), z0 = (i) => g2(i).split("").sort().join("");
Fe.prototype.assign = function(...i) {
  if (this.isStackNode !== !0)
    return Ua !== null ? Ua.assign(this, ...i) : le("TSL: No stack defined for assign operation. Make sure the assign is inside a Fn().", new Yn()), this;
  {
    const e = Hp.get("assign");
    return this.addToStack(e(...i));
  }
};
Fe.prototype.toVarIntent = function() {
  return this;
};
Fe.prototype.get = function(i) {
  return new m2(this, i);
};
const vc = {};
function Wu(i, e, t) {
  vc[i] = vc[e] = vc[t] = {
    get() {
      this._cache = this._cache || {};
      let a = this._cache[i];
      return a === void 0 && (a = new d2(this, i), this._cache[i] = a), a;
    },
    set(a) {
      this[i].assign(Le(a));
    }
  };
  const n = i.toUpperCase(), r = e.toUpperCase(), s = t.toUpperCase();
  Fe.prototype["set" + n] = Fe.prototype["set" + r] = Fe.prototype["set" + s] = function(a) {
    const o = z0(i);
    return new f2(this, o, Le(a));
  }, Fe.prototype["flip" + n] = Fe.prototype["flip" + r] = Fe.prototype["flip" + s] = function() {
    const a = z0(i);
    return new p2(this, a);
  };
}
const lr = ["x", "y", "z", "w"], cr = ["r", "g", "b", "a"], ur = ["s", "t", "p", "q"];
for (let i = 0; i < 4; i++) {
  let e = lr[i], t = cr[i], n = ur[i];
  Wu(e, t, n);
  for (let r = 0; r < 4; r++) {
    e = lr[i] + lr[r], t = cr[i] + cr[r], n = ur[i] + ur[r], Wu(e, t, n);
    for (let s = 0; s < 4; s++) {
      e = lr[i] + lr[r] + lr[s], t = cr[i] + cr[r] + cr[s], n = ur[i] + ur[r] + ur[s], Wu(e, t, n);
      for (let a = 0; a < 4; a++)
        e = lr[i] + lr[r] + lr[s] + lr[a], t = cr[i] + cr[r] + cr[s] + cr[a], n = ur[i] + ur[r] + ur[s] + ur[a], Wu(e, t, n);
    }
  }
}
for (let i = 0; i < 32; i++)
  vc[i] = {
    get() {
      this._cache = this._cache || {};
      let e = this._cache[i];
      return e === void 0 && (e = new wl(this, new Ir(i, "uint")), this._cache[i] = e), e;
    },
    set(e) {
      this[i].assign(Le(e));
    }
  };
Object.defineProperties(Fe.prototype, vc);
const H0 = /* @__PURE__ */ new WeakMap(), _2 = function(i, e = null) {
  const t = zh(i);
  return t === "node" ? i : e === null && (t === "float" || t === "boolean") || t && t !== "shader" && t !== "string" ? Le($p(i, e)) : t === "shader" ? i.isFn ? i : ee(i) : i;
}, x2 = function(i, e = null) {
  for (const t in i)
    i[t] = Le(i[t], e);
  return i;
}, v2 = function(i, e = null) {
  const t = i.length;
  for (let n = 0; n < t; n++)
    i[n] = Le(i[n], e);
  return i;
}, Sb = function(i, e = null, t = null, n = null) {
  function r(u) {
    return n !== null ? (u = Le(Object.assign(u, n)), n.intent === !0 && (u = u.toVarIntent())) : u = Le(u), u;
  }
  let s, a = e, o, l;
  function c(u) {
    let h;
    return a ? h = /[a-z]/i.test(a) ? a + "()" : a : h = i.type, o !== void 0 && u.length < o ? (le(`TSL: "${h}" parameter length is less than minimum required.`, new Yn()), u.concat(new Array(o - u.length).fill(0))) : l !== void 0 && u.length > l ? (le(`TSL: "${h}" parameter length exceeds limit.`, new Yn()), u.slice(0, l)) : u;
  }
  return e === null ? s = (...u) => r(new i(...Fo(c(u)))) : t !== null ? (t = Le(t), s = (...u) => r(new i(e, ...Fo(c(u)), t))) : s = (...u) => r(new i(e, ...Fo(c(u)))), s.setParameterLength = (...u) => (u.length === 1 ? o = l = u[0] : u.length === 2 && ([o, l] = u), s), s.setName = (u) => (a = u, s), s;
}, y2 = function(i, ...e) {
  return new i(...Fo(e));
};
class b2 extends Fe {
  constructor(e, t) {
    super(), this.shaderNode = e, this.rawInputs = t, this.isShaderCallNodeInternal = !0;
  }
  getNodeType(e) {
    return this.shaderNode.nodeType || this.getOutputNode(e).getNodeType(e);
  }
  getElementType(e) {
    return this.getOutputNode(e).getElementType(e);
  }
  getMemberType(e, t) {
    return this.getOutputNode(e).getMemberType(e, t);
  }
  call(e) {
    const { shaderNode: t, rawInputs: n } = this, r = e.getNodeProperties(t), s = e.getClosestSubBuild(t.subBuilds) || "", a = s || "default";
    if (r[a])
      return r[a];
    const o = e.subBuildFn, l = e.fnCall;
    e.subBuildFn = s, e.fnCall = this;
    let c = null;
    if (t.layout) {
      let u = H0.get(e.constructor);
      u === void 0 && (u = /* @__PURE__ */ new WeakMap(), H0.set(e.constructor, u));
      let h = u.get(t);
      h === void 0 && (h = Le(e.buildFunctionNode(t)), u.set(t, h)), e.addInclude(h);
      const d = n ? S2(n) : null;
      c = Le(h.call(d));
    } else {
      const u = new Proxy(e, {
        get: (_, g, m) => {
          let x;
          return Symbol.iterator === g ? x = function* () {
            yield void 0;
          } : x = Reflect.get(_, g, m), x;
        }
      }), h = n ? T2(n) : null, d = Array.isArray(n) ? n.length > 0 : n !== null, f = t.jsFunc, p = d || f.length > 1 ? f(h, u) : f(u);
      c = Le(p);
    }
    return e.subBuildFn = o, e.fnCall = l, t.once && (r[a] = c), c;
  }
  setupOutput(e) {
    return e.addStack(), e.stack.outputNode = this.call(e), e.removeStack();
  }
  getOutputNode(e) {
    const t = e.getNodeProperties(this), n = e.getSubBuildOutput(this);
    return t[n] = t[n] || this.setupOutput(e), t[n].subBuild = e.getClosestSubBuild(this), t[n];
  }
  build(e, t = null) {
    let n = null;
    const r = e.getBuildStage(), s = e.getNodeProperties(this), a = e.getSubBuildOutput(this), o = this.getOutputNode(e), l = e.fnCall;
    if (e.fnCall = this, r === "setup") {
      const c = e.getSubBuildProperty("initialized", this);
      if (s[c] !== !0 && (s[c] = !0, s[a] = this.getOutputNode(e), s[a].build(e), this.shaderNode.subBuilds))
        for (const u of e.chaining) {
          const h = e.getDataFromNode(u, "any");
          h.subBuilds = h.subBuilds || /* @__PURE__ */ new Set();
          for (const d of this.shaderNode.subBuilds)
            h.subBuilds.add(d);
        }
      n = s[a];
    } else
      r === "analyze" ? o.build(e, t) : r === "generate" && (n = o.build(e, t) || "");
    return e.fnCall = l, n;
  }
}
function S2(i) {
  let e;
  return Tg(i), i[0] && (i[0].isNode || Object.getPrototypeOf(i[0]) !== Object.prototype) ? e = [...i] : e = i[0], e;
}
function T2(i) {
  let e = 0;
  return Tg(i), new Proxy(i, {
    get: (t, n, r) => {
      let s;
      if (n === "length")
        return s = i.length, s;
      if (Symbol.iterator === n)
        s = function* () {
          for (const a of i)
            yield Le(a);
        };
      else {
        if (i.length > 0)
          if (Object.getPrototypeOf(i[0]) === Object.prototype) {
            const a = i[0];
            a[n] === void 0 ? s = a[e++] : s = Reflect.get(a, n, r);
          } else
            i[0] instanceof Fe && (i[n] === void 0 ? s = i[e++] : s = Reflect.get(i, n, r));
        else
          s = Reflect.get(t, n, r);
        s = Le(s);
      }
      return s;
    }
  });
}
class M2 extends Fe {
  constructor(e, t) {
    super(t), this.jsFunc = e, this.layout = null, this.global = !0, this.once = !1;
  }
  setLayout(e) {
    return this.layout = e, this;
  }
  getLayout() {
    return this.layout;
  }
  call(e = null) {
    return new b2(this, e);
  }
  setup() {
    return this.call();
  }
}
const E2 = [!1, !0], w2 = [0, 1, 2, 3], A2 = [-1, -2], Tb = [0.5, 1.5, 1 / 3, 1e-6, 1e6, Math.PI, Math.PI * 2, 1 / Math.PI, 2 / Math.PI, 1 / (Math.PI * 2), Math.PI / 2], yg = /* @__PURE__ */ new Map();
for (const i of E2)
  yg.set(i, new Ir(i));
const bg = /* @__PURE__ */ new Map();
for (const i of w2)
  bg.set(i, new Ir(i, "uint"));
const Sg = new Map([...bg].map((i) => new Ir(i.value, "int")));
for (const i of A2)
  Sg.set(i, new Ir(i, "int"));
const vd = new Map([...Sg].map((i) => new Ir(i.value)));
for (const i of Tb)
  vd.set(i, new Ir(i));
for (const i of Tb)
  vd.set(-i, new Ir(-i));
const yd = { bool: yg, uint: bg, ints: Sg, float: vd }, $0 = new Map([...yg, ...vd]), $p = (i, e) => $0.has(i) ? $0.get(i) : i.isNode === !0 ? i : new Ir(i, e), vn = function(i, e = null) {
  return (...t) => {
    for (const r of t)
      if (r === void 0)
        return le(`TSL: Invalid parameter for the type "${i}".`, new Yn()), new Ir(0, i);
    if ((t.length === 0 || !["bool", "float", "int", "uint"].includes(i) && t.every((r) => {
      const s = typeof r;
      return s !== "object" && s !== "function";
    })) && (t = [xg(i, ...t)]), t.length === 1 && e !== null && e.has(t[0]))
      return qu(e.get(t[0]));
    if (t.length === 1) {
      const r = $p(t[0], i);
      return r.nodeType === i ? qu(r) : qu(new bb(r, i));
    }
    const n = t.map((r) => $p(r));
    return qu(new u2(n, i));
  };
}, W0 = (i) => typeof i == "object" && i !== null ? i.value : i, R2 = (i) => i != null ? i.nodeType || i.convertTo || (typeof i == "string" ? i : null) : null;
function cc(i, e) {
  return new M2(i, e);
}
const Le = (i, e = null) => (
  /* new */
  _2(i, e)
), qu = (i, e = null) => (
  /* new */
  Le(i, e).toVarIntent()
), Tg = (i, e = null) => new x2(i, e), Fo = (i, e = null) => new v2(i, e), Mt = (i, e = null, t = null, n = null) => new Sb(i, e, t, n), xe = (i, ...e) => new y2(i, ...e), Ae = (i, e = null, t = null, n = {}) => new Sb(i, e, t, { ...n, intent: !0 });
let C2 = 0;
class N2 extends Fe {
  constructor(e, t = null) {
    super();
    let n = null;
    t !== null && (typeof t == "object" ? n = t.return : (typeof t == "string" ? n = t : le("TSL: Invalid layout type.", new Yn()), t = null)), this.shaderNode = new cc(e, n), t !== null && this.setLayout(t), this.isFn = !0;
  }
  setLayout(e) {
    const t = this.shaderNode.nodeType;
    if (typeof e.inputs != "object") {
      const n = {
        name: "fn" + C2++,
        type: t,
        inputs: []
      };
      for (const r in e)
        r !== "return" && n.inputs.push({
          name: r,
          type: e[r]
        });
      e = n;
    }
    return this.shaderNode.setLayout(e), this;
  }
  getNodeType(e) {
    return this.shaderNode.getNodeType(e) || "float";
  }
  call(...e) {
    const t = this.shaderNode.call(e);
    return this.shaderNode.nodeType === "void" && t.toStack(), t.toVarIntent();
  }
  once(e = null) {
    return this.shaderNode.once = !0, this.shaderNode.subBuilds = e, this;
  }
  generate(e) {
    const t = this.getNodeType(e);
    return le('TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".', this.stackTrace), e.generateConst(t);
  }
}
function ee(i, e = null) {
  const t = new N2(i, e);
  return new Proxy(() => {
  }, {
    apply(n, r, s) {
      return t.call(...s);
    },
    get(n, r, s) {
      return Reflect.get(t, r, s);
    },
    set(n, r, s, a) {
      return Reflect.set(t, r, s, a);
    }
  });
}
const Hh = (i) => {
  Ua = i;
}, Mb = () => Ua, Bt = (...i) => Ua.If(...i);
function Eb(i) {
  return Ua && Ua.addToStack(i), i;
}
Q("toStack", Eb);
const P2 = new vn("color"), K = new vn("float", yd.float), Kt = new vn("int", yd.ints), gt = new vn("uint", yd.uint), Mg = new vn("bool", yd.bool), Pe = new vn("vec2"), gr = new vn("ivec2"), wb = new vn("uvec2"), D2 = new vn("bvec2"), Y = new vn("vec3"), Ab = new vn("ivec3"), Rb = new vn("uvec3"), L2 = new vn("bvec3"), et = new vn("vec4"), Cb = new vn("ivec4"), Nb = new vn("uvec4"), F2 = new vn("bvec4"), Eg = new vn("mat2"), On = new vn("mat3"), Ta = new vn("mat4");
Q("toColor", P2);
Q("toFloat", K);
Q("toInt", Kt);
Q("toUint", gt);
Q("toBool", Mg);
Q("toVec2", Pe);
Q("toIVec2", gr);
Q("toUVec2", wb);
Q("toBVec2", D2);
Q("toVec3", Y);
Q("toIVec3", Ab);
Q("toUVec3", Rb);
Q("toBVec3", L2);
Q("toVec4", et);
Q("toIVec4", Cb);
Q("toUVec4", Nb);
Q("toBVec4", F2);
Q("toMat2", Eg);
Q("toMat3", On);
Q("toMat4", Ta);
const I2 = /* @__PURE__ */ Mt(wl).setParameterLength(2), U2 = (i, e) => new bb(Le(i), e);
Q("element", I2);
Q("convert", U2);
Q("append", (i) => (oe("TSL: .append() has been renamed to .toStack().", new Yn()), Eb(i)));
class Et extends Fe {
  static get type() {
    return "PropertyNode";
  }
  /**
   * Constructs a new property node.
   *
   * @param {string} nodeType - The type of the node.
   * @param {?string} [name=null] - The name of the property in the shader.
   * @param {boolean} [varying=false] - Whether this property is a varying or not.
   */
  constructor(e, t = null, n = !1) {
    super(e), this.name = t, this.varying = n, this.isPropertyNode = !0, this.global = !0;
  }
  customCacheKey() {
    return Ml(this.type + ":" + (this.name || "") + ":" + (this.varying ? "1" : "0"));
  }
  getHash(e) {
    return this.name || super.getHash(e);
  }
  generate(e) {
    let t;
    return this.varying === !0 ? (t = e.getVaryingFromNode(this, this.name), t.needsInterpolation = !0) : t = e.getVarFromNode(this, this.name), e.getPropertyName(t);
  }
}
const Vs = (i, e) => new Et(i, e), $h = (i, e) => new Et(i, e, !0), Nt = /* @__PURE__ */ xe(Et, "vec4", "DiffuseColor"), To = /* @__PURE__ */ xe(Et, "vec3", "DiffuseContribution"), q0 = /* @__PURE__ */ xe(Et, "vec3", "EmissiveColor"), Jr = /* @__PURE__ */ xe(Et, "float", "Roughness"), Fs = /* @__PURE__ */ xe(Et, "float", "Metalness"), Wp = /* @__PURE__ */ xe(Et, "float", "Clearcoat"), yc = /* @__PURE__ */ xe(Et, "float", "ClearcoatRoughness"), Li = /* @__PURE__ */ xe(Et, "vec3", "Sheen"), ma = /* @__PURE__ */ xe(Et, "float", "SheenRoughness"), wg = /* @__PURE__ */ xe(Et, "float", "Iridescence"), qp = /* @__PURE__ */ xe(Et, "float", "IridescenceIOR"), Xp = /* @__PURE__ */ xe(Et, "float", "IridescenceThickness"), jp = /* @__PURE__ */ xe(Et, "float", "AlphaT"), da = /* @__PURE__ */ xe(Et, "float", "Anisotropy"), Eh = /* @__PURE__ */ xe(Et, "vec3", "AnisotropyT"), Io = /* @__PURE__ */ xe(Et, "vec3", "AnisotropyB"), Ba = /* @__PURE__ */ xe(Et, "color", "SpecularColor"), Eo = /* @__PURE__ */ xe(Et, "color", "SpecularColorBlended"), wo = /* @__PURE__ */ xe(Et, "float", "SpecularF90"), Yp = /* @__PURE__ */ xe(Et, "float", "Shininess"), bc = /* @__PURE__ */ xe(Et, "vec4", "Output"), Lf = /* @__PURE__ */ xe(Et, "float", "dashSize"), X0 = /* @__PURE__ */ xe(Et, "float", "gapSize"), wh = /* @__PURE__ */ xe(Et, "float", "IOR"), Kp = /* @__PURE__ */ xe(Et, "float", "Transmission"), Pb = /* @__PURE__ */ xe(Et, "float", "Thickness"), Db = /* @__PURE__ */ xe(Et, "float", "AttenuationDistance"), Lb = /* @__PURE__ */ xe(Et, "color", "AttenuationColor"), Fb = /* @__PURE__ */ xe(Et, "float", "Dispersion");
class Ib extends Fe {
  static get type() {
    return "UniformGroupNode";
  }
  /**
   * Constructs a new uniform group node.
   *
   * @param {string} name - The name of the uniform group node.
   * @param {boolean} [shared=false] - Whether this uniform group node is shared or not.
   * @param {number} [order=1] - Influences the internal sorting.
   */
  constructor(e, t = !1, n = 1) {
    super("string"), this.name = e, this.shared = t, this.order = n, this.isUniformGroup = !0;
  }
  serialize(e) {
    super.serialize(e), e.name = this.name, e.version = this.version, e.shared = this.shared;
  }
  deserialize(e) {
    super.deserialize(e), this.name = e.name, this.version = e.version, this.shared = e.shared;
  }
}
const B2 = (i) => new Ib(i), Ag = (i, e = 0) => new Ib(i, !0, e), O2 = /* @__PURE__ */ Ag("frame"), Xe = /* @__PURE__ */ Ag("render"), Ub = /* @__PURE__ */ B2("object");
class lu extends vg {
  static get type() {
    return "UniformNode";
  }
  /**
   * Constructs a new uniform node.
   *
   * @param {any} value - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color, texture).
   * @param {?string} nodeType - The node type. If no explicit type is defined, the node tries to derive the type from its value.
   */
  constructor(e, t = null) {
    super(e, t), this.isUniformNode = !0, this.name = "", this.groupNode = Ub;
  }
  /**
   * Sets the {@link UniformNode#name} property.
   *
   * @param {string} name - The name of the uniform.
   * @return {UniformNode} A reference to this node.
   */
  setName(e) {
    return this.name = e, this;
  }
  /**
   * Sets the {@link UniformNode#name} property.
   *
   * @deprecated
   * @param {string} name - The name of the uniform.
   * @return {UniformNode} A reference to this node.
   */
  label(e) {
    return oe('TSL: "label()" has been deprecated. Use "setName()" instead.', new Yn()), this.setName(e);
  }
  /**
   * Sets the {@link UniformNode#groupNode} property.
   *
   * @param {UniformGroupNode} group - The uniform group.
   * @return {UniformNode} A reference to this node.
   */
  setGroup(e) {
    return this.groupNode = e, this;
  }
  /**
   * Returns the {@link UniformNode#groupNode}.
   *
   * @return {UniformGroupNode} The uniform group.
   */
  getGroup() {
    return this.groupNode;
  }
  /**
   * By default, this method returns the result of {@link Node#getHash} but derived
   * classes might overwrite this method with a different implementation.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The uniform hash.
   */
  getUniformHash(e) {
    return this.getHash(e);
  }
  onUpdate(e, t) {
    return e = e.bind(this), super.onUpdate((n) => {
      const r = e(n, this);
      r !== void 0 && (this.value = r);
    }, t);
  }
  getInputType(e) {
    let t = super.getInputType(e);
    return t === "bool" && (t = "uint"), t;
  }
  generate(e, t) {
    const n = this.getNodeType(e), r = this.getUniformHash(e);
    let s = e.getNodeFromHash(r);
    s === void 0 && (e.setHashNode(this, r), s = this);
    const a = s.getInputType(e), o = e.getUniformFromNode(s, a, e.shaderStage, this.name || e.context.nodeName), l = e.getPropertyName(o);
    e.context.nodeName !== void 0 && delete e.context.nodeName;
    let c = l;
    if (n === "bool") {
      const u = e.getDataFromNode(this);
      let h = u.propertyName;
      if (h === void 0) {
        const d = e.getVarFromNode(this, null, "bool");
        h = e.getPropertyName(d), u.propertyName = h, c = e.format(l, a, n), e.addLineFlowCode(`${h} = ${c}`, this);
      }
      c = h;
    }
    return e.format(c, n, t);
  }
}
const je = (i, e) => {
  const t = R2(e || i);
  if (t === i && (i = xg(t)), i && i.isNode === !0) {
    let n = i.value;
    i.traverse((r) => {
      r.isConstNode === !0 && (n = r.value);
    }), i = n;
  }
  return new lu(i, t);
};
class j0 extends xn {
  static get type() {
    return "ArrayNode";
  }
  /**
   * Constructs a new array node.
   *
   * @param {?string} nodeType - The data type of the elements.
   * @param {number} count - Size of the array.
   * @param {?Array<Node>} [values=null] - Array default values.
   */
  constructor(e, t, n = null) {
    super(e), this.count = t, this.values = n, this.isArrayNode = !0;
  }
  /**
   * Returns the number of elements in the node array.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {number} The number of elements in the node array.
   */
  getArrayCount() {
    return this.count;
  }
  /**
   * Returns the node's type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The type of the node.
   */
  getNodeType(e) {
    return this.nodeType === null ? this.values[0].getNodeType(e) : this.nodeType;
  }
  /**
   * Returns the node's type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The type of the node.
   */
  getElementType(e) {
    return this.getNodeType(e);
  }
  /**
   * Returns the type of a member variable.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The name of the member variable.
   * @return {string} The type of the member variable.
   */
  getMemberType(e, t) {
    return this.nodeType === null ? this.values[0].getMemberType(e, t) : super.getMemberType(e, t);
  }
  /**
   * This method builds the output node and returns the resulting array as a shader string.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated shader string.
   */
  generate(e) {
    const t = this.getNodeType(e);
    return e.generateArray(t, this.count, this.values);
  }
}
const k2 = (...i) => {
  let e;
  if (i.length === 1) {
    const t = i[0];
    e = new j0(null, t.length, t);
  } else {
    const t = i[0], n = i[1];
    e = new j0(t, n);
  }
  return Le(e);
};
Q("toArray", (i, e) => k2(Array(e).fill(i)));
class G2 extends xn {
  static get type() {
    return "AssignNode";
  }
  /**
   * Constructs a new assign node.
   *
   * @param {Node} targetNode - The target node.
   * @param {Node} sourceNode - The source type.
   */
  constructor(e, t) {
    super(), this.targetNode = e, this.sourceNode = t, this.isAssignNode = !0;
  }
  /**
   * Whether this node is used more than once in context of other nodes. This method
   * is overwritten since it always returns `false` (assigns are unique).
   *
   * @return {boolean} A flag that indicates if there is more than one dependency to other nodes. Always `false`.
   */
  hasDependencies() {
    return !1;
  }
  getNodeType(e, t) {
    return t !== "void" ? this.targetNode.getNodeType(e) : "void";
  }
  /**
   * Whether a split is required when assigning source to target. This can happen when the component length of
   * target and source data type does not match.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {boolean} Whether a split is required when assigning source to target.
   */
  needsSplitAssign(e) {
    const { targetNode: t } = this;
    if (e.isAvailable("swizzleAssign") === !1 && t.isSplitNode && t.components.length > 1) {
      const n = e.getTypeLength(t.node.getNodeType(e));
      return El.join("").slice(0, n) !== t.components;
    }
    return !1;
  }
  setup(e) {
    const { targetNode: t, sourceNode: n } = this, r = t.getScope(), s = e.getDataFromNode(r);
    s.assign = !0;
    const a = e.getNodeProperties(this);
    a.sourceNode = n, a.targetNode = t.context({ assign: !0 });
  }
  generate(e, t) {
    const { targetNode: n, sourceNode: r } = e.getNodeProperties(this), s = this.needsSplitAssign(e), a = n.build(e), o = n.getNodeType(e), l = r.build(e, o), c = r.getNodeType(e), u = e.getDataFromNode(this);
    let h;
    if (u.initialized === !0)
      t !== "void" && (h = a);
    else if (s) {
      const d = e.getVarFromNode(this, null, o), f = e.getPropertyName(d);
      e.addLineFlowCode(`${f} = ${l}`, this);
      const p = n.node, g = p.node.context({ assign: !0 }).build(e);
      for (let m = 0; m < p.components.length; m++) {
        const x = p.components[m];
        e.addLineFlowCode(`${g}.${x} = ${f}[ ${m} ]`, this);
      }
      t !== "void" && (h = a);
    } else
      h = `${a} = ${l}`, (t === "void" || c === "void") && (e.addLineFlowCode(h, this), t !== "void" && (h = a));
    return u.initialized = !0, e.format(h, o, t);
  }
}
const V2 = /* @__PURE__ */ Mt(G2).setParameterLength(2);
Q("assign", V2);
class z2 extends xn {
  static get type() {
    return "FunctionCallNode";
  }
  /**
   * Constructs a new function call node.
   *
   * @param {?FunctionNode} functionNode - The function node.
   * @param {Object<string, Node>} [parameters={}] - The parameters for the function call.
   */
  constructor(e = null, t = {}) {
    super(), this.functionNode = e, this.parameters = t;
  }
  /**
   * Sets the parameters of the function call node.
   *
   * @param {Object<string, Node>} parameters - The parameters to set.
   * @return {FunctionCallNode} A reference to this node.
   */
  setParameters(e) {
    return this.parameters = e, this;
  }
  /**
   * Returns the parameters of the function call node.
   *
   * @return {Object<string, Node>} The parameters of this node.
   */
  getParameters() {
    return this.parameters;
  }
  /**
   * Returns the type of this function call node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @returns {string} The type of this node.
   */
  getNodeType(e) {
    return this.functionNode.getNodeType(e);
  }
  /**
   * Returns the function node of this function call node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} [name] - The name of the member.
   * @returns {string} The type of the member.
   */
  getMemberType(e, t) {
    return this.functionNode.getMemberType(e, t);
  }
  generate(e) {
    const t = [], n = this.functionNode, r = n.getInputs(e), s = this.parameters, a = (l, c) => {
      const u = c.type, h = u === "pointer";
      let d;
      return h ? d = "&" + l.build(e) : d = l.build(e, u), d;
    };
    if (Array.isArray(s)) {
      if (s.length > r.length)
        le("TSL: The number of provided parameters exceeds the expected number of inputs in 'Fn()'."), s.length = r.length;
      else if (s.length < r.length)
        for (le("TSL: The number of provided parameters is less than the expected number of inputs in 'Fn()'."); s.length < r.length; )
          s.push(K(0));
      for (let l = 0; l < s.length; l++)
        t.push(a(s[l], r[l]));
    } else
      for (const l of r) {
        const c = s[l.name];
        c !== void 0 ? t.push(a(c, l)) : (le(`TSL: Input '${l.name}' not found in 'Fn()'.`), t.push(a(K(0), l)));
      }
    return `${n.build(e, "property")}( ${t.join(", ")} )`;
  }
}
const H2 = (i, ...e) => (e = e.length > 1 || e[0] && e[0].isNode === !0 ? Fo(e) : Tg(e[0]), new z2(Le(i), e));
Q("call", H2);
const $2 = {
  "==": "equal",
  "!=": "notEqual",
  "<": "lessThan",
  ">": "greaterThan",
  "<=": "lessThanEqual",
  ">=": "greaterThanEqual",
  "%": "mod"
};
class sn extends xn {
  static get type() {
    return "OperatorNode";
  }
  /**
   * Constructs a new operator node.
   *
   * @param {string} op - The operator.
   * @param {Node} aNode - The first input.
   * @param {Node} bNode - The second input.
   * @param {...Node} params - Additional input parameters.
   */
  constructor(e, t, n, ...r) {
    if (super(), r.length > 0) {
      let s = new sn(e, t, n);
      for (let a = 0; a < r.length - 1; a++)
        s = new sn(e, s, r[a]);
      t = s, n = r[r.length - 1];
    }
    this.op = e, this.aNode = t, this.bNode = n, this.isOperatorNode = !0;
  }
  /**
   * Returns the operator method name.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} output - The output type.
   * @returns {string} The operator method name.
   */
  getOperatorMethod(e, t) {
    return e.getMethod($2[this.op], t);
  }
  /**
   * This method is overwritten since the node type is inferred from the operator
   * and the input node types.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {?string} [output=null] - The output type.
   * @return {string} The node type.
   */
  getNodeType(e, t = null) {
    const n = this.op, r = this.aNode, s = this.bNode, a = r.getNodeType(e), o = s ? s.getNodeType(e) : null;
    if (a === "void" || o === "void")
      return t || "void";
    if (n === "%")
      return a;
    if (n === "~" || n === "&" || n === "|" || n === "^" || n === ">>" || n === "<<")
      return e.getIntegerType(a);
    if (n === "!" || n === "&&" || n === "||" || n === "^^")
      return "bool";
    if (n === "==" || n === "!=" || n === "<" || n === ">" || n === "<=" || n === ">=") {
      const l = Math.max(e.getTypeLength(a), e.getTypeLength(o));
      return l > 1 ? `bvec${l}` : "bool";
    } else {
      if (e.isMatrix(a)) {
        if (o === "float")
          return a;
        if (e.isVector(o))
          return e.getVectorFromMatrix(a);
        if (e.isMatrix(o))
          return a;
      } else if (e.isMatrix(o)) {
        if (a === "float")
          return o;
        if (e.isVector(a))
          return e.getVectorFromMatrix(o);
      }
      return e.getTypeLength(o) > e.getTypeLength(a) ? o : a;
    }
  }
  generate(e, t) {
    const n = this.op, { aNode: r, bNode: s } = this, a = this.getNodeType(e, t);
    let o = null, l = null;
    a !== "void" ? (o = r.getNodeType(e), l = s ? s.getNodeType(e) : null, n === "<" || n === ">" || n === "<=" || n === ">=" || n === "==" || n === "!=" ? e.isVector(o) ? l = o : e.isVector(l) ? o = l : o !== l && (o = l = "float") : n === ">>" || n === "<<" ? (o = a, l = e.changeComponentType(l, "uint")) : n === "%" ? (o = a, l = e.isInteger(o) && e.isInteger(l) ? l : o) : e.isMatrix(o) ? l === "float" ? l = "float" : e.isVector(l) ? l = e.getVectorFromMatrix(o) : e.isMatrix(l) || (o = l = a) : e.isMatrix(l) ? o === "float" ? o = "float" : e.isVector(o) ? o = e.getVectorFromMatrix(l) : o = l = a : o = l = a) : o = l = a;
    const c = r.build(e, o), u = s ? s.build(e, l) : null, h = e.getFunctionOperator(n);
    if (t !== "void") {
      const d = e.renderer.coordinateSystem === si;
      if (n === "==" || n === "!=" || n === "<" || n === ">" || n === "<=" || n === ">=")
        return d ? e.isVector(o) ? e.format(`${this.getOperatorMethod(e, t)}( ${c}, ${u} )`, a, t) : e.format(`( ${c} ${n} ${u} )`, a, t) : e.format(`( ${c} ${n} ${u} )`, a, t);
      if (n === "%")
        return e.isInteger(l) ? e.format(`( ${c} % ${u} )`, a, t) : e.format(`${this.getOperatorMethod(e, a)}( ${c}, ${u} )`, a, t);
      if (n === "!" || n === "~")
        return e.format(`(${n}${c})`, o, t);
      if (h)
        return e.format(`${h}( ${c}, ${u} )`, a, t);
      if (e.isMatrix(o) && l === "float")
        return e.format(`( ${u} ${n} ${c} )`, a, t);
      if (o === "float" && e.isMatrix(l))
        return e.format(`${c} ${n} ${u}`, a, t);
      {
        let f = `( ${c} ${n} ${u} )`;
        return !d && a === "bool" && e.isVector(o) && e.isVector(l) && (f = `all${f}`), e.format(f, a, t);
      }
    } else if (o !== "void")
      return h ? e.format(`${h}( ${c}, ${u} )`, a, t) : e.isMatrix(o) && l === "float" ? e.format(`${u} ${n} ${c}`, a, t) : e.format(`${c} ${n} ${u}`, a, t);
  }
  serialize(e) {
    super.serialize(e), e.op = this.op;
  }
  deserialize(e) {
    super.deserialize(e), this.op = e.op;
  }
}
const _i = /* @__PURE__ */ Ae(sn, "+").setParameterLength(2, 1 / 0).setName("add"), ui = /* @__PURE__ */ Ae(sn, "-").setParameterLength(2, 1 / 0).setName("sub"), at = /* @__PURE__ */ Ae(sn, "*").setParameterLength(2, 1 / 0).setName("mul"), Nr = /* @__PURE__ */ Ae(sn, "/").setParameterLength(2, 1 / 0).setName("div"), Rg = /* @__PURE__ */ Ae(sn, "%").setParameterLength(2).setName("mod"), W2 = /* @__PURE__ */ Ae(sn, "==").setParameterLength(2).setName("equal"), q2 = /* @__PURE__ */ Ae(sn, "!=").setParameterLength(2).setName("notEqual"), X2 = /* @__PURE__ */ Ae(sn, "<").setParameterLength(2).setName("lessThan"), j2 = /* @__PURE__ */ Ae(sn, ">").setParameterLength(2).setName("greaterThan"), Y2 = /* @__PURE__ */ Ae(sn, "<=").setParameterLength(2).setName("lessThanEqual"), K2 = /* @__PURE__ */ Ae(sn, ">=").setParameterLength(2).setName("greaterThanEqual"), Z2 = /* @__PURE__ */ Ae(sn, "&&").setParameterLength(2, 1 / 0).setName("and"), Q2 = /* @__PURE__ */ Ae(sn, "||").setParameterLength(2, 1 / 0).setName("or"), J2 = /* @__PURE__ */ Ae(sn, "!").setParameterLength(1).setName("not"), eF = /* @__PURE__ */ Ae(sn, "^^").setParameterLength(2).setName("xor"), tF = /* @__PURE__ */ Ae(sn, "&").setParameterLength(2).setName("bitAnd"), nF = /* @__PURE__ */ Ae(sn, "~").setParameterLength(1).setName("bitNot"), iF = /* @__PURE__ */ Ae(sn, "|").setParameterLength(2).setName("bitOr"), rF = /* @__PURE__ */ Ae(sn, "^").setParameterLength(2).setName("bitXor"), sF = /* @__PURE__ */ Ae(sn, "<<").setParameterLength(2).setName("shiftLeft"), aF = /* @__PURE__ */ Ae(sn, ">>").setParameterLength(2).setName("shiftRight"), oF = ee(([i]) => (i.addAssign(1), i)), lF = ee(([i]) => (i.subAssign(1), i)), cF = /* @__PURE__ */ ee(([i]) => {
  const e = Kt(i).toConst();
  return i.addAssign(1), e;
}), uF = /* @__PURE__ */ ee(([i]) => {
  const e = Kt(i).toConst();
  return i.subAssign(1), e;
});
Q("add", _i);
Q("sub", ui);
Q("mul", at);
Q("div", Nr);
Q("mod", Rg);
Q("equal", W2);
Q("notEqual", q2);
Q("lessThan", X2);
Q("greaterThan", j2);
Q("lessThanEqual", Y2);
Q("greaterThanEqual", K2);
Q("and", Z2);
Q("or", Q2);
Q("not", J2);
Q("xor", eF);
Q("bitAnd", tF);
Q("bitNot", nF);
Q("bitOr", iF);
Q("bitXor", rF);
Q("shiftLeft", sF);
Q("shiftRight", aF);
Q("incrementBefore", oF);
Q("decrementBefore", lF);
Q("increment", cF);
Q("decrement", uF);
const hF = (i, e) => (oe('TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.', new Yn()), Rg(Kt(i), Kt(e)));
Q("modInt", hF);
class $ extends xn {
  static get type() {
    return "MathNode";
  }
  /**
   * Constructs a new math node.
   *
   * @param {string} method - The method name.
   * @param {Node} aNode - The first input.
   * @param {?Node} [bNode=null] - The second input.
   * @param {?Node} [cNode=null] - The third input.
   */
  constructor(e, t, n = null, r = null) {
    if (super(), (e === $.MAX || e === $.MIN) && arguments.length > 3) {
      let s = new $(e, t, n);
      for (let a = 2; a < arguments.length - 1; a++)
        s = new $(e, s, arguments[a]);
      t = s, n = arguments[arguments.length - 1], r = null;
    }
    this.method = e, this.aNode = t, this.bNode = n, this.cNode = r, this.isMathNode = !0;
  }
  /**
   * The input type is inferred from the node types of the input nodes.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType(e) {
    const t = this.aNode.getNodeType(e), n = this.bNode ? this.bNode.getNodeType(e) : null, r = this.cNode ? this.cNode.getNodeType(e) : null, s = e.isMatrix(t) ? 0 : e.getTypeLength(t), a = e.isMatrix(n) ? 0 : e.getTypeLength(n), o = e.isMatrix(r) ? 0 : e.getTypeLength(r);
    return s > a && s > o ? t : a > o ? n : o > s ? r : t;
  }
  /**
   * The selected method as well as the input type determine the node type of this node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    const t = this.method;
    return t === $.LENGTH || t === $.DISTANCE || t === $.DOT ? "float" : t === $.CROSS ? "vec3" : t === $.ALL || t === $.ANY ? "bool" : t === $.EQUALS ? e.changeComponentType(this.aNode.getNodeType(e), "bool") : this.getInputType(e);
  }
  setup(e) {
    const { aNode: t, bNode: n, method: r } = this;
    let s = null;
    if (r === $.ONE_MINUS)
      s = ui(1, t);
    else if (r === $.RECIPROCAL)
      s = Nr(1, t);
    else if (r === $.DIFFERENCE)
      s = Ai(ui(t, n));
    else if (r === $.TRANSFORM_DIRECTION) {
      let a = t, o = n;
      e.isMatrix(a.getNodeType(e)) ? o = et(Y(o), 0) : a = et(Y(a), 0);
      const l = at(a, o).xyz;
      s = Ar(l);
    }
    return s !== null ? s : super.setup(e);
  }
  generate(e, t) {
    if (e.getNodeProperties(this).outputNode)
      return super.generate(e, t);
    let r = this.method;
    const s = this.getNodeType(e), a = this.getInputType(e), o = this.aNode, l = this.bNode, c = this.cNode, u = e.renderer.coordinateSystem;
    if (r === $.NEGATE)
      return e.format("( - " + o.build(e, a) + " )", s, t);
    {
      const h = [];
      return r === $.CROSS ? h.push(
        o.build(e, s),
        l.build(e, s)
      ) : u === si && r === $.STEP ? h.push(
        o.build(e, e.getTypeLength(o.getNodeType(e)) === 1 ? "float" : a),
        l.build(e, a)
      ) : u === si && (r === $.MIN || r === $.MAX) ? h.push(
        o.build(e, a),
        l.build(e, e.getTypeLength(l.getNodeType(e)) === 1 ? "float" : a)
      ) : r === $.REFRACT ? h.push(
        o.build(e, a),
        l.build(e, a),
        c.build(e, "float")
      ) : r === $.MIX ? h.push(
        o.build(e, a),
        l.build(e, a),
        c.build(e, e.getTypeLength(c.getNodeType(e)) === 1 ? "float" : a)
      ) : (u === Cr && r === $.ATAN && l !== null && (r = "atan2"), e.shaderStage !== "fragment" && (r === $.DFDX || r === $.DFDY) && (oe(`TSL: '${r}' is not supported in the ${e.shaderStage} stage.`, this.stackTrace), r = "/*" + r + "*/"), h.push(o.build(e, a)), l !== null && h.push(l.build(e, a)), c !== null && h.push(c.build(e, a))), e.format(`${e.getMethod(r, s)}( ${h.join(", ")} )`, s, t);
    }
  }
  serialize(e) {
    super.serialize(e), e.method = this.method;
  }
  deserialize(e) {
    super.deserialize(e), this.method = e.method;
  }
}
$.ALL = "all";
$.ANY = "any";
$.RADIANS = "radians";
$.DEGREES = "degrees";
$.EXP = "exp";
$.EXP2 = "exp2";
$.LOG = "log";
$.LOG2 = "log2";
$.SQRT = "sqrt";
$.INVERSE_SQRT = "inversesqrt";
$.FLOOR = "floor";
$.CEIL = "ceil";
$.NORMALIZE = "normalize";
$.FRACT = "fract";
$.SIN = "sin";
$.COS = "cos";
$.TAN = "tan";
$.ASIN = "asin";
$.ACOS = "acos";
$.ATAN = "atan";
$.ABS = "abs";
$.SIGN = "sign";
$.LENGTH = "length";
$.NEGATE = "negate";
$.ONE_MINUS = "oneMinus";
$.DFDX = "dFdx";
$.DFDY = "dFdy";
$.ROUND = "round";
$.RECIPROCAL = "reciprocal";
$.TRUNC = "trunc";
$.FWIDTH = "fwidth";
$.TRANSPOSE = "transpose";
$.DETERMINANT = "determinant";
$.INVERSE = "inverse";
$.EQUALS = "equals";
$.MIN = "min";
$.MAX = "max";
$.STEP = "step";
$.REFLECT = "reflect";
$.DISTANCE = "distance";
$.DIFFERENCE = "difference";
$.DOT = "dot";
$.CROSS = "cross";
$.POW = "pow";
$.TRANSFORM_DIRECTION = "transformDirection";
$.MIX = "mix";
$.CLAMP = "clamp";
$.REFRACT = "refract";
$.SMOOTHSTEP = "smoothstep";
$.FACEFORWARD = "faceforward";
const Bb = /* @__PURE__ */ K(1e-6), dF = /* @__PURE__ */ K(Math.PI), fF = /* @__PURE__ */ Ae($, $.ALL).setParameterLength(1), pF = /* @__PURE__ */ Ae($, $.ANY).setParameterLength(1), mF = /* @__PURE__ */ Ae($, $.RADIANS).setParameterLength(1), gF = /* @__PURE__ */ Ae($, $.DEGREES).setParameterLength(1), Ob = /* @__PURE__ */ Ae($, $.EXP).setParameterLength(1), Wc = /* @__PURE__ */ Ae($, $.EXP2).setParameterLength(1), kb = /* @__PURE__ */ Ae($, $.LOG).setParameterLength(1), ls = /* @__PURE__ */ Ae($, $.LOG2).setParameterLength(1), zs = /* @__PURE__ */ Ae($, $.SQRT).setParameterLength(1), _F = /* @__PURE__ */ Ae($, $.INVERSE_SQRT).setParameterLength(1), Ma = /* @__PURE__ */ Ae($, $.FLOOR).setParameterLength(1), Cg = /* @__PURE__ */ Ae($, $.CEIL).setParameterLength(1), Ar = /* @__PURE__ */ Ae($, $.NORMALIZE).setParameterLength(1), Pr = /* @__PURE__ */ Ae($, $.FRACT).setParameterLength(1), wi = /* @__PURE__ */ Ae($, $.SIN).setParameterLength(1), _r = /* @__PURE__ */ Ae($, $.COS).setParameterLength(1), xF = /* @__PURE__ */ Ae($, $.TAN).setParameterLength(1), vF = /* @__PURE__ */ Ae($, $.ASIN).setParameterLength(1), Gb = /* @__PURE__ */ Ae($, $.ACOS).setParameterLength(1), yF = /* @__PURE__ */ Ae($, $.ATAN).setParameterLength(1, 2), Ai = /* @__PURE__ */ Ae($, $.ABS).setParameterLength(1), Vb = /* @__PURE__ */ Ae($, $.SIGN).setParameterLength(1), cs = /* @__PURE__ */ Ae($, $.LENGTH).setParameterLength(1), zb = /* @__PURE__ */ Ae($, $.NEGATE).setParameterLength(1), bF = /* @__PURE__ */ Ae($, $.ONE_MINUS).setParameterLength(1), Hb = /* @__PURE__ */ Ae($, $.DFDX).setParameterLength(1), $b = /* @__PURE__ */ Ae($, $.DFDY).setParameterLength(1), SF = /* @__PURE__ */ Ae($, $.ROUND).setParameterLength(1), TF = /* @__PURE__ */ Ae($, $.RECIPROCAL).setParameterLength(1), MF = /* @__PURE__ */ Ae($, $.TRUNC).setParameterLength(1), Wb = /* @__PURE__ */ Ae($, $.FWIDTH).setParameterLength(1), EF = /* @__PURE__ */ Ae($, $.TRANSPOSE).setParameterLength(1), wF = /* @__PURE__ */ Ae($, $.DETERMINANT).setParameterLength(1), AF = /* @__PURE__ */ Ae($, $.INVERSE).setParameterLength(1), fl = /* @__PURE__ */ Ae($, $.MIN).setParameterLength(2, 1 / 0), kn = /* @__PURE__ */ Ae($, $.MAX).setParameterLength(2, 1 / 0), qc = /* @__PURE__ */ Ae($, $.STEP).setParameterLength(2), RF = /* @__PURE__ */ Ae($, $.REFLECT).setParameterLength(2), CF = /* @__PURE__ */ Ae($, $.DISTANCE).setParameterLength(2), NF = /* @__PURE__ */ Ae($, $.DIFFERENCE).setParameterLength(2), Oa = /* @__PURE__ */ Ae($, $.DOT).setParameterLength(2), ka = /* @__PURE__ */ Ae($, $.CROSS).setParameterLength(2), bd = /* @__PURE__ */ Ae($, $.POW).setParameterLength(2), qb = (i) => at(i, i), PF = (i) => at(i, i, i), Xb = (i) => at(i, i, i, i), DF = /* @__PURE__ */ Ae($, $.TRANSFORM_DIRECTION).setParameterLength(2), LF = (i) => at(Vb(i), bd(Ai(i), 1 / 3)), jb = (i) => Oa(i, i), Lt = /* @__PURE__ */ Ae($, $.MIX).setParameterLength(3), $s = (i, e = 0, t = 1) => new $($.CLAMP, Le(i), Le(e), Le(t)), Ng = (i) => $s(i), Yb = /* @__PURE__ */ Ae($, $.REFRACT).setParameterLength(3), hs = /* @__PURE__ */ Ae($, $.SMOOTHSTEP).setParameterLength(3), FF = /* @__PURE__ */ Ae($, $.FACEFORWARD).setParameterLength(3), IF = /* @__PURE__ */ ee(([i]) => {
  const n = 43758.5453, r = Oa(i.xy, Pe(12.9898, 78.233)), s = Rg(r, dF);
  return Pr(wi(s).mul(n));
}), UF = (i, e, t) => Lt(e, t, i), BF = (i, e, t) => hs(e, t, i), OF = (i, e) => qc(e, i);
Q("all", fF);
Q("any", pF);
Q("radians", mF);
Q("degrees", gF);
Q("exp", Ob);
Q("exp2", Wc);
Q("log", kb);
Q("log2", ls);
Q("sqrt", zs);
Q("inverseSqrt", _F);
Q("floor", Ma);
Q("ceil", Cg);
Q("normalize", Ar);
Q("fract", Pr);
Q("sin", wi);
Q("cos", _r);
Q("tan", xF);
Q("asin", vF);
Q("acos", Gb);
Q("atan", yF);
Q("abs", Ai);
Q("sign", Vb);
Q("length", cs);
Q("lengthSq", jb);
Q("negate", zb);
Q("oneMinus", bF);
Q("dFdx", Hb);
Q("dFdy", $b);
Q("round", SF);
Q("reciprocal", TF);
Q("trunc", MF);
Q("fwidth", Wb);
Q("min", fl);
Q("max", kn);
Q("step", OF);
Q("reflect", RF);
Q("distance", CF);
Q("dot", Oa);
Q("cross", ka);
Q("pow", bd);
Q("pow2", qb);
Q("pow3", PF);
Q("pow4", Xb);
Q("transformDirection", DF);
Q("mix", UF);
Q("clamp", $s);
Q("refract", Yb);
Q("smoothstep", BF);
Q("faceForward", FF);
Q("difference", NF);
Q("saturate", Ng);
Q("cbrt", LF);
Q("transpose", EF);
Q("determinant", wF);
Q("inverse", AF);
Q("rand", IF);
class kF extends Fe {
  static get type() {
    return "ConditionalNode";
  }
  /**
   * Constructs a new conditional node.
   *
   * @param {Node} condNode - The node that defines the condition.
   * @param {Node} ifNode - The node that is evaluate when the condition ends up `true`.
   * @param {?Node} [elseNode=null] - The node that is evaluate when the condition ends up `false`.
   */
  constructor(e, t, n = null) {
    super(), this.condNode = e, this.ifNode = t, this.elseNode = n;
  }
  /**
   * This method is overwritten since the node type is inferred from the if/else
   * nodes.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    const { ifNode: t, elseNode: n } = e.getNodeProperties(this);
    if (t === void 0)
      return e.flowBuildStage(this, "setup"), this.getNodeType(e);
    const r = t.getNodeType(e);
    if (n !== null) {
      const s = n.getNodeType(e);
      if (e.getTypeLength(s) > e.getTypeLength(r))
        return s;
    }
    return r;
  }
  setup(e) {
    const t = this.condNode, n = this.ifNode.isolate(), r = this.elseNode ? this.elseNode.isolate() : null, s = e.context.nodeBlock;
    e.getDataFromNode(n).parentNodeBlock = s, r !== null && (e.getDataFromNode(r).parentNodeBlock = s);
    const a = e.context.uniformFlow, o = e.getNodeProperties(this);
    o.condNode = t, o.ifNode = a ? n : n.context({ nodeBlock: n }), o.elseNode = r ? a ? r : r.context({ nodeBlock: r }) : null;
  }
  generate(e, t) {
    const n = this.getNodeType(e), r = e.getDataFromNode(this);
    if (r.nodeProperty !== void 0)
      return r.nodeProperty;
    const { condNode: s, ifNode: a, elseNode: o } = e.getNodeProperties(this), l = e.currentFunctionNode, c = t !== "void", u = c ? Vs(n).build(e) : "";
    r.nodeProperty = u;
    const h = s.build(e, "bool");
    if (e.context.uniformFlow && o !== null) {
      const p = a.build(e, n), _ = o.build(e, n), g = e.getTernary(h, p, _);
      return e.format(g, n, t);
    }
    e.addFlowCode(`
${e.tab}if ( ${h} ) {

`).addFlowTab();
    let f = a.build(e, n);
    if (f && (c ? f = u + " = " + f + ";" : (f = "return " + f + ";", l === null && (oe("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values.", this.stackTrace), f = "// " + f))), e.removeFlowTab().addFlowCode(e.tab + "	" + f + `

` + e.tab + "}"), o !== null) {
      e.addFlowCode(` else {

`).addFlowTab();
      let p = o.build(e, n);
      p && (c ? p = u + " = " + p + ";" : (p = "return " + p + ";", l === null && (oe("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values.", this.stackTrace), p = "// " + p))), e.removeFlowTab().addFlowCode(e.tab + "	" + p + `

` + e.tab + `}

`);
    } else
      e.addFlowCode(`

`);
    return e.format(u, n, t);
  }
}
const Ri = /* @__PURE__ */ Mt(kF).setParameterLength(2, 3);
Q("select", Ri);
class Kb extends Fe {
  static get type() {
    return "ContextNode";
  }
  /**
   * Constructs a new context node.
   *
   * @param {Node} node - The node whose context should be modified.
   * @param {Object} [value={}] - The modified context data.
   */
  constructor(e = null, t = {}) {
    super(), this.isContextNode = !0, this.node = e, this.value = t;
  }
  /**
   * This method is overwritten to ensure it returns the reference to {@link ContextNode#node}.
   *
   * @return {Node} A reference to {@link ContextNode#node}.
   */
  getScope() {
    return this.node.getScope();
  }
  /**
   * This method is overwritten to ensure it returns the type of {@link ContextNode#node}.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.node.getNodeType(e);
  }
  /**
   * Gathers the context data from all parent context nodes.
   *
   * @return {Object} The gathered context data.
   */
  getFlowContextData() {
    const e = [];
    return this.traverse((t) => {
      t.isContextNode === !0 && e.push(t.value);
    }), Object.assign({}, ...e);
  }
  /**
   * This method is overwritten to ensure it returns the member type of {@link ContextNode#node}.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The member name.
   * @returns {string} The member type.
   */
  getMemberType(e, t) {
    return this.node.getMemberType(e, t);
  }
  analyze(e) {
    const t = e.addContext(this.value);
    this.node.build(e), e.setContext(t);
  }
  setup(e) {
    const t = e.addContext(this.value);
    this.node.build(e), e.setContext(t);
  }
  generate(e, t) {
    const n = e.addContext(this.value), r = this.node.build(e, t);
    return e.setContext(n), r;
  }
}
const qa = (i = null, e = {}) => {
  let t = i;
  return (t === null || t.isNode !== !0) && (e = t || e, t = null), new Kb(t, e);
}, GF = (i) => qa(i, { uniformFlow: !0 }), Zb = (i, e) => qa(i, { nodeName: e });
function VF(i, e, t = null) {
  return qa(t, {
    getShadow: ({ light: n, shadowColorNode: r }) => e === n ? r.mul(i) : r
  });
}
function zF(i, e = null) {
  return qa(e, {
    getAO: (t, { material: n }) => n.transparent === !0 ? t : t !== null ? t.mul(i) : i
  });
}
function HF(i, e) {
  return oe('TSL: "label()" has been deprecated. Use "setName()" instead.'), Zb(i, e);
}
Q("context", qa);
Q("label", HF);
Q("uniformFlow", GF);
Q("setName", Zb);
Q("builtinShadowContext", (i, e, t) => VF(e, t, i));
Q("builtinAOContext", (i, e) => zF(e, i));
class Ah extends Fe {
  static get type() {
    return "VarNode";
  }
  /**
   * Constructs a new variable node.
   *
   * @param {Node} node - The node for which a variable should be created.
   * @param {?string} [name=null] - The name of the variable in the shader.
   * @param {boolean} [readOnly=false] - The read-only flag.
   */
  constructor(e, t = null, n = !1) {
    super(), this.node = e, this.name = t, this.global = !0, this.isVarNode = !0, this.readOnly = n, this.parents = !0, this.intent = !1;
  }
  /**
   * Sets the intent flag for this node.
   *
   * This flag is used to indicate that this node is used for intent
   * and should not be built directly. Instead, it is used to indicate that
   * the node should be treated as a variable intent.
   *
   * It's useful for assigning variables without needing creating a new variable node.
   *
   * @param {boolean} value - The value to set for the intent flag.
   * @returns {VarNode} This node.
   */
  setIntent(e) {
    return this.intent = e, this;
  }
  /**
   * Checks if this node is used for intent.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @returns {boolean} Whether this node is used for intent.
   */
  isIntent(e) {
    return e.getDataFromNode(this).forceDeclaration === !0 ? !1 : this.intent;
  }
  /**
   * Returns the intent flag of this node.
   *
   * @return {boolean} The intent flag.
   */
  getIntent() {
    return this.intent;
  }
  getMemberType(e, t) {
    return this.node.getMemberType(e, t);
  }
  getElementType(e) {
    return this.node.getElementType(e);
  }
  getNodeType(e) {
    return this.node.getNodeType(e);
  }
  getArrayCount(e) {
    return this.node.getArrayCount(e);
  }
  isAssign(e) {
    return e.getDataFromNode(this).assign;
  }
  build(...e) {
    const t = e[0];
    if (this._hasStack(t) === !1 && t.buildStage === "setup" && (t.context.nodeLoop || t.context.nodeBlock)) {
      let n = !1;
      if (this.node.isShaderCallNodeInternal && this.node.shaderNode.getLayout() === null && t.fnCall && t.fnCall.shaderNode && t.getDataFromNode(this.node.shaderNode).hasLoop) {
        const a = t.getDataFromNode(this);
        a.forceDeclaration = !0, n = !0;
      }
      const r = t.getBaseStack();
      n ? r.addToStackBefore(this) : r.addToStack(this);
    }
    return this.isIntent(t) && this.isAssign(t) !== !0 ? this.node.build(...e) : super.build(...e);
  }
  generate(e) {
    const { node: t, name: n, readOnly: r } = this, { renderer: s } = e, a = s.backend.isWebGPUBackend === !0;
    let o = !1, l = !1;
    r && (o = e.isDeterministic(t), l = a ? r : o);
    const c = this.getNodeType(e);
    if (c == "void")
      return this.isIntent(e) !== !0 && le('TSL: ".toVar()" can not be used with void type.', this.stackTrace), t.build(e);
    const u = e.getVectorType(c), h = t.build(e, u), d = e.getVarFromNode(this, n, u, void 0, l), f = e.getPropertyName(d);
    let p = f;
    if (l)
      if (a)
        p = o ? `const ${f}` : `let ${f}`;
      else {
        const _ = t.getArrayCount(e);
        p = `const ${e.getVar(d.type, f, _)}`;
      }
    return e.addLineFlowCode(`${p} = ${h}`, this), f;
  }
  _hasStack(e) {
    return e.getDataFromNode(this).stack !== void 0;
  }
}
const Pg = /* @__PURE__ */ Mt(Ah), $F = (i, e = null) => Pg(i, e).toStack(), WF = (i, e = null) => Pg(i, e, !0).toStack(), qF = (i) => Pg(i).setIntent(!0).toStack();
Q("toVar", $F);
Q("toConst", WF);
Q("toVarIntent", qF);
class XF extends Fe {
  static get type() {
    return "SubBuild";
  }
  constructor(e, t, n = null) {
    super(n), this.node = e, this.name = t, this.isSubBuildNode = !0;
  }
  getNodeType(e) {
    if (this.nodeType !== null)
      return this.nodeType;
    e.addSubBuild(this.name);
    const t = this.node.getNodeType(e);
    return e.removeSubBuild(), t;
  }
  build(e, ...t) {
    e.addSubBuild(this.name);
    const n = this.node.build(e, ...t);
    return e.removeSubBuild(), n;
  }
}
const Uo = (i, e, t = null) => new XF(Le(i), e, t);
class jF extends Fe {
  static get type() {
    return "VaryingNode";
  }
  /**
   * Constructs a new varying node.
   *
   * @param {Node} node - The node for which a varying should be created.
   * @param {?string} name - The name of the varying in the shader.
   */
  constructor(e, t = null) {
    super(), this.node = Uo(e, "VERTEX"), this.name = t, this.isVaryingNode = !0, this.interpolationType = null, this.interpolationSampling = null, this.global = !0;
  }
  /**
   * Defines the interpolation type of the varying.
   *
   * @param {string} type - The interpolation type.
   * @param {?string} sampling - The interpolation sampling type
   * @return {VaryingNode} A reference to this node.
   */
  setInterpolation(e, t = null) {
    return this.interpolationType = e, this.interpolationSampling = t, this;
  }
  getHash(e) {
    return this.name || super.getHash(e);
  }
  getNodeType(e) {
    return this.node.getNodeType(e);
  }
  /**
   * This method performs the setup of a varying node with the current node builder.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {NodeVarying} The node varying from the node builder.
   */
  setupVarying(e) {
    const t = e.getNodeProperties(this);
    let n = t.varying;
    if (n === void 0) {
      const r = this.name, s = this.getNodeType(e), a = this.interpolationType, o = this.interpolationSampling;
      t.varying = n = e.getVaryingFromNode(this, r, s, a, o), t.node = Uo(this.node, "VERTEX");
    }
    return n.needsInterpolation || (n.needsInterpolation = e.shaderStage === "fragment"), n;
  }
  setup(e) {
    this.setupVarying(e), e.flowNodeFromShaderStage($u.VERTEX, this.node);
  }
  analyze(e) {
    this.setupVarying(e), e.flowNodeFromShaderStage($u.VERTEX, this.node);
  }
  generate(e) {
    const t = e.getSubBuildProperty("property", e.currentStack), n = e.getNodeProperties(this), r = this.setupVarying(e);
    if (n[t] === void 0) {
      const s = this.getNodeType(e), a = e.getPropertyName(r, $u.VERTEX);
      e.flowNodeFromShaderStage($u.VERTEX, n.node, s, a), n[t] = a;
    }
    return e.getPropertyName(r);
  }
}
const Xa = /* @__PURE__ */ Mt(jF).setParameterLength(1, 2), YF = (i) => Xa(i);
Q("toVarying", Xa);
Q("toVertexStage", YF);
const KF = /* @__PURE__ */ ee(([i]) => {
  const e = i.mul(0.9478672986).add(0.0521327014).pow(2.4), t = i.mul(0.0773993808), n = i.lessThanEqual(0.04045);
  return Lt(e, t, n);
}).setLayout({
  name: "sRGBTransferEOTF",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" }
  ]
}), ZF = /* @__PURE__ */ ee(([i]) => {
  const e = i.pow(0.41666).mul(1.055).sub(0.055), t = i.mul(12.92), n = i.lessThanEqual(31308e-7);
  return Lt(e, t, n);
}).setLayout({
  name: "sRGBTransferOETF",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" }
  ]
}), Dg = "WorkingColorSpace", QF = "OutputColorSpace";
class Qb extends xn {
  static get type() {
    return "ColorSpaceNode";
  }
  /**
   * Constructs a new color space node.
   *
   * @param {Node} colorNode - Represents the color to convert.
   * @param {string} source - The source color space.
   * @param {string} target - The target color space.
   */
  constructor(e, t, n) {
    super("vec4"), this.colorNode = e, this.source = t, this.target = n;
  }
  /**
   * This method resolves the constants `WORKING_COLOR_SPACE` and
   * `OUTPUT_COLOR_SPACE` based on the current configuration of the
   * color management and renderer.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} colorSpace - The color space to resolve.
   * @return {string} The resolved color space.
   */
  resolveColorSpace(e, t) {
    return t === Dg ? Ke.workingColorSpace : t === QF ? e.context.outputColorSpace || e.renderer.outputColorSpace : t;
  }
  setup(e) {
    const { colorNode: t } = this, n = this.resolveColorSpace(e, this.source), r = this.resolveColorSpace(e, this.target);
    let s = t;
    return Ke.enabled === !1 || n === r || !n || !r || (Ke.getTransfer(n) === Te && (s = et(KF(s.rgb), s.a)), Ke.getPrimaries(n) !== Ke.getPrimaries(r) && (s = et(
      On(Ke._getMatrix(new nt(), n, r)).mul(s.rgb),
      s.a
    )), Ke.getTransfer(r) === Te && (s = et(ZF(s.rgb), s.a))), s;
  }
}
const JF = (i, e) => new Qb(Le(i), Dg, e), Lg = (i, e) => new Qb(Le(i), e, Dg);
Q("workingToColorSpace", JF);
Q("colorSpaceToWorking", Lg);
let eI = class extends wl {
  static get type() {
    return "ReferenceElementNode";
  }
  /**
   * Constructs a new reference element node.
   *
   * @param {ReferenceBaseNode} referenceNode - The reference node.
   * @param {Node} indexNode - The index node that defines the element access.
   */
  constructor(e, t) {
    super(e, t), this.referenceNode = e, this.isReferenceElementNode = !0;
  }
  /**
   * This method is overwritten since the node type is inferred from
   * the uniform type of the reference node.
   *
   * @return {string} The node type.
   */
  getNodeType() {
    return this.referenceNode.uniformType;
  }
  generate(e) {
    const t = super.generate(e), n = this.referenceNode.getNodeType(), r = this.getNodeType();
    return e.format(t, n, r);
  }
};
class Jb extends Fe {
  static get type() {
    return "ReferenceBaseNode";
  }
  /**
   * Constructs a new reference base node.
   *
   * @param {string} property - The name of the property the node refers to.
   * @param {string} uniformType - The uniform type that should be used to represent the property value.
   * @param {?Object} [object=null] - The object the property belongs to.
   * @param {?number} [count=null] - When the linked property is an array-like, this parameter defines its length.
   */
  constructor(e, t, n = null, r = null) {
    super(), this.property = e, this.uniformType = t, this.object = n, this.count = r, this.properties = e.split("."), this.reference = n, this.node = null, this.group = null, this.updateType = it.OBJECT;
  }
  /**
   * Sets the uniform group for this reference node.
   *
   * @param {UniformGroupNode} group - The uniform group to set.
   * @return {ReferenceBaseNode} A reference to this node.
   */
  setGroup(e) {
    return this.group = e, this;
  }
  /**
   * When the referred property is array-like, this method can be used
   * to access elements via an index node.
   *
   * @param {IndexNode} indexNode - indexNode.
   * @return {ReferenceElementNode} A reference to an element.
   */
  element(e) {
    return new eI(this, Le(e));
  }
  /**
   * Sets the node type which automatically defines the internal
   * uniform type.
   *
   * @param {string} uniformType - The type to set.
   */
  setNodeType(e) {
    const t = je(null, e);
    this.group !== null && t.setGroup(this.group), this.node = t;
  }
  /**
   * This method is overwritten since the node type is inferred from
   * the type of the reference node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.node === null && (this.updateReference(e), this.updateValue()), this.node.getNodeType(e);
  }
  /**
   * Returns the property value from the given referred object.
   *
   * @param {Object} [object=this.reference] - The object to retrieve the property value from.
   * @return {any} The value.
   */
  getValueFromReference(e = this.reference) {
    const { properties: t } = this;
    let n = e[t[0]];
    for (let r = 1; r < t.length; r++)
      n = n[t[r]];
    return n;
  }
  /**
   * Allows to update the reference based on the given state. The state is only
   * evaluated {@link ReferenceBaseNode#object} is not set.
   *
   * @param {(NodeFrame|NodeBuilder)} state - The current state.
   * @return {Object} The updated reference.
   */
  updateReference(e) {
    return this.reference = this.object !== null ? this.object : e.object, this.reference;
  }
  /**
   * The output of the reference node is the internal uniform node.
   *
   * @return {UniformNode} The output node.
   */
  setup() {
    return this.updateValue(), this.node;
  }
  /**
   * Overwritten to update the internal uniform value.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update() {
    this.updateValue();
  }
  /**
   * Retrieves the value from the referred object property and uses it
   * to updated the internal uniform.
   */
  updateValue() {
    this.node === null && this.setNodeType(this.uniformType);
    const e = this.getValueFromReference();
    Array.isArray(e) ? this.node.array = e : this.node.value = e;
  }
}
const tI = (i, e, t) => new Jb(i, e, t);
class nI extends Jb {
  static get type() {
    return "RendererReferenceNode";
  }
  /**
   * Constructs a new renderer reference node.
   *
   * @param {string} property - The name of the property the node refers to.
   * @param {string} inputType - The uniform type that should be used to represent the property value.
   * @param {?Renderer} [renderer=null] - The renderer the property belongs to. When no renderer is set,
   * the node refers to the renderer of the current state.
   */
  constructor(e, t, n = null) {
    super(e, t, n), this.renderer = n, this.setGroup(Xe);
  }
  /**
   * Updates the reference based on the given state. The state is only evaluated
   * {@link RendererReferenceNode#renderer} is not set.
   *
   * @param {(NodeFrame|NodeBuilder)} state - The current state.
   * @return {Object} The updated reference.
   */
  updateReference(e) {
    return this.reference = this.renderer !== null ? this.renderer : e.renderer, this.reference;
  }
}
const iI = (i, e, t = null) => new nI(i, e, t);
class rI extends xn {
  static get type() {
    return "ToneMappingNode";
  }
  /**
   * Constructs a new tone mapping node.
   *
   * @param {number} toneMapping - The tone mapping type.
   * @param {Node} exposureNode - The tone mapping exposure.
   * @param {Node} [colorNode=null] - The color node to process.
   */
  constructor(e, t = aI, n = null) {
    super("vec3"), this._toneMapping = e, this.exposureNode = t, this.colorNode = n;
  }
  /**
   * Overwrites the default `customCacheKey()` implementation by including the tone
   * mapping type into the cache key.
   *
   * @return {number} The hash.
   */
  customCacheKey() {
    return xc(this._toneMapping);
  }
  /**
   * Sets the tone mapping type.
   *
   * @param {number} value - The tone mapping type.
   * @return {ToneMappingNode} A reference to this node.
   */
  setToneMapping(e) {
    return this._toneMapping = e, this;
  }
  /**
   * Gets the tone mapping type.
   *
   * @returns {number} The tone mapping type.
   */
  getToneMapping() {
    return this._toneMapping;
  }
  setup(e) {
    const t = this.colorNode || e.context.color, n = this._toneMapping;
    if (n === In)
      return t;
    let r = null;
    const s = e.renderer.library.getToneMappingFunction(n);
    return s !== null ? r = et(s(t.rgb, this.exposureNode), t.a) : (le("ToneMappingNode: Unsupported Tone Mapping configuration.", n), r = t), r;
  }
}
const sI = (i, e, t) => new rI(i, Le(e), Le(t)), aI = /* @__PURE__ */ iI("toneMappingExposure", "float");
Q("toneMapping", (i, e, t) => sI(e, t, i));
const Y0 = /* @__PURE__ */ new WeakMap();
function K0(i, e) {
  let t = Y0.get(i);
  return t === void 0 && (t = new ty(i, e), Y0.set(i, t)), t;
}
class Ts extends vg {
  static get type() {
    return "BufferAttributeNode";
  }
  /**
   * Constructs a new buffer attribute node.
   *
   * @param {BufferAttribute|InterleavedBuffer|TypedArray} value - The attribute data.
   * @param {?string} [bufferType=null] - The buffer type (e.g. `'vec3'`).
   * @param {number} [bufferStride=0] - The buffer stride.
   * @param {number} [bufferOffset=0] - The buffer offset.
   */
  constructor(e, t = null, n = 0, r = 0) {
    super(e, t), this.isBufferNode = !0, this.bufferType = t, this.bufferStride = n, this.bufferOffset = r, this.usage = cl, this.instanced = !1, this.attribute = null, this.global = !0, e && e.isBufferAttribute === !0 && e.itemSize <= 4 && (this.attribute = e, this.usage = e.usage, this.instanced = e.isInstancedBufferAttribute);
  }
  /**
   * This method is overwritten since the attribute data might be shared
   * and thus the hash should be shared as well.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The hash.
   */
  getHash(e) {
    if (this.bufferStride === 0 && this.bufferOffset === 0) {
      let t = e.globalCache.getData(this.value);
      return t === void 0 && (t = {
        node: this
      }, e.globalCache.setData(this.value, t)), t.node.uuid;
    }
    return this.uuid;
  }
  /**
   * This method is overwritten since the node type is inferred from
   * the buffer attribute.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.bufferType === null && (this.bufferType = e.getTypeFromAttribute(this.attribute)), this.bufferType;
  }
  /**
   * Depending on which value was passed to the node, `setup()` behaves
   * differently. If no instance of `BufferAttribute` was passed, the method
   * creates an internal attribute and configures it respectively.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    if (this.attribute !== null)
      return;
    const t = this.getNodeType(e), n = e.getTypeLength(t), r = this.value, s = this.bufferStride || n, a = this.bufferOffset;
    let o;
    r.isInterleavedBuffer === !0 ? o = r : r.isBufferAttribute === !0 ? o = K0(r.array, s) : o = K0(r, s);
    const l = new Km(o, n, a);
    o.setUsage(this.usage), this.attribute = l, this.attribute.isInstancedBufferAttribute = this.instanced;
  }
  /**
   * Generates the code snippet of the buffer attribute node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated code snippet.
   */
  generate(e) {
    const t = this.getNodeType(e), n = e.getBufferAttributeFromNode(this, t), r = e.getPropertyName(n);
    let s = null;
    return e.shaderStage === "vertex" || e.shaderStage === "compute" ? (this.name = r, s = r) : s = Xa(this).build(e, t), s;
  }
  /**
   * Overwrites the default implementation to return a fixed value `'bufferAttribute'`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return "bufferAttribute";
  }
  /**
   * Sets the `usage` property to the given value.
   *
   * @param {number} value - The usage to set.
   * @return {BufferAttributeNode} A reference to this node.
   */
  setUsage(e) {
    return this.usage = e, this.attribute && this.attribute.isBufferAttribute === !0 && (this.attribute.usage = e), this;
  }
  /**
   * Sets the `instanced` property to the given value.
   *
   * @param {boolean} value - The value to set.
   * @return {BufferAttributeNode} A reference to this node.
   */
  setInstanced(e) {
    return this.instanced = e, this;
  }
}
function Fg(i, e = null, t = 0, n = 0, r = cl, s = !1) {
  return e === "mat3" || e === null && i.itemSize === 9 ? On(
    new Ts(i, "vec3", 9, 0).setUsage(r).setInstanced(s),
    new Ts(i, "vec3", 9, 3).setUsage(r).setInstanced(s),
    new Ts(i, "vec3", 9, 6).setUsage(r).setInstanced(s)
  ) : e === "mat4" || e === null && i.itemSize === 16 ? Ta(
    new Ts(i, "vec4", 16, 0).setUsage(r).setInstanced(s),
    new Ts(i, "vec4", 16, 4).setUsage(r).setInstanced(s),
    new Ts(i, "vec4", 16, 8).setUsage(r).setInstanced(s),
    new Ts(i, "vec4", 16, 12).setUsage(r).setInstanced(s)
  ) : new Ts(i, e, t, n).setUsage(r);
}
const eS = (i, e = null, t = 0, n = 0) => Fg(i, e, t, n), Z0 = (i, e = null, t = 0, n = 0) => Fg(i, e, t, n, cl, !0), Q0 = (i, e = null, t = 0, n = 0) => Fg(i, e, t, n, Dh, !0);
Q("toAttribute", (i) => eS(i.value));
class oI extends Fe {
  static get type() {
    return "ComputeNode";
  }
  /**
   * Constructs a new compute node.
   *
   * @param {Node} computeNode - TODO
   * @param {Array<number>} workgroupSize - TODO.
   */
  constructor(e, t) {
    super("void"), this.isComputeNode = !0, this.computeNode = e, this.workgroupSize = t, this.count = null, this.version = 1, this.name = "", this.updateBeforeType = it.OBJECT, this.onInitFunction = null;
  }
  /**
   * TODO
   *
   * @param {number|Array<number>} count - Array with [ x, y, z ] values for dispatch or a single number for the count
   * @return {ComputeNode}
   */
  setCount(e) {
    return this.count = e, this;
  }
  /**
   * TODO
   *
   * @return {number|Array<number>}
   */
  getCount() {
    return this.count;
  }
  /**
   * Executes the `dispose` event for this node.
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
  /**
   * Sets the {@link ComputeNode#name} property.
   *
   * @param {string} name - The name of the uniform.
   * @return {ComputeNode} A reference to this node.
   */
  setName(e) {
    return this.name = e, this;
  }
  /**
   * Sets the {@link ComputeNode#name} property.
   *
   * @deprecated
   * @param {string} name - The name of the uniform.
   * @return {ComputeNode} A reference to this node.
   */
  label(e) {
    return oe('TSL: "label()" has been deprecated. Use "setName()" instead.', new Yn()), this.setName(e);
  }
  /**
   * TODO
   *
   * @param {Function} callback - TODO.
   * @return {ComputeNode} A reference to this node.
   */
  onInit(e) {
    return this.onInitFunction = e, this;
  }
  /**
   * The method execute the compute for this node.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  updateBefore({ renderer: e }) {
    e.compute(this);
  }
  setup(e) {
    const t = this.computeNode.build(e);
    if (t) {
      const n = e.getNodeProperties(this);
      n.outputComputeNode = t.outputNode, t.outputNode = null;
    }
    return t;
  }
  generate(e, t) {
    const { shaderStage: n } = e;
    if (n === "compute") {
      const r = this.computeNode.build(e, "void");
      r !== "" && e.addLineFlowCode(r, this);
    } else {
      const s = e.getNodeProperties(this).outputComputeNode;
      if (s)
        return s.build(e, t);
    }
  }
}
const tS = (i, e = [64]) => {
  (e.length === 0 || e.length > 3) && le("TSL: compute() workgroupSize must have 1, 2, or 3 elements", new Yn());
  for (let t = 0; t < e.length; t++) {
    const n = e[t];
    (typeof n != "number" || n <= 0 || !Number.isInteger(n)) && le(`TSL: compute() workgroupSize element at index [ ${t} ] must be a positive integer`, new Yn());
  }
  for (; e.length < 3; )
    e.push(1);
  return new oI(Le(i), e);
}, lI = (i, e, t) => tS(i, t).setCount(e);
Q("compute", lI);
Q("computeKernel", tS);
class cI extends Fe {
  static get type() {
    return "IsolateNode";
  }
  /**
   * Constructs a new cache node.
   *
   * @param {Node} node - The node that should be cached.
   * @param {boolean} [parent=true] - Whether this node refers to a shared parent cache or not.
   */
  constructor(e, t = !0) {
    super(), this.node = e, this.parent = t, this.isIsolateNode = !0;
  }
  getNodeType(e) {
    const t = e.getCache(), n = e.getCacheFromNode(this, this.parent);
    e.setCache(n);
    const r = this.node.getNodeType(e);
    return e.setCache(t), r;
  }
  build(e, ...t) {
    const n = e.getCache(), r = e.getCacheFromNode(this, this.parent);
    e.setCache(r);
    const s = this.node.build(e, ...t);
    return e.setCache(n), s;
  }
  setParent(e) {
    return this.parent = e, this;
  }
  getParent() {
    return this.parent;
  }
}
const Sc = (i) => new cI(Le(i));
function uI(i, e = !0) {
  return oe('TSL: "cache()" has been deprecated. Use "isolate()" instead.'), Sc(i).setParent(e);
}
Q("cache", uI);
Q("isolate", Sc);
class hI extends Fe {
  static get type() {
    return "BypassNode";
  }
  /**
   * Constructs a new bypass node.
   *
   * @param {Node} outputNode - The output node.
   * @param {Node} callNode - The call node.
   */
  constructor(e, t) {
    super(), this.isBypassNode = !0, this.outputNode = e, this.callNode = t;
  }
  getNodeType(e) {
    return this.outputNode.getNodeType(e);
  }
  generate(e) {
    const t = this.callNode.build(e, "void");
    return t !== "" && e.addLineFlowCode(t, this), this.outputNode.build(e);
  }
}
const dI = /* @__PURE__ */ Mt(hI).setParameterLength(2);
Q("bypass", dI);
class nS extends Fe {
  static get type() {
    return "RemapNode";
  }
  /**
   * Constructs a new remap node.
   *
   * @param {Node} node - The node that should be remapped.
   * @param {Node} inLowNode - The source or current lower bound of the range.
   * @param {Node} inHighNode - The source or current upper bound of the range.
   * @param {Node} [outLowNode=float(0)] - The target lower bound of the range.
   * @param {Node} [outHighNode=float(1)] - The target upper bound of the range.
   */
  constructor(e, t, n, r = K(0), s = K(1)) {
    super(), this.node = e, this.inLowNode = t, this.inHighNode = n, this.outLowNode = r, this.outHighNode = s, this.doClamp = !0;
  }
  setup() {
    const { node: e, inLowNode: t, inHighNode: n, outLowNode: r, outHighNode: s, doClamp: a } = this;
    let o = e.sub(t).div(n.sub(t));
    return a === !0 && (o = o.clamp()), o.mul(s.sub(r)).add(r);
  }
}
const fI = /* @__PURE__ */ Mt(nS, null, null, { doClamp: !1 }).setParameterLength(3, 5), pI = /* @__PURE__ */ Mt(nS).setParameterLength(3, 5);
Q("remap", fI);
Q("remapClamp", pI);
class Rh extends Fe {
  static get type() {
    return "ExpressionNode";
  }
  /**
   * Constructs a new expression node.
   *
   * @param {string} [snippet=''] - The native code snippet.
   * @param {string} [nodeType='void'] - The node type.
   */
  constructor(e = "", t = "void") {
    super(t), this.snippet = e;
  }
  generate(e, t) {
    const n = this.getNodeType(e), r = this.snippet;
    if (n === "void")
      e.addLineFlowCode(r, this);
    else
      return e.format(r, n, t);
  }
}
const vr = /* @__PURE__ */ Mt(Rh).setParameterLength(1, 2), mI = (i) => (i ? Ri(i, vr("discard")) : vr("discard")).toStack();
Q("discard", mI);
class gI extends xn {
  static get type() {
    return "RenderOutputNode";
  }
  /**
   * Constructs a new render output node.
   *
   * @param {Node} colorNode - The color node to process.
   * @param {?number} toneMapping - The tone mapping type.
   * @param {?string} outputColorSpace - The output color space.
   */
  constructor(e, t, n) {
    super("vec4"), this.colorNode = e, this._toneMapping = t, this.outputColorSpace = n, this.isRenderOutputNode = !0;
  }
  /**
   * Sets the tone mapping type.
   *
   * @param {number} value - The tone mapping type.
   * @return {ToneMappingNode} A reference to this node.
   */
  setToneMapping(e) {
    return this._toneMapping = e, this;
  }
  /**
   * Gets the tone mapping type.
   *
   * @returns {number} The tone mapping type.
   */
  getToneMapping() {
    return this._toneMapping;
  }
  setup({ context: e }) {
    let t = this.colorNode || e.color;
    const n = (this._toneMapping !== null ? this._toneMapping : e.toneMapping) || In, r = (this.outputColorSpace !== null ? this.outputColorSpace : e.outputColorSpace) || hi;
    return n !== In && (t = t.toneMapping(n)), r !== hi && r !== Ke.workingColorSpace && (t = t.workingToColorSpace(r)), t;
  }
}
const _I = (i, e = null, t = null) => new gI(Le(i), e, t);
Q("renderOutput", _I);
class xI extends xn {
  static get type() {
    return "DebugNode";
  }
  constructor(e, t = null) {
    super(), this.node = e, this.callback = t;
  }
  getNodeType(e) {
    return this.node.getNodeType(e);
  }
  setup(e) {
    return this.node.build(e);
  }
  analyze(e) {
    return this.node.build(e);
  }
  generate(e) {
    const t = this.callback, n = this.node.build(e);
    if (t !== null)
      t(e, n);
    else {
      const r = "--- TSL debug - " + e.shaderStage + " shader ---", s = "-".repeat(r.length);
      let a = "";
      a += "// #" + r + `#
`, a += e.flow.code.replace(/^\t/mg, "") + `
`, a += "/* ... */ " + n + ` /* ... */
`, a += "// #" + s + `#
`, Hc(a);
    }
    return n;
  }
}
const vI = (i, e = null) => new xI(Le(i), e).toStack();
Q("debug", vI);
class iS {
  /**
   * Creates a new InspectorBase.
   */
  constructor() {
    this._renderer = null, this.currentFrame = null;
  }
  /**
   * Returns the node frame for the current renderer.
   *
   * @return {Object} The node frame.
   */
  get nodeFrame() {
    return this._renderer._nodes.nodeFrame;
  }
  /**
   * Sets the renderer for this inspector.
   *
   * @param {WebGLRenderer} renderer - The renderer to associate with this inspector.
   * @return {InspectorBase} This inspector instance.
   */
  setRenderer(e) {
    return this._renderer = e, this;
  }
  /**
   * Returns the renderer associated with this inspector.
   *
   * @return {WebGLRenderer} The associated renderer.
   */
  getRenderer() {
    return this._renderer;
  }
  /**
   * Initializes the inspector.
   */
  init() {
  }
  /**
   * Called when a frame begins.
   */
  begin() {
  }
  /**
   * Called when a frame ends.
   */
  finish() {
  }
  /**
   * Inspects a node.
   *
   * @param {Node} node - The node to inspect.
   */
  inspect() {
  }
  /**
   * When a compute operation is performed.
   *
   * @param {ComputeNode} computeNode - The compute node being executed.
   * @param {number|Array<number>} dispatchSizeOrCount - The dispatch size or count.
   */
  computeAsync() {
  }
  /**
   * Called when a compute operation begins.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @param {ComputeNode} computeNode - The compute node being executed.
   */
  beginCompute() {
  }
  /**
   * Called when a compute operation ends.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @param {ComputeNode} computeNode - The compute node being executed.
   */
  finishCompute() {
  }
  /**
   * Called when a render operation begins.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @param {Scene} scene - The scene being rendered.
   * @param {Camera} camera - The camera being used for rendering.
   * @param {?WebGLRenderTarget} renderTarget - The render target, if any.
   */
  beginRender() {
  }
  /**
   * Called when an animation loop ends.
   *
   * @param {string} uid - A unique identifier for the render context.
   */
  finishRender() {
  }
  /**
   * Called when a texture copy operation is performed.
   *
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   */
  copyTextureToTexture() {
  }
  /**
   * Called when a framebuffer copy operation is performed.
   *
   * @param {Texture} framebufferTexture - The texture associated with the framebuffer.
   */
  copyFramebufferToTexture() {
  }
}
class yI extends Fe {
  /**
   * Returns the type of the node.
   *
   * @returns {string}
   */
  static get type() {
    return "InspectorNode";
  }
  /**
   * Creates an InspectorNode.
   *
   * @param {Node} node - The node to inspect.
   * @param {string} [name=''] - Optional name for the inspector node.
   * @param {Function|null} [callback=null] - Optional callback to modify the node during setup.
   */
  constructor(e, t = "", n = null) {
    super(), this.node = e, this.name = t, this.callback = n, this.updateType = it.FRAME, this.isInspectorNode = !0;
  }
  /**
   * Returns the name of the inspector node.
   *
   * @returns {string}
   */
  getName() {
    return this.name || this.node.name;
  }
  /**
   * Updates the inspector node, allowing inspection of the wrapped node.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    e.renderer.inspector.inspect(this);
  }
  /**
   * Returns the type of the wrapped node.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @returns {string}
   */
  getNodeType(e) {
    return this.node.getNodeType(e);
  }
  /**
   * Sets up the inspector node.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @returns {Node} The setup node.
   */
  setup(e) {
    let t = this.node;
    return e.context.inspector === !0 && this.callback !== null && (t = this.callback(t)), e.renderer.backend.isWebGPUBackend !== !0 && e.renderer.inspector.constructor !== iS && Pt('TSL: ".toInspector()" is only available with WebGPU.'), t;
  }
}
function bI(i, e = "", t = null) {
  return i = Le(i), i.before(new yI(i, e, t));
}
Q("toInspector", bI);
class rS extends Fe {
  static get type() {
    return "AttributeNode";
  }
  /**
   * Constructs a new attribute node.
   *
   * @param {string} attributeName - The name of the attribute.
   * @param {?string} nodeType - The node type.
   */
  constructor(e, t = null) {
    super(t), this.global = !0, this._attributeName = e;
  }
  getHash(e) {
    return this.getAttributeName(e);
  }
  getNodeType(e) {
    let t = this.nodeType;
    if (t === null) {
      const n = this.getAttributeName(e);
      if (e.hasGeometryAttribute(n)) {
        const r = e.geometry.getAttribute(n);
        t = e.getTypeFromAttribute(r);
      } else
        t = "float";
    }
    return t;
  }
  /**
   * Sets the attribute name to the given value. The method can be
   * overwritten in derived classes if the final name must be computed
   * analytically.
   *
   * @param {string} attributeName - The name of the attribute.
   * @return {AttributeNode} A reference to this node.
   */
  setAttributeName(e) {
    return this._attributeName = e, this;
  }
  /**
   * Returns the attribute name of this node. The method can be
   * overwritten in derived classes if the final name must be computed
   * analytically.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The attribute name.
   */
  getAttributeName() {
    return this._attributeName;
  }
  generate(e) {
    const t = this.getAttributeName(e), n = this.getNodeType(e);
    if (e.hasGeometryAttribute(t) === !0) {
      const s = e.geometry.getAttribute(t), a = e.getTypeFromAttribute(s), o = e.getAttribute(t, a);
      return e.shaderStage === "vertex" ? e.format(o.name, a, n) : Xa(this).build(e, n);
    } else
      return oe(`AttributeNode: Vertex attribute "${t}" not found on geometry.`), e.generateConst(n);
  }
  serialize(e) {
    super.serialize(e), e.global = this.global, e._attributeName = this._attributeName;
  }
  deserialize(e) {
    super.deserialize(e), this.global = e.global, this._attributeName = e._attributeName;
  }
}
const Ws = (i, e = null) => new rS(i, e), Al = (i = 0) => Ws("uv" + (i > 0 ? i : ""), "vec2");
class SI extends Fe {
  static get type() {
    return "TextureSizeNode";
  }
  /**
   * Constructs a new texture size node.
   *
   * @param {TextureNode} textureNode - A texture node which size should be retrieved.
   * @param {?Node<int>} [levelNode=null] - A level node which defines the requested mip.
   */
  constructor(e, t = null) {
    super("uvec2"), this.isTextureSizeNode = !0, this.textureNode = e, this.levelNode = t;
  }
  generate(e, t) {
    const n = this.textureNode.build(e, "property"), r = this.levelNode === null ? "0" : this.levelNode.build(e, "int");
    return e.format(`${e.getMethod("textureDimensions")}( ${n}, ${r} )`, this.getNodeType(e), t);
  }
}
const Bo = /* @__PURE__ */ Mt(SI).setParameterLength(1, 2);
class TI extends lu {
  static get type() {
    return "MaxMipLevelNode";
  }
  /**
   * Constructs a new max mip level node.
   *
   * @param {TextureNode} textureNode - The texture node to compute the max mip level for.
   */
  constructor(e) {
    super(0), this._textureNode = e, this.updateType = it.FRAME;
  }
  /**
   * The texture node to compute the max mip level for.
   *
   * @readonly
   * @type {TextureNode}
   */
  get textureNode() {
    return this._textureNode;
  }
  /**
   * The texture.
   *
   * @readonly
   * @type {Texture}
   */
  get texture() {
    return this._textureNode.value;
  }
  update() {
    const e = this.texture, t = e.images, n = t && t.length > 0 ? t[0] && t[0].image || t[0] : e.image;
    if (n && n.width !== void 0) {
      const { width: r, height: s } = n;
      this.value = Math.log2(Math.max(r, s));
    }
  }
}
const MI = /* @__PURE__ */ Mt(TI).setParameterLength(1);
class EI extends Error {
  constructor(e, t = null) {
    super(e), this.name = "NodeError", this.stackTrace = t;
  }
}
const sS = /* @__PURE__ */ new mn();
class Rl extends lu {
  static get type() {
    return "TextureNode";
  }
  /**
   * Constructs a new texture node.
   *
   * @param {Texture} [value=EmptyTexture] - The texture.
   * @param {?Node<vec2|vec3>} [uvNode=null] - The uv node.
   * @param {?Node<int>} [levelNode=null] - The level node.
   * @param {?Node<float>} [biasNode=null] - The bias node.
   */
  constructor(e = sS, t = null, n = null, r = null) {
    super(e), this.isTextureNode = !0, this.uvNode = t, this.levelNode = n, this.biasNode = r, this.compareNode = null, this.depthNode = null, this.gradNode = null, this.offsetNode = null, this.sampler = !0, this.updateMatrix = !1, this.updateType = it.NONE, this.referenceNode = null, this._value = e, this._matrixUniform = null, this._flipYUniform = null, this.setUpdateMatrix(t === null);
  }
  set value(e) {
    this.referenceNode ? this.referenceNode.value = e : this._value = e;
  }
  /**
   * The texture value.
   *
   * @type {Texture}
   */
  get value() {
    return this.referenceNode ? this.referenceNode.value : this._value;
  }
  /**
   * Overwritten since the uniform hash is defined by the texture's UUID.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The uniform hash.
   */
  getUniformHash() {
    return this.value.uuid;
  }
  /**
   * Overwritten since the node type is inferred from the texture type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType() {
    return this.value.isDepthTexture === !0 ? "float" : this.value.type === Dt ? "uvec4" : this.value.type === wn ? "ivec4" : "vec4";
  }
  /**
   * Overwrites the default implementation to return a fixed value `'texture'`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return "texture";
  }
  /**
   * Returns a default uvs based on the current texture's channel.
   *
   * @return {AttributeNode<vec2>} The default uvs.
   */
  getDefaultUV() {
    return Al(this.value.channel);
  }
  /**
   * Overwritten to always return the texture reference of the node.
   *
   * @param {any} state - This method can be invocated in different contexts so `state` can refer to any object type.
   * @return {Texture} The texture reference.
   */
  updateReference() {
    return this.value;
  }
  /**
   * Transforms the given uv node with the texture transformation matrix.
   *
   * @param {Node} uvNode - The uv node to transform.
   * @return {Node} The transformed uv node.
   */
  getTransformedUV(e) {
    return this._matrixUniform === null && (this._matrixUniform = je(this.value.matrix)), this._matrixUniform.mul(Y(e, 1)).xy;
  }
  /**
   * Defines whether the uv transformation matrix should automatically be updated or not.
   *
   * @param {boolean} value - The update toggle.
   * @return {TextureNode} A reference to this node.
   */
  setUpdateMatrix(e) {
    return this.updateMatrix = e, this;
  }
  /**
   * Setups the uv node. Depending on the backend as well as texture's image and type, it might be necessary
   * to modify the uv node for correct sampling.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} uvNode - The uv node to setup.
   * @return {Node} The updated uv node.
   */
  setupUV(e, t) {
    return e.isFlipY() && (this._flipYUniform === null && (this._flipYUniform = je(!1)), t = t.toVar(), this.sampler ? t = this._flipYUniform.select(t.flipY(), t) : t = this._flipYUniform.select(t.setY(Kt(Bo(this, this.levelNode).y).sub(t.y).sub(1)), t)), t;
  }
  /**
   * Setups texture node by preparing the internal nodes for code generation.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    const t = e.getNodeProperties(this);
    t.referenceNode = this.referenceNode;
    const n = this.value;
    if (!n || n.isTexture !== !0)
      throw new EI("THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().", this.stackTrace);
    const r = ee(() => {
      let l = this.uvNode;
      return (l === null || e.context.forceUVContext === !0) && e.context.getUV && (l = e.context.getUV(this, e)), l || (l = this.getDefaultUV()), this.updateMatrix === !0 && (l = this.getTransformedUV(l)), l = this.setupUV(e, l), this.updateType = this._matrixUniform !== null || this._flipYUniform !== null ? it.OBJECT : it.NONE, l;
    })();
    let s = this.levelNode;
    s === null && e.context.getTextureLevel && (s = e.context.getTextureLevel(this));
    let a = null, o = null;
    if (this.compareNode !== null)
      if (e.renderer.hasCompatibility(rs.TEXTURE_COMPARE))
        a = this.compareNode;
      else {
        const l = n.compareFunction;
        l === null || l === ld || l === Xs || l === Vc || l === us ? o = this.compareNode : (a = this.compareNode, Pt('TSL: Only "LessCompare", "LessEqualCompare", "GreaterCompare" and "GreaterEqualCompare" are supported for depth texture comparison fallback.'));
      }
    t.uvNode = r, t.levelNode = s, t.biasNode = this.biasNode, t.compareNode = a, t.compareStepNode = o, t.gradNode = this.gradNode, t.depthNode = this.depthNode, t.offsetNode = this.offsetNode;
  }
  /**
   * Generates the uv code snippet.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} uvNode - The uv node to generate code for.
   * @return {string} The generated code snippet.
   */
  generateUV(e, t) {
    return t.build(e, this.sampler === !0 ? "vec2" : "ivec2");
  }
  /**
   * Generates the offset code snippet.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} offsetNode - The offset node to generate code for.
   * @return {string} The generated code snippet.
   */
  generateOffset(e, t) {
    return t.build(e, "ivec2");
  }
  /**
   * Generates the snippet for the texture sampling.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} textureProperty - The texture property.
   * @param {string} uvSnippet - The uv snippet.
   * @param {?string} levelSnippet - The level snippet.
   * @param {?string} biasSnippet - The bias snippet.
   * @param {?string} depthSnippet - The depth snippet.
   * @param {?string} compareSnippet - The compare snippet.
   * @param {?Array<string>} gradSnippet - The grad snippet.
   * @param {?string} offsetSnippet - The offset snippet.
   * @return {string} The generated code snippet.
   */
  generateSnippet(e, t, n, r, s, a, o, l, c) {
    const u = this.value;
    let h;
    return s ? h = e.generateTextureBias(u, t, n, s, a, c) : l ? h = e.generateTextureGrad(u, t, n, l, a, c) : o ? h = e.generateTextureCompare(u, t, n, o, a, c) : this.sampler === !1 ? h = e.generateTextureLoad(u, t, n, r, a, c) : r ? h = e.generateTextureLevel(u, t, n, r, a, c) : h = e.generateTexture(u, t, n, a, c), h;
  }
  /**
   * Generates the code snippet of the texture node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} output - The current output.
   * @return {string} The generated code snippet.
   */
  generate(e, t) {
    const n = this.value, r = e.getNodeProperties(this), s = super.generate(e, "property");
    if (/^sampler/.test(t))
      return s + "_sampler";
    if (e.isReference(t))
      return s;
    {
      const a = e.getDataFromNode(this), o = this.getNodeType(e);
      let l = a.propertyName;
      if (l === void 0) {
        const { uvNode: u, levelNode: h, biasNode: d, compareNode: f, compareStepNode: p, depthNode: _, gradNode: g, offsetNode: m } = r, x = this.generateUV(e, u), y = h ? h.build(e, "float") : null, b = d ? d.build(e, "float") : null, T = _ ? _.build(e, "int") : null, S = f ? f.build(e, "float") : null, E = p ? p.build(e, "float") : null, v = g ? [g[0].build(e, "vec2"), g[1].build(e, "vec2")] : null, M = m ? this.generateOffset(e, m) : null, F = e.getVarFromNode(this);
        l = e.getPropertyName(F);
        let R = this.generateSnippet(e, s, x, y, b, T, S, v, M);
        if (E !== null) {
          const I = n.compareFunction;
          I === Vc || I === us ? R = qc(vr(R, o), vr(E, "float")).build(e, o) : R = qc(vr(E, "float"), vr(R, o)).build(e, o);
        }
        e.addLineFlowCode(`${l} = ${R}`, this), a.snippet = R, a.propertyName = l;
      }
      let c = l;
      return e.needsToWorkingColorSpace(n) && (c = Lg(vr(c, o), n.colorSpace).setup(e).build(e, o)), e.format(c, o, t);
    }
  }
  /**
   * Sets the sampler value.
   *
   * @param {boolean} value - The sampler value to set.
   * @return {TextureNode} A reference to this texture node.
   */
  setSampler(e) {
    return this.sampler = e, this;
  }
  /**
   * Returns the sampler value.
   *
   * @return {boolean} The sampler value.
   */
  getSampler() {
    return this.sampler;
  }
  // @TODO: Move to TSL
  /**
   * Samples the texture with the given uv node.
   *
   * @param {Node} uvNode - The uv node.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  sample(e) {
    const t = this.clone();
    return t.uvNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  /**
   * TSL function for creating a texture node that fetches/loads texels without interpolation.
   *
   * @param {Node<uvec2>} uvNode - The uv node.
   * @returns {TextureNode} A texture node representing the texture load.
   */
  load(e) {
    return this.sample(e).setSampler(!1);
  }
  /**
   * Samples a blurred version of the texture by defining an internal bias.
   *
   * @param {Node<float>} amountNode - How blurred the texture should be.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  blur(e) {
    const t = this.clone();
    t.biasNode = Le(e).mul(MI(t)), t.referenceNode = this.getBase();
    const n = t.value;
    return t.generateMipmaps === !1 && (n && n.generateMipmaps === !1 || n.minFilter === Tt || n.magFilter === Tt) && (oe("TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture."), t.biasNode = null), Le(t);
  }
  /**
   * Samples a specific mip of the texture.
   *
   * @param {Node<int>} levelNode - The mip level to sample.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  level(e) {
    const t = this.clone();
    return t.levelNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  /**
   * Returns the texture size of the requested level.
   *
   * @param {Node<int>} levelNode - The level to compute the size for.
   * @return {TextureSizeNode} The texture size.
   */
  size(e) {
    return Bo(this, e);
  }
  /**
   * Samples the texture with the given bias.
   *
   * @param {Node<float>} biasNode - The bias node.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  bias(e) {
    const t = this.clone();
    return t.biasNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  /**
   * Returns the base texture of this node.
   * @return {TextureNode} The base texture node.
   */
  getBase() {
    return this.referenceNode ? this.referenceNode.getBase() : this;
  }
  /**
   * Samples the texture by executing a compare operation.
   *
   * @param {Node<float>} compareNode - The node that defines the compare value.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  compare(e) {
    const t = this.clone();
    return t.compareNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  /**
   * Samples the texture using an explicit gradient.
   *
   * @param {Node<vec2>} gradNodeX - The gradX node.
   * @param {Node<vec2>} gradNodeY - The gradY node.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  grad(e, t) {
    const n = this.clone();
    return n.gradNode = [Le(e), Le(t)], n.referenceNode = this.getBase(), Le(n);
  }
  /**
   * Samples the texture by defining a depth node.
   *
   * @param {Node<int>} depthNode - The depth node.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  depth(e) {
    const t = this.clone();
    return t.depthNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  /**
   * Samples the texture by defining an offset node.
   *
   * @param {Node<ivec2>} offsetNode - The offset node.
   * @return {TextureNode} A texture node representing the texture sample.
   */
  offset(e) {
    const t = this.clone();
    return t.offsetNode = Le(e), t.referenceNode = this.getBase(), Le(t);
  }
  // --
  serialize(e) {
    super.serialize(e), e.value = this.value.toJSON(e.meta).uuid, e.sampler = this.sampler, e.updateMatrix = this.updateMatrix, e.updateType = this.updateType;
  }
  deserialize(e) {
    super.deserialize(e), this.value = e.meta.textures[e.value], this.sampler = e.sampler, this.updateMatrix = e.updateMatrix, this.updateType = e.updateType;
  }
  /**
   * The update is used to implement the update of the uv transformation matrix.
   */
  update() {
    const e = this.value, t = this._matrixUniform;
    t !== null && (t.value = e.matrix), e.matrixAutoUpdate === !0 && e.updateMatrix();
    const n = this._flipYUniform;
    n !== null && (n.value = e.image instanceof ImageBitmap && e.flipY === !0 || e.isRenderTargetTexture === !0 || e.isFramebufferTexture === !0 || e.isDepthTexture === !0);
  }
  /**
   * Clones the texture node.
   *
   * @return {TextureNode} The cloned texture node.
   */
  clone() {
    const e = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode);
    return e.sampler = this.sampler, e.depthNode = this.depthNode, e.compareNode = this.compareNode, e.gradNode = this.gradNode, e.offsetNode = this.offsetNode, e;
  }
}
const wI = /* @__PURE__ */ Mt(Rl).setParameterLength(1, 4).setName("texture"), qt = (i = sS, e = null, t = null, n = null) => {
  let r;
  return i && i.isTextureNode === !0 ? (r = Le(i.clone()), r.referenceNode = i.getBase(), e !== null && (r.uvNode = Le(e)), t !== null && (r.levelNode = Le(t)), n !== null && (r.biasNode = Le(n))) : r = wI(i, e, t, n), r;
}, Fi = (...i) => qt(...i).setSampler(!1);
class Ig extends lu {
  static get type() {
    return "BufferNode";
  }
  /**
   * Constructs a new buffer node.
   *
   * @param {Array<number>} value - Array-like buffer data.
   * @param {string} bufferType - The data type of the buffer.
   * @param {number} [bufferCount=0] - The count of buffer elements.
   */
  constructor(e, t, n = 0) {
    super(e, t), this.isBufferNode = !0, this.bufferType = t, this.bufferCount = n, this.updateRanges = [];
  }
  /**
   * Adds a range of data in the data array to be updated on the GPU.
   *
   * @param {number} start - Position at which to start update.
   * @param {number} count - The number of components to update.
   */
  addUpdateRange(e, t) {
    this.updateRanges.push({ start: e, count: t });
  }
  /**
   * Clears the update ranges.
   */
  clearUpdateRanges() {
    this.updateRanges.length = 0;
  }
  /**
   * The data type of the buffer elements.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The element type.
   */
  getElementType(e) {
    return this.getNodeType(e);
  }
  /**
   * Overwrites the default implementation to return a fixed value `'buffer'`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return "buffer";
  }
}
const aS = (i, e, t) => new Ig(i, e, t);
class AI extends wl {
  static get type() {
    return "UniformArrayElementNode";
  }
  /**
   * Constructs a new buffer node.
   *
   * @param {UniformArrayNode} uniformArrayNode - The uniform array node to access.
   * @param {IndexNode} indexNode - The index data that define the position of the accessed element in the array.
   */
  constructor(e, t) {
    super(e, t), this.isArrayBufferElementNode = !0;
  }
  generate(e) {
    const t = super.generate(e), n = this.getNodeType(), r = this.node.getPaddedType();
    return e.format(t, r, n);
  }
}
class RI extends Ig {
  static get type() {
    return "UniformArrayNode";
  }
  /**
   * Constructs a new uniform array node.
   *
   * @param {Array<any>} value - Array holding the buffer data.
   * @param {?string} [elementType=null] - The data type of a buffer element.
   */
  constructor(e, t = null) {
    super(null), this.array = e, this.elementType = t === null ? zh(e[0]) : t, this.paddedType = this.getPaddedType(), this.updateType = it.RENDER, this.isArrayBufferNode = !0;
  }
  /**
   * This method is overwritten since the node type is inferred from the
   * {@link UniformArrayNode#paddedType}.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType() {
    return this.paddedType;
  }
  /**
   * The data type of the array elements.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The element type.
   */
  getElementType() {
    return this.elementType;
  }
  /**
   * Returns the padded type based on the element type.
   *
   * @return {string} The padded type.
   */
  getPaddedType() {
    const e = this.elementType;
    let t = "vec4";
    return e === "mat2" ? t = "mat2" : /mat/.test(e) === !0 ? t = "mat4" : e.charAt(0) === "i" ? t = "ivec4" : e.charAt(0) === "u" && (t = "uvec4"), t;
  }
  /**
   * The update makes sure to correctly transfer the data from the (complex) objects
   * in the array to the internal, correctly padded value buffer.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update() {
    const { array: e, value: t } = this, n = this.elementType;
    if (n === "float" || n === "int" || n === "uint")
      for (let r = 0; r < e.length; r++) {
        const s = r * 4;
        t[s] = e[r];
      }
    else if (n === "color")
      for (let r = 0; r < e.length; r++) {
        const s = r * 4, a = e[r];
        t[s] = a.r, t[s + 1] = a.g, t[s + 2] = a.b || 0;
      }
    else if (n === "mat2")
      for (let r = 0; r < e.length; r++) {
        const s = r * 4, a = e[r];
        t[s] = a.elements[0], t[s + 1] = a.elements[1], t[s + 2] = a.elements[2], t[s + 3] = a.elements[3];
      }
    else if (n === "mat3")
      for (let r = 0; r < e.length; r++) {
        const s = r * 16, a = e[r];
        t[s] = a.elements[0], t[s + 1] = a.elements[1], t[s + 2] = a.elements[2], t[s + 4] = a.elements[3], t[s + 5] = a.elements[4], t[s + 6] = a.elements[5], t[s + 8] = a.elements[6], t[s + 9] = a.elements[7], t[s + 10] = a.elements[8], t[s + 15] = 1;
      }
    else if (n === "mat4")
      for (let r = 0; r < e.length; r++) {
        const s = r * 16, a = e[r];
        for (let o = 0; o < a.elements.length; o++)
          t[s + o] = a.elements[o];
      }
    else
      for (let r = 0; r < e.length; r++) {
        const s = r * 4, a = e[r];
        t[s] = a.x, t[s + 1] = a.y, t[s + 2] = a.z || 0, t[s + 3] = a.w || 0;
      }
  }
  /**
   * Implement the value buffer creation based on the array data.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {null}
   */
  setup(e) {
    const t = this.array.length, n = this.elementType;
    let r = Float32Array;
    const s = this.paddedType, a = e.getTypeLength(s);
    return n.charAt(0) === "i" && (r = Int32Array), n.charAt(0) === "u" && (r = Uint32Array), this.value = new r(t * a), this.bufferCount = t, this.bufferType = s, this.update(), super.setup(e);
  }
  /**
   * Overwrites the default `element()` method to provide element access
   * based on {@link UniformArrayNode}.
   *
   * @param {IndexNode} indexNode - The index node.
   * @return {UniformArrayElementNode}
   */
  element(e) {
    return new AI(this, Le(e));
  }
}
const Ii = (i, e) => new RI(i, e);
class CI extends Fe {
  /**
   * Constructs a new builtin node.
   *
   * @param {string} name - The name of the built-in shader variable.
   */
  constructor(e) {
    super("float"), this.name = e, this.isBuiltinNode = !0;
  }
  /**
   * Generates the code snippet of the builtin node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated code snippet.
   */
  generate() {
    return this.name;
  }
}
const Cl = Mt(CI).setParameterLength(1);
let Xl, jl;
class Ht extends Fe {
  static get type() {
    return "ScreenNode";
  }
  /**
   * Constructs a new screen node.
   *
   * @param {('coordinate'|'viewport'|'size'|'uv'|'dpr')} scope - The node's scope.
   */
  constructor(e) {
    super(), this.scope = e, this._output = null, this.isViewportNode = !0;
  }
  /**
   * This method is overwritten since the node type depends on the selected scope.
   *
   * @return {('float'|'vec2'|'vec4')} The node type.
   */
  getNodeType() {
    return this.scope === Ht.DPR ? "float" : this.scope === Ht.VIEWPORT ? "vec4" : "vec2";
  }
  /**
   * This method is overwritten since the node's update type depends on the selected scope.
   *
   * @return {NodeUpdateType} The update type.
   */
  getUpdateType() {
    let e = it.NONE;
    return (this.scope === Ht.SIZE || this.scope === Ht.VIEWPORT || this.scope === Ht.DPR) && (e = it.RENDER), this.updateType = e, e;
  }
  /**
   * `ScreenNode` implements {@link Node#update} to retrieve viewport and size information
   * from the current renderer.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update({ renderer: e }) {
    const t = e.getRenderTarget();
    this.scope === Ht.VIEWPORT ? t !== null ? jl.copy(t.viewport) : (e.getViewport(jl), jl.multiplyScalar(e.getPixelRatio())) : this.scope === Ht.DPR ? this._output.value = e.getPixelRatio() : t !== null ? (Xl.width = t.width, Xl.height = t.height) : e.getDrawingBufferSize(Xl);
  }
  setup() {
    const e = this.scope;
    let t = null;
    return e === Ht.SIZE ? t = je(Xl || (Xl = new de())) : e === Ht.VIEWPORT ? t = je(jl || (jl = new rt())) : e === Ht.DPR ? t = je(1) : t = Pe(Nl.div(Zp)), this._output = t, t;
  }
  generate(e) {
    if (this.scope === Ht.COORDINATE) {
      let t = e.getFragCoord();
      if (e.isFlipY()) {
        const n = e.getNodeProperties(Zp).outputNode.build(e);
        t = `${e.getType("vec2")}( ${t}.x, ${n}.y - ${t}.y )`;
      }
      return t;
    }
    return super.generate(e);
  }
}
Ht.COORDINATE = "coordinate";
Ht.VIEWPORT = "viewport";
Ht.SIZE = "size";
Ht.UV = "uv";
Ht.DPR = "dpr";
const NI = /* @__PURE__ */ xe(Ht, Ht.DPR), Ea = /* @__PURE__ */ xe(Ht, Ht.UV), Zp = /* @__PURE__ */ xe(Ht, Ht.SIZE), Nl = /* @__PURE__ */ xe(Ht, Ht.COORDINATE), oS = /* @__PURE__ */ xe(Ht, Ht.VIEWPORT), PI = oS.zw;
oS.xy;
let Ff = null, Xu = null, If = null, ju = null, Uf = null, Yu = null, Bf = null, Ku = null;
const Sd = /* @__PURE__ */ je(0, "uint").setName("u_cameraIndex").setGroup(Ag("cameraIndex")).toVarying("v_cameraIndex"), ga = /* @__PURE__ */ je("float").setName("cameraNear").setGroup(Xe).onRenderUpdate(({ camera: i }) => i.near), _a = /* @__PURE__ */ je("float").setName("cameraFar").setGroup(Xe).onRenderUpdate(({ camera: i }) => i.far), Tc = /* @__PURE__ */ ee(({ camera: i }) => {
  let e;
  if (i.isArrayCamera && i.cameras.length > 0) {
    const t = [];
    for (const n of i.cameras)
      t.push(n.projectionMatrix);
    Xu === null ? Xu = Ii(t).setGroup(Xe).setName("cameraProjectionMatrices") : Xu.array = t, e = Xu.element(i.isMultiViewCamera ? Cl("gl_ViewID_OVR") : Sd).toConst("cameraProjectionMatrix");
  } else
    Ff === null && (Ff = je(i.projectionMatrix).setName("cameraProjectionMatrix").setGroup(Xe).onRenderUpdate(({ camera: t }) => t.projectionMatrix)), e = Ff;
  return e;
}).once()(), DI = /* @__PURE__ */ ee(({ camera: i }) => {
  let e;
  if (i.isArrayCamera && i.cameras.length > 0) {
    const t = [];
    for (const n of i.cameras)
      t.push(n.projectionMatrixInverse);
    ju === null ? ju = Ii(t).setGroup(Xe).setName("cameraProjectionMatricesInverse") : ju.array = t, e = ju.element(i.isMultiViewCamera ? Cl("gl_ViewID_OVR") : Sd).toConst("cameraProjectionMatrixInverse");
  } else
    If === null && (If = je(i.projectionMatrixInverse).setName("cameraProjectionMatrixInverse").setGroup(Xe).onRenderUpdate(({ camera: t }) => t.projectionMatrixInverse)), e = If;
  return e;
}).once()(), fs = /* @__PURE__ */ ee(({ camera: i }) => {
  let e;
  if (i.isArrayCamera && i.cameras.length > 0) {
    const t = [];
    for (const n of i.cameras)
      t.push(n.matrixWorldInverse);
    Yu === null ? Yu = Ii(t).setGroup(Xe).setName("cameraViewMatrices") : Yu.array = t, e = Yu.element(i.isMultiViewCamera ? Cl("gl_ViewID_OVR") : Sd).toConst("cameraViewMatrix");
  } else
    Uf === null && (Uf = je(i.matrixWorldInverse).setName("cameraViewMatrix").setGroup(Xe).onRenderUpdate(({ camera: t }) => t.matrixWorldInverse)), e = Uf;
  return e;
}).once()(), LI = /* @__PURE__ */ ee(({ camera: i }) => {
  let e;
  if (i.isArrayCamera && i.cameras.length > 0) {
    const t = [];
    for (let n = 0, r = i.cameras.length; n < r; n++)
      t.push(new P());
    Ku === null ? Ku = Ii(t).setGroup(Xe).setName("cameraPositions").onRenderUpdate(({ camera: n }, r) => {
      const s = n.cameras, a = r.array;
      for (let o = 0, l = s.length; o < l; o++)
        a[o].setFromMatrixPosition(s[o].matrixWorld);
    }) : Ku.array = t, e = Ku.element(i.isMultiViewCamera ? Cl("gl_ViewID_OVR") : Sd).toConst("cameraPosition");
  } else
    Bf === null && (Bf = je(new P()).setName("cameraPosition").setGroup(Xe).onRenderUpdate(({ camera: t }, n) => n.value.setFromMatrixPosition(t.matrixWorld))), e = Bf;
  return e;
}).once()(), J0 = /* @__PURE__ */ new tu();
class Yt extends Fe {
  static get type() {
    return "Object3DNode";
  }
  /**
   * Constructs a new object 3D node.
   *
   * @param {('position'|'viewPosition'|'direction'|'scale'|'worldMatrix')} scope - The node represents a different type of transformation depending on the scope.
   * @param {?Object3D} [object3d=null] - The 3D object.
   */
  constructor(e, t = null) {
    super(), this.scope = e, this.object3d = t, this.updateType = it.OBJECT, this.uniformNode = new lu(null);
  }
  /**
   * Overwritten since the node type is inferred from the scope.
   *
   * @return {('mat4'|'vec3'|'float')} The node type.
   */
  getNodeType() {
    const e = this.scope;
    if (e === Yt.WORLD_MATRIX)
      return "mat4";
    if (e === Yt.POSITION || e === Yt.VIEW_POSITION || e === Yt.DIRECTION || e === Yt.SCALE)
      return "vec3";
    if (e === Yt.RADIUS)
      return "float";
  }
  /**
   * Updates the uniform value depending on the scope.
   *
   * @param {NodeFrame} frame - The current node frame.
   */
  update(e) {
    const t = this.object3d, n = this.uniformNode, r = this.scope;
    if (r === Yt.WORLD_MATRIX)
      n.value = t.matrixWorld;
    else if (r === Yt.POSITION)
      n.value = n.value || new P(), n.value.setFromMatrixPosition(t.matrixWorld);
    else if (r === Yt.SCALE)
      n.value = n.value || new P(), n.value.setFromMatrixScale(t.matrixWorld);
    else if (r === Yt.DIRECTION)
      n.value = n.value || new P(), t.getWorldDirection(n.value);
    else if (r === Yt.VIEW_POSITION) {
      const s = e.camera;
      n.value = n.value || new P(), n.value.setFromMatrixPosition(t.matrixWorld), n.value.applyMatrix4(s.matrixWorldInverse);
    } else if (r === Yt.RADIUS) {
      const s = e.object.geometry;
      s.boundingSphere === null && s.computeBoundingSphere(), J0.copy(s.boundingSphere).applyMatrix4(t.matrixWorld), n.value = J0.radius;
    }
  }
  /**
   * Generates the code snippet of the uniform node. The node type of the uniform
   * node also depends on the selected scope.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated code snippet.
   */
  generate(e) {
    const t = this.scope;
    return t === Yt.WORLD_MATRIX ? this.uniformNode.nodeType = "mat4" : t === Yt.POSITION || t === Yt.VIEW_POSITION || t === Yt.DIRECTION || t === Yt.SCALE ? this.uniformNode.nodeType = "vec3" : t === Yt.RADIUS && (this.uniformNode.nodeType = "float"), this.uniformNode.build(e);
  }
  serialize(e) {
    super.serialize(e), e.scope = this.scope;
  }
  deserialize(e) {
    super.deserialize(e), this.scope = e.scope;
  }
}
Yt.WORLD_MATRIX = "worldMatrix";
Yt.POSITION = "position";
Yt.SCALE = "scale";
Yt.VIEW_POSITION = "viewPosition";
Yt.DIRECTION = "direction";
Yt.RADIUS = "radius";
class zi extends Yt {
  static get type() {
    return "ModelNode";
  }
  /**
   * Constructs a new object model node.
   *
   * @param {('position'|'viewPosition'|'direction'|'scale'|'worldMatrix')} scope - The node represents a different type of transformation depending on the scope.
   */
  constructor(e) {
    super(e);
  }
  /**
   * Extracts the model reference from the frame state and then
   * updates the uniform value depending on the scope.
   *
   * @param {NodeFrame} frame - The current node frame.
   */
  update(e) {
    this.object3d = e.object, super.update(e);
  }
}
zi.DIRECTION;
const Ga = /* @__PURE__ */ xe(zi, zi.WORLD_MATRIX);
zi.POSITION;
zi.SCALE;
zi.VIEW_POSITION;
zi.RADIUS;
const FI = /* @__PURE__ */ je(new nt()).onObjectUpdate(({ object: i }, e) => e.value.getNormalMatrix(i.matrixWorld)), cu = /* @__PURE__ */ ee((i) => i.context.modelViewMatrix || II).once()().toVar("modelViewMatrix"), II = /* @__PURE__ */ fs.mul(Ga), ex = /* @__PURE__ */ ee((i) => (i.context.isHighPrecisionModelViewMatrix = !0, je("mat4").onObjectUpdate(({ object: e, camera: t }) => e.modelViewMatrix.multiplyMatrices(t.matrixWorldInverse, e.matrixWorld)))).once()().toVar("highpModelViewMatrix"), tx = /* @__PURE__ */ ee((i) => {
  const e = i.context.isHighPrecisionModelViewMatrix;
  return je("mat3").onObjectUpdate(({ object: t, camera: n }) => (e !== !0 && t.modelViewMatrix.multiplyMatrices(n.matrixWorldInverse, t.matrixWorld), t.normalMatrix.getNormalMatrix(t.modelViewMatrix)));
}).once()().toVar("highpModelNormalViewMatrix"), UI = /* @__PURE__ */ ee((i) => i.shaderStage !== "fragment" ? (Pt("TSL: `clipSpace` is only available in fragment stage."), et()) : i.context.clipSpace.toVarying("v_clipSpace")).once()(), Td = /* @__PURE__ */ Ws("position", "vec3"), Cn = /* @__PURE__ */ Td.toVarying("positionLocal"), Wh = /* @__PURE__ */ Td.toVarying("positionPrevious"), pl = /* @__PURE__ */ ee((i) => Ga.mul(Cn).xyz.toVarying(i.getSubBuildProperty("v_positionWorld")), "vec3").once(["POSITION"])(), lS = /* @__PURE__ */ ee(() => Cn.transformDirection(Ga).toVarying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"), "vec3").once(["POSITION"])(), hn = /* @__PURE__ */ ee((i) => {
  if (i.shaderStage === "fragment" && i.material.vertexNode) {
    const e = DI.mul(UI);
    return e.xyz.div(e.w).toVar("positionView");
  }
  return i.context.setupPositionView().toVarying("v_positionView");
}, "vec3").once(["POSITION", "VERTEX"])(), $t = /* @__PURE__ */ ee((i) => {
  let e;
  return i.camera.isOrthographicCamera ? e = Y(0, 0, 1) : e = hn.negate().toVarying("v_positionViewDirection").normalize(), e.toVar("positionViewDirection");
}, "vec3").once(["POSITION"])();
class BI extends Fe {
  static get type() {
    return "FrontFacingNode";
  }
  /**
   * Constructs a new front facing node.
   */
  constructor() {
    super("bool"), this.isFrontFacingNode = !0;
  }
  generate(e) {
    if (e.shaderStage !== "fragment")
      return "true";
    const { material: t } = e;
    return t.side === Ft ? "false" : e.getFrontFacing();
  }
}
const OI = /* @__PURE__ */ xe(BI), cS = /* @__PURE__ */ K(OI).mul(2).sub(1), uu = /* @__PURE__ */ ee(([i], { material: e }) => {
  const t = e.side;
  return t === Ft ? i = i.mul(-1) : t === Rn && (i = i.mul(cS)), i;
}), uS = /* @__PURE__ */ Ws("normal", "vec3"), Dr = /* @__PURE__ */ ee((i) => i.geometry.hasAttribute("normal") === !1 ? (oe('TSL: Vertex attribute "normal" not found on geometry.'), Y(0, 1, 0)) : uS, "vec3").once()().toVar("normalLocal"), kI = /* @__PURE__ */ hn.dFdx().cross(hn.dFdy()).normalize().toVar("normalFlat"), Xc = /* @__PURE__ */ ee((i) => {
  let e;
  return i.isFlatShading() ? e = kI : e = hS(Dr).toVarying("v_normalViewGeometry").normalize(), e;
}, "vec3").once()().toVar("normalViewGeometry"), GI = /* @__PURE__ */ ee((i) => {
  let e = Xc.transformDirection(fs);
  return i.isFlatShading() !== !0 && (e = e.toVarying("v_normalWorldGeometry")), e.normalize().toVar("normalWorldGeometry");
}, "vec3").once()(), vt = /* @__PURE__ */ ee((i) => {
  let e;
  return i.subBuildFn === "NORMAL" || i.subBuildFn === "VERTEX" ? (e = Xc, i.isFlatShading() !== !0 && (e = uu(e))) : e = i.context.setupNormal().context({ getUV: null, getTextureLevel: null }), e;
}, "vec3").once(["NORMAL", "VERTEX"])().toVar("normalView"), Pl = /* @__PURE__ */ vt.transformDirection(fs).toVar("normalWorld"), xa = /* @__PURE__ */ ee(({ subBuildFn: i, context: e }) => {
  let t;
  return i === "NORMAL" || i === "VERTEX" ? t = vt : t = e.setupClearcoatNormal().context({ getUV: null, getTextureLevel: null }), t;
}, "vec3").once(["NORMAL", "VERTEX"])().toVar("clearcoatNormalView"), VI = /* @__PURE__ */ ee(([i, e = Ga]) => {
  const t = On(e), n = i.div(Y(t[0].dot(t[0]), t[1].dot(t[1]), t[2].dot(t[2])));
  return t.mul(n).xyz;
}), hS = /* @__PURE__ */ ee(([i], e) => {
  const t = e.context.modelNormalViewMatrix;
  if (t)
    return t.transformDirection(i);
  const n = FI.mul(i);
  return fs.transformDirection(n);
});
ee(() => (oe('TSL: "transformedNormalView" is deprecated. Use "normalView" instead.'), vt)).once(["NORMAL", "VERTEX"])();
ee(() => (oe('TSL: "transformedNormalWorld" is deprecated. Use "normalWorld" instead.'), Pl)).once(["NORMAL", "VERTEX"])();
ee(() => (oe('TSL: "transformedClearcoatNormalView" is deprecated. Use "clearcoatNormalView" instead.'), xa)).once(["NORMAL", "VERTEX"])();
const nx = /* @__PURE__ */ new gi(), Of = /* @__PURE__ */ new pt(), zI = /* @__PURE__ */ je(0).onReference(({ material: i }) => i).onObjectUpdate(({ material: i }) => i.refractionRatio), kf = /* @__PURE__ */ je(1).onReference(({ material: i }) => i).onObjectUpdate(function({ material: i, scene: e }) {
  return i.envMap ? i.envMapIntensity : e.environmentIntensity;
}), dS = /* @__PURE__ */ je(new pt()).onReference(function(i) {
  return i.material;
}).onObjectUpdate(function({ material: i, scene: e }) {
  const t = e.environment !== null && i.envMap === null ? e.environmentRotation : i.envMapRotation;
  return t ? (nx.copy(t), Of.makeRotationFromEuler(nx)) : Of.identity(), Of;
}), HI = /* @__PURE__ */ $t.negate().reflect(vt), $I = /* @__PURE__ */ $t.negate().refract(vt, zI), WI = /* @__PURE__ */ HI.transformDirection(fs).toVar("reflectVector"), qI = /* @__PURE__ */ $I.transformDirection(fs).toVar("reflectVector"), XI = /* @__PURE__ */ new yl();
class jI extends Rl {
  static get type() {
    return "CubeTextureNode";
  }
  /**
   * Constructs a new cube texture node.
   *
   * @param {CubeTexture} value - The cube texture.
   * @param {?Node<vec3>} [uvNode=null] - The uv node.
   * @param {?Node<int>} [levelNode=null] - The level node.
   * @param {?Node<float>} [biasNode=null] - The bias node.
   */
  constructor(e, t = null, n = null, r = null) {
    super(e, t, n, r), this.isCubeTextureNode = !0;
  }
  /**
   * Overwrites the default implementation to return the appropriate cube texture type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return this.value.isDepthTexture === !0 ? "cubeDepthTexture" : "cubeTexture";
  }
  /**
   * Returns a default uvs based on the mapping type of the cube texture.
   *
   * @return {Node<vec3>} The default uv attribute.
   */
  getDefaultUV() {
    const e = this.value;
    return e.mapping === nr ? WI : e.mapping === Rr ? qI : (le('CubeTextureNode: Mapping "%s" not supported.', e.mapping), Y(0, 0, 0));
  }
  /**
   * Overwritten with an empty implementation since the `updateMatrix` flag is ignored
   * for cube textures. The uv transformation matrix is not applied to cube textures.
   *
   * @param {boolean} value - The update toggle.
   */
  setUpdateMatrix() {
  }
  // Ignore .updateMatrix for CubeTextureNode
  /**
   * Setups the uv node. Depending on the backend as well as the texture type, it might be necessary
   * to modify the uv node for correct sampling.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} uvNode - The uv node to setup.
   * @return {Node} The updated uv node.
   */
  setupUV(e, t) {
    const n = this.value;
    return n.isDepthTexture === !0 ? e.renderer.coordinateSystem === Cr ? Y(t.x, t.y.negate(), t.z) : t : ((e.renderer.coordinateSystem === Cr || !n.isRenderTargetTexture) && (t = Y(t.x.negate(), t.yz)), dS.mul(t));
  }
  /**
   * Generates the uv code snippet.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} cubeUV - The uv node to generate code for.
   * @return {string} The generated code snippet.
   */
  generateUV(e, t) {
    return t.build(e, this.sampler === !0 ? "vec3" : "ivec3");
  }
}
const YI = /* @__PURE__ */ Mt(jI).setParameterLength(1, 4).setName("cubeTexture"), di = (i = XI, e = null, t = null, n = null) => {
  let r;
  return i && i.isCubeTextureNode === !0 ? (r = Le(i.clone()), r.referenceNode = i, e !== null && (r.uvNode = Le(e)), t !== null && (r.levelNode = Le(t)), n !== null && (r.biasNode = Le(n))) : r = YI(i, e, t, n), r;
};
class KI extends wl {
  static get type() {
    return "ReferenceElementNode";
  }
  /**
   * Constructs a new reference element node.
   *
   * @param {?ReferenceNode} referenceNode - The reference node.
   * @param {Node} indexNode - The index node that defines the element access.
   */
  constructor(e, t) {
    super(e, t), this.referenceNode = e, this.isReferenceElementNode = !0;
  }
  /**
   * This method is overwritten since the node type is inferred from
   * the uniform type of the reference node.
   *
   * @return {string} The node type.
   */
  getNodeType() {
    return this.referenceNode.uniformType;
  }
  generate(e) {
    const t = super.generate(e), n = this.referenceNode.getNodeType(), r = this.getNodeType();
    return e.format(t, n, r);
  }
}
class Ug extends Fe {
  static get type() {
    return "ReferenceNode";
  }
  /**
   * Constructs a new reference node.
   *
   * @param {string} property - The name of the property the node refers to.
   * @param {string} uniformType - The uniform type that should be used to represent the property value.
   * @param {?Object} [object=null] - The object the property belongs to.
   * @param {?number} [count=null] - When the linked property is an array-like, this parameter defines its length.
   */
  constructor(e, t, n = null, r = null) {
    super(), this.property = e, this.uniformType = t, this.object = n, this.count = r, this.properties = e.split("."), this.reference = n, this.node = null, this.group = null, this.name = null, this.updateType = it.OBJECT;
  }
  /**
   * When the referred property is array-like, this method can be used
   * to access elements via an index node.
   *
   * @param {IndexNode} indexNode - indexNode.
   * @return {ReferenceElementNode} A reference to an element.
   */
  element(e) {
    return new KI(this, Le(e));
  }
  /**
   * Sets the uniform group for this reference node.
   *
   * @param {UniformGroupNode} group - The uniform group to set.
   * @return {ReferenceNode} A reference to this node.
   */
  setGroup(e) {
    return this.group = e, this;
  }
  /**
   * Sets the name for the internal uniform.
   *
   * @param {string} name - The label to set.
   * @return {ReferenceNode} A reference to this node.
   */
  setName(e) {
    return this.name = e, this;
  }
  /**
   * Sets the label for the internal uniform.
   *
   * @deprecated
   * @param {string} name - The label to set.
   * @return {ReferenceNode} A reference to this node.
   */
  label(e) {
    return oe('TSL: "label()" has been deprecated. Use "setName()" instead.'), this.setName(e);
  }
  /**
   * Sets the node type which automatically defines the internal
   * uniform type.
   *
   * @param {string} uniformType - The type to set.
   */
  setNodeType(e) {
    let t = null;
    this.count !== null ? t = aS(null, e, this.count) : Array.isArray(this.getValueFromReference()) ? t = Ii(null, e) : e === "texture" ? t = qt(null) : e === "cubeTexture" ? t = di(null) : t = je(null, e), this.group !== null && t.setGroup(this.group), this.name !== null && t.setName(this.name), this.node = t;
  }
  /**
   * This method is overwritten since the node type is inferred from
   * the type of the reference node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.node === null && (this.updateReference(e), this.updateValue()), this.node.getNodeType(e);
  }
  /**
   * Returns the property value from the given referred object.
   *
   * @param {Object} [object=this.reference] - The object to retrieve the property value from.
   * @return {any} The value.
   */
  getValueFromReference(e = this.reference) {
    const { properties: t } = this;
    let n = e[t[0]];
    for (let r = 1; r < t.length; r++)
      n = n[t[r]];
    return n;
  }
  /**
   * Allows to update the reference based on the given state. The state is only
   * evaluated {@link ReferenceNode#object} is not set.
   *
   * @param {(NodeFrame|NodeBuilder)} state - The current state.
   * @return {Object} The updated reference.
   */
  updateReference(e) {
    return this.reference = this.object !== null ? this.object : e.object, this.reference;
  }
  /**
   * The output of the reference node is the internal uniform node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {UniformNode} The output node.
   */
  setup() {
    return this.updateValue(), this.node;
  }
  /**
   * Overwritten to update the internal uniform value.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update() {
    this.updateValue();
  }
  /**
   * Retrieves the value from the referred object property and uses it
   * to updated the internal uniform.
   */
  updateValue() {
    this.node === null && this.setNodeType(this.uniformType);
    const e = this.getValueFromReference();
    Array.isArray(e) ? this.node.array = e : this.node.value = e;
  }
}
const Qt = (i, e, t) => new Ug(i, e, t), ix = (i, e, t, n) => new Ug(i, e, n, t);
class ZI extends Ug {
  static get type() {
    return "MaterialReferenceNode";
  }
  /**
   * Constructs a new material reference node.
   *
   * @param {string} property - The name of the property the node refers to.
   * @param {string} inputType - The uniform type that should be used to represent the property value.
   * @param {?Material} [material=null] - The material the property belongs to. When no material is set,
   * the node refers to the material of the current rendered object.
   */
  constructor(e, t, n = null) {
    super(e, t, n), this.material = n, this.isMaterialReferenceNode = !0;
  }
  /**
   * Updates the reference based on the given state. The state is only evaluated
   * {@link MaterialReferenceNode#material} is not set.
   *
   * @param {(NodeFrame|NodeBuilder)} state - The current state.
   * @return {Object} The updated reference.
   */
  updateReference(e) {
    return this.reference = this.material !== null ? this.material : e.material, this.reference;
  }
}
const Rs = (i, e, t = null) => new ZI(i, e, t), fS = Al(), QI = hn.dFdx(), JI = hn.dFdy(), pS = fS.dFdx(), mS = fS.dFdy(), gS = vt, _S = JI.cross(gS), xS = gS.cross(QI), Qp = _S.mul(pS.x).add(xS.mul(mS.x)), Jp = _S.mul(pS.y).add(xS.mul(mS.y)), rx = Qp.dot(Qp).max(Jp.dot(Jp)), vS = rx.equal(0).select(0, rx.inverseSqrt()), eU = /* @__PURE__ */ Qp.mul(vS).toVar("tangentViewFrame"), tU = /* @__PURE__ */ Jp.mul(vS).toVar("bitangentViewFrame"), yS = /* @__PURE__ */ Ws("tangent", "vec4"), qh = /* @__PURE__ */ yS.xyz.toVar("tangentLocal"), bS = /* @__PURE__ */ ee((i) => {
  let e;
  return i.subBuildFn === "VERTEX" || i.geometry.hasAttribute("tangent") ? e = cu.mul(et(qh, 0)).xyz.toVarying("v_tangentView").normalize() : e = eU, i.isFlatShading() !== !0 && (e = uu(e)), e;
}, "vec3").once(["NORMAL", "VERTEX"])().toVar("tangentView"), nU = /* @__PURE__ */ ee(([i, e], t) => {
  let n = i.mul(yS.w).xyz;
  return t.subBuildFn === "NORMAL" && t.isFlatShading() !== !0 && (n = n.toVarying(e)), n;
}).once(["NORMAL"]), iU = /* @__PURE__ */ ee((i) => {
  let e;
  return i.subBuildFn === "VERTEX" || i.geometry.hasAttribute("tangent") ? e = nU(vt.cross(bS), "v_bitangentView").normalize() : e = tU, i.isFlatShading() !== !0 && (e = uu(e)), e;
}, "vec3").once(["NORMAL", "VERTEX"])().toVar("bitangentView"), uc = /* @__PURE__ */ On(bS, iU, vt).toVar("TBNViewMatrix"), rU = /* @__PURE__ */ ee(() => {
  let i = Io.cross($t);
  return i = i.cross(Io).normalize(), i = Lt(i, vt, da.mul(Jr.oneMinus()).oneMinus().pow2().pow2()).normalize(), i;
}).once()(), sU = (i) => Le(i).mul(0.5).add(0.5), sx = (i) => Y(i, zs(Ng(K(1).sub(Oa(i, i)))));
class aU extends xn {
  static get type() {
    return "NormalMapNode";
  }
  /**
   * Constructs a new normal map node.
   *
   * @param {Node<vec3>} node - Represents the normal map data.
   * @param {?Node<vec2>} [scaleNode=null] - Controls the intensity of the effect.
   */
  constructor(e, t = null) {
    super("vec3"), this.node = e, this.scaleNode = t, this.normalMapType = wr, this.unpackNormalMode = Od;
  }
  setup(e) {
    const { normalMapType: t, scaleNode: n, unpackNormalMode: r } = this;
    let s = this.node.mul(2).sub(1);
    if (t === wr ? r === Kv ? s = sx(s.xy) : r === fM ? s = sx(s.yw) : r !== Od && console.error(`THREE.NodeMaterial: Unexpected unpack normal mode: ${r}`) : r !== Od && console.error(`THREE.NodeMaterial: Normal map type '${t}' is not compatible with unpack normal mode '${r}'`), n !== null) {
      let o = n;
      e.isFlatShading() === !0 && (o = uu(o)), s = Y(s.xy.mul(o), s.z);
    }
    let a = null;
    return t === Yv ? a = hS(s) : t === wr ? a = uc.mul(s).normalize() : (le(`NodeMaterial: Unsupported normal map type: ${t}`), a = vt), a;
  }
}
const ax = /* @__PURE__ */ Mt(aU).setParameterLength(1, 2), oU = ee(({ textureNode: i, bumpScale: e }) => {
  const t = (r) => i.isolate().context({ getUV: (s) => r(s.uvNode || Al()), forceUVContext: !0 }), n = K(t((r) => r));
  return Pe(
    K(t((r) => r.add(r.dFdx()))).sub(n),
    K(t((r) => r.add(r.dFdy()))).sub(n)
  ).mul(e);
}), lU = ee((i) => {
  const { surf_pos: e, surf_norm: t, dHdxy: n } = i, r = e.dFdx().normalize(), s = e.dFdy().normalize(), a = t, o = s.cross(a), l = a.cross(r), c = r.dot(o).mul(cS), u = c.sign().mul(n.x.mul(o).add(n.y.mul(l)));
  return c.abs().mul(t).sub(u).normalize();
});
class cU extends xn {
  static get type() {
    return "BumpMapNode";
  }
  /**
   * Constructs a new bump map node.
   *
   * @param {Node<float>} textureNode - Represents the bump map data.
   * @param {?Node<float>} [scaleNode=null] - Controls the intensity of the bump effect.
   */
  constructor(e, t = null) {
    super("vec3"), this.textureNode = e, this.scaleNode = t;
  }
  setup() {
    const e = this.scaleNode !== null ? this.scaleNode : 1, t = oU({ textureNode: this.textureNode, bumpScale: e });
    return lU({
      surf_pos: hn,
      surf_norm: vt,
      dHdxy: t
    });
  }
}
const uU = /* @__PURE__ */ Mt(cU).setParameterLength(1, 2), ox = /* @__PURE__ */ new Map();
class J extends Fe {
  static get type() {
    return "MaterialNode";
  }
  /**
   * Constructs a new material node.
   *
   * @param {string} scope - The scope defines what kind of material property is referred by the node.
   */
  constructor(e) {
    super(), this.scope = e;
  }
  /**
   * Returns a cached reference node for the given property and type.
   *
   * @param {string} property - The name of the material property.
   * @param {string} type - The uniform type of the property.
   * @return {MaterialReferenceNode} A material reference node representing the property access.
   */
  getCache(e, t) {
    let n = ox.get(e);
    return n === void 0 && (n = Rs(e, t), ox.set(e, n)), n;
  }
  /**
   * Returns a float-typed material reference node for the given property name.
   *
   * @param {string} property - The name of the material property.
   * @return {MaterialReferenceNode<float>} A material reference node representing the property access.
   */
  getFloat(e) {
    return this.getCache(e, "float");
  }
  /**
   * Returns a color-typed material reference node for the given property name.
   *
   * @param {string} property - The name of the material property.
   * @return {MaterialReferenceNode<color>} A material reference node representing the property access.
   */
  getColor(e) {
    return this.getCache(e, "color");
  }
  /**
   * Returns a texture-typed material reference node for the given property name.
   *
   * @param {string} property - The name of the material property.
   * @return {MaterialReferenceNode} A material reference node representing the property access.
   */
  getTexture(e) {
    return this.getCache(e === "map" ? "map" : e + "Map", "texture");
  }
  /**
   * The node setup is done depending on the selected scope. Multiple material properties
   * might be grouped into a single node composition if they logically belong together.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node} The node representing the selected scope.
   */
  setup(e) {
    const t = e.context.material, n = this.scope;
    let r = null;
    if (n === J.COLOR) {
      const s = t.color !== void 0 ? this.getColor(n) : Y();
      t.map && t.map.isTexture === !0 ? r = s.mul(this.getTexture("map")) : r = s;
    } else if (n === J.OPACITY) {
      const s = this.getFloat(n);
      t.alphaMap && t.alphaMap.isTexture === !0 ? r = s.mul(this.getTexture("alpha")) : r = s;
    } else if (n === J.SPECULAR_STRENGTH)
      t.specularMap && t.specularMap.isTexture === !0 ? r = this.getTexture("specular").r : r = K(1);
    else if (n === J.SPECULAR_INTENSITY) {
      const s = this.getFloat(n);
      t.specularIntensityMap && t.specularIntensityMap.isTexture === !0 ? r = s.mul(this.getTexture(n).a) : r = s;
    } else if (n === J.SPECULAR_COLOR) {
      const s = this.getColor(n);
      t.specularColorMap && t.specularColorMap.isTexture === !0 ? r = s.mul(this.getTexture(n).rgb) : r = s;
    } else if (n === J.ROUGHNESS) {
      const s = this.getFloat(n);
      t.roughnessMap && t.roughnessMap.isTexture === !0 ? r = s.mul(this.getTexture(n).g) : r = s;
    } else if (n === J.METALNESS) {
      const s = this.getFloat(n);
      t.metalnessMap && t.metalnessMap.isTexture === !0 ? r = s.mul(this.getTexture(n).b) : r = s;
    } else if (n === J.EMISSIVE) {
      const s = this.getFloat("emissiveIntensity"), a = this.getColor(n).mul(s);
      t.emissiveMap && t.emissiveMap.isTexture === !0 ? r = a.mul(this.getTexture(n)) : r = a;
    } else if (n === J.NORMAL)
      t.normalMap ? (r = ax(this.getTexture("normal"), this.getCache("normalScale", "vec2")), r.normalMapType = t.normalMapType, (t.normalMap.format == ri || t.normalMap.format == Da || t.normalMap.format == Pa) && (r.unpackNormalMode = Kv)) : t.bumpMap ? r = uU(this.getTexture("bump").r, this.getFloat("bumpScale")) : r = vt;
    else if (n === J.CLEARCOAT) {
      const s = this.getFloat(n);
      t.clearcoatMap && t.clearcoatMap.isTexture === !0 ? r = s.mul(this.getTexture(n).r) : r = s;
    } else if (n === J.CLEARCOAT_ROUGHNESS) {
      const s = this.getFloat(n);
      t.clearcoatRoughnessMap && t.clearcoatRoughnessMap.isTexture === !0 ? r = s.mul(this.getTexture(n).r) : r = s;
    } else if (n === J.CLEARCOAT_NORMAL)
      t.clearcoatNormalMap ? r = ax(this.getTexture(n), this.getCache(n + "Scale", "vec2")) : r = vt;
    else if (n === J.SHEEN) {
      const s = this.getColor("sheenColor").mul(this.getFloat("sheen"));
      t.sheenColorMap && t.sheenColorMap.isTexture === !0 ? r = s.mul(this.getTexture("sheenColor").rgb) : r = s;
    } else if (n === J.SHEEN_ROUGHNESS) {
      const s = this.getFloat(n);
      t.sheenRoughnessMap && t.sheenRoughnessMap.isTexture === !0 ? r = s.mul(this.getTexture(n).a) : r = s, r = r.clamp(1e-4, 1);
    } else if (n === J.ANISOTROPY)
      if (t.anisotropyMap && t.anisotropyMap.isTexture === !0) {
        const s = this.getTexture(n);
        r = Eg(Yl.x, Yl.y, Yl.y.negate(), Yl.x).mul(s.rg.mul(2).sub(Pe(1)).normalize().mul(s.b));
      } else
        r = Yl;
    else if (n === J.IRIDESCENCE_THICKNESS) {
      const s = Qt("1", "float", t.iridescenceThicknessRange);
      if (t.iridescenceThicknessMap) {
        const a = Qt("0", "float", t.iridescenceThicknessRange);
        r = s.sub(a).mul(this.getTexture(n).g).add(a);
      } else
        r = s;
    } else if (n === J.TRANSMISSION) {
      const s = this.getFloat(n);
      t.transmissionMap ? r = s.mul(this.getTexture(n).r) : r = s;
    } else if (n === J.THICKNESS) {
      const s = this.getFloat(n);
      t.thicknessMap ? r = s.mul(this.getTexture(n).g) : r = s;
    } else if (n === J.IOR)
      r = this.getFloat(n);
    else if (n === J.LIGHT_MAP)
      r = this.getTexture(n).rgb.mul(this.getFloat("lightMapIntensity"));
    else if (n === J.AO)
      r = this.getTexture(n).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1);
    else if (n === J.LINE_DASH_OFFSET)
      r = t.dashOffset ? this.getFloat(n) : K(0);
    else {
      const s = this.getNodeType(e);
      r = this.getCache(n, s);
    }
    return r;
  }
}
J.ALPHA_TEST = "alphaTest";
J.COLOR = "color";
J.OPACITY = "opacity";
J.SHININESS = "shininess";
J.SPECULAR = "specular";
J.SPECULAR_STRENGTH = "specularStrength";
J.SPECULAR_INTENSITY = "specularIntensity";
J.SPECULAR_COLOR = "specularColor";
J.REFLECTIVITY = "reflectivity";
J.ROUGHNESS = "roughness";
J.METALNESS = "metalness";
J.NORMAL = "normal";
J.CLEARCOAT = "clearcoat";
J.CLEARCOAT_ROUGHNESS = "clearcoatRoughness";
J.CLEARCOAT_NORMAL = "clearcoatNormal";
J.EMISSIVE = "emissive";
J.ROTATION = "rotation";
J.SHEEN = "sheen";
J.SHEEN_ROUGHNESS = "sheenRoughness";
J.ANISOTROPY = "anisotropy";
J.IRIDESCENCE = "iridescence";
J.IRIDESCENCE_IOR = "iridescenceIOR";
J.IRIDESCENCE_THICKNESS = "iridescenceThickness";
J.IOR = "ior";
J.TRANSMISSION = "transmission";
J.THICKNESS = "thickness";
J.ATTENUATION_DISTANCE = "attenuationDistance";
J.ATTENUATION_COLOR = "attenuationColor";
J.LINE_SCALE = "scale";
J.LINE_DASH_SIZE = "dashSize";
J.LINE_GAP_SIZE = "gapSize";
J.LINE_WIDTH = "linewidth";
J.LINE_DASH_OFFSET = "dashOffset";
J.POINT_SIZE = "size";
J.DISPERSION = "dispersion";
J.LIGHT_MAP = "light";
J.AO = "ao";
const hU = /* @__PURE__ */ xe(J, J.ALPHA_TEST), dU = /* @__PURE__ */ xe(J, J.COLOR), fU = /* @__PURE__ */ xe(J, J.SHININESS), pU = /* @__PURE__ */ xe(J, J.EMISSIVE), SS = /* @__PURE__ */ xe(J, J.OPACITY), mU = /* @__PURE__ */ xe(J, J.SPECULAR), lx = /* @__PURE__ */ xe(J, J.SPECULAR_INTENSITY), gU = /* @__PURE__ */ xe(J, J.SPECULAR_COLOR), Ch = /* @__PURE__ */ xe(J, J.SPECULAR_STRENGTH), Gf = /* @__PURE__ */ xe(J, J.REFLECTIVITY), _U = /* @__PURE__ */ xe(J, J.ROUGHNESS), xU = /* @__PURE__ */ xe(J, J.METALNESS), vU = /* @__PURE__ */ xe(J, J.NORMAL), yU = /* @__PURE__ */ xe(J, J.CLEARCOAT), bU = /* @__PURE__ */ xe(J, J.CLEARCOAT_ROUGHNESS), SU = /* @__PURE__ */ xe(J, J.CLEARCOAT_NORMAL), TU = /* @__PURE__ */ xe(J, J.ROTATION), MU = /* @__PURE__ */ xe(J, J.SHEEN), EU = /* @__PURE__ */ xe(J, J.SHEEN_ROUGHNESS), wU = /* @__PURE__ */ xe(J, J.ANISOTROPY), AU = /* @__PURE__ */ xe(J, J.IRIDESCENCE), RU = /* @__PURE__ */ xe(J, J.IRIDESCENCE_IOR), CU = /* @__PURE__ */ xe(J, J.IRIDESCENCE_THICKNESS), NU = /* @__PURE__ */ xe(J, J.TRANSMISSION), PU = /* @__PURE__ */ xe(J, J.THICKNESS), DU = /* @__PURE__ */ xe(J, J.IOR), LU = /* @__PURE__ */ xe(J, J.ATTENUATION_DISTANCE), FU = /* @__PURE__ */ xe(J, J.ATTENUATION_COLOR), IU = /* @__PURE__ */ xe(J, J.LINE_SCALE), UU = /* @__PURE__ */ xe(J, J.LINE_DASH_SIZE), BU = /* @__PURE__ */ xe(J, J.LINE_GAP_SIZE);
J.LINE_WIDTH;
const OU = /* @__PURE__ */ xe(J, J.LINE_DASH_OFFSET), kU = /* @__PURE__ */ xe(J, J.POINT_SIZE), GU = /* @__PURE__ */ xe(J, J.DISPERSION), TS = /* @__PURE__ */ xe(J, J.LIGHT_MAP), VU = /* @__PURE__ */ xe(J, J.AO), Yl = /* @__PURE__ */ je(new de()).onReference(function(i) {
  return i.material;
}).onRenderUpdate(function({ material: i }) {
  this.value.set(i.anisotropy * Math.cos(i.anisotropyRotation), i.anisotropy * Math.sin(i.anisotropyRotation));
}), zU = /* @__PURE__ */ ee((i) => i.context.setupModelViewProjection(), "vec4").once()().toVarying("v_modelViewProjection");
class HU extends wl {
  static get type() {
    return "StorageArrayElementNode";
  }
  /**
   * Constructs storage buffer element node.
   *
   * @param {StorageBufferNode} storageBufferNode - The storage buffer node.
   * @param {Node} indexNode - The index node that defines the element access.
   */
  constructor(e, t) {
    super(e, t), this.isStorageArrayElementNode = !0;
  }
  /**
   * The storage buffer node.
   *
   * @param {Node} value
   * @type {StorageBufferNode}
   */
  set storageBufferNode(e) {
    this.node = e;
  }
  get storageBufferNode() {
    return this.node;
  }
  getMemberType(e, t) {
    const n = this.storageBufferNode.structTypeNode;
    return n ? n.getMemberType(e, t) : "void";
  }
  setup(e) {
    return e.isAvailable("storageBuffer") === !1 && this.node.isPBO === !0 && e.setupPBO(this.node), super.setup(e);
  }
  generate(e, t) {
    let n;
    const r = e.context.assign;
    if (e.isAvailable("storageBuffer") === !1 ? this.node.isPBO === !0 && r !== !0 && (this.node.value.isInstancedBufferAttribute || e.shaderStage !== "compute") ? n = e.generatePBO(this) : n = this.node.build(e) : n = super.generate(e), r !== !0) {
      const s = this.getNodeType(e);
      n = e.format(n, s, t);
    }
    return n;
  }
}
const $U = /* @__PURE__ */ Mt(HU).setParameterLength(2);
class WU extends Ig {
  static get type() {
    return "StorageBufferNode";
  }
  /**
   * Constructs a new storage buffer node.
   *
   * @param {StorageBufferAttribute|StorageInstancedBufferAttribute|BufferAttribute} value - The buffer data.
   * @param {?(string|Struct)} [bufferType=null] - The buffer type (e.g. `'vec3'`).
   * @param {number} [bufferCount=0] - The buffer count.
   */
  constructor(e, t = null, n = 0) {
    let r, s = null;
    t && t.isStruct ? (r = "struct", s = t.layout, (e.isStorageBufferAttribute || e.isStorageInstancedBufferAttribute) && (n = e.count)) : t === null && (e.isStorageBufferAttribute || e.isStorageInstancedBufferAttribute) ? (r = vb(e.itemSize), n = e.count) : r = t, super(e, r, n), this.isStorageBufferNode = !0, this.structTypeNode = s, this.access = Bi.READ_WRITE, this.isAtomic = !1, this.isPBO = !1, this._attribute = null, this._varying = null, this.global = !0, e.isStorageBufferAttribute !== !0 && e.isStorageInstancedBufferAttribute !== !0 && (e.isInstancedBufferAttribute ? e.isStorageInstancedBufferAttribute = !0 : e.isStorageBufferAttribute = !0);
  }
  /**
   * This method is overwritten since the buffer data might be shared
   * and thus the hash should be shared as well.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The hash.
   */
  getHash(e) {
    if (this.bufferCount === 0) {
      let t = e.globalCache.getData(this.value);
      return t === void 0 && (t = {
        node: this
      }, e.globalCache.setData(this.value, t)), t.node.uuid;
    }
    return this.uuid;
  }
  /**
   * Overwrites the default implementation to return a fixed value `'indirectStorageBuffer'` or `'storageBuffer'`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return this.value.isIndirectStorageBufferAttribute ? "indirectStorageBuffer" : "storageBuffer";
  }
  /**
   * Enables element access with the given index node.
   *
   * @param {IndexNode} indexNode - The index node.
   * @return {StorageArrayElementNode} A node representing the element access.
   */
  element(e) {
    return $U(this, e);
  }
  /**
   * Defines whether this node is a PBO or not. Only relevant for WebGL.
   *
   * @param {boolean} value - The value so set.
   * @return {StorageBufferNode} A reference to this node.
   */
  setPBO(e) {
    return this.isPBO = e, this;
  }
  /**
   * Returns the `isPBO` value.
   *
   * @return {boolean} Whether the node represents a PBO or not.
   */
  getPBO() {
    return this.isPBO;
  }
  /**
   * Defines the node access.
   *
   * @param {string} value - The node access.
   * @return {StorageBufferNode} A reference to this node.
   */
  setAccess(e) {
    return this.access = e, this;
  }
  /**
   * Convenience method for configuring a read-only node access.
   *
   * @return {StorageBufferNode} A reference to this node.
   */
  toReadOnly() {
    return this.setAccess(Bi.READ_ONLY);
  }
  /**
   * Defines whether the node is atomic or not.
   *
   * @param {boolean} value - The atomic flag.
   * @return {StorageBufferNode} A reference to this node.
   */
  setAtomic(e) {
    return this.isAtomic = e, this;
  }
  /**
   * Convenience method for making this node atomic.
   *
   * @return {StorageBufferNode} A reference to this node.
   */
  toAtomic() {
    return this.setAtomic(!0);
  }
  /**
   * Returns attribute data for this storage buffer node.
   *
   * @return {{attribute: BufferAttributeNode, varying: VaryingNode}} The attribute data.
   */
  getAttributeData() {
    return this._attribute === null && (this._attribute = eS(this.value), this._varying = Xa(this._attribute)), {
      attribute: this._attribute,
      varying: this._varying
    };
  }
  /**
   * This method is overwritten since the node type from the availability of storage buffers
   * and the attribute data.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    if (this.structTypeNode !== null)
      return this.structTypeNode.getNodeType(e);
    if (e.isAvailable("storageBuffer") || e.isAvailable("indirectStorageBuffer"))
      return super.getNodeType(e);
    const { attribute: t } = this.getAttributeData();
    return t.getNodeType(e);
  }
  /**
   * Returns the type of a member of the struct.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The name of the member.
   * @return {string} The type of the member.
   */
  getMemberType(e, t) {
    return this.structTypeNode !== null ? this.structTypeNode.getMemberType(e, t) : "void";
  }
  /**
   * Generates the code snippet of the storage buffer node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The generated code snippet.
   */
  generate(e) {
    if (this.structTypeNode !== null && this.structTypeNode.build(e), e.isAvailable("storageBuffer") || e.isAvailable("indirectStorageBuffer"))
      return super.generate(e);
    const { attribute: t, varying: n } = this.getAttributeData(), r = n.build(e);
    return e.registerTransform(r, t), r;
  }
}
const cx = (i, e = null, t = 0) => new WU(i, e, t);
class Jt extends Fe {
  static get type() {
    return "IndexNode";
  }
  /**
   * Constructs a new index node.
   *
   * @param {('vertex'|'instance'|'subgroup'|'invocationLocal'|'invocationGlobal'|'invocationSubgroup'|'draw')} scope - The scope of the index node.
   */
  constructor(e) {
    super("uint"), this.scope = e, this.isIndexNode = !0;
  }
  generate(e) {
    const t = this.getNodeType(e), n = this.scope;
    let r;
    if (n === Jt.VERTEX)
      r = e.getVertexIndex();
    else if (n === Jt.INSTANCE)
      r = e.getInstanceIndex();
    else if (n === Jt.DRAW)
      r = e.getDrawIndex();
    else if (n === Jt.INVOCATION_LOCAL)
      r = e.getInvocationLocalIndex();
    else if (n === Jt.INVOCATION_SUBGROUP)
      r = e.getInvocationSubgroupIndex();
    else if (n === Jt.SUBGROUP)
      r = e.getSubgroupIndex();
    else
      throw new Error("THREE.IndexNode: Unknown scope: " + n);
    let s;
    return e.shaderStage === "vertex" || e.shaderStage === "compute" ? s = r : s = Xa(this).build(e, t), s;
  }
}
Jt.VERTEX = "vertex";
Jt.INSTANCE = "instance";
Jt.SUBGROUP = "subgroup";
Jt.INVOCATION_LOCAL = "invocationLocal";
Jt.INVOCATION_SUBGROUP = "invocationSubgroup";
Jt.DRAW = "draw";
const qU = /* @__PURE__ */ xe(Jt, Jt.VERTEX), Mc = /* @__PURE__ */ xe(Jt, Jt.INSTANCE);
Jt.SUBGROUP;
Jt.INVOCATION_SUBGROUP;
Jt.INVOCATION_LOCAL;
const XU = /* @__PURE__ */ xe(Jt, Jt.DRAW);
class jU extends Fe {
  static get type() {
    return "InstanceNode";
  }
  /**
   * Constructs a new instance node.
   *
   * @param {number} count - The number of instances.
   * @param {InstancedBufferAttribute|StorageInstancedBufferAttribute} instanceMatrix - Instanced buffer attribute representing the instance transformations.
   * @param {?InstancedBufferAttribute|StorageInstancedBufferAttribute} instanceColor - Instanced buffer attribute representing the instance colors.
   */
  constructor(e, t, n = null) {
    super("void"), this.count = e, this.instanceMatrix = t, this.instanceColor = n, this.instanceMatrixNode = null, this.instanceColorNode = null, this.updateType = it.FRAME, this.buffer = null, this.bufferColor = null, this.previousInstanceMatrixNode = null;
  }
  /**
   * Tracks whether the matrix data is provided via a storage buffer.
   *
   * @type {boolean}
   */
  get isStorageMatrix() {
    const { instanceMatrix: e } = this;
    return e && e.isStorageInstancedBufferAttribute === !0;
  }
  /**
   * Tracks whether the color data is provided via a storage buffer.
   *
   * @type {boolean}
   */
  get isStorageColor() {
    const { instanceColor: e } = this;
    return e && e.isStorageInstancedBufferAttribute === !0;
  }
  /**
   * Setups the internal buffers and nodes and assigns the transformed vertex data
   * to predefined node variables for accumulation. That follows the same patterns
   * like with morph and skinning nodes.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    let { instanceMatrixNode: t, instanceColorNode: n } = this;
    t === null && (t = this._createInstanceMatrixNode(!0, e), this.instanceMatrixNode = t);
    const { instanceColor: r, isStorageColor: s } = this;
    if (r && n === null) {
      if (s)
        n = cx(r, "vec3", Math.max(r.count, 1)).element(Mc);
      else {
        const o = new hE(r.array, 3), l = r.usage === Dh ? Q0 : Z0;
        this.bufferColor = o, n = Y(l(o, "vec3", 3, 0));
      }
      this.instanceColorNode = n;
    }
    const a = t.mul(Cn).xyz;
    if (Cn.assign(a), e.needsPreviousData() && Wh.assign(this.getPreviousInstancedPosition(e)), e.hasGeometryAttribute("normal")) {
      const o = VI(Dr, t);
      Dr.assign(o);
    }
    this.instanceColorNode !== null && $h("vec3", "vInstanceColor").assign(this.instanceColorNode);
  }
  /**
   * Checks if the internal buffers require an update.
   *
   * @param {NodeFrame} frame - The current node frame.
   */
  update(e) {
    this.buffer !== null && this.isStorageMatrix !== !0 && (this.buffer.clearUpdateRanges(), this.buffer.updateRanges.push(...this.instanceMatrix.updateRanges), this.instanceMatrix.version !== this.buffer.version && (this.buffer.version = this.instanceMatrix.version)), this.instanceColor && this.bufferColor !== null && this.isStorageColor !== !0 && (this.bufferColor.clearUpdateRanges(), this.bufferColor.updateRanges.push(...this.instanceColor.updateRanges), this.instanceColor.version !== this.bufferColor.version && (this.bufferColor.version = this.instanceColor.version)), this.previousInstanceMatrixNode !== null && e.object.previousInstanceMatrix.array.set(this.instanceMatrix.array);
  }
  /**
   * Computes the transformed/instanced vertex position of the previous frame.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The instanced position from the previous frame.
   */
  getPreviousInstancedPosition(e) {
    const t = e.object;
    return this.previousInstanceMatrixNode === null && (t.previousInstanceMatrix = this.instanceMatrix.clone(), this.previousInstanceMatrixNode = this._createInstanceMatrixNode(!1, e)), this.previousInstanceMatrixNode.mul(Wh).xyz;
  }
  /**
   * Creates a node representing the instance matrix data.
   *
   * @private
   * @param {boolean} assignBuffer - Whether the created interleaved buffer should be assigned to the `buffer` member or not.
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {Node} The instance matrix node.
   */
  _createInstanceMatrixNode(e, t) {
    let n;
    const { instanceMatrix: r } = this, { count: s } = r;
    if (this.isStorageMatrix)
      n = cx(r, "mat4", Math.max(s, 1)).element(Mc);
    else if (s * 16 * 4 <= t.getUniformBufferLimit())
      n = aS(r.array, "mat4", Math.max(s, 1)).element(Mc);
    else {
      const o = new sw(r.array, 16, 1);
      e === !0 && (this.buffer = o);
      const l = r.usage === Dh ? Q0 : Z0, c = [
        l(o, "vec4", 16, 0),
        l(o, "vec4", 16, 4),
        l(o, "vec4", 16, 8),
        l(o, "vec4", 16, 12)
      ];
      n = Ta(...c);
    }
    return n;
  }
}
class YU extends jU {
  static get type() {
    return "InstancedMeshNode";
  }
  /**
   * Constructs a new instanced mesh node.
   *
   * @param {InstancedMesh} instancedMesh - The instanced mesh.
   */
  constructor(e) {
    const { count: t, instanceMatrix: n, instanceColor: r } = e;
    super(t, n, r), this.instancedMesh = e;
  }
}
const KU = /* @__PURE__ */ Mt(YU).setParameterLength(1);
class ZU extends Fe {
  static get type() {
    return "BatchNode";
  }
  /**
   * Constructs a new batch node.
   *
   * @param {BatchedMesh} batchMesh - A reference to batched mesh.
   */
  constructor(e) {
    super("void"), this.batchMesh = e, this.batchingIdNode = null;
  }
  /**
   * Setups the internal buffers and nodes and assigns the transformed vertex data
   * to predefined node variables for accumulation. That follows the same patterns
   * like with morph and skinning nodes.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    this.batchingIdNode === null && (e.getDrawIndex() === null ? this.batchingIdNode = Mc : this.batchingIdNode = XU);
    const n = ee(([p]) => {
      const _ = Kt(Bo(Fi(this.batchMesh._indirectTexture), 0).x).toConst(), g = Kt(p).mod(_).toConst(), m = Kt(p).div(_).toConst();
      return Fi(this.batchMesh._indirectTexture, gr(g, m)).x;
    }).setLayout({
      name: "getIndirectIndex",
      type: "uint",
      inputs: [
        { name: "id", type: "int" }
      ]
    })(Kt(this.batchingIdNode)), r = this.batchMesh._matricesTexture, s = Kt(Bo(Fi(r), 0).x).toConst(), a = K(n).mul(4).toInt().toConst(), o = a.mod(s).toConst(), l = a.div(s).toConst(), c = Ta(
      Fi(r, gr(o, l)),
      Fi(r, gr(o.add(1), l)),
      Fi(r, gr(o.add(2), l)),
      Fi(r, gr(o.add(3), l))
    ), u = this.batchMesh._colorsTexture;
    if (u !== null) {
      const _ = ee(([g]) => {
        const m = Kt(Bo(Fi(u), 0).x).toConst(), x = g, y = x.mod(m).toConst(), b = x.div(m).toConst();
        return Fi(u, gr(y, b)).rgb;
      }).setLayout({
        name: "getBatchingColor",
        type: "vec3",
        inputs: [
          { name: "id", type: "int" }
        ]
      })(n);
      $h("vec3", "vBatchColor").assign(_);
    }
    const h = On(c);
    Cn.assign(c.mul(Cn));
    const d = Dr.div(Y(h[0].dot(h[0]), h[1].dot(h[1]), h[2].dot(h[2]))), f = h.mul(d).xyz;
    Dr.assign(f), e.hasGeometryAttribute("tangent") && qh.mulAssign(h);
  }
}
const QU = /* @__PURE__ */ Mt(ZU).setParameterLength(1), ux = /* @__PURE__ */ new WeakMap();
class JU extends Fe {
  static get type() {
    return "SkinningNode";
  }
  /**
   * Constructs a new skinning node.
   *
   * @param {SkinnedMesh} skinnedMesh - The skinned mesh.
   */
  constructor(e) {
    super("void"), this.skinnedMesh = e, this.updateType = it.OBJECT, this.skinIndexNode = Ws("skinIndex", "uvec4"), this.skinWeightNode = Ws("skinWeight", "vec4"), this.bindMatrixNode = Qt("bindMatrix", "mat4"), this.bindMatrixInverseNode = Qt("bindMatrixInverse", "mat4"), this.boneMatricesNode = ix("skeleton.boneMatrices", "mat4", e.skeleton.bones.length), this.positionNode = Cn, this.toPositionNode = Cn, this.previousBoneMatricesNode = null;
  }
  /**
   * Transforms the given vertex position via skinning.
   *
   * @param {Node} [boneMatrices=this.boneMatricesNode] - The bone matrices
   * @param {Node<vec3>} [position=this.positionNode] - The vertex position in local space.
   * @return {Node<vec3>} The transformed vertex position.
   */
  getSkinnedPosition(e = this.boneMatricesNode, t = this.positionNode) {
    const { skinIndexNode: n, skinWeightNode: r, bindMatrixNode: s, bindMatrixInverseNode: a } = this, o = e.element(n.x), l = e.element(n.y), c = e.element(n.z), u = e.element(n.w), h = s.mul(t), d = _i(
      o.mul(r.x).mul(h),
      l.mul(r.y).mul(h),
      c.mul(r.z).mul(h),
      u.mul(r.w).mul(h)
    );
    return a.mul(d).xyz;
  }
  /**
   * Transforms the given vertex normal and tangent via skinning.
   *
   * @param {Node} [boneMatrices=this.boneMatricesNode] - The bone matrices
   * @param {Node<vec3>} [normal=normalLocal] - The vertex normal in local space.
   * @param {Node<vec3>} [tangent=tangentLocal] - The vertex tangent in local space.
   * @return {{skinNormal: Node<vec3>, skinTangent:Node<vec3>}} The transformed vertex normal and tangent.
   */
  getSkinnedNormalAndTangent(e = this.boneMatricesNode, t = Dr, n = qh) {
    const { skinIndexNode: r, skinWeightNode: s, bindMatrixNode: a, bindMatrixInverseNode: o } = this, l = e.element(r.x), c = e.element(r.y), u = e.element(r.z), h = e.element(r.w);
    let d = _i(
      s.x.mul(l),
      s.y.mul(c),
      s.z.mul(u),
      s.w.mul(h)
    );
    d = o.mul(d).mul(a);
    const f = d.transformDirection(t).xyz, p = d.transformDirection(n).xyz;
    return { skinNormal: f, skinTangent: p };
  }
  /**
   * Computes the transformed/skinned vertex position of the previous frame.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The skinned position from the previous frame.
   */
  getPreviousSkinnedPosition(e) {
    const t = e.object;
    return this.previousBoneMatricesNode === null && (t.skeleton.previousBoneMatrices = new Float32Array(t.skeleton.boneMatrices), this.previousBoneMatricesNode = ix("skeleton.previousBoneMatrices", "mat4", t.skeleton.bones.length)), this.getSkinnedPosition(this.previousBoneMatricesNode, Wh);
  }
  /**
   * Setups the skinning node by assigning the transformed vertex data to predefined node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The transformed vertex position.
   */
  setup(e) {
    e.needsPreviousData() && Wh.assign(this.getPreviousSkinnedPosition(e));
    const t = this.getSkinnedPosition();
    if (this.toPositionNode && this.toPositionNode.assign(t), e.hasGeometryAttribute("normal")) {
      const { skinNormal: n, skinTangent: r } = this.getSkinnedNormalAndTangent();
      Dr.assign(n), e.hasGeometryAttribute("tangent") && qh.assign(r);
    }
    return t;
  }
  /**
   * Generates the code snippet of the skinning node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} output - The current output.
   * @return {string} The generated code snippet.
   */
  generate(e, t) {
    if (t !== "void")
      return super.generate(e, t);
  }
  /**
   * Updates the state of the skinned mesh by updating the skeleton once per frame.
   *
   * @param {NodeFrame} frame - The current node frame.
   */
  update(e) {
    const t = e.object && e.object.skeleton ? e.object.skeleton : this.skinnedMesh.skeleton;
    ux.get(t) !== e.frameId && (ux.set(t, e.frameId), this.previousBoneMatricesNode !== null && (t.previousBoneMatrices === null && (t.previousBoneMatrices = new Float32Array(t.boneMatrices)), t.previousBoneMatrices.set(t.boneMatrices)), t.update());
  }
}
const e3 = (i) => new JU(i);
class t3 extends Fe {
  static get type() {
    return "LoopNode";
  }
  /**
   * Constructs a new loop node.
   *
   * @param {Array<any>} params - Depending on the loop type, array holds different parameterization values for the loop.
   */
  constructor(e = []) {
    super("void"), this.params = e;
  }
  /**
   * Returns a loop variable name based on an index. The pattern is
   * `0` = `i`, `1`= `j`, `2`= `k` and so on.
   *
   * @param {number} index - The index.
   * @return {string} The loop variable name.
   */
  getVarName(e) {
    return String.fromCharCode(105 + e);
  }
  /**
   * Returns properties about this node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Object} The node properties.
   */
  getProperties(e) {
    const t = e.getNodeProperties(this);
    if (t.stackNode !== void 0)
      return t;
    const n = {};
    for (let o = 0, l = this.params.length - 1; o < l; o++) {
      const c = this.params[o], u = c.isNode !== !0 && c.name || this.getVarName(o), h = c.isNode !== !0 && c.type || "int";
      n[u] = vr(u, h);
    }
    const r = e.addStack(), s = this.params[this.params.length - 1](n);
    t.returnsNode = s.context({ nodeLoop: s }), t.stackNode = r;
    const a = this.params[0];
    if (a.isNode !== !0 && typeof a.update == "function") {
      const o = ee(this.params[0].update)(n);
      t.updateNode = o.context({ nodeLoop: o });
    }
    return e.removeStack(), t;
  }
  setup(e) {
    if (this.getProperties(e), e.fnCall) {
      const t = e.getDataFromNode(e.fnCall.shaderNode);
      t.hasLoop = !0;
    }
  }
  generate(e) {
    const t = this.getProperties(e), n = this.params, r = t.stackNode;
    for (let a = 0, o = n.length - 1; a < o; a++) {
      const l = n[a];
      let c = !1, u = null, h = null, d = null, f = null, p = null, _ = null;
      l.isNode ? l.getNodeType(e) === "bool" ? (c = !0, f = "bool", h = l.build(e, f)) : (f = "int", d = this.getVarName(a), u = "0", h = l.build(e, f), p = "<") : (f = l.type || "int", d = l.name || this.getVarName(a), u = l.start, h = l.end, p = l.condition, _ = l.update, typeof u == "number" ? u = e.generateConst(f, u) : u && u.isNode && (u = u.build(e, f)), typeof h == "number" ? h = e.generateConst(f, h) : h && h.isNode && (h = h.build(e, f)), u !== void 0 && h === void 0 ? (u = u + " - 1", h = "0", p = ">=") : h !== void 0 && u === void 0 && (u = "0", p = "<"), p === void 0 && (Number(u) > Number(h) ? p = ">=" : p = "<"));
      let g;
      if (c)
        g = `while ( ${h} )`;
      else {
        const m = { start: u, end: h }, x = m.start, y = m.end;
        let b;
        const T = () => p.includes("<") ? "+=" : "-=";
        if (_ != null)
          switch (typeof _) {
            case "function":
              b = e.flowStagesNode(t.updateNode, "void").code.replace(/\t|;/g, "");
              break;
            case "number":
              b = d + " " + T() + " " + e.generateConst(f, _);
              break;
            case "string":
              b = d + " " + _;
              break;
            default:
              _.isNode ? b = d + " " + T() + " " + _.build(e) : (le("TSL: 'Loop( { update: ... } )' is not a function, string or number.", this.stackTrace), b = "break /* invalid update */");
          }
        else
          f === "int" || f === "uint" ? _ = p.includes("<") ? "++" : "--" : _ = T() + " 1.", b = d + " " + _;
        const S = e.getVar(f, d) + " = " + x, E = d + " " + p + " " + y;
        g = `for ( ${S}; ${E}; ${b} )`;
      }
      e.addFlowCode((a === 0 ? `
` : "") + e.tab + g + ` {

`).addFlowTab();
    }
    const s = r.build(e, "void");
    t.returnsNode.build(e, "void"), e.removeFlowTab().addFlowCode(`
` + e.tab + s);
    for (let a = 0, o = this.params.length - 1; a < o; a++)
      e.addFlowCode((a === 0 ? "" : e.tab) + `}

`).removeFlowTab();
    e.addFlowTab();
  }
}
const Ui = (...i) => new t3(Fo(i, "int")).toStack(), n3 = () => vr("break").toStack(), Vf = /* @__PURE__ */ new WeakMap(), Mi = /* @__PURE__ */ new rt(), hx = /* @__PURE__ */ ee(({ bufferMap: i, influence: e, stride: t, width: n, depth: r, offset: s }) => {
  const a = Kt(qU).mul(t).add(s), o = a.div(n), l = a.sub(o.mul(n));
  return Fi(i, gr(l, o)).depth(r).xyz.mul(e);
});
function i3(i) {
  const e = i.morphAttributes.position !== void 0, t = i.morphAttributes.normal !== void 0, n = i.morphAttributes.color !== void 0, r = i.morphAttributes.position || i.morphAttributes.normal || i.morphAttributes.color, s = r !== void 0 ? r.length : 0;
  let a = Vf.get(i);
  if (a === void 0 || a.count !== s) {
    let m = function() {
      _.dispose(), Vf.delete(i), i.removeEventListener("dispose", m);
    };
    a !== void 0 && a.texture.dispose();
    const o = i.morphAttributes.position || [], l = i.morphAttributes.normal || [], c = i.morphAttributes.color || [];
    let u = 0;
    e === !0 && (u = 1), t === !0 && (u = 2), n === !0 && (u = 3);
    let h = i.attributes.position.count * u, d = 1;
    const f = 4096;
    h > f && (d = Math.ceil(h / f), h = f);
    const p = new Float32Array(h * d * 4 * s), _ = new Wm(p, h, d, s);
    _.type = ln, _.needsUpdate = !0;
    const g = u * 4;
    for (let x = 0; x < s; x++) {
      const y = o[x], b = l[x], T = c[x], S = h * d * 4 * x;
      for (let E = 0; E < y.count; E++) {
        const v = E * g;
        e === !0 && (Mi.fromBufferAttribute(y, E), p[S + v + 0] = Mi.x, p[S + v + 1] = Mi.y, p[S + v + 2] = Mi.z, p[S + v + 3] = 0), t === !0 && (Mi.fromBufferAttribute(b, E), p[S + v + 4] = Mi.x, p[S + v + 5] = Mi.y, p[S + v + 6] = Mi.z, p[S + v + 7] = 0), n === !0 && (Mi.fromBufferAttribute(T, E), p[S + v + 8] = Mi.x, p[S + v + 9] = Mi.y, p[S + v + 10] = Mi.z, p[S + v + 11] = T.itemSize === 4 ? Mi.w : 1);
      }
    }
    a = {
      count: s,
      texture: _,
      stride: u,
      size: new de(h, d)
    }, Vf.set(i, a), i.addEventListener("dispose", m);
  }
  return a;
}
class r3 extends Fe {
  static get type() {
    return "MorphNode";
  }
  /**
   * Constructs a new morph node.
   *
   * @param {Mesh} mesh - The mesh holding the morph targets.
   */
  constructor(e) {
    super("void"), this.mesh = e, this.morphBaseInfluence = je(1), this.updateType = it.OBJECT;
  }
  /**
   * Setups the morph node by assigning the transformed vertex data to predefined node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    const { geometry: t } = e, n = t.morphAttributes.position !== void 0, r = t.hasAttribute("normal") && t.morphAttributes.normal !== void 0, s = t.morphAttributes.position || t.morphAttributes.normal || t.morphAttributes.color, a = s !== void 0 ? s.length : 0, { texture: o, stride: l, size: c } = i3(t);
    n === !0 && Cn.mulAssign(this.morphBaseInfluence), r === !0 && Dr.mulAssign(this.morphBaseInfluence);
    const u = Kt(c.width);
    Ui(a, ({ i: h }) => {
      const d = K(0).toVar();
      this.mesh.count > 1 && this.mesh.morphTexture !== null && this.mesh.morphTexture !== void 0 ? d.assign(Fi(this.mesh.morphTexture, gr(Kt(h).add(1), Kt(Mc))).r) : d.assign(Qt("morphTargetInfluences", "float").element(h).toVar()), Bt(d.notEqual(0), () => {
        n === !0 && Cn.addAssign(hx({
          bufferMap: o,
          influence: d,
          stride: l,
          width: u,
          depth: h,
          offset: Kt(0)
        })), r === !0 && Dr.addAssign(hx({
          bufferMap: o,
          influence: d,
          stride: l,
          width: u,
          depth: h,
          offset: Kt(1)
        }));
      });
    });
  }
  /**
   * Updates the state of the morphed mesh by updating the base influence.
   *
   * @param {NodeFrame} frame - The current node frame.
   */
  update() {
    const e = this.morphBaseInfluence;
    this.mesh.geometry.morphTargetsRelative ? e.value = 1 : e.value = 1 - this.mesh.morphTargetInfluences.reduce((t, n) => t + n, 0);
  }
}
const s3 = /* @__PURE__ */ Mt(r3).setParameterLength(1);
class Dl extends Fe {
  static get type() {
    return "LightingNode";
  }
  /**
   * Constructs a new lighting node.
   */
  constructor() {
    super("vec3"), this.isLightingNode = !0;
  }
}
class a3 extends Dl {
  static get type() {
    return "AONode";
  }
  /**
   * Constructs a new AO node.
   *
   * @param {?Node<float>} [aoNode=null] - The ambient occlusion node.
   */
  constructor(e = null) {
    super(), this.aoNode = e;
  }
  setup(e) {
    e.context.ambientOcclusion.mulAssign(this.aoNode);
  }
}
class o3 extends Kb {
  static get type() {
    return "LightingContextNode";
  }
  /**
   * Constructs a new lighting context node.
   *
   * @param {LightsNode} lightsNode - The lights node.
   * @param {?LightingModel} [lightingModel=null] - The current lighting model.
   * @param {?Node<vec3>} [backdropNode=null] - A backdrop node.
   * @param {?Node<float>} [backdropAlphaNode=null] - A backdrop alpha node.
   */
  constructor(e, t = null, n = null, r = null) {
    super(e), this.lightingModel = t, this.backdropNode = n, this.backdropAlphaNode = r, this._value = null;
  }
  /**
   * Returns a lighting context object.
   *
   * @return {{
   * radiance: Node<vec3>,
   * irradiance: Node<vec3>,
   * iblIrradiance: Node<vec3>,
   * ambientOcclusion: Node<float>,
   * reflectedLight: {directDiffuse: Node<vec3>, directSpecular: Node<vec3>, indirectDiffuse: Node<vec3>, indirectSpecular: Node<vec3>},
   * backdrop: Node<vec3>,
   * backdropAlpha: Node<float>
   * }} The lighting context object.
   */
  getContext() {
    const { backdropNode: e, backdropAlphaNode: t } = this, n = Y().toVar("directDiffuse"), r = Y().toVar("directSpecular"), s = Y().toVar("indirectDiffuse"), a = Y().toVar("indirectSpecular"), o = {
      directDiffuse: n,
      directSpecular: r,
      indirectDiffuse: s,
      indirectSpecular: a
    };
    return {
      radiance: Y().toVar("radiance"),
      irradiance: Y().toVar("irradiance"),
      iblIrradiance: Y().toVar("iblIrradiance"),
      ambientOcclusion: K(1).toVar("ambientOcclusion"),
      reflectedLight: o,
      backdrop: e,
      backdropAlpha: t
    };
  }
  setup(e) {
    return this.value = this._value || (this._value = this.getContext()), this.value.lightingModel = this.lightingModel || e.context.lightingModel, super.setup(e);
  }
}
const l3 = /* @__PURE__ */ Mt(o3);
class c3 extends Dl {
  static get type() {
    return "IrradianceNode";
  }
  /**
   * Constructs a new irradiance node.
   *
   * @param {Node<vec3>} node - A node contributing irradiance.
   */
  constructor(e) {
    super(), this.node = e;
  }
  setup(e) {
    e.context.irradiance.addAssign(this.node);
  }
}
const mo = /* @__PURE__ */ new de();
class MS extends Rl {
  static get type() {
    return "ViewportTextureNode";
  }
  /**
   * Constructs a new viewport texture node.
   *
   * @param {Node} [uvNode=screenUV] - The uv node.
   * @param {?Node} [levelNode=null] - The level node.
   * @param {?Texture} [framebufferTexture=null] - A framebuffer texture holding the viewport data. If not provided, a framebuffer texture is created automatically.
   */
  constructor(e = Ea, t = null, n = null) {
    let r = null;
    n === null ? (r = new ny(), r.minFilter = pi, n = r) : r = n, super(n, e, t), this.generateMipmaps = !1, this.defaultFramebuffer = r, this.isOutputTextureNode = !0, this.updateBeforeType = it.RENDER, this._cacheTextures = /* @__PURE__ */ new WeakMap();
  }
  /**
   * This methods returns a texture for the given render target reference.
   *
   * To avoid rendering errors, `ViewportTextureNode` must use unique framebuffer textures
   * for different render contexts.
   *
   * @param {?RenderTarget} [reference=null] - The render target reference.
   * @return {Texture} The framebuffer texture.
   */
  getTextureForReference(e = null) {
    let t, n;
    if (this.referenceNode ? (t = this.referenceNode.defaultFramebuffer, n = this.referenceNode._cacheTextures) : (t = this.defaultFramebuffer, n = this._cacheTextures), e === null)
      return t;
    if (n.has(e) === !1) {
      const r = t.clone();
      n.set(e, r);
    }
    return n.get(e);
  }
  updateReference(e) {
    const t = e.renderer.getRenderTarget();
    return this.value = this.getTextureForReference(t), this.value;
  }
  updateBefore(e) {
    const t = e.renderer, n = t.getRenderTarget();
    n === null ? t.getDrawingBufferSize(mo) : mo.set(n.width, n.height);
    const r = this.getTextureForReference(n);
    (r.image.width !== mo.width || r.image.height !== mo.height) && (r.image.width = mo.width, r.image.height = mo.height, r.needsUpdate = !0);
    const s = r.generateMipmaps;
    r.generateMipmaps = this.generateMipmaps, t.copyFramebufferToTexture(r), r.generateMipmaps = s;
  }
  clone() {
    const e = new this.constructor(this.uvNode, this.levelNode, this.value);
    return e.generateMipmaps = this.generateMipmaps, e;
  }
}
const ES = /* @__PURE__ */ Mt(MS, null, null, { generateMipmaps: !0 }).setParameterLength(0, 3), u3 = /* @__PURE__ */ ES(), h3 = (i = Ea, e = null) => u3.sample(i, e);
let Zu = null;
class d3 extends MS {
  static get type() {
    return "ViewportDepthTextureNode";
  }
  /**
   * Constructs a new viewport depth texture node.
   *
   * @param {Node} [uvNode=screenUV] - The uv node.
   * @param {?Node} [levelNode=null] - The level node.
   */
  constructor(e = Ea, t = null) {
    Zu === null && (Zu = new oi()), super(e, t, Zu);
  }
  /**
   * Overwritten so the method always returns the unique shared
   * depth texture.
   *
   * @return {DepthTexture} The shared depth texture.
   */
  getTextureForReference() {
    return Zu;
  }
}
const f3 = /* @__PURE__ */ Mt(d3).setParameterLength(0, 2);
class mi extends Fe {
  static get type() {
    return "ViewportDepthNode";
  }
  /**
   * Constructs a new viewport depth node.
   *
   * @param {('depth'|'depthBase'|'linearDepth')} scope - The node's scope.
   * @param {?Node} [valueNode=null] - The value node.
   */
  constructor(e, t = null) {
    super("float"), this.scope = e, this.valueNode = t, this.isViewportDepthNode = !0;
  }
  generate(e) {
    const { scope: t } = this;
    return t === mi.DEPTH_BASE ? e.getFragDepth() : super.generate(e);
  }
  setup({ camera: e }) {
    const { scope: t } = this, n = this.valueNode;
    let r = null;
    if (t === mi.DEPTH_BASE)
      n !== null && (r = CS().assign(n));
    else if (t === mi.DEPTH)
      e.isPerspectiveCamera ? r = wS(hn.z, ga, _a) : r = Ec(hn.z, ga, _a);
    else if (t === mi.LINEAR_DEPTH)
      if (n !== null)
        if (e.isPerspectiveCamera) {
          const s = AS(n, ga, _a);
          r = Ec(s, ga, _a);
        } else
          r = n;
      else
        r = Ec(hn.z, ga, _a);
    return r;
  }
}
mi.DEPTH_BASE = "depthBase";
mi.DEPTH = "depth";
mi.LINEAR_DEPTH = "linearDepth";
const Ec = (i, e, t) => i.add(e).div(e.sub(t)), wS = (i, e, t) => e.add(i).mul(t).div(t.sub(e).mul(i)), p3 = (i, e, t) => e.mul(i.add(t)).div(i.mul(e.sub(t))), AS = /* @__PURE__ */ ee(([i, e, t], n) => n.renderer.reversedDepthBuffer === !0 ? e.mul(t).div(e.sub(t).mul(i).sub(e)) : e.mul(t).div(t.sub(e).mul(i).sub(t))), RS = (i, e, t) => {
  e = e.max(1e-6).toVar();
  const n = ls(i.negate().div(e)), r = ls(t.div(e));
  return n.div(r);
}, CS = /* @__PURE__ */ Mt(mi, mi.DEPTH_BASE), NS = /* @__PURE__ */ xe(mi, mi.DEPTH), m3 = /* @__PURE__ */ Mt(mi, mi.LINEAR_DEPTH).setParameterLength(0, 1);
f3();
NS.assign = (i) => CS(i);
class ki extends Fe {
  static get type() {
    return "ClippingNode";
  }
  /**
   * Constructs a new clipping node.
   *
   * @param {('default'|'hardware'|'alphaToCoverage')} [scope='default'] - The node's scope. Similar to other nodes,
   * the selected scope influences the behavior of the node and what type of code is generated.
   */
  constructor(e = ki.DEFAULT) {
    super(), this.scope = e;
  }
  /**
   * Setups the node depending on the selected scope.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node} The result node.
   */
  setup(e) {
    super.setup(e);
    const t = e.clippingContext, { intersectionPlanes: n, unionPlanes: r } = t;
    return this.hardwareClipping = e.material.hardwareClipping, this.scope === ki.ALPHA_TO_COVERAGE ? this.setupAlphaToCoverage(n, r) : this.scope === ki.HARDWARE ? this.setupHardwareClipping(r, e) : this.setupDefault(n, r);
  }
  /**
   * Setups alpha to coverage.
   *
   * @param {Array<Vector4>} intersectionPlanes - The intersection planes.
   * @param {Array<Vector4>} unionPlanes - The union planes.
   * @return {Node} The result node.
   */
  setupAlphaToCoverage(e, t) {
    return ee(() => {
      const n = K().toVar("distanceToPlane"), r = K().toVar("distanceToGradient"), s = K(1).toVar("clipOpacity"), a = t.length;
      if (this.hardwareClipping === !1 && a > 0) {
        const l = Ii(t).setGroup(Xe);
        Ui(a, ({ i: c }) => {
          const u = l.element(c);
          n.assign(hn.dot(u.xyz).negate().add(u.w)), r.assign(n.fwidth().div(2)), s.mulAssign(hs(r.negate(), r, n));
        });
      }
      const o = e.length;
      if (o > 0) {
        const l = Ii(e).setGroup(Xe), c = K(1).toVar("intersectionClipOpacity");
        Ui(o, ({ i: u }) => {
          const h = l.element(u);
          n.assign(hn.dot(h.xyz).negate().add(h.w)), r.assign(n.fwidth().div(2)), c.mulAssign(hs(r.negate(), r, n).oneMinus());
        }), s.mulAssign(c.oneMinus());
      }
      Nt.a.mulAssign(s), Nt.a.equal(0).discard();
    })();
  }
  /**
   * Setups the default clipping.
   *
   * @param {Array<Vector4>} intersectionPlanes - The intersection planes.
   * @param {Array<Vector4>} unionPlanes - The union planes.
   * @return {Node} The result node.
   */
  setupDefault(e, t) {
    return ee(() => {
      const n = t.length;
      if (this.hardwareClipping === !1 && n > 0) {
        const s = Ii(t).setGroup(Xe);
        Ui(n, ({ i: a }) => {
          const o = s.element(a);
          hn.dot(o.xyz).greaterThan(o.w).discard();
        });
      }
      const r = e.length;
      if (r > 0) {
        const s = Ii(e).setGroup(Xe), a = Mg(!0).toVar("clipped");
        Ui(r, ({ i: o }) => {
          const l = s.element(o);
          a.assign(hn.dot(l.xyz).greaterThan(l.w).and(a));
        }), a.discard();
      }
    })();
  }
  /**
   * Setups hardware clipping.
   *
   * @param {Array<Vector4>} unionPlanes - The union planes.
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node} The result node.
   */
  setupHardwareClipping(e, t) {
    const n = e.length;
    return t.enableHardwareClipping(n), ee(() => {
      const r = Ii(e).setGroup(Xe), s = Cl(t.getClipDistance());
      Ui(n, ({ i: a }) => {
        const o = r.element(a), l = hn.dot(o.xyz).sub(o.w).negate();
        s.element(a).assign(l);
      });
    })();
  }
}
ki.ALPHA_TO_COVERAGE = "alphaToCoverage";
ki.DEFAULT = "default";
ki.HARDWARE = "hardware";
const g3 = () => new ki(), _3 = () => new ki(ki.ALPHA_TO_COVERAGE), x3 = () => new ki(ki.HARDWARE), v3 = 0.05, dx = /* @__PURE__ */ ee(([i]) => Pr(at(1e4, wi(at(17, i.x).add(at(0.1, i.y)))).mul(_i(0.1, Ai(wi(at(13, i.y).add(i.x))))))), fx = /* @__PURE__ */ ee(([i]) => dx(Pe(dx(i.xy), i.z))), y3 = /* @__PURE__ */ ee(([i]) => {
  const e = kn(
    cs(Hb(i.xyz)),
    cs($b(i.xyz))
  ), t = K(1).div(K(v3).mul(e)).toVar("pixScale"), n = Pe(
    Wc(Ma(ls(t))),
    Wc(Cg(ls(t)))
  ), r = Pe(
    fx(Ma(n.x.mul(i.xyz))),
    fx(Ma(n.y.mul(i.xyz)))
  ), s = Pr(ls(t)), a = _i(at(s.oneMinus(), r.x), at(s, r.y)), o = fl(s, s.oneMinus()), l = Y(
    a.mul(a).div(at(2, o).mul(ui(1, o))),
    a.sub(at(0.5, o)).div(ui(1, o)),
    ui(1, ui(1, a).mul(ui(1, a)).div(at(2, o).mul(ui(1, o))))
  ), c = a.lessThan(o.oneMinus()).select(a.lessThan(o).select(l.x, l.y), l.z);
  return $s(c, 1e-6, 1);
}).setLayout({
  name: "getAlphaHashThreshold",
  type: "float",
  inputs: [
    { name: "position", type: "vec3" }
  ]
});
class b3 extends rS {
  static get type() {
    return "VertexColorNode";
  }
  /**
   * Constructs a new vertex color node.
   *
   * @param {number} index - The attribute index.
   */
  constructor(e) {
    super(null, "vec4"), this.isVertexColorNode = !0, this.index = e;
  }
  /**
   * Overwrites the default implementation by honoring the attribute index.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The attribute name.
   */
  getAttributeName() {
    const e = this.index;
    return "color" + (e > 0 ? e : "");
  }
  generate(e) {
    const t = this.getAttributeName(e), n = e.hasGeometryAttribute(t);
    let r;
    return n === !0 ? r = super.generate(e) : r = e.generateConst(this.nodeType, new rt(1, 1, 1, 1)), r;
  }
  serialize(e) {
    super.serialize(e), e.index = this.index;
  }
  deserialize(e) {
    super.deserialize(e), this.index = e.index;
  }
}
const S3 = (i = 0) => new b3(i), T3 = /* @__PURE__ */ ee(([i]) => et(i.rgb.mul(i.a), i.a), { color: "vec4", return: "vec4" });
class dn extends jn {
  static get type() {
    return "NodeMaterial";
  }
  /**
   * Represents the type of the node material.
   *
   * @type {string}
   */
  get type() {
    return this.constructor.type;
  }
  set type(e) {
  }
  /**
   * Constructs a new node material.
   */
  constructor() {
    super(), this.isNodeMaterial = !0, this.fog = !0, this.lights = !1, this.hardwareClipping = !1, this.lightsNode = null, this.envNode = null, this.aoNode = null, this.colorNode = null, this.normalNode = null, this.opacityNode = null, this.backdropNode = null, this.backdropAlphaNode = null, this.alphaTestNode = null, this.maskNode = null, this.maskShadowNode = null, this.positionNode = null, this.geometryNode = null, this.depthNode = null, this.receivedShadowPositionNode = null, this.castShadowPositionNode = null, this.receivedShadowNode = null, this.castShadowNode = null, this.outputNode = null, this.mrtNode = null, this.fragmentNode = null, this.vertexNode = null, this.contextNode = null;
  }
  /**
   * Returns an array of child nodes for this material.
   *
   * @private
   * @returns {Array<{property: string, childNode: Node}>}
   */
  _getNodeChildren() {
    const e = [];
    for (const t of Object.getOwnPropertyNames(this)) {
      if (t.startsWith("_") === !0)
        continue;
      const n = this[t];
      n && n.isNode === !0 && e.push({ property: t, childNode: n });
    }
    return e;
  }
  /**
   * Allows to define a custom cache key that influence the material key computation
   * for render objects.
   *
   * @return {string} The custom cache key.
   */
  customProgramCacheKey() {
    const e = [];
    for (const { property: t, childNode: n } of this._getNodeChildren())
      e.push(Ml(t.slice(0, -4)), n.getCacheKey());
    return this.type + ou(e);
  }
  /**
   * Builds this material with the given node builder.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  build(e) {
    this.setup(e);
  }
  /**
   * Setups a node material observer with the given builder.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {NodeMaterialObserver} The node material observer.
   */
  setupObserver(e) {
    return new t2(e);
  }
  /**
   * Setups the vertex and fragment stage of this node material.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    e.context.setupNormal = () => Uo(this.setupNormal(e), "NORMAL", "vec3"), e.context.setupPositionView = () => this.setupPositionView(e), e.context.setupModelViewProjection = () => this.setupModelViewProjection(e);
    const t = e.renderer, n = t.getRenderTarget();
    t.contextNode.isContextNode === !0 ? e.context = { ...e.context, ...t.contextNode.getFlowContextData() } : le('NodeMaterial: "renderer.contextNode" must be an instance of `context()`.'), this.contextNode !== null && (this.contextNode.isContextNode === !0 ? e.context = { ...e.context, ...this.contextNode.getFlowContextData() } : le('NodeMaterial: "material.contextNode" must be an instance of `context()`.')), e.addStack();
    const r = this.setupVertex(e), s = Uo(this.vertexNode || r, "VERTEX");
    e.context.clipSpace = s, e.stack.outputNode = s, this.setupHardwareClipping(e), this.geometryNode !== null && (e.stack.outputNode = e.stack.outputNode.bypass(this.geometryNode)), e.addFlow("vertex", e.removeStack()), e.addStack();
    let a;
    const o = this.setupClipping(e);
    if ((this.depthWrite === !0 || this.depthTest === !0) && (n !== null ? n.depthBuffer === !0 && this.setupDepth(e) : t.depth === !0 && this.setupDepth(e)), this.fragmentNode === null) {
      this.setupDiffuseColor(e), this.setupVariants(e);
      const l = this.setupLighting(e);
      o !== null && e.stack.addToStack(o);
      const c = et(l, Nt.a).max(0);
      a = this.setupOutput(e, c), bc.assign(a);
      const u = this.outputNode !== null;
      if (u && (a = this.outputNode), e.context.getOutput && (a = e.context.getOutput(a, e)), n !== null) {
        const h = t.getMRT(), d = this.mrtNode;
        h !== null ? (u && bc.assign(a), a = h, d !== null && (a = h.merge(d))) : d !== null && (a = d);
      }
    } else {
      let l = this.fragmentNode;
      l.isOutputStructNode !== !0 && (l = et(l)), a = this.setupOutput(e, l);
    }
    e.stack.outputNode = a, e.addFlow("fragment", e.removeStack()), e.observer = this.setupObserver(e);
  }
  /**
   * Setups the clipping node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {ClippingNode} The clipping node.
   */
  setupClipping(e) {
    if (e.clippingContext === null)
      return null;
    const { unionPlanes: t, intersectionPlanes: n } = e.clippingContext;
    let r = null;
    if (t.length > 0 || n.length > 0) {
      const s = e.renderer.currentSamples;
      this.alphaToCoverage && s > 1 ? r = _3() : e.stack.addToStack(g3());
    }
    return r;
  }
  /**
   * Setups the hardware clipping if available on the current device.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupHardwareClipping(e) {
    if (this.hardwareClipping = !1, e.clippingContext === null)
      return;
    const t = e.clippingContext.unionPlanes.length;
    t > 0 && t <= 8 && e.isAvailable("clipDistance") && (e.stack.addToStack(x3()), this.hardwareClipping = !0);
  }
  /**
   * Setups the depth of this material.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupDepth(e) {
    const { renderer: t, camera: n } = e;
    let r = this.depthNode;
    if (r === null) {
      const s = t.getMRT();
      s && s.has("depth") ? r = s.get("depth") : t.logarithmicDepthBuffer === !0 && (n.isPerspectiveCamera ? r = RS(hn.z, ga, _a) : r = Ec(hn.z, ga, _a));
    }
    r !== null && NS.assign(r).toStack();
  }
  /**
   * Setups the position node in view space. This method exists
   * so derived node materials can modify the implementation e.g. sprite materials.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The position in view space.
   */
  setupPositionView() {
    return cu.mul(Cn).xyz;
  }
  /**
   * Setups the position in clip space.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec4>} The position in view space.
   */
  setupModelViewProjection() {
    return Tc.mul(hn);
  }
  /**
   * Setups the logic for the vertex stage.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec4>} The position in clip space.
   */
  setupVertex(e) {
    return e.addStack(), this.setupPosition(e), e.context.position = e.removeStack(), zU;
  }
  /**
   * Setups the computation of the position in local space.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The position in local space.
   */
  setupPosition(e) {
    const { object: t, geometry: n } = e;
    if ((n.morphAttributes.position || n.morphAttributes.normal || n.morphAttributes.color) && s3(t).toStack(), t.isSkinnedMesh === !0 && e3(t).toStack(), this.displacementMap) {
      const r = Rs("displacementMap", "texture"), s = Rs("displacementScale", "float"), a = Rs("displacementBias", "float");
      Cn.addAssign(Dr.normalize().mul(r.x.mul(s).add(a)));
    }
    return t.isBatchedMesh && QU(t).toStack(), t.isInstancedMesh && t.instanceMatrix && t.instanceMatrix.isInstancedBufferAttribute === !0 && KU(t).toStack(), this.positionNode !== null && Cn.assign(Uo(this.positionNode, "POSITION", "vec3")), Cn;
  }
  /**
   * Setups the computation of the material's diffuse color.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {BufferGeometry} geometry - The geometry.
   */
  setupDiffuseColor(e) {
    const { object: t, geometry: n } = e;
    this.maskNode !== null && Mg(this.maskNode).not().discard();
    let r = this.colorNode ? et(this.colorNode) : dU;
    this.vertexColors === !0 && n.hasAttribute("color") && (r = r.mul(S3())), t.instanceColor && (r = $h("vec3", "vInstanceColor").mul(r)), t.isBatchedMesh && t._colorsTexture && (r = $h("vec3", "vBatchColor").mul(r)), Nt.assign(r);
    const s = this.opacityNode ? K(this.opacityNode) : SS;
    Nt.a.assign(Nt.a.mul(s));
    let a = null;
    (this.alphaTestNode !== null || this.alphaTest > 0) && (a = this.alphaTestNode !== null ? K(this.alphaTestNode) : hU, this.alphaToCoverage === !0 ? (Nt.a = hs(a, a.add(Wb(Nt.a)), Nt.a), Nt.a.lessThanEqual(0).discard()) : Nt.a.lessThanEqual(a).discard()), this.alphaHash === !0 && Nt.a.lessThan(y3(Cn)).discard(), e.isOpaque() && Nt.a.assign(1);
  }
  /**
   * Abstract interface method that can be implemented by derived materials
   * to setup material-specific node variables.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants() {
  }
  /**
   * Setups the outgoing light node variable
   *
   * @return {Node<vec3>} The outgoing light node.
   */
  setupOutgoingLight() {
    return this.lights === !0 ? Y(0) : Nt.rgb;
  }
  /**
   * Setups the normal node from the material.
   *
   * @return {Node<vec3>} The normal node.
   */
  setupNormal() {
    return this.normalNode ? Y(this.normalNode) : vU;
  }
  /**
   * Setups the environment node from the material.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec4>} The environment node.
   */
  setupEnvironment() {
    let e = null;
    return this.envNode ? e = this.envNode : this.envMap && (e = this.envMap.isCubeTexture ? Rs("envMap", "cubeTexture") : Rs("envMap", "texture")), e;
  }
  /**
   * Setups the light map node from the material.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The light map node.
   */
  setupLightMap(e) {
    let t = null;
    return e.material.lightMap && (t = new c3(TS)), t;
  }
  /**
   * Setups the lights node based on the scene, environment and material.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {LightsNode} The lights node.
   */
  setupLights(e) {
    const t = [], n = this.setupEnvironment(e);
    n && n.isLightingNode && t.push(n);
    const r = this.setupLightMap(e);
    r && r.isLightingNode && t.push(r);
    let s = this.aoNode;
    s === null && e.material.aoMap && (s = VU), e.context.getAO && (s = e.context.getAO(s, e)), s && t.push(new a3(s));
    let a = this.lightsNode || e.lightsNode;
    return t.length > 0 && (a = e.renderer.lighting.createNode([...a.getLights(), ...t])), a;
  }
  /**
   * This method should be implemented by most derived materials
   * since it defines the material's lighting model.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   * @return {LightingModel} The lighting model.
   */
  setupLightingModel() {
  }
  /**
   * Setups the outgoing light node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The outgoing light node.
   */
  setupLighting(e) {
    const { material: t } = e, { backdropNode: n, backdropAlphaNode: r, emissiveNode: s } = this, o = this.lights === !0 || this.lightsNode !== null ? this.setupLights(e) : null;
    let l = this.setupOutgoingLight(e);
    if (o && o.getScope().hasLights) {
      const c = this.setupLightingModel(e) || null;
      l = l3(o, c, n, r);
    } else
      n !== null && (l = Y(r !== null ? Lt(l, n, r) : n));
    return (s && s.isNode === !0 || t.emissive && t.emissive.isColor === !0) && (q0.assign(Y(s || pU)), l = l.add(q0)), l;
  }
  /**
   * Setup the fog.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node<vec4>} outputNode - The existing output node.
   * @return {Node<vec4>} The output node.
   */
  setupFog(e, t) {
    const n = e.fogNode;
    return n && (bc.assign(t), t = et(n.toVar())), t;
  }
  /**
   * Setups premultiplied alpha.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node<vec4>} outputNode - The existing output node.
   * @return {Node<vec4>} The output node.
   */
  setupPremultipliedAlpha(e, t) {
    return T3(t);
  }
  /**
   * Setups the output node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node<vec4>} outputNode - The existing output node.
   * @return {Node<vec4>} The output node.
   */
  setupOutput(e, t) {
    return this.fog === !0 && (t = this.setupFog(e, t)), this.premultipliedAlpha === !0 && (t = this.setupPremultipliedAlpha(e, t)), t;
  }
  /**
   * Most classic material types have a node pendant e.g. for `MeshBasicMaterial`
   * there is `MeshBasicNodeMaterial`. This utility method is intended for
   * defining all material properties of the classic type in the node type.
   *
   * @param {Material} material - The material to copy properties with their values to this node material.
   */
  setDefaultValues(e) {
    for (const n in e) {
      const r = e[n];
      this[n] === void 0 && (this[n] = r, r && r.clone && (this[n] = r.clone()));
    }
    const t = Object.getOwnPropertyDescriptors(e.constructor.prototype);
    for (const n in t)
      Object.getOwnPropertyDescriptor(this.constructor.prototype, n) === void 0 && t[n].get !== void 0 && Object.defineProperty(this.constructor.prototype, n, t[n]);
  }
  /**
   * Serializes this material to JSON.
   *
   * @param {?(Object|string)} meta - The meta information for serialization.
   * @return {Object} The serialized node.
   */
  toJSON(e) {
    const t = e === void 0 || typeof e == "string";
    t && (e = {
      textures: {},
      images: {},
      nodes: {}
    });
    const n = jn.prototype.toJSON.call(this, e);
    n.inputNodes = {};
    for (const { property: s, childNode: a } of this._getNodeChildren())
      n.inputNodes[s] = a.toJSON(e).uuid;
    function r(s) {
      const a = [];
      for (const o in s) {
        const l = s[o];
        delete l.metadata, a.push(l);
      }
      return a;
    }
    if (t) {
      const s = r(e.textures), a = r(e.images), o = r(e.nodes);
      s.length > 0 && (n.textures = s), a.length > 0 && (n.images = a), o.length > 0 && (n.nodes = o);
    }
    return n;
  }
  /**
   * Copies the properties of the given node material to this instance.
   *
   * @param {NodeMaterial} source - The material to copy.
   * @return {NodeMaterial} A reference to this node material.
   */
  copy(e) {
    return this.lightsNode = e.lightsNode, this.envNode = e.envNode, this.aoNode = e.aoNode, this.colorNode = e.colorNode, this.normalNode = e.normalNode, this.opacityNode = e.opacityNode, this.backdropNode = e.backdropNode, this.backdropAlphaNode = e.backdropAlphaNode, this.alphaTestNode = e.alphaTestNode, this.maskNode = e.maskNode, this.maskShadowNode = e.maskShadowNode, this.positionNode = e.positionNode, this.geometryNode = e.geometryNode, this.depthNode = e.depthNode, this.receivedShadowPositionNode = e.receivedShadowPositionNode, this.castShadowPositionNode = e.castShadowPositionNode, this.receivedShadowNode = e.receivedShadowNode, this.castShadowNode = e.castShadowNode, this.outputNode = e.outputNode, this.mrtNode = e.mrtNode, this.fragmentNode = e.fragmentNode, this.vertexNode = e.vertexNode, this.contextNode = e.contextNode, super.copy(e);
  }
}
const M3 = /* @__PURE__ */ new ud();
class E3 extends dn {
  static get type() {
    return "LineBasicNodeMaterial";
  }
  /**
   * Constructs a new line basic node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isLineBasicNodeMaterial = !0, this.setDefaultValues(M3), this.setValues(e);
  }
}
const w3 = /* @__PURE__ */ new $E();
class A3 extends dn {
  static get type() {
    return "LineDashedNodeMaterial";
  }
  /**
   * Constructs a new line dashed node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isLineDashedNodeMaterial = !0, this.setDefaultValues(w3), this.dashOffset = 0, this.offsetNode = null, this.dashScaleNode = null, this.dashSizeNode = null, this.gapSizeNode = null, this.setValues(e);
  }
  /**
   * Setups the dash specific node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants() {
    const e = this.offsetNode ? K(this.offsetNode) : OU, t = this.dashScaleNode ? K(this.dashScaleNode) : IU, n = this.dashSizeNode ? K(this.dashSizeNode) : UU, r = this.gapSizeNode ? K(this.gapSizeNode) : BU;
    Lf.assign(n), X0.assign(r);
    const s = Xa(Ws("lineDistance").mul(t));
    (e ? s.add(e) : s).mod(Lf.add(X0)).greaterThan(Lf).discard();
  }
}
const R3 = /* @__PURE__ */ new GE();
class C3 extends dn {
  static get type() {
    return "MeshNormalNodeMaterial";
  }
  /**
   * Constructs a new mesh normal node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshNormalNodeMaterial = !0, this.setDefaultValues(R3), this.setValues(e);
  }
  /**
   * Overwrites the default implementation by computing the diffuse color
   * based on the normal data.
   */
  setupDiffuseColor() {
    const e = this.opacityNode ? K(this.opacityNode) : SS;
    Nt.assign(Lg(et(sU(vt), e), Jn));
  }
}
const PS = /* @__PURE__ */ ee(([i = lS]) => {
  const e = i.z.atan(i.x).mul(1 / (Math.PI * 2)).add(0.5), t = i.y.clamp(-1, 1).asin().mul(1 / Math.PI).add(0.5);
  return Pe(e, t);
});
class DS extends js {
  /**
   * Constructs a new cube render target.
   *
   * @param {number} [size=1] - The size of the render target.
   * @param {RenderTarget~Options} [options] - The configuration object.
   */
  constructor(e = 1, t = {}) {
    super(e, e, t), this.isCubeRenderTarget = !0;
    const n = { width: e, height: e, depth: 1 }, r = [n, n, n, n, n, n];
    this.texture = new yl(r), this._setTextureOptions(t), this.texture.isRenderTargetTexture = !0;
  }
  /**
   * Converts the given equirectangular texture to a cube map.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {Texture} texture - The equirectangular texture.
   * @return {CubeRenderTarget} A reference to this cube render target.
   */
  fromEquirectangularTexture(e, t) {
    const n = t.minFilter, r = t.generateMipmaps;
    t.generateMipmaps = !0, this.texture.type = t.type, this.texture.colorSpace = t.colorSpace, this.texture.generateMipmaps = t.generateMipmaps, this.texture.minFilter = t.minFilter, this.texture.magFilter = t.magFilter;
    const s = new $a(5, 5, 5), a = PS(lS), o = new dn();
    o.colorNode = qt(t, a, 0), o.side = Ft, o.blending = Nn;
    const l = new _n(s, o), c = new Xm();
    c.add(l), t.minFilter === pi && (t.minFilter = Ot);
    const u = new py(1, 10, this), h = e.getMRT();
    return e.setMRT(null), u.update(e, c), e.setMRT(h), t.minFilter = n, t.currentGenerateMipmaps = r, l.geometry.dispose(), l.material.dispose(), this;
  }
  /**
   * Clears this cube render target.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {boolean} [color=true] - Whether the color buffer should be cleared or not.
   * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not.
   * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not.
   */
  clear(e, t = !0, n = !0, r = !0) {
    const s = e.getRenderTarget();
    for (let a = 0; a < 6; a++)
      e.setRenderTarget(this, a), e.clear(t, n, r);
    e.setRenderTarget(s);
  }
}
const wc = /* @__PURE__ */ new WeakMap();
class N3 extends xn {
  static get type() {
    return "CubeMapNode";
  }
  /**
   * Constructs a new cube map node.
   *
   * @param {Node} envNode - The node representing the environment map.
   */
  constructor(e) {
    super("vec3"), this.envNode = e, this._cubeTexture = null, this._cubeTextureNode = di(null);
    const t = new yl();
    t.isRenderTargetTexture = !0, this._defaultTexture = t, this.updateBeforeType = it.RENDER;
  }
  updateBefore(e) {
    const { renderer: t, material: n } = e, r = this.envNode;
    if (r.isTextureNode || r.isMaterialReferenceNode) {
      const s = r.isTextureNode ? r.value : n[r.property];
      if (s && s.isTexture) {
        const a = s.mapping;
        if (a === Co || a === No) {
          if (wc.has(s)) {
            const o = wc.get(s);
            px(o, s.mapping), this._cubeTexture = o;
          } else {
            const o = s.image;
            if (P3(o)) {
              const l = new DS(o.height);
              l.fromEquirectangularTexture(t, s), px(l.texture, s.mapping), this._cubeTexture = l.texture, wc.set(s, l.texture), s.addEventListener("dispose", LS);
            } else
              this._cubeTexture = this._defaultTexture;
          }
          this._cubeTextureNode.value = this._cubeTexture;
        } else
          this._cubeTextureNode = this.envNode;
      }
    }
  }
  setup(e) {
    return this.updateBefore(e), this._cubeTextureNode;
  }
}
function P3(i) {
  return i == null ? !1 : i.height > 0;
}
function LS(i) {
  const e = i.target;
  e.removeEventListener("dispose", LS);
  const t = wc.get(e);
  t !== void 0 && (wc.delete(e), t.dispose());
}
function px(i, e) {
  e === Co ? i.mapping = nr : e === No && (i.mapping = Rr);
}
const FS = /* @__PURE__ */ Mt(N3).setParameterLength(1);
class Bg extends Dl {
  static get type() {
    return "BasicEnvironmentNode";
  }
  /**
   * Constructs a new basic environment node.
   *
   * @param {Node} [envNode=null] - A node representing the environment.
   */
  constructor(e = null) {
    super(), this.envNode = e;
  }
  setup(e) {
    e.context.environment = FS(this.envNode);
  }
}
class D3 extends Dl {
  static get type() {
    return "BasicLightMapNode";
  }
  /**
   * Constructs a new basic light map node.
   *
   * @param {?Node<vec3>} [lightMapNode=null] - The light map node.
   */
  constructor(e = null) {
    super(), this.lightMapNode = e;
  }
  setup(e) {
    const t = K(1 / Math.PI);
    e.context.irradianceLightMap = this.lightMapNode.mul(t);
  }
}
class Md {
  /**
   * This method is intended for setting up lighting model and context data
   * which are later used in the evaluation process.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   */
  start(e) {
    e.lightsNode.setupLights(e, e.lightsNode.getLightNodes(e)), this.indirect(e);
  }
  /**
   * This method is intended for executing final tasks like final updates
   * to the outgoing light.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   */
  finish() {
  }
  /**
   * This method is intended for implementing the direct light term and
   * executed during the build process of directional, point and spot light nodes.
   *
   * @abstract
   * @param {Object} lightData - The light data.
   * @param {NodeBuilder} builder - The current node builder.
   */
  direct() {
  }
  /**
   * This method is intended for implementing the direct light term for
   * rect area light nodes.
   *
   * @abstract
   * @param {Object} lightData - The light data.
   * @param {NodeBuilder} builder - The current node builder.
   */
  directRectArea() {
  }
  /**
   * This method is intended for implementing the indirect light term.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirect() {
  }
  /**
   * This method is intended for implementing the ambient occlusion term.
   * Unlike other methods, this method must be called manually by the lighting
   * model in its indirect term.
   *
   * @abstract
   * @param {NodeBuilder} builder - The current node builder.
   */
  ambientOcclusion() {
  }
}
class IS extends Md {
  /**
   * Constructs a new basic lighting model.
   */
  constructor() {
    super();
  }
  /**
   * Implements the baked indirect lighting with its modulation.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirect({ context: e }) {
    const t = e.ambientOcclusion, n = e.reflectedLight, r = e.irradianceLightMap;
    n.indirectDiffuse.assign(et(0)), r ? n.indirectDiffuse.addAssign(r) : n.indirectDiffuse.addAssign(et(1, 1, 1, 0)), n.indirectDiffuse.mulAssign(t), n.indirectDiffuse.mulAssign(Nt.rgb);
  }
  /**
   * Implements the environment mapping.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  finish(e) {
    const { material: t, context: n } = e, r = n.outgoingLight, s = e.context.environment;
    if (s)
      switch (t.combine) {
        case Qc:
          r.rgb.assign(Lt(r.rgb, r.rgb.mul(s.rgb), Ch.mul(Gf)));
          break;
        case qv:
          r.rgb.assign(Lt(r.rgb, s.rgb, Ch.mul(Gf)));
          break;
        case Xv:
          r.rgb.addAssign(s.rgb.mul(Ch.mul(Gf)));
          break;
        default:
          oe("BasicLightingModel: Unsupported .combine value:", t.combine);
          break;
      }
  }
}
const L3 = /* @__PURE__ */ new xr();
class F3 extends dn {
  static get type() {
    return "MeshBasicNodeMaterial";
  }
  /**
   * Constructs a new mesh basic node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshBasicNodeMaterial = !0, this.lights = !0, this.setDefaultValues(L3), this.setValues(e);
  }
  /**
   * Basic materials are not affected by normal and bump maps so we
   * return by default {@link normalViewGeometry}.
   *
   * @return {Node<vec3>} The normal node.
   */
  setupNormal() {
    return uu(Xc);
  }
  /**
   * Overwritten since this type of material uses {@link BasicEnvironmentNode}
   * to implement the default environment mapping.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?BasicEnvironmentNode<vec3>} The environment node.
   */
  setupEnvironment(e) {
    const t = super.setupEnvironment(e);
    return t ? new Bg(t) : null;
  }
  /**
   * This method must be overwritten since light maps are evaluated
   * with a special scaling factor for basic materials.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?BasicLightMapNode<vec3>} The light map node.
   */
  setupLightMap(e) {
    let t = null;
    return e.material.lightMap && (t = new D3(TS)), t;
  }
  /**
   * The material overwrites this method because `lights` is set to `true` but
   * we still want to return the diffuse color as the outgoing light.
   *
   * @return {Node<vec3>} The outgoing light node.
   */
  setupOutgoingLight() {
    return Nt.rgb;
  }
  /**
   * Setups the lighting model.
   *
   * @return {BasicLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new IS();
  }
}
const jc = /* @__PURE__ */ ee(({ f0: i, f90: e, dotVH: t }) => {
  const n = t.mul(-5.55473).sub(6.98316).mul(t).exp2();
  return i.mul(n.oneMinus()).add(e.mul(n));
}), ml = /* @__PURE__ */ ee((i) => i.diffuseColor.mul(1 / Math.PI)), I3 = () => K(0.25), U3 = /* @__PURE__ */ ee(({ dotNH: i }) => Yp.mul(K(0.5)).add(1).mul(K(1 / Math.PI)).mul(i.pow(Yp))), B3 = /* @__PURE__ */ ee(({ lightDirection: i }) => {
  const e = i.add($t).normalize(), t = vt.dot(e).clamp(), n = $t.dot(e).clamp(), r = jc({ f0: Ba, f90: 1, dotVH: n }), s = I3(), a = U3({ dotNH: t });
  return r.mul(s).mul(a);
});
class US extends IS {
  /**
   * Constructs a new phong lighting model.
   *
   * @param {boolean} [specular=true] - Whether specular is supported or not.
   */
  constructor(e = !0) {
    super(), this.specular = e;
  }
  /**
   * Implements the direct lighting. The specular portion is optional an can be controlled
   * with the {@link PhongLightingModel#specular} flag.
   *
   * @param {Object} lightData - The light data.
   */
  direct({ lightDirection: e, lightColor: t, reflectedLight: n }) {
    const s = vt.dot(e).clamp().mul(t);
    n.directDiffuse.addAssign(s.mul(ml({ diffuseColor: Nt.rgb }))), this.specular === !0 && n.directSpecular.addAssign(s.mul(B3({ lightDirection: e })).mul(Ch));
  }
  /**
   * Implements the indirect lighting.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirect(e) {
    const { ambientOcclusion: t, irradiance: n, reflectedLight: r } = e.context;
    r.indirectDiffuse.addAssign(n.mul(ml({ diffuseColor: Nt }))), r.indirectDiffuse.mulAssign(t);
  }
}
const O3 = /* @__PURE__ */ new uy();
class k3 extends dn {
  static get type() {
    return "MeshLambertNodeMaterial";
  }
  /**
   * Constructs a new mesh lambert node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshLambertNodeMaterial = !0, this.lights = !0, this.setDefaultValues(O3), this.setValues(e);
  }
  /**
   * Overwritten since this type of material uses {@link BasicEnvironmentNode}
   * to implement the default environment mapping.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?BasicEnvironmentNode<vec3>} The environment node.
   */
  setupEnvironment(e) {
    const t = super.setupEnvironment(e);
    return t ? new Bg(t) : null;
  }
  /**
   * Setups the lighting model.
   *
   * @return {PhongLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new US(!1);
  }
}
const G3 = /* @__PURE__ */ new OE();
class V3 extends dn {
  static get type() {
    return "MeshPhongNodeMaterial";
  }
  /**
   * Constructs a new mesh lambert node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshPhongNodeMaterial = !0, this.lights = !0, this.shininessNode = null, this.specularNode = null, this.setDefaultValues(G3), this.setValues(e);
  }
  /**
   * Overwritten since this type of material uses {@link BasicEnvironmentNode}
   * to implement the default environment mapping.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?BasicEnvironmentNode<vec3>} The environment node.
   */
  setupEnvironment(e) {
    const t = super.setupEnvironment(e);
    return t ? new Bg(t) : null;
  }
  /**
   * Setups the lighting model.
   *
   * @return {PhongLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new US();
  }
  /**
   * Setups the phong specific node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants() {
    const e = (this.shininessNode ? K(this.shininessNode) : fU).max(1e-4);
    Yp.assign(e);
    const t = this.specularNode || mU;
    Ba.assign(t);
  }
  copy(e) {
    return this.shininessNode = e.shininessNode, this.specularNode = e.specularNode, super.copy(e);
  }
}
const z3 = /* @__PURE__ */ ee((i) => {
  if (i.geometry.hasAttribute("normal") === !1)
    return K(0);
  const e = Xc.dFdx().abs().max(Xc.dFdy().abs());
  return e.x.max(e.y).max(e.z);
}), BS = /* @__PURE__ */ ee((i) => {
  const { roughness: e } = i, t = z3();
  let n = e.max(0.0525);
  return n = n.add(t), n = n.min(1), n;
}), H3 = /* @__PURE__ */ ee(({ alpha: i, dotNL: e, dotNV: t }) => {
  const n = i.pow2(), r = e.mul(n.add(n.oneMinus().mul(t.pow2())).sqrt()), s = t.mul(n.add(n.oneMinus().mul(e.pow2())).sqrt());
  return Nr(0.5, r.add(s).max(Bb));
}).setLayout({
  name: "V_GGX_SmithCorrelated",
  type: "float",
  inputs: [
    { name: "alpha", type: "float" },
    { name: "dotNL", type: "float" },
    { name: "dotNV", type: "float" }
  ]
}), $3 = /* @__PURE__ */ ee(({ alphaT: i, alphaB: e, dotTV: t, dotBV: n, dotTL: r, dotBL: s, dotNV: a, dotNL: o }) => {
  const l = o.mul(Y(i.mul(t), e.mul(n), a).length()), c = a.mul(Y(i.mul(r), e.mul(s), o).length());
  return Nr(0.5, l.add(c));
}).setLayout({
  name: "V_GGX_SmithCorrelated_Anisotropic",
  type: "float",
  inputs: [
    { name: "alphaT", type: "float", qualifier: "in" },
    { name: "alphaB", type: "float", qualifier: "in" },
    { name: "dotTV", type: "float", qualifier: "in" },
    { name: "dotBV", type: "float", qualifier: "in" },
    { name: "dotTL", type: "float", qualifier: "in" },
    { name: "dotBL", type: "float", qualifier: "in" },
    { name: "dotNV", type: "float", qualifier: "in" },
    { name: "dotNL", type: "float", qualifier: "in" }
  ]
}), W3 = /* @__PURE__ */ ee(({ alpha: i, dotNH: e }) => {
  const t = i.pow2(), n = e.pow2().mul(t.oneMinus()).oneMinus();
  return t.div(n.pow2()).mul(1 / Math.PI);
}).setLayout({
  name: "D_GGX",
  type: "float",
  inputs: [
    { name: "alpha", type: "float" },
    { name: "dotNH", type: "float" }
  ]
}), q3 = /* @__PURE__ */ K(1 / Math.PI), X3 = /* @__PURE__ */ ee(({ alphaT: i, alphaB: e, dotNH: t, dotTH: n, dotBH: r }) => {
  const s = i.mul(e), a = Y(e.mul(n), i.mul(r), s.mul(t)), o = a.dot(a), l = s.div(o);
  return q3.mul(s.mul(l.pow2()));
}).setLayout({
  name: "D_GGX_Anisotropic",
  type: "float",
  inputs: [
    { name: "alphaT", type: "float", qualifier: "in" },
    { name: "alphaB", type: "float", qualifier: "in" },
    { name: "dotNH", type: "float", qualifier: "in" },
    { name: "dotTH", type: "float", qualifier: "in" },
    { name: "dotBH", type: "float", qualifier: "in" }
  ]
}), OS = /* @__PURE__ */ ee(({ lightDirection: i, f0: e, f90: t, roughness: n, f: r, normalView: s = vt, USE_IRIDESCENCE: a, USE_ANISOTROPY: o }) => {
  const l = n.pow2(), c = i.add($t).normalize(), u = s.dot(i).clamp(), h = s.dot($t).clamp(), d = s.dot(c).clamp(), f = $t.dot(c).clamp();
  let p = jc({ f0: e, f90: t, dotVH: f }), _, g;
  if (W0(a) && (p = wg.mix(p, r)), W0(o)) {
    const m = Eh.dot(i), x = Eh.dot($t), y = Eh.dot(c), b = Io.dot(i), T = Io.dot($t), S = Io.dot(c);
    _ = $3({ alphaT: jp, alphaB: l, dotTV: x, dotBV: T, dotTL: m, dotBL: b, dotNV: h, dotNL: u }), g = X3({ alphaT: jp, alphaB: l, dotNH: d, dotTH: y, dotBH: S });
  } else
    _ = H3({ alpha: l, dotNL: u, dotNV: h }), g = W3({ alpha: l, dotNH: d });
  return p.mul(_).mul(g);
}), j3 = new Uint16Array([
  12469,
  15057,
  12620,
  14925,
  13266,
  14620,
  13807,
  14376,
  14323,
  13990,
  14545,
  13625,
  14713,
  13328,
  14840,
  12882,
  14931,
  12528,
  14996,
  12233,
  15039,
  11829,
  15066,
  11525,
  15080,
  11295,
  15085,
  10976,
  15082,
  10705,
  15073,
  10495,
  13880,
  14564,
  13898,
  14542,
  13977,
  14430,
  14158,
  14124,
  14393,
  13732,
  14556,
  13410,
  14702,
  12996,
  14814,
  12596,
  14891,
  12291,
  14937,
  11834,
  14957,
  11489,
  14958,
  11194,
  14943,
  10803,
  14921,
  10506,
  14893,
  10278,
  14858,
  9960,
  14484,
  14039,
  14487,
  14025,
  14499,
  13941,
  14524,
  13740,
  14574,
  13468,
  14654,
  13106,
  14743,
  12678,
  14818,
  12344,
  14867,
  11893,
  14889,
  11509,
  14893,
  11180,
  14881,
  10751,
  14852,
  10428,
  14812,
  10128,
  14765,
  9754,
  14712,
  9466,
  14764,
  13480,
  14764,
  13475,
  14766,
  13440,
  14766,
  13347,
  14769,
  13070,
  14786,
  12713,
  14816,
  12387,
  14844,
  11957,
  14860,
  11549,
  14868,
  11215,
  14855,
  10751,
  14825,
  10403,
  14782,
  10044,
  14729,
  9651,
  14666,
  9352,
  14599,
  9029,
  14967,
  12835,
  14966,
  12831,
  14963,
  12804,
  14954,
  12723,
  14936,
  12564,
  14917,
  12347,
  14900,
  11958,
  14886,
  11569,
  14878,
  11247,
  14859,
  10765,
  14828,
  10401,
  14784,
  10011,
  14727,
  9600,
  14660,
  9289,
  14586,
  8893,
  14508,
  8533,
  15111,
  12234,
  15110,
  12234,
  15104,
  12216,
  15092,
  12156,
  15067,
  12010,
  15028,
  11776,
  14981,
  11500,
  14942,
  11205,
  14902,
  10752,
  14861,
  10393,
  14812,
  9991,
  14752,
  9570,
  14682,
  9252,
  14603,
  8808,
  14519,
  8445,
  14431,
  8145,
  15209,
  11449,
  15208,
  11451,
  15202,
  11451,
  15190,
  11438,
  15163,
  11384,
  15117,
  11274,
  15055,
  10979,
  14994,
  10648,
  14932,
  10343,
  14871,
  9936,
  14803,
  9532,
  14729,
  9218,
  14645,
  8742,
  14556,
  8381,
  14461,
  8020,
  14365,
  7603,
  15273,
  10603,
  15272,
  10607,
  15267,
  10619,
  15256,
  10631,
  15231,
  10614,
  15182,
  10535,
  15118,
  10389,
  15042,
  10167,
  14963,
  9787,
  14883,
  9447,
  14800,
  9115,
  14710,
  8665,
  14615,
  8318,
  14514,
  7911,
  14411,
  7507,
  14279,
  7198,
  15314,
  9675,
  15313,
  9683,
  15309,
  9712,
  15298,
  9759,
  15277,
  9797,
  15229,
  9773,
  15166,
  9668,
  15084,
  9487,
  14995,
  9274,
  14898,
  8910,
  14800,
  8539,
  14697,
  8234,
  14590,
  7790,
  14479,
  7409,
  14367,
  7067,
  14178,
  6621,
  15337,
  8619,
  15337,
  8631,
  15333,
  8677,
  15325,
  8769,
  15305,
  8871,
  15264,
  8940,
  15202,
  8909,
  15119,
  8775,
  15022,
  8565,
  14916,
  8328,
  14804,
  8009,
  14688,
  7614,
  14569,
  7287,
  14448,
  6888,
  14321,
  6483,
  14088,
  6171,
  15350,
  7402,
  15350,
  7419,
  15347,
  7480,
  15340,
  7613,
  15322,
  7804,
  15287,
  7973,
  15229,
  8057,
  15148,
  8012,
  15046,
  7846,
  14933,
  7611,
  14810,
  7357,
  14682,
  7069,
  14552,
  6656,
  14421,
  6316,
  14251,
  5948,
  14007,
  5528,
  15356,
  5942,
  15356,
  5977,
  15353,
  6119,
  15348,
  6294,
  15332,
  6551,
  15302,
  6824,
  15249,
  7044,
  15171,
  7122,
  15070,
  7050,
  14949,
  6861,
  14818,
  6611,
  14679,
  6349,
  14538,
  6067,
  14398,
  5651,
  14189,
  5311,
  13935,
  4958,
  15359,
  4123,
  15359,
  4153,
  15356,
  4296,
  15353,
  4646,
  15338,
  5160,
  15311,
  5508,
  15263,
  5829,
  15188,
  6042,
  15088,
  6094,
  14966,
  6001,
  14826,
  5796,
  14678,
  5543,
  14527,
  5287,
  14377,
  4985,
  14133,
  4586,
  13869,
  4257,
  15360,
  1563,
  15360,
  1642,
  15358,
  2076,
  15354,
  2636,
  15341,
  3350,
  15317,
  4019,
  15273,
  4429,
  15203,
  4732,
  15105,
  4911,
  14981,
  4932,
  14836,
  4818,
  14679,
  4621,
  14517,
  4386,
  14359,
  4156,
  14083,
  3795,
  13808,
  3437,
  15360,
  122,
  15360,
  137,
  15358,
  285,
  15355,
  636,
  15344,
  1274,
  15322,
  2177,
  15281,
  2765,
  15215,
  3223,
  15120,
  3451,
  14995,
  3569,
  14846,
  3567,
  14681,
  3466,
  14511,
  3305,
  14344,
  3121,
  14037,
  2800,
  13753,
  2467,
  15360,
  0,
  15360,
  1,
  15359,
  21,
  15355,
  89,
  15346,
  253,
  15325,
  479,
  15287,
  796,
  15225,
  1148,
  15133,
  1492,
  15008,
  1749,
  14856,
  1882,
  14685,
  1886,
  14506,
  1783,
  14324,
  1608,
  13996,
  1398,
  13702,
  1183
]);
let hr = null;
const Xh = /* @__PURE__ */ ee(({ roughness: i, dotNV: e }) => {
  hr === null && (hr = new Zm(j3, 16, 16, ri, nn), hr.name = "DFG_LUT", hr.minFilter = Ot, hr.magFilter = Ot, hr.wrapS = fi, hr.wrapT = fi, hr.generateMipmaps = !1, hr.needsUpdate = !0);
  const t = Pe(i, e);
  return qt(hr, t).rg;
}), Y3 = /* @__PURE__ */ ee(({ lightDirection: i, f0: e, f90: t, roughness: n, f: r, USE_IRIDESCENCE: s, USE_ANISOTROPY: a }) => {
  const o = OS({ lightDirection: i, f0: e, f90: t, roughness: n, f: r, USE_IRIDESCENCE: s, USE_ANISOTROPY: a }), l = vt.dot(i).clamp(), c = vt.dot($t).clamp(), u = Xh({ roughness: n, dotNV: c }), h = Xh({ roughness: n, dotNV: l }), d = e.mul(u.x).add(t.mul(u.y)), f = e.mul(h.x).add(t.mul(h.y)), p = u.x.add(u.y), _ = h.x.add(h.y), g = K(1).sub(p), m = K(1).sub(_), x = e.add(e.oneMinus().mul(0.047619)), y = d.mul(f).mul(x).div(K(1).sub(g.mul(m).mul(x).mul(x)).add(Bb)), b = g.mul(m), T = y.mul(b);
  return o.add(T);
}), kS = /* @__PURE__ */ ee((i) => {
  const { dotNV: e, specularColor: t, specularF90: n, roughness: r } = i, s = Xh({ dotNV: e, roughness: r });
  return t.mul(s.x).add(n.mul(s.y));
}), mx = /* @__PURE__ */ ee(({ f: i, f90: e, dotVH: t }) => {
  const n = t.oneMinus().saturate(), r = n.mul(n), s = n.mul(r, r).clamp(0, 0.9999);
  return i.sub(Y(e).mul(s)).div(s.oneMinus());
}).setLayout({
  name: "Schlick_to_F0",
  type: "vec3",
  inputs: [
    { name: "f", type: "vec3" },
    { name: "f90", type: "float" },
    { name: "dotVH", type: "float" }
  ]
}), K3 = /* @__PURE__ */ ee(({ roughness: i, dotNH: e }) => {
  const t = i.pow2(), n = K(1).div(t), s = e.pow2().oneMinus().max(78125e-7);
  return K(2).add(n).mul(s.pow(n.mul(0.5))).div(2 * Math.PI);
}).setLayout({
  name: "D_Charlie",
  type: "float",
  inputs: [
    { name: "roughness", type: "float" },
    { name: "dotNH", type: "float" }
  ]
}), Z3 = /* @__PURE__ */ ee(({ dotNV: i, dotNL: e }) => K(1).div(K(4).mul(e.add(i).sub(e.mul(i))))).setLayout({
  name: "V_Neubelt",
  type: "float",
  inputs: [
    { name: "dotNV", type: "float" },
    { name: "dotNL", type: "float" }
  ]
}), Q3 = /* @__PURE__ */ ee(({ lightDirection: i }) => {
  const e = i.add($t).normalize(), t = vt.dot(i).clamp(), n = vt.dot($t).clamp(), r = vt.dot(e).clamp(), s = K3({ roughness: ma, dotNH: r }), a = Z3({ dotNV: n, dotNL: t });
  return Li.mul(s).mul(a);
}), gx = /* @__PURE__ */ ee(({ N: i, V: e, roughness: t }) => {
  const s = 78125e-7, a = i.dot(e).saturate(), o = Pe(t, a.oneMinus().sqrt());
  return o.assign(o.mul(0.984375).add(s)), o;
}).setLayout({
  name: "LTC_Uv",
  type: "vec2",
  inputs: [
    { name: "N", type: "vec3" },
    { name: "V", type: "vec3" },
    { name: "roughness", type: "float" }
  ]
}), J3 = /* @__PURE__ */ ee(({ f: i }) => {
  const e = i.length();
  return kn(e.mul(e).add(i.z).div(e.add(1)), 0);
}).setLayout({
  name: "LTC_ClippedSphereFormFactor",
  type: "float",
  inputs: [
    { name: "f", type: "vec3" }
  ]
}), Qu = /* @__PURE__ */ ee(({ v1: i, v2: e }) => {
  const t = i.dot(e), n = t.abs().toVar(), r = n.mul(0.0145206).add(0.4965155).mul(n).add(0.8543985).toVar(), s = n.add(4.1616724).mul(n).add(3.417594).toVar(), a = r.div(s), o = t.greaterThan(0).select(a, kn(t.mul(t).oneMinus(), 1e-7).inverseSqrt().mul(0.5).sub(a));
  return i.cross(e).mul(o);
}).setLayout({
  name: "LTC_EdgeVectorFormFactor",
  type: "vec3",
  inputs: [
    { name: "v1", type: "vec3" },
    { name: "v2", type: "vec3" }
  ]
}), zf = /* @__PURE__ */ ee(({ N: i, V: e, P: t, mInv: n, p0: r, p1: s, p2: a, p3: o }) => {
  const l = s.sub(r).toVar(), c = o.sub(r).toVar(), u = l.cross(c), h = Y().toVar();
  return Bt(u.dot(t.sub(r)).greaterThanEqual(0), () => {
    const d = e.sub(i.mul(e.dot(i))).normalize(), f = i.cross(d).negate(), p = n.mul(On(d, f, i).transpose()).toVar(), _ = p.mul(r.sub(t)).normalize().toVar(), g = p.mul(s.sub(t)).normalize().toVar(), m = p.mul(a.sub(t)).normalize().toVar(), x = p.mul(o.sub(t)).normalize().toVar(), y = Y(0).toVar();
    y.addAssign(Qu({ v1: _, v2: g })), y.addAssign(Qu({ v1: g, v2: m })), y.addAssign(Qu({ v1: m, v2: x })), y.addAssign(Qu({ v1: x, v2: _ })), h.assign(Y(J3({ f: y })));
  }), h;
}).setLayout({
  name: "LTC_Evaluate",
  type: "vec3",
  inputs: [
    { name: "N", type: "vec3" },
    { name: "V", type: "vec3" },
    { name: "P", type: "vec3" },
    { name: "mInv", type: "mat3" },
    { name: "p0", type: "vec3" },
    { name: "p1", type: "vec3" },
    { name: "p2", type: "vec3" },
    { name: "p3", type: "vec3" }
  ]
}), Ed = 1 / 6, GS = (i) => at(Ed, at(i, at(i, i.negate().add(3)).sub(3)).add(1)), em = (i) => at(Ed, at(i, at(i, at(3, i).sub(6))).add(4)), VS = (i) => at(Ed, at(i, at(i, at(-3, i).add(3)).add(3)).add(1)), tm = (i) => at(Ed, bd(i, 3)), _x = (i) => GS(i).add(em(i)), xx = (i) => VS(i).add(tm(i)), vx = (i) => _i(-1, em(i).div(GS(i).add(em(i)))), yx = (i) => _i(1, tm(i).div(VS(i).add(tm(i)))), bx = (i, e, t) => {
  const n = i.uvNode, r = at(n, e.zw).add(0.5), s = Ma(r), a = Pr(r), o = _x(a.x), l = xx(a.x), c = vx(a.x), u = yx(a.x), h = vx(a.y), d = yx(a.y), f = Pe(s.x.add(c), s.y.add(h)).sub(0.5).mul(e.xy), p = Pe(s.x.add(u), s.y.add(h)).sub(0.5).mul(e.xy), _ = Pe(s.x.add(c), s.y.add(d)).sub(0.5).mul(e.xy), g = Pe(s.x.add(u), s.y.add(d)).sub(0.5).mul(e.xy), m = _x(a.y).mul(_i(o.mul(i.sample(f).level(t)), l.mul(i.sample(p).level(t)))), x = xx(a.y).mul(_i(o.mul(i.sample(_).level(t)), l.mul(i.sample(g).level(t))));
  return m.add(x);
}, eB = /* @__PURE__ */ ee(([i, e]) => {
  const t = Pe(i.size(Kt(e))), n = Pe(i.size(Kt(e.add(1)))), r = Nr(1, t), s = Nr(1, n), a = bx(i, et(r, t), Ma(e)), o = bx(i, et(s, n), Cg(e));
  return Pr(e).mix(a, o);
}), Sx = /* @__PURE__ */ ee(([i, e, t, n, r]) => {
  const s = Y(Yb(e.negate(), Ar(i), Nr(1, n))), a = Y(
    cs(r[0].xyz),
    cs(r[1].xyz),
    cs(r[2].xyz)
  );
  return Ar(s).mul(t.mul(a));
}).setLayout({
  name: "getVolumeTransmissionRay",
  type: "vec3",
  inputs: [
    { name: "n", type: "vec3" },
    { name: "v", type: "vec3" },
    { name: "thickness", type: "float" },
    { name: "ior", type: "float" },
    { name: "modelMatrix", type: "mat4" }
  ]
}), tB = /* @__PURE__ */ ee(([i, e]) => i.mul($s(e.mul(2).sub(2), 0, 1))).setLayout({
  name: "applyIorToRoughness",
  type: "float",
  inputs: [
    { name: "roughness", type: "float" },
    { name: "ior", type: "float" }
  ]
}), nB = /* @__PURE__ */ ES(), iB = /* @__PURE__ */ h3(), Tx = /* @__PURE__ */ ee(([i, e, t], { material: n }) => {
  const s = (n.side === Ft ? nB : iB).sample(i), a = ls(Zp.x).mul(tB(e, t));
  return eB(s, a);
}), Mx = /* @__PURE__ */ ee(([i, e, t]) => (Bt(t.notEqual(0), () => {
  const n = kb(e).negate().div(t);
  return Ob(n.negate().mul(i));
}), Y(1))).setLayout({
  name: "volumeAttenuation",
  type: "vec3",
  inputs: [
    { name: "transmissionDistance", type: "float" },
    { name: "attenuationColor", type: "vec3" },
    { name: "attenuationDistance", type: "float" }
  ]
}), rB = /* @__PURE__ */ ee(([i, e, t, n, r, s, a, o, l, c, u, h, d, f, p]) => {
  let _, g;
  if (p) {
    _ = et().toVar(), g = Y().toVar();
    const T = u.sub(1).mul(p.mul(0.025)), S = Y(u.sub(T), u, u.add(T));
    Ui({ start: 0, end: 3 }, ({ i: E }) => {
      const v = S.element(E), M = Sx(i, e, h, v, o), F = a.add(M), R = c.mul(l.mul(et(F, 1))), I = Pe(R.xy.div(R.w)).toVar();
      I.addAssign(1), I.divAssign(2), I.assign(Pe(I.x, I.y.oneMinus()));
      const B = Tx(I, t, v);
      _.element(E).assign(B.element(E)), _.a.addAssign(B.a), g.element(E).assign(n.element(E).mul(Mx(cs(M), d, f).element(E)));
    }), _.a.divAssign(3);
  } else {
    const T = Sx(i, e, h, u, o), S = a.add(T), E = c.mul(l.mul(et(S, 1))), v = Pe(E.xy.div(E.w)).toVar();
    v.addAssign(1), v.divAssign(2), v.assign(Pe(v.x, v.y.oneMinus())), _ = Tx(v, t, u), g = n.mul(Mx(cs(T), d, f));
  }
  const m = g.rgb.mul(_.rgb), x = i.dot(e).clamp(), y = Y(kS({
    // n, v, specularColor, specularF90, roughness
    dotNV: x,
    specularColor: r,
    specularF90: s,
    roughness: t
  })), b = g.r.add(g.g, g.b).div(3);
  return et(y.oneMinus().mul(m), _.a.oneMinus().mul(b).oneMinus());
}), sB = /* @__PURE__ */ On(
  3.2404542,
  -0.969266,
  0.0556434,
  -1.5371385,
  1.8760108,
  -0.2040259,
  -0.4985314,
  0.041556,
  1.0572252
), aB = (i) => {
  const e = i.sqrt();
  return Y(1).add(e).div(Y(1).sub(e));
}, Ex = (i, e) => i.sub(e).div(i.add(e)).pow2(), oB = (i, e) => {
  const t = i.mul(2 * Math.PI * 1e-9), n = Y(54856e-17, 44201e-17, 52481e-17), r = Y(1681e3, 1795300, 2208400), s = Y(43278e5, 93046e5, 66121e5), a = K(9747e-17 * Math.sqrt(2 * Math.PI * 45282e5)).mul(t.mul(2239900).add(e.x).cos()).mul(t.pow2().mul(-45282e5).exp());
  let o = n.mul(s.mul(2 * Math.PI).sqrt()).mul(r.mul(t).add(e).cos()).mul(t.pow2().negate().mul(s).exp());
  return o = Y(o.x.add(a), o.y, o.z).div(10685e-11), sB.mul(o);
}, wx = /* @__PURE__ */ ee(({ outsideIOR: i, eta2: e, cosTheta1: t, thinFilmThickness: n, baseF0: r }) => {
  const s = Lt(i, e, hs(0, 0.03, n)), o = i.div(s).pow2().mul(t.pow2().oneMinus()).oneMinus();
  Bt(o.lessThan(0), () => Y(1));
  const l = o.sqrt(), c = Ex(s, i), u = jc({ f0: c, f90: 1, dotVH: t }), h = u.oneMinus(), d = s.lessThan(i).select(Math.PI, 0), f = K(Math.PI).sub(d), p = aB(r.clamp(0, 0.9999)), _ = Ex(p, s.toVec3()), g = jc({ f0: _, f90: 1, dotVH: l }), m = Y(
    p.x.lessThan(s).select(Math.PI, 0),
    p.y.lessThan(s).select(Math.PI, 0),
    p.z.lessThan(s).select(Math.PI, 0)
  ), x = s.mul(n, l, 2), y = Y(f).add(m), b = u.mul(g).clamp(1e-5, 0.9999), T = b.sqrt(), S = h.pow2().mul(g).div(Y(1).sub(b)), v = u.add(S).toVar(), M = S.sub(h).toVar();
  return Ui({ start: 1, end: 2, condition: "<=", name: "m" }, ({ m: F }) => {
    M.mulAssign(T);
    const R = oB(K(F).mul(x), K(F).mul(y)).mul(2);
    v.addAssign(M.mul(R));
  }), v.max(Y(0));
}).setLayout({
  name: "evalIridescence",
  type: "vec3",
  inputs: [
    { name: "outsideIOR", type: "float" },
    { name: "eta2", type: "float" },
    { name: "cosTheta1", type: "float" },
    { name: "thinFilmThickness", type: "float" },
    { name: "baseF0", type: "vec3" }
  ]
}), Kl = /* @__PURE__ */ ee(({ normal: i, viewDir: e, roughness: t }) => {
  const n = i.dot(e).saturate(), r = t.mul(t), s = t.add(0.1).reciprocal(), a = K(-1.9362).add(t.mul(1.0678)).add(r.mul(0.4573)).sub(s.mul(0.8469)), o = K(-0.6014).add(t.mul(0.5538)).sub(r.mul(0.467)).sub(s.mul(0.1255));
  return a.mul(n).add(o).exp().saturate();
}), Zl = Y(0.04), Ju = K(1);
class zS extends Md {
  /**
   * Constructs a new physical lighting model.
   *
   * @param {boolean} [clearcoat=false] - Whether clearcoat is supported or not.
   * @param {boolean} [sheen=false] - Whether sheen is supported or not.
   * @param {boolean} [iridescence=false] - Whether iridescence is supported or not.
   * @param {boolean} [anisotropy=false] - Whether anisotropy is supported or not.
   * @param {boolean} [transmission=false] - Whether transmission is supported or not.
   * @param {boolean} [dispersion=false] - Whether dispersion is supported or not.
   */
  constructor(e = !1, t = !1, n = !1, r = !1, s = !1, a = !1) {
    super(), this.clearcoat = e, this.sheen = t, this.iridescence = n, this.anisotropy = r, this.transmission = s, this.dispersion = a, this.clearcoatRadiance = null, this.clearcoatSpecularDirect = null, this.clearcoatSpecularIndirect = null, this.sheenSpecularDirect = null, this.sheenSpecularIndirect = null, this.iridescenceFresnel = null, this.iridescenceF0 = null, this.iridescenceF0Dielectric = null, this.iridescenceF0Metallic = null;
  }
  /**
   * Depending on what features are requested, the method prepares certain node variables
   * which are later used for lighting computations.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  start(e) {
    if (this.clearcoat === !0 && (this.clearcoatRadiance = Y().toVar("clearcoatRadiance"), this.clearcoatSpecularDirect = Y().toVar("clearcoatSpecularDirect"), this.clearcoatSpecularIndirect = Y().toVar("clearcoatSpecularIndirect")), this.sheen === !0 && (this.sheenSpecularDirect = Y().toVar("sheenSpecularDirect"), this.sheenSpecularIndirect = Y().toVar("sheenSpecularIndirect")), this.iridescence === !0) {
      const t = vt.dot($t).clamp(), n = wx({
        outsideIOR: K(1),
        eta2: qp,
        cosTheta1: t,
        thinFilmThickness: Xp,
        baseF0: Ba
      }), r = wx({
        outsideIOR: K(1),
        eta2: qp,
        cosTheta1: t,
        thinFilmThickness: Xp,
        baseF0: Nt.rgb
      });
      this.iridescenceFresnel = Lt(n, r, Fs), this.iridescenceF0Dielectric = mx({ f: n, f90: 1, dotVH: t }), this.iridescenceF0Metallic = mx({ f: r, f90: 1, dotVH: t }), this.iridescenceF0 = Lt(this.iridescenceF0Dielectric, this.iridescenceF0Metallic, Fs);
    }
    if (this.transmission === !0) {
      const t = pl, n = LI.sub(pl).normalize(), r = Pl, s = e.context;
      s.backdrop = rB(
        r,
        n,
        Jr,
        To,
        Eo,
        wo,
        // specularF90
        t,
        // positionWorld
        Ga,
        // modelMatrix
        fs,
        // viewMatrix
        Tc,
        // projMatrix
        wh,
        Pb,
        Lb,
        Db,
        this.dispersion ? Fb : null
      ), s.backdropAlpha = Kp, Nt.a.mulAssign(Lt(1, s.backdrop.a, Kp));
    }
    super.start(e);
  }
  // Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
  // Approximates multi-scattering in order to preserve energy.
  // http://www.jcgt.org/published/0008/01/03/
  computeMultiscattering(e, t, n, r, s = null) {
    const a = vt.dot($t).clamp(), o = Xh({ roughness: Jr, dotNV: a }), l = s ? wg.mix(r, s) : r, c = l.mul(o.x).add(n.mul(o.y)), h = o.x.add(o.y).oneMinus(), d = l.add(l.oneMinus().mul(0.047619)), f = c.mul(d).div(h.mul(d).oneMinus());
    e.addAssign(c), t.addAssign(f.mul(h));
  }
  /**
   * Implements the direct light.
   *
   * @param {Object} lightData - The light data.
   * @param {NodeBuilder} builder - The current node builder.
   */
  direct({ lightDirection: e, lightColor: t, reflectedLight: n }) {
    const s = vt.dot(e).clamp().mul(t).toVar();
    if (this.sheen === !0) {
      this.sheenSpecularDirect.addAssign(s.mul(Q3({ lightDirection: e })));
      const a = Kl({ normal: vt, viewDir: $t, roughness: ma }), o = Kl({ normal: vt, viewDir: e, roughness: ma }), l = Li.r.max(Li.g).max(Li.b).mul(a.max(o)).oneMinus();
      s.mulAssign(l);
    }
    if (this.clearcoat === !0) {
      const o = xa.dot(e).clamp().mul(t);
      this.clearcoatSpecularDirect.addAssign(o.mul(OS({ lightDirection: e, f0: Zl, f90: Ju, roughness: yc, normalView: xa })));
    }
    n.directDiffuse.addAssign(s.mul(ml({ diffuseColor: To }))), n.directSpecular.addAssign(s.mul(Y3({ lightDirection: e, f0: Eo, f90: 1, roughness: Jr, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy })));
  }
  /**
   * This method is intended for implementing the direct light term for
   * rect area light nodes.
   *
   * @param {Object} input - The input data.
   * @param {NodeBuilder} builder - The current node builder.
   */
  directRectArea({ lightColor: e, lightPosition: t, halfWidth: n, halfHeight: r, reflectedLight: s, ltc_1: a, ltc_2: o }) {
    const l = t.add(n).sub(r), c = t.sub(n).sub(r), u = t.sub(n).add(r), h = t.add(n).add(r), d = vt, f = $t, p = hn.toVar(), _ = gx({ N: d, V: f, roughness: Jr }), g = a.sample(_).toVar(), m = o.sample(_).toVar(), x = On(
      Y(g.x, 0, g.y),
      Y(0, 1, 0),
      Y(g.z, 0, g.w)
    ).toVar(), y = Eo.mul(m.x).add(wo.sub(Eo).mul(m.y)).toVar();
    if (s.directSpecular.addAssign(e.mul(y).mul(zf({ N: d, V: f, P: p, mInv: x, p0: l, p1: c, p2: u, p3: h }))), s.directDiffuse.addAssign(e.mul(To).mul(zf({ N: d, V: f, P: p, mInv: On(1, 0, 0, 0, 1, 0, 0, 0, 1), p0: l, p1: c, p2: u, p3: h }))), this.clearcoat === !0) {
      const b = xa, T = gx({ N: b, V: f, roughness: yc }), S = a.sample(T), E = o.sample(T), v = On(
        Y(S.x, 0, S.y),
        Y(0, 1, 0),
        Y(S.z, 0, S.w)
      ), M = Zl.mul(E.x).add(Ju.sub(Zl).mul(E.y));
      this.clearcoatSpecularDirect.addAssign(e.mul(M).mul(zf({ N: b, V: f, P: p, mInv: v, p0: l, p1: c, p2: u, p3: h })));
    }
  }
  /**
   * Implements the indirect lighting.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirect(e) {
    this.indirectDiffuse(e), this.indirectSpecular(e), this.ambientOcclusion(e);
  }
  /**
   * Implements the indirect diffuse term.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirectDiffuse(e) {
    const { irradiance: t, reflectedLight: n } = e.context, r = t.mul(ml({ diffuseColor: To })).toVar();
    if (this.sheen === !0) {
      const s = Kl({ normal: vt, viewDir: $t, roughness: ma }), a = Li.r.max(Li.g).max(Li.b).mul(s).oneMinus();
      r.mulAssign(a);
    }
    n.indirectDiffuse.addAssign(r);
  }
  /**
   * Implements the indirect specular term.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirectSpecular(e) {
    const { radiance: t, iblIrradiance: n, reflectedLight: r } = e.context;
    if (this.sheen === !0 && this.sheenSpecularIndirect.addAssign(n.mul(
      Li,
      Kl({
        normal: vt,
        viewDir: $t,
        roughness: ma
      })
    )), this.clearcoat === !0) {
      const g = xa.dot($t).clamp(), m = kS({
        dotNV: g,
        specularColor: Zl,
        specularF90: Ju,
        roughness: yc
      });
      this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(m));
    }
    const s = Y().toVar("singleScatteringDielectric"), a = Y().toVar("multiScatteringDielectric"), o = Y().toVar("singleScatteringMetallic"), l = Y().toVar("multiScatteringMetallic");
    this.computeMultiscattering(s, a, wo, Ba, this.iridescenceF0Dielectric), this.computeMultiscattering(o, l, wo, Nt.rgb, this.iridescenceF0Metallic);
    const c = Lt(s, o, Fs), u = Lt(a, l, Fs), h = s.add(a), d = To.mul(h.oneMinus()), f = n.mul(1 / Math.PI), p = t.mul(c).add(u.mul(f)).toVar(), _ = d.mul(f).toVar();
    if (this.sheen === !0) {
      const g = Kl({ normal: vt, viewDir: $t, roughness: ma }), m = Li.r.max(Li.g).max(Li.b).mul(g).oneMinus();
      p.mulAssign(m), _.mulAssign(m);
    }
    r.indirectSpecular.addAssign(p), r.indirectDiffuse.addAssign(_);
  }
  /**
   * Implements the ambient occlusion term.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  ambientOcclusion(e) {
    const { ambientOcclusion: t, reflectedLight: n } = e.context, s = vt.dot($t).clamp().add(t), a = Jr.mul(-16).oneMinus().negate().exp2(), o = t.sub(s.pow(a).oneMinus()).clamp();
    this.clearcoat === !0 && this.clearcoatSpecularIndirect.mulAssign(t), this.sheen === !0 && this.sheenSpecularIndirect.mulAssign(t), n.indirectDiffuse.mulAssign(t), n.indirectSpecular.mulAssign(o);
  }
  /**
   * Used for final lighting accumulations depending on the requested features.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  finish({ context: e }) {
    const { outgoingLight: t } = e;
    if (this.clearcoat === !0) {
      const n = xa.dot($t).clamp(), r = jc({
        dotVH: n,
        f0: Zl,
        f90: Ju
      }), s = t.mul(Wp.mul(r).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul(Wp));
      t.assign(s);
    }
    if (this.sheen === !0) {
      const n = t.add(this.sheenSpecularDirect, this.sheenSpecularIndirect.mul(1 / Math.PI));
      t.assign(n);
    }
  }
}
const Ax = /* @__PURE__ */ K(1), nm = /* @__PURE__ */ K(-2), eh = /* @__PURE__ */ K(0.8), Hf = /* @__PURE__ */ K(-1), th = /* @__PURE__ */ K(0.4), $f = /* @__PURE__ */ K(2), nh = /* @__PURE__ */ K(0.305), Wf = /* @__PURE__ */ K(3), Rx = /* @__PURE__ */ K(0.21), lB = /* @__PURE__ */ K(4), Cx = /* @__PURE__ */ K(4), cB = /* @__PURE__ */ K(16), uB = /* @__PURE__ */ ee(([i]) => {
  const e = Y(Ai(i)).toVar(), t = K(-1).toVar();
  return Bt(e.x.greaterThan(e.z), () => {
    Bt(e.x.greaterThan(e.y), () => {
      t.assign(Ri(i.x.greaterThan(0), 0, 3));
    }).Else(() => {
      t.assign(Ri(i.y.greaterThan(0), 1, 4));
    });
  }).Else(() => {
    Bt(e.z.greaterThan(e.y), () => {
      t.assign(Ri(i.z.greaterThan(0), 2, 5));
    }).Else(() => {
      t.assign(Ri(i.y.greaterThan(0), 1, 4));
    });
  }), t;
}).setLayout({
  name: "getFace",
  type: "float",
  inputs: [
    { name: "direction", type: "vec3" }
  ]
}), hB = /* @__PURE__ */ ee(([i, e]) => {
  const t = Pe().toVar();
  return Bt(e.equal(0), () => {
    t.assign(Pe(i.z, i.y).div(Ai(i.x)));
  }).ElseIf(e.equal(1), () => {
    t.assign(Pe(i.x.negate(), i.z.negate()).div(Ai(i.y)));
  }).ElseIf(e.equal(2), () => {
    t.assign(Pe(i.x.negate(), i.y).div(Ai(i.z)));
  }).ElseIf(e.equal(3), () => {
    t.assign(Pe(i.z.negate(), i.y).div(Ai(i.x)));
  }).ElseIf(e.equal(4), () => {
    t.assign(Pe(i.x.negate(), i.z).div(Ai(i.y)));
  }).Else(() => {
    t.assign(Pe(i.x, i.y).div(Ai(i.z)));
  }), at(0.5, t.add(1));
}).setLayout({
  name: "getUV",
  type: "vec2",
  inputs: [
    { name: "direction", type: "vec3" },
    { name: "face", type: "float" }
  ]
}), dB = /* @__PURE__ */ ee(([i]) => {
  const e = K(0).toVar();
  return Bt(i.greaterThanEqual(eh), () => {
    e.assign(Ax.sub(i).mul(Hf.sub(nm)).div(Ax.sub(eh)).add(nm));
  }).ElseIf(i.greaterThanEqual(th), () => {
    e.assign(eh.sub(i).mul($f.sub(Hf)).div(eh.sub(th)).add(Hf));
  }).ElseIf(i.greaterThanEqual(nh), () => {
    e.assign(th.sub(i).mul(Wf.sub($f)).div(th.sub(nh)).add($f));
  }).ElseIf(i.greaterThanEqual(Rx), () => {
    e.assign(nh.sub(i).mul(lB.sub(Wf)).div(nh.sub(Rx)).add(Wf));
  }).Else(() => {
    e.assign(K(-2).mul(ls(at(1.16, i))));
  }), e;
}).setLayout({
  name: "roughnessToMip",
  type: "float",
  inputs: [
    { name: "roughness", type: "float" }
  ]
}), fB = /* @__PURE__ */ ee(([i, e]) => {
  const t = i.toVar();
  t.assign(at(2, t).sub(1));
  const n = Y(t, 1).toVar();
  return Bt(e.equal(0), () => {
    n.assign(n.zyx);
  }).ElseIf(e.equal(1), () => {
    n.assign(n.xzy), n.xz.mulAssign(-1);
  }).ElseIf(e.equal(2), () => {
    n.x.mulAssign(-1);
  }).ElseIf(e.equal(3), () => {
    n.assign(n.zyx), n.xz.mulAssign(-1);
  }).ElseIf(e.equal(4), () => {
    n.assign(n.xzy), n.xy.mulAssign(-1);
  }).ElseIf(e.equal(5), () => {
    n.z.mulAssign(-1);
  }), n;
}).setLayout({
  name: "getDirection",
  type: "vec3",
  inputs: [
    { name: "uv", type: "vec2" },
    { name: "face", type: "float" }
  ]
}), pB = /* @__PURE__ */ ee(([i, e, t, n, r, s]) => {
  const a = K(t), o = Y(e), l = $s(dB(a), nm, s), c = Pr(l), u = Ma(l), h = Y(Yc(i, o, u, n, r, s)).toVar();
  return Bt(c.notEqual(0), () => {
    const d = Y(Yc(i, o, u.add(1), n, r, s)).toVar();
    h.assign(Lt(h, d, c));
  }), h;
}), Yc = /* @__PURE__ */ ee(([i, e, t, n, r, s]) => {
  const a = K(t).toVar(), o = Y(e), l = K(uB(o)).toVar(), c = K(kn(Cx.sub(a), 0)).toVar();
  a.assign(kn(a, Cx));
  const u = K(Wc(a)).toVar(), h = Pe(hB(o, l).mul(u.sub(2)).add(1)).toVar();
  return Bt(l.greaterThan(2), () => {
    h.y.addAssign(u), l.subAssign(3);
  }), h.x.addAssign(l.mul(u)), h.x.addAssign(c.mul(at(3, cB))), h.y.addAssign(at(4, Wc(s).sub(u))), h.x.mulAssign(n), h.y.mulAssign(r), i.sample(h).grad(Pe(), Pe());
}), qf = /* @__PURE__ */ ee(({ envMap: i, mipInt: e, outputDirection: t, theta: n, axis: r, CUBEUV_TEXEL_WIDTH: s, CUBEUV_TEXEL_HEIGHT: a, CUBEUV_MAX_MIP: o }) => {
  const l = _r(n), c = t.mul(l).add(r.cross(t).mul(wi(n))).add(r.mul(r.dot(t).mul(l.oneMinus())));
  return Yc(i, c, e, s, a, o);
}), mB = /* @__PURE__ */ ee(({ n: i, latitudinal: e, poleAxis: t, outputDirection: n, weights: r, samples: s, dTheta: a, mipInt: o, envMap: l, CUBEUV_TEXEL_WIDTH: c, CUBEUV_TEXEL_HEIGHT: u, CUBEUV_MAX_MIP: h }) => {
  const d = Y(Ri(e, t, ka(t, n))).toVar();
  Bt(d.equal(Y(0)), () => {
    d.assign(Y(n.z, 0, n.x.negate()));
  }), d.assign(Ar(d));
  const f = Y().toVar();
  return f.addAssign(r.element(0).mul(qf({ theta: 0, axis: d, outputDirection: n, mipInt: o, envMap: l, CUBEUV_TEXEL_WIDTH: c, CUBEUV_TEXEL_HEIGHT: u, CUBEUV_MAX_MIP: h }))), Ui({ start: Kt(1), end: i }, ({ i: p }) => {
    Bt(p.greaterThanEqual(s), () => {
      n3();
    });
    const _ = K(a.mul(K(p))).toVar();
    f.addAssign(r.element(p).mul(qf({ theta: _.mul(-1), axis: d, outputDirection: n, mipInt: o, envMap: l, CUBEUV_TEXEL_WIDTH: c, CUBEUV_TEXEL_HEIGHT: u, CUBEUV_MAX_MIP: h }))), f.addAssign(r.element(p).mul(qf({ theta: _, axis: d, outputDirection: n, mipInt: o, envMap: l, CUBEUV_TEXEL_WIDTH: c, CUBEUV_TEXEL_HEIGHT: u, CUBEUV_MAX_MIP: h })));
  }), et(f, 1);
}), gB = /* @__PURE__ */ ee(([i]) => {
  const e = gt(i).toVar();
  return e.assign(e.shiftLeft(gt(16)).bitOr(e.shiftRight(gt(16)))), e.assign(e.bitAnd(gt(1431655765)).shiftLeft(gt(1)).bitOr(e.bitAnd(gt(2863311530)).shiftRight(gt(1)))), e.assign(e.bitAnd(gt(858993459)).shiftLeft(gt(2)).bitOr(e.bitAnd(gt(3435973836)).shiftRight(gt(2)))), e.assign(e.bitAnd(gt(252645135)).shiftLeft(gt(4)).bitOr(e.bitAnd(gt(4042322160)).shiftRight(gt(4)))), e.assign(e.bitAnd(gt(16711935)).shiftLeft(gt(8)).bitOr(e.bitAnd(gt(4278255360)).shiftRight(gt(8)))), K(e).mul(23283064365386963e-26);
}), _B = /* @__PURE__ */ ee(([i, e]) => Pe(K(i).div(K(e)), gB(i))), xB = /* @__PURE__ */ ee(([i, e, t]) => {
  const n = t.mul(t).toConst(), r = Y(1, 0, 0).toConst(), s = ka(e, r).toConst(), a = zs(i.x).toConst(), o = at(2, 3.14159265359).mul(i.y).toConst(), l = a.mul(_r(o)).toConst(), c = a.mul(wi(o)).toVar(), u = at(0.5, e.z.add(1)).toConst();
  c.assign(u.oneMinus().mul(zs(l.mul(l).oneMinus())).add(u.mul(c)));
  const h = r.mul(l).add(s.mul(c)).add(e.mul(zs(kn(0, l.mul(l).add(c.mul(c)).oneMinus()))));
  return Ar(Y(n.mul(h.x), n.mul(h.y), kn(0, h.z)));
}), vB = /* @__PURE__ */ ee(({ roughness: i, mipInt: e, envMap: t, N_immutable: n, GGX_SAMPLES: r, CUBEUV_TEXEL_WIDTH: s, CUBEUV_TEXEL_HEIGHT: a, CUBEUV_MAX_MIP: o }) => {
  const l = Y(n).toVar(), c = Y(0).toVar(), u = K(0).toVar();
  return Bt(i.lessThan(1e-3), () => {
    c.assign(Yc(t, l, e, s, a, o));
  }).Else(() => {
    const h = Ri(Ai(l.z).lessThan(0.999), Y(0, 0, 1), Y(1, 0, 0)), d = Ar(ka(h, l)).toVar(), f = ka(l, d).toVar();
    Ui({ start: gt(0), end: r }, ({ i: p }) => {
      const _ = _B(p, r), g = xB(_, Y(0, 0, 1), i), m = Ar(d.mul(g.x).add(f.mul(g.y)).add(l.mul(g.z))), x = Ar(m.mul(Oa(l, m).mul(2)).sub(l)), y = kn(Oa(l, x), 0);
      Bt(y.greaterThan(0), () => {
        const b = Yc(t, x, e, s, a, o);
        c.addAssign(b.mul(y)), u.addAssign(y);
      });
    }), Bt(u.greaterThan(0), () => {
      c.assign(c.div(u));
    });
  }), et(c, 1);
}), Is = 4, Nx = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582], va = 20, yB = 512, Ql = /* @__PURE__ */ new bl(-1, 1, 1, -1, 0, 1), bB = /* @__PURE__ */ new An(90, 1), Px = /* @__PURE__ */ new He();
let Xf = null, jf = 0, Yf = 0;
const SB = /* @__PURE__ */ new P(), jh = /* @__PURE__ */ new WeakMap(), TB = [
  3,
  1,
  5,
  0,
  4,
  2
], Kf = /* @__PURE__ */ fB(Al(), Ws("faceIndex")).normalize(), wd = /* @__PURE__ */ Y(Kf.x, Kf.y, Kf.z);
class MB {
  /**
   * Constructs a new PMREM generator.
   *
   * @param {Renderer} renderer - The renderer.
   */
  constructor(e) {
    this._renderer = e, this._pingPongRenderTarget = null, this._lodMax = 0, this._cubeSize = 0, this._sizeLods = [], this._sigmas = [], this._lodMeshes = [], this._blurMaterial = null, this._ggxMaterial = null, this._cubemapMaterial = null, this._equirectMaterial = null, this._backgroundBox = null;
  }
  get _hasInitialized() {
    return this._renderer.hasInitialized();
  }
  /**
   * Generates a PMREM from a supplied Scene, which can be faster than using an
   * image if networking bandwidth is low. Optional sigma specifies a blur radius
   * in radians to be applied to the scene before PMREM generation. Optional near
   * and far planes ensure the scene is rendered in its entirety.
   *
   * @param {Scene} scene - The scene to be captured.
   * @param {number} [sigma=0] - The blur radius in radians.
   * @param {number} [near=0.1] - The near plane distance.
   * @param {number} [far=100] - The far plane distance.
   * @param {Object} [options={}] - The configuration options.
   * @param {number} [options.size=256] - The texture size of the PMREM.
   * @param {Vector3} [options.renderTarget=origin] - The position of the internal cube camera that renders the scene.
   * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
   * @return {RenderTarget} The resulting PMREM.
   * @see {@link PMREMGenerator#fromScene}
   */
  fromScene(e, t = 0, n = 0.1, r = 100, s = {}) {
    const {
      size: a = 256,
      position: o = SB,
      renderTarget: l = null
    } = s;
    if (this._setSize(a), this._hasInitialized === !1) {
      oe('PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.');
      const u = l || this._allocateTarget();
      return s.renderTarget = u, this.fromSceneAsync(e, t, n, r, s), u;
    }
    Xf = this._renderer.getRenderTarget(), jf = this._renderer.getActiveCubeFace(), Yf = this._renderer.getActiveMipmapLevel();
    const c = l || this._allocateTarget();
    return c.depthBuffer = !0, this._init(c), this._sceneToCubeUV(e, n, r, c, o), t > 0 && this._blur(c, 0, 0, t), this._applyPMREM(c), this._cleanup(c), c;
  }
  /**
   * Generates a PMREM from a supplied Scene, which can be faster than using an
   * image if networking bandwidth is low. Optional sigma specifies a blur radius
   * in radians to be applied to the scene before PMREM generation. Optional near
   * and far planes ensure the scene is rendered in its entirety (the cubeCamera
   * is placed at the origin).
   *
   * @deprecated
   * @param {Scene} scene - The scene to be captured.
   * @param {number} [sigma=0] - The blur radius in radians.
   * @param {number} [near=0.1] - The near plane distance.
   * @param {number} [far=100] - The far plane distance.
   * @param {Object} [options={}] - The configuration options.
   * @param {number} [options.size=256] - The texture size of the PMREM.
   * @param {Vector3} [options.position=origin] - The position of the internal cube camera that renders the scene.
   * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
   * @return {Promise<RenderTarget>} A Promise that resolve with the PMREM when the generation has been finished.
   * @see {@link PMREMGenerator#fromScene}
   */
  async fromSceneAsync(e, t = 0, n = 0.1, r = 100, s = {}) {
    return Pt('PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.'), await this._renderer.init(), this.fromScene(e, t, n, r, s);
  }
  /**
   * Generates a PMREM from an equirectangular texture, which can be either LDR
   * or HDR. The ideal input image size is 1k (1024 x 512),
   * as this matches best with the 256 x 256 cubemap output.
   *
   * @param {Texture} equirectangular - The equirectangular texture to be converted.
   * @param {?RenderTarget} [renderTarget=null] - The render target to use.
   * @return {RenderTarget} The resulting PMREM.
   * @see {@link PMREMGenerator#fromEquirectangularAsync}
   */
  fromEquirectangular(e, t = null) {
    if (this._hasInitialized === !1) {
      oe('PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.'), this._setSizeFromTexture(e);
      const n = t || this._allocateTarget();
      return this.fromEquirectangularAsync(e, n), n;
    }
    return this._fromTexture(e, t);
  }
  /**
   * Generates a PMREM from an equirectangular texture, which can be either LDR
   * or HDR. The ideal input image size is 1k (1024 x 512),
   * as this matches best with the 256 x 256 cubemap output.
   *
   * @deprecated
   * @param {Texture} equirectangular - The equirectangular texture to be converted.
   * @param {?RenderTarget} [renderTarget=null] - The render target to use.
   * @return {Promise<RenderTarget>} The resulting PMREM.
   * @see {@link PMREMGenerator#fromEquirectangular}
   */
  async fromEquirectangularAsync(e, t = null) {
    return Pt('PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.'), await this._renderer.init(), this._fromTexture(e, t);
  }
  /**
   * Generates a PMREM from an cubemap texture, which can be either LDR
   * or HDR. The ideal input cube size is 256 x 256,
   * as this matches best with the 256 x 256 cubemap output.
   *
   * @param {Texture} cubemap - The cubemap texture to be converted.
   * @param {?RenderTarget} [renderTarget=null] - The render target to use.
   * @return {RenderTarget} The resulting PMREM.
   * @see {@link PMREMGenerator#fromCubemapAsync}
   */
  fromCubemap(e, t = null) {
    if (this._hasInitialized === !1) {
      oe("PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead."), this._setSizeFromTexture(e);
      const n = t || this._allocateTarget();
      return this.fromCubemapAsync(e, t), n;
    }
    return this._fromTexture(e, t);
  }
  /**
   * Generates a PMREM from an cubemap texture, which can be either LDR
   * or HDR. The ideal input cube size is 256 x 256,
   * with the 256 x 256 cubemap output.
   *
   * @deprecated
   * @param {Texture} cubemap - The cubemap texture to be converted.
   * @param {?RenderTarget} [renderTarget=null] - The render target to use.
   * @return {Promise<RenderTarget>} The resulting PMREM.
   * @see {@link PMREMGenerator#fromCubemap}
   */
  async fromCubemapAsync(e, t = null) {
    return Pt('PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.'), await this._renderer.init(), this._fromTexture(e, t);
  }
  /**
   * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
   * your texture's network fetch for increased concurrency.
   *
   * @returns {Promise}
   */
  async compileCubemapShader() {
    this._cubemapMaterial === null && (this._cubemapMaterial = Lx(), await this._compileMaterial(this._cubemapMaterial));
  }
  /**
   * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
   * your texture's network fetch for increased concurrency.
   *
   * @returns {Promise}
   */
  async compileEquirectangularShader() {
    this._equirectMaterial === null && (this._equirectMaterial = Fx(), await this._compileMaterial(this._equirectMaterial));
  }
  /**
   * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
   * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
   * one of them will cause any others to also become unusable.
   */
  dispose() {
    this._dispose(), this._cubemapMaterial !== null && this._cubemapMaterial.dispose(), this._equirectMaterial !== null && this._equirectMaterial.dispose(), this._backgroundBox !== null && (this._backgroundBox.geometry.dispose(), this._backgroundBox.material.dispose());
  }
  // private interface
  _setSizeFromTexture(e) {
    e.mapping === nr || e.mapping === Rr ? this._setSize(e.image.length === 0 ? 16 : e.image[0].width || e.image[0].image.width) : this._setSize(e.image.width / 4);
  }
  _setSize(e) {
    this._lodMax = Math.floor(Math.log2(e)), this._cubeSize = Math.pow(2, this._lodMax);
  }
  _dispose() {
    this._blurMaterial !== null && this._blurMaterial.dispose(), this._ggxMaterial !== null && this._ggxMaterial.dispose(), this._pingPongRenderTarget !== null && this._pingPongRenderTarget.dispose();
    for (let e = 0; e < this._lodMeshes.length; e++)
      this._lodMeshes[e].geometry.dispose();
  }
  _cleanup(e) {
    this._renderer.setRenderTarget(Xf, jf, Yf), e.scissorTest = !1, go(e, 0, 0, e.width, e.height);
  }
  _fromTexture(e, t) {
    this._setSizeFromTexture(e), Xf = this._renderer.getRenderTarget(), jf = this._renderer.getActiveCubeFace(), Yf = this._renderer.getActiveMipmapLevel();
    const n = t || this._allocateTarget();
    return this._init(n), this._textureToCubeUV(e, n), this._applyPMREM(n), this._cleanup(n), n;
  }
  _allocateTarget() {
    const e = 3 * Math.max(this._cubeSize, 112), t = 4 * this._cubeSize;
    return Dx(e, t);
  }
  _init(e) {
    if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== e.width || this._pingPongRenderTarget.height !== e.height) {
      this._pingPongRenderTarget !== null && this._dispose(), this._pingPongRenderTarget = Dx(e.width, e.height);
      const { _lodMax: t } = this;
      ({ lodMeshes: this._lodMeshes, sizeLods: this._sizeLods, sigmas: this._sigmas } = EB(t)), this._blurMaterial = wB(t, e.width, e.height), this._ggxMaterial = AB(t, e.width, e.height);
    }
  }
  async _compileMaterial(e) {
    const t = new _n(new Pn(), e);
    await this._renderer.compile(t, Ql);
  }
  _sceneToCubeUV(e, t, n, r, s) {
    const a = bB;
    a.near = t, a.far = n;
    const o = [1, 1, 1, 1, -1, 1], l = [1, -1, 1, -1, 1, -1], c = this._renderer, u = c.autoClear;
    c.getClearColor(Px), c.autoClear = !1, this._backgroundBox === null && (this._backgroundBox = new _n(
      new $a(),
      new xr({
        name: "PMREM.Background",
        side: Ft,
        depthWrite: !1,
        depthTest: !1
      })
    ));
    const h = this._backgroundBox, d = h.material;
    let f = !1;
    const p = e.background;
    p ? p.isColor && (d.color.copy(p), e.background = null, f = !0) : (d.color.copy(Px), f = !0), c.setRenderTarget(r), c.clear(), f && c.render(h, a);
    for (let _ = 0; _ < 6; _++) {
      const g = _ % 3;
      g === 0 ? (a.up.set(0, o[_], 0), a.position.set(s.x, s.y, s.z), a.lookAt(s.x + l[_], s.y, s.z)) : g === 1 ? (a.up.set(0, 0, o[_]), a.position.set(s.x, s.y, s.z), a.lookAt(s.x, s.y + l[_], s.z)) : (a.up.set(0, o[_], 0), a.position.set(s.x, s.y, s.z), a.lookAt(s.x, s.y, s.z + l[_]));
      const m = this._cubeSize;
      go(r, g * m, _ > 2 ? m : 0, m, m), c.render(e, a);
    }
    c.autoClear = u, e.background = p;
  }
  _textureToCubeUV(e, t) {
    const n = this._renderer, r = e.mapping === nr || e.mapping === Rr;
    r ? this._cubemapMaterial === null && (this._cubemapMaterial = Lx(e)) : this._equirectMaterial === null && (this._equirectMaterial = Fx(e));
    const s = r ? this._cubemapMaterial : this._equirectMaterial;
    s.fragmentNode.value = e;
    const a = this._lodMeshes[0];
    a.material = s;
    const o = this._cubeSize;
    go(t, 0, 0, 3 * o, 2 * o), n.setRenderTarget(t), n.render(a, Ql);
  }
  _applyPMREM(e) {
    const t = this._renderer, n = t.autoClear;
    t.autoClear = !1;
    const r = this._lodMeshes.length;
    for (let s = 1; s < r; s++)
      this._applyGGXFilter(e, s - 1, s);
    t.autoClear = n;
  }
  /**
   * Applies GGX VNDF importance sampling filter to generate a prefiltered environment map.
   * Uses Monte Carlo integration with VNDF importance sampling to accurately represent the
   * GGX BRDF for physically-based rendering. Reads from the previous LOD level and
   * applies incremental roughness filtering to avoid over-blurring.
   *
   * @private
   * @param {RenderTarget} cubeUVRenderTarget
   * @param {number} lodIn - Source LOD level to read from
   * @param {number} lodOut - Target LOD level to write to
   */
  _applyGGXFilter(e, t, n) {
    const r = this._renderer, s = this._pingPongRenderTarget, a = this._ggxMaterial, o = this._lodMeshes[n];
    o.material = a;
    const l = jh.get(a), c = n / (this._lodMeshes.length - 1), u = t / (this._lodMeshes.length - 1), h = Math.sqrt(c * c - u * u), d = 0 + c * 1.25, f = h * d, { _lodMax: p } = this, _ = this._sizeLods[n], g = 3 * _ * (n > p - Is ? n - p + Is : 0), m = 4 * (this._cubeSize - _);
    e.texture.frame = (e.texture.frame || 0) + 1, l.envMap.value = e.texture, l.roughness.value = f, l.mipInt.value = p - t, go(s, g, m, 3 * _, 2 * _), r.setRenderTarget(s), r.render(o, Ql), s.texture.frame = (s.texture.frame || 0) + 1, l.envMap.value = s.texture, l.roughness.value = 0, l.mipInt.value = p - n, go(e, g, m, 3 * _, 2 * _), r.setRenderTarget(e), r.render(o, Ql);
  }
  /**
   * This is a two-pass Gaussian blur for a cubemap. Normally this is done
   * vertically and horizontally, but this breaks down on a cube. Here we apply
   * the blur latitudinally (around the poles), and then longitudinally (towards
   * the poles) to approximate the orthogonally-separable blur. It is least
   * accurate at the poles, but still does a decent job.
   *
   * Used for initial scene blur in fromScene() method when sigma > 0.
   *
   * @private
   * @param {RenderTarget} cubeUVRenderTarget - The cubemap render target.
   * @param {number} lodIn - The input level-of-detail.
   * @param {number} lodOut - The output level-of-detail.
   * @param {number} sigma - The blur radius in radians.
   * @param {Vector3} [poleAxis] - The pole axis.
   */
  _blur(e, t, n, r, s) {
    const a = this._pingPongRenderTarget;
    this._halfBlur(
      e,
      a,
      t,
      n,
      r,
      "latitudinal",
      s
    ), this._halfBlur(
      a,
      e,
      n,
      n,
      r,
      "longitudinal",
      s
    );
  }
  _halfBlur(e, t, n, r, s, a, o) {
    const l = this._renderer, c = this._blurMaterial;
    a !== "latitudinal" && a !== "longitudinal" && le("blur direction must be either latitudinal or longitudinal!");
    const u = 3, h = this._lodMeshes[r];
    h.material = c;
    const d = jh.get(c), f = this._sizeLods[n] - 1, p = isFinite(s) ? Math.PI / (2 * f) : 2 * Math.PI / (2 * va - 1), _ = s / p, g = isFinite(s) ? 1 + Math.floor(u * _) : va;
    g > va && oe(`sigmaRadians, ${s}, is too large and will clip, as it requested ${g} samples when the maximum is set to ${va}`);
    const m = [];
    let x = 0;
    for (let E = 0; E < va; ++E) {
      const v = E / _, M = Math.exp(-v * v / 2);
      m.push(M), E === 0 ? x += M : E < g && (x += 2 * M);
    }
    for (let E = 0; E < m.length; E++)
      m[E] = m[E] / x;
    e.texture.frame = (e.texture.frame || 0) + 1, d.envMap.value = e.texture, d.samples.value = g, d.weights.array = m, d.latitudinal.value = a === "latitudinal" ? 1 : 0, o && (d.poleAxis.value = o);
    const { _lodMax: y } = this;
    d.dTheta.value = p, d.mipInt.value = y - n;
    const b = this._sizeLods[r], T = 3 * b * (r > y - Is ? r - y + Is : 0), S = 4 * (this._cubeSize - b);
    go(t, T, S, 3 * b, 2 * b), l.setRenderTarget(t), l.render(h, Ql);
  }
}
function EB(i) {
  const e = [], t = [], n = [];
  let r = i;
  const s = i - Is + 1 + Nx.length;
  for (let a = 0; a < s; a++) {
    const o = Math.pow(2, r);
    e.push(o);
    let l = 1 / o;
    a > i - Is ? l = Nx[a - i + Is - 1] : a === 0 && (l = 0), t.push(l);
    const c = 1 / (o - 2), u = -c, h = 1 + c, d = [u, u, h, u, h, h, u, u, h, h, u, h], f = 6, p = 6, _ = 3, g = 2, m = 1, x = new Float32Array(_ * p * f), y = new Float32Array(g * p * f), b = new Float32Array(m * p * f);
    for (let S = 0; S < f; S++) {
      const E = S % 3 * 2 / 3 - 1, v = S > 2 ? 0 : -1, M = [
        E,
        v,
        0,
        E + 2 / 3,
        v,
        0,
        E + 2 / 3,
        v + 1,
        0,
        E,
        v,
        0,
        E + 2 / 3,
        v + 1,
        0,
        E,
        v + 1,
        0
      ], F = TB[S];
      x.set(M, _ * p * F), y.set(d, g * p * F);
      const R = [F, F, F, F, F, F];
      b.set(R, m * p * F);
    }
    const T = new Pn();
    T.setAttribute("position", new Bn(x, _)), T.setAttribute("uv", new Bn(y, g)), T.setAttribute("faceIndex", new Bn(b, m)), n.push(new _n(T, null)), r > Is && r--;
  }
  return { lodMeshes: n, sizeLods: e, sigmas: t };
}
function Dx(i, e) {
  const t = {
    magFilter: Ot,
    minFilter: Ot,
    generateMipmaps: !1,
    type: nn,
    format: cn,
    colorSpace: La
    //depthBuffer: false
  }, n = new js(i, e, t);
  return n.texture.mapping = Ra, n.texture.name = "PMREM.cubeUv", n.texture.isPMREMTexture = !0, n.scissorTest = !0, n;
}
function go(i, e, t, n, r) {
  i.viewport.set(e, t, n, r), i.scissor.set(e, t, n, r);
}
function Ad(i) {
  const e = new dn();
  return e.depthTest = !1, e.depthWrite = !1, e.blending = Nn, e.name = `PMREM_${i}`, e;
}
function wB(i, e, t) {
  const n = Ii(new Array(va).fill(0)), r = je(new P(0, 1, 0)), s = je(0), a = K(va), o = je(0), l = je(1), c = qt(), u = je(0), h = K(1 / e), d = K(1 / t), f = K(i), p = {
    n: a,
    latitudinal: o,
    weights: n,
    poleAxis: r,
    outputDirection: wd,
    dTheta: s,
    samples: l,
    envMap: c,
    mipInt: u,
    CUBEUV_TEXEL_WIDTH: h,
    CUBEUV_TEXEL_HEIGHT: d,
    CUBEUV_MAX_MIP: f
  }, _ = Ad("blur");
  return _.fragmentNode = mB({ ...p, latitudinal: o.equal(1) }), jh.set(_, p), _;
}
function AB(i, e, t) {
  const n = qt(), r = je(0), s = je(0), a = K(1 / e), o = K(1 / t), l = K(i), c = {
    envMap: n,
    roughness: r,
    mipInt: s,
    CUBEUV_TEXEL_WIDTH: a,
    CUBEUV_TEXEL_HEIGHT: o,
    CUBEUV_MAX_MIP: l
  }, u = Ad("ggx");
  return u.fragmentNode = vB({
    ...c,
    N_immutable: wd,
    GGX_SAMPLES: gt(yB)
  }), jh.set(u, c), u;
}
function Lx(i) {
  const e = Ad("cubemap");
  return e.fragmentNode = di(i, wd), e;
}
function Fx(i) {
  const e = Ad("equirect");
  return e.fragmentNode = qt(i, PS(wd), 0), e;
}
const Ix = /* @__PURE__ */ new WeakMap();
function RB(i) {
  const e = Math.log2(i) - 2, t = 1 / i;
  return { texelWidth: 1 / (3 * Math.max(Math.pow(2, e), 7 * 16)), texelHeight: t, maxMip: e };
}
function CB(i, e, t) {
  const n = NB(e);
  let r = n.get(i);
  if ((r !== void 0 ? r.pmremVersion : -1) !== i.pmremVersion) {
    const a = i.image;
    if (i.isCubeTexture)
      if (DB(a))
        r = t.fromCubemap(i, r);
      else
        return null;
    else if (LB(a))
      r = t.fromEquirectangular(i, r);
    else
      return null;
    r.pmremVersion = i.pmremVersion, n.set(i, r);
  }
  return r.texture;
}
function NB(i) {
  let e = Ix.get(i);
  return e === void 0 && (e = /* @__PURE__ */ new WeakMap(), Ix.set(i, e)), e;
}
class PB extends xn {
  static get type() {
    return "PMREMNode";
  }
  /**
   * Constructs a new function overloading node.
   *
   * @param {Texture} value - The input texture.
   * @param {Node<vec2>} [uvNode=null] - The uv node.
   * @param {Node<float>} [levelNode=null] - The level node.
   */
  constructor(e, t = null, n = null) {
    super("vec3"), this._value = e, this._pmrem = null, this.uvNode = t, this.levelNode = n, this._generator = null;
    const r = new mn();
    r.isRenderTargetTexture = !0, this._texture = qt(r), this._width = je(0), this._height = je(0), this._maxMip = je(0), this.updateBeforeType = it.RENDER;
  }
  set value(e) {
    this._value = e, this._pmrem = null;
  }
  /**
   * The node's texture value.
   *
   * @type {Texture}
   */
  get value() {
    return this._value;
  }
  /**
   * Uses the given PMREM texture to update internal values.
   *
   * @param {Texture} texture - The PMREM texture.
   */
  updateFromTexture(e) {
    const t = RB(e.image.height);
    this._texture.value = e, this._width.value = t.texelWidth, this._height.value = t.texelHeight, this._maxMip.value = t.maxMip;
  }
  updateBefore(e) {
    let t = this._pmrem;
    const n = t ? t.pmremVersion : -1, r = this._value;
    n !== r.pmremVersion && (r.isPMREMTexture === !0 ? t = r : t = CB(r, e.renderer, this._generator), t !== null && (this._pmrem = t, this.updateFromTexture(t)));
  }
  setup(e) {
    this._generator === null && (this._generator = new MB(e.renderer)), this.updateBefore(e);
    let t = this.uvNode;
    t === null && e.context.getUV && (t = e.context.getUV(this, e)), t = dS.mul(Y(t.x, t.y.negate(), t.z));
    let n = this.levelNode;
    return n === null && e.context.getTextureLevel && (n = e.context.getTextureLevel(this)), pB(this._texture, t, n, this._width, this._height, this._maxMip);
  }
  dispose() {
    super.dispose(), this._generator !== null && this._generator.dispose();
  }
}
function DB(i) {
  if (i == null)
    return !1;
  let e = 0;
  const t = 6;
  for (let n = 0; n < t; n++)
    i[n] !== void 0 && e++;
  return e === t;
}
function LB(i) {
  return i == null ? !1 : i.height > 0;
}
const HS = /* @__PURE__ */ Mt(PB).setParameterLength(1, 3), Ux = /* @__PURE__ */ new WeakMap();
class FB extends Dl {
  static get type() {
    return "EnvironmentNode";
  }
  /**
   * Constructs a new environment node.
   *
   * @param {Node} [envNode=null] - A node representing the environment.
   */
  constructor(e = null) {
    super(), this.envNode = e;
  }
  setup(e) {
    const { material: t } = e;
    let n = this.envNode;
    if (n.isTextureNode || n.isMaterialReferenceNode) {
      const h = n.isTextureNode ? n.value : t[n.property], d = this._getPMREMNodeCache(e.renderer);
      let f = d.get(h);
      f === void 0 && (f = HS(h), d.set(h, f)), n = f;
    }
    const s = t.useAnisotropy === !0 || t.anisotropy > 0 ? rU : vt, a = n.context(Bx(Jr, s)).mul(kf), o = n.context(IB(Pl)).mul(Math.PI).mul(kf), l = Sc(a), c = Sc(o);
    e.context.radiance.addAssign(l), e.context.iblIrradiance.addAssign(c);
    const u = e.context.lightingModel.clearcoatRadiance;
    if (u) {
      const h = n.context(Bx(yc, xa)).mul(kf), d = Sc(h);
      u.addAssign(d);
    }
  }
  /**
   * Returns the PMREM node cache of the current renderer.
   *
   * @private
   * @param {Renderer} renderer - The current renderer.
   * @return {WeakMap} The node cache.
   */
  _getPMREMNodeCache(e) {
    let t = Ux.get(e);
    return t === void 0 && (t = /* @__PURE__ */ new WeakMap(), Ux.set(e, t)), t;
  }
}
const Bx = (i, e) => {
  let t = null;
  return {
    getUV: () => (t === null && (t = $t.negate().reflect(e), t = Xb(i).mix(t, e).normalize(), t = t.transformDirection(fs)), t),
    getTextureLevel: () => i
  };
}, IB = (i) => ({
  getUV: () => i,
  getTextureLevel: () => K(1)
}), UB = /* @__PURE__ */ new cy();
class $S extends dn {
  static get type() {
    return "MeshStandardNodeMaterial";
  }
  /**
   * Constructs a new mesh standard node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshStandardNodeMaterial = !0, this.lights = !0, this.emissiveNode = null, this.metalnessNode = null, this.roughnessNode = null, this.setDefaultValues(UB), this.setValues(e);
  }
  /**
   * Overwritten since this type of material uses {@link EnvironmentNode}
   * to implement the PBR (PMREM based) environment mapping. Besides, the
   * method honors `Scene.environment`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {?EnvironmentNode<vec3>} The environment node.
   */
  setupEnvironment(e) {
    let t = super.setupEnvironment(e);
    return t === null && e.environmentNode && (t = e.environmentNode), t ? new FB(t) : null;
  }
  /**
   * Setups the lighting model.
   *
   * @return {PhysicalLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new zS();
  }
  /**
   * Setups the specular related node variables.
   */
  setupSpecular() {
    const e = Lt(Y(0.04), Nt.rgb, Fs);
    Ba.assign(Y(0.04)), Eo.assign(e), wo.assign(1);
  }
  /**
   * Setups the standard specific node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants() {
    const e = this.metalnessNode ? K(this.metalnessNode) : xU;
    Fs.assign(e);
    let t = this.roughnessNode ? K(this.roughnessNode) : _U;
    t = BS({ roughness: t }), Jr.assign(t), this.setupSpecular(), To.assign(Nt.rgb.mul(e.oneMinus()));
  }
  copy(e) {
    return this.emissiveNode = e.emissiveNode, this.metalnessNode = e.metalnessNode, this.roughnessNode = e.roughnessNode, super.copy(e);
  }
}
const BB = /* @__PURE__ */ new BE();
class OB extends $S {
  static get type() {
    return "MeshPhysicalNodeMaterial";
  }
  /**
   * Constructs a new mesh physical node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshPhysicalNodeMaterial = !0, this.clearcoatNode = null, this.clearcoatRoughnessNode = null, this.clearcoatNormalNode = null, this.sheenNode = null, this.sheenRoughnessNode = null, this.iridescenceNode = null, this.iridescenceIORNode = null, this.iridescenceThicknessNode = null, this.specularIntensityNode = null, this.specularColorNode = null, this.iorNode = null, this.transmissionNode = null, this.thicknessNode = null, this.attenuationDistanceNode = null, this.attenuationColorNode = null, this.dispersionNode = null, this.anisotropyNode = null, this.setDefaultValues(BB), this.setValues(e);
  }
  /**
   * Whether the lighting model should use clearcoat or not.
   *
   * @type {boolean}
   * @default true
   */
  get useClearcoat() {
    return this.clearcoat > 0 || this.clearcoatNode !== null;
  }
  /**
   * Whether the lighting model should use iridescence or not.
   *
   * @type {boolean}
   * @default true
   */
  get useIridescence() {
    return this.iridescence > 0 || this.iridescenceNode !== null;
  }
  /**
   * Whether the lighting model should use sheen or not.
   *
   * @type {boolean}
   * @default true
   */
  get useSheen() {
    return this.sheen > 0 || this.sheenNode !== null;
  }
  /**
   * Whether the lighting model should use anisotropy or not.
   *
   * @type {boolean}
   * @default true
   */
  get useAnisotropy() {
    return this.anisotropy > 0 || this.anisotropyNode !== null;
  }
  /**
   * Whether the lighting model should use transmission or not.
   *
   * @type {boolean}
   * @default true
   */
  get useTransmission() {
    return this.transmission > 0 || this.transmissionNode !== null;
  }
  /**
   * Whether the lighting model should use dispersion or not.
   *
   * @type {boolean}
   * @default true
   */
  get useDispersion() {
    return this.dispersion > 0 || this.dispersionNode !== null;
  }
  /**
   * Setups the specular related node variables.
   */
  setupSpecular() {
    const e = this.iorNode ? K(this.iorNode) : DU;
    wh.assign(e), Ba.assign(fl(qb(wh.sub(1).div(wh.add(1))).mul(gU), Y(1)).mul(lx)), Eo.assign(Lt(Ba, Nt.rgb, Fs)), wo.assign(Lt(lx, 1, Fs));
  }
  /**
   * Setups the lighting model.
   *
   * @return {PhysicalLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new zS(this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission, this.useDispersion);
  }
  /**
   * Setups the physical specific node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants(e) {
    if (super.setupVariants(e), this.useClearcoat) {
      const t = this.clearcoatNode ? K(this.clearcoatNode) : yU, n = this.clearcoatRoughnessNode ? K(this.clearcoatRoughnessNode) : bU;
      Wp.assign(t), yc.assign(BS({ roughness: n }));
    }
    if (this.useSheen) {
      const t = this.sheenNode ? Y(this.sheenNode) : MU, n = this.sheenRoughnessNode ? K(this.sheenRoughnessNode) : EU;
      Li.assign(t), ma.assign(n);
    }
    if (this.useIridescence) {
      const t = this.iridescenceNode ? K(this.iridescenceNode) : AU, n = this.iridescenceIORNode ? K(this.iridescenceIORNode) : RU, r = this.iridescenceThicknessNode ? K(this.iridescenceThicknessNode) : CU;
      wg.assign(t), qp.assign(n), Xp.assign(r);
    }
    if (this.useAnisotropy) {
      const t = (this.anisotropyNode ? Pe(this.anisotropyNode) : wU).toVar();
      da.assign(t.length()), Bt(da.equal(0), () => {
        t.assign(Pe(1, 0));
      }).Else(() => {
        t.divAssign(Pe(da)), da.assign(da.saturate());
      }), jp.assign(da.pow2().mix(Jr.pow2(), 1)), Eh.assign(uc[0].mul(t.x).add(uc[1].mul(t.y))), Io.assign(uc[1].mul(t.x).sub(uc[0].mul(t.y)));
    }
    if (this.useTransmission) {
      const t = this.transmissionNode ? K(this.transmissionNode) : NU, n = this.thicknessNode ? K(this.thicknessNode) : PU, r = this.attenuationDistanceNode ? K(this.attenuationDistanceNode) : LU, s = this.attenuationColorNode ? Y(this.attenuationColorNode) : FU;
      if (Kp.assign(t), Pb.assign(n), Db.assign(r), Lb.assign(s), this.useDispersion) {
        const a = this.dispersionNode ? K(this.dispersionNode) : GU;
        Fb.assign(a);
      }
    }
  }
  /**
   * Setups the clearcoat normal node.
   *
   * @return {Node<vec3>} The clearcoat normal.
   */
  setupClearcoatNormal() {
    return this.clearcoatNormalNode ? Y(this.clearcoatNormalNode) : SU;
  }
  setup(e) {
    e.context.setupClearcoatNormal = () => Uo(this.setupClearcoatNormal(e), "NORMAL", "vec3"), super.setup(e);
  }
  copy(e) {
    return this.clearcoatNode = e.clearcoatNode, this.clearcoatRoughnessNode = e.clearcoatRoughnessNode, this.clearcoatNormalNode = e.clearcoatNormalNode, this.sheenNode = e.sheenNode, this.sheenRoughnessNode = e.sheenRoughnessNode, this.iridescenceNode = e.iridescenceNode, this.iridescenceIORNode = e.iridescenceIORNode, this.iridescenceThicknessNode = e.iridescenceThicknessNode, this.specularIntensityNode = e.specularIntensityNode, this.specularColorNode = e.specularColorNode, this.iorNode = e.iorNode, this.transmissionNode = e.transmissionNode, this.thicknessNode = e.thicknessNode, this.attenuationDistanceNode = e.attenuationDistanceNode, this.attenuationColorNode = e.attenuationColorNode, this.dispersionNode = e.dispersionNode, this.anisotropyNode = e.anisotropyNode, super.copy(e);
  }
}
const kB = /* @__PURE__ */ ee(({ normal: i, lightDirection: e, builder: t }) => {
  const n = i.dot(e), r = Pe(n.mul(0.5).add(0.5), 0);
  if (t.material.gradientMap) {
    const s = Rs("gradientMap", "texture").context({ getUV: () => r });
    return Y(s.r);
  } else {
    const s = r.fwidth().mul(0.5);
    return Lt(Y(0.7), Y(1), hs(K(0.7).sub(s.x), K(0.7).add(s.x), r.x));
  }
});
class GB extends Md {
  /**
   * Implements the direct lighting. Instead of using a conventional smooth irradiance, the irradiance is
   * reduced to a small number of discrete shades to create a comic-like, flat look.
   *
   * @param {Object} lightData - The light data.
   * @param {NodeBuilder} builder - The current node builder.
   */
  direct({ lightDirection: e, lightColor: t, reflectedLight: n }, r) {
    const s = kB({ normal: uS, lightDirection: e, builder: r }).mul(t);
    n.directDiffuse.addAssign(s.mul(ml({ diffuseColor: Nt.rgb })));
  }
  /**
   * Implements the indirect lighting.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  indirect(e) {
    const { ambientOcclusion: t, irradiance: n, reflectedLight: r } = e.context;
    r.indirectDiffuse.addAssign(n.mul(ml({ diffuseColor: Nt }))), r.indirectDiffuse.mulAssign(t);
  }
}
const VB = /* @__PURE__ */ new kE();
class zB extends dn {
  static get type() {
    return "MeshToonNodeMaterial";
  }
  /**
   * Constructs a new mesh toon node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshToonNodeMaterial = !0, this.lights = !0, this.setDefaultValues(VB), this.setValues(e);
  }
  /**
   * Setups the lighting model.
   *
   * @return {ToonLightingModel} The lighting model.
   */
  setupLightingModel() {
    return new GB();
  }
}
const HB = /* @__PURE__ */ ee(() => {
  const i = Y($t.z, 0, $t.x.negate()).normalize(), e = $t.cross(i);
  return Pe(i.dot(vt), e.dot(vt)).mul(0.495).add(0.5);
}).once(["NORMAL", "VERTEX"])().toVar("matcapUV"), $B = /* @__PURE__ */ new HE();
class WB extends dn {
  static get type() {
    return "MeshMatcapNodeMaterial";
  }
  /**
   * Constructs a new mesh normal node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isMeshMatcapNodeMaterial = !0, this.setDefaultValues($B), this.setValues(e);
  }
  /**
   * Setups the matcap specific node variables.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupVariants(e) {
    const t = HB;
    let n;
    e.material.matcap ? n = Rs("matcap", "texture").context({ getUV: () => t }) : n = Y(Lt(0.2, 0.8, t.y)), Nt.rgb.mulAssign(n.rgb);
  }
}
class qB extends xn {
  static get type() {
    return "RotateNode";
  }
  /**
   * Constructs a new rotate node.
   *
   * @param {Node} positionNode - The position node.
   * @param {Node} rotationNode - Represents the rotation that is applied to the position node. Depending
   * on whether the position data are 2D or 3D, the rotation is expressed a single float value or an Euler value.
   */
  constructor(e, t) {
    super(), this.positionNode = e, this.rotationNode = t;
  }
  /**
   * The type of the {@link RotateNode#positionNode} defines the node's type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node's type.
   */
  getNodeType(e) {
    return this.positionNode.getNodeType(e);
  }
  setup(e) {
    const { rotationNode: t, positionNode: n } = this;
    if (this.getNodeType(e) === "vec2") {
      const s = t.cos(), a = t.sin();
      return Eg(
        s,
        a,
        a.negate(),
        s
      ).mul(n);
    } else {
      const s = t, a = Ta(et(1, 0, 0, 0), et(0, _r(s.x), wi(s.x).negate(), 0), et(0, wi(s.x), _r(s.x), 0), et(0, 0, 0, 1)), o = Ta(et(_r(s.y), 0, wi(s.y), 0), et(0, 1, 0, 0), et(wi(s.y).negate(), 0, _r(s.y), 0), et(0, 0, 0, 1)), l = Ta(et(_r(s.z), wi(s.z).negate(), 0, 0), et(wi(s.z), _r(s.z), 0, 0), et(0, 0, 1, 0), et(0, 0, 0, 1));
      return a.mul(o).mul(l).mul(et(n, 1)).xyz;
    }
  }
}
const WS = /* @__PURE__ */ Mt(qB).setParameterLength(2), XB = /* @__PURE__ */ new cE();
class qS extends dn {
  static get type() {
    return "SpriteNodeMaterial";
  }
  /**
   * Constructs a new sprite node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isSpriteNodeMaterial = !0, this._useSizeAttenuation = !0, this.positionNode = null, this.rotationNode = null, this.scaleNode = null, this.transparent = !0, this.setDefaultValues(XB), this.setValues(e);
  }
  /**
   * Setups the position node in view space. This method implements
   * the sprite specific vertex shader.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Node<vec3>} The position in view space.
   */
  setupPositionView(e) {
    const { object: t, camera: n } = e, { positionNode: r, rotationNode: s, scaleNode: a, sizeAttenuation: o } = this, l = cu.mul(Y(r || 0));
    let c = Pe(Ga[0].xyz.length(), Ga[1].xyz.length());
    a !== null && (c = c.mul(Pe(a))), n.isPerspectiveCamera && o === !1 && (c = c.mul(l.z.negate()));
    let u = Td.xy;
    if (t.center && t.center.isVector2 === !0) {
      const f = tI("center", "vec2", t);
      u = u.sub(f.sub(0.5));
    }
    u = u.mul(c);
    const h = K(s || TU), d = WS(u, h);
    return et(l.xy.add(d), l.zw);
  }
  copy(e) {
    return this.positionNode = e.positionNode, this.rotationNode = e.rotationNode, this.scaleNode = e.scaleNode, super.copy(e);
  }
  /**
   * Whether to use size attenuation or not.
   *
   * @type {boolean}
   * @default true
   */
  get sizeAttenuation() {
    return this._useSizeAttenuation;
  }
  set sizeAttenuation(e) {
    this._useSizeAttenuation !== e && (this._useSizeAttenuation = e, this.needsUpdate = !0);
  }
}
const jB = /* @__PURE__ */ new gE(), YB = /* @__PURE__ */ new de();
class KB extends qS {
  static get type() {
    return "PointsNodeMaterial";
  }
  /**
   * Constructs a new points node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.sizeNode = null, this.isPointsNodeMaterial = !0, this.setDefaultValues(jB), this.setValues(e);
  }
  setupPositionView() {
    const { positionNode: e } = this;
    return cu.mul(Y(e || Cn)).xyz;
  }
  setupVertexSprite(e) {
    const { material: t, camera: n } = e, { rotationNode: r, scaleNode: s, sizeNode: a, sizeAttenuation: o } = this;
    let l = super.setupVertex(e);
    if (t.isNodeMaterial !== !0)
      return l;
    let c = a !== null ? Pe(a) : kU;
    c = c.mul(NI), n.isPerspectiveCamera && o === !0 && (c = c.mul(ZB.div(hn.z.negate()))), s && s.isNode && (c = c.mul(Pe(s)));
    let u = Td.xy;
    if (r && r.isNode) {
      const h = K(r);
      u = WS(u, h);
    }
    return u = u.mul(c), u = u.div(PI.div(2)), u = u.mul(l.w), l = l.add(et(u, 0, 0)), l;
  }
  setupVertex(e) {
    return e.object.isPoints ? super.setupVertex(e) : this.setupVertexSprite(e);
  }
  /**
   * Whether alpha to coverage should be used or not.
   *
   * @type {boolean}
   * @default true
   */
  get alphaToCoverage() {
    return this._useAlphaToCoverage;
  }
  set alphaToCoverage(e) {
    this._useAlphaToCoverage !== e && (this._useAlphaToCoverage = e, this.needsUpdate = !0);
  }
}
const ZB = /* @__PURE__ */ je(1).onFrameUpdate(function({ renderer: i }) {
  const e = i.getSize(YB);
  this.value = 0.5 * e.y;
});
class QB extends Md {
  /**
   * Constructs a new shadow mask model.
   */
  constructor() {
    super(), this.shadowNode = K(1).toVar("shadowMask");
  }
  /**
   * Only used to save the shadow mask.
   *
   * @param {Object} input - The input data.
   */
  direct({ lightNode: e }) {
    e.shadowNode !== null && this.shadowNode.mulAssign(e.shadowNode);
  }
  /**
   * Uses the shadow mask to produce the final color.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  finish({ context: e }) {
    Nt.a.mulAssign(this.shadowNode.oneMinus()), e.outgoingLight.rgb.assign(Nt.rgb);
  }
}
const JB = /* @__PURE__ */ new DE();
class eO extends dn {
  static get type() {
    return "ShadowNodeMaterial";
  }
  /**
   * Constructs a new shadow node material.
   *
   * @param {Object} [parameters] - The configuration parameter.
   */
  constructor(e) {
    super(), this.isShadowNodeMaterial = !0, this.lights = !0, this.transparent = !0, this.setDefaultValues(JB), this.setValues(e);
  }
  /**
   * Setups the lighting model.
   *
   * @return {ShadowMaskModel} The lighting model.
   */
  setupLightingModel() {
    return new QB();
  }
}
Vs("vec3");
Vs("vec3");
Vs("vec3");
class tO {
  /**
   * Constructs a new animation loop management component.
   *
   * @param {Renderer} renderer - A reference to the main renderer.
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   * @param {Info} info - Renderer component for managing metrics and monitoring data.
   */
  constructor(e, t, n) {
    this.renderer = e, this.nodes = t, this.info = n, this._context = typeof self < "u" ? self : null, this._animationLoop = null, this._requestId = null;
  }
  /**
   * Starts the internal animation loop.
   */
  start() {
    const e = (t, n) => {
      this._requestId = this._context.requestAnimationFrame(e), this.info.autoReset === !0 && this.info.reset(), this.nodes.nodeFrame.update(), this.info.frame = this.nodes.nodeFrame.frameId, this.renderer._inspector.begin(), this._animationLoop !== null && this._animationLoop(t, n), this.renderer._inspector.finish();
    };
    e();
  }
  /**
   * Stops the internal animation loop.
   */
  stop() {
    this._context.cancelAnimationFrame(this._requestId), this._requestId = null;
  }
  /**
   * Returns the user-level animation loop.
   *
   * @return {?Function} The animation loop.
   */
  getAnimationLoop() {
    return this._animationLoop;
  }
  /**
   * Defines the user-level animation loop.
   *
   * @param {?Function} callback - The animation loop.
   */
  setAnimationLoop(e) {
    this._animationLoop = e;
  }
  /**
   * Returns the animation context.
   *
   * @return {Window|XRSession} The animation context.
   */
  getContext() {
    return this._context;
  }
  /**
   * Defines the context in which `requestAnimationFrame()` is executed.
   *
   * @param {Window|XRSession} context - The context to set.
   */
  setContext(e) {
    this._context = e;
  }
  /**
   * Frees all internal resources and stops the animation loop.
   */
  dispose() {
    this.stop();
  }
}
class qs {
  /**
   * Constructs a new Chain Map.
   */
  constructor() {
    this.weakMaps = {};
  }
  /**
   * Returns the Weak Map for the given keys.
   *
   * @param {Array<Object>} keys - List of keys.
   * @return {WeakMap} The weak map.
   */
  _getWeakMap(e) {
    const t = e.length;
    let n = this.weakMaps[t];
    return n === void 0 && (n = /* @__PURE__ */ new WeakMap(), this.weakMaps[t] = n), n;
  }
  /**
   * Returns the value for the given array of keys.
   *
   * @param {Array<Object>} keys - List of keys.
   * @return {any} The value. Returns `undefined` if no value was found.
   */
  get(e) {
    let t = this._getWeakMap(e);
    for (let n = 0; n < e.length - 1; n++)
      if (t = t.get(e[n]), t === void 0)
        return;
    return t.get(e[e.length - 1]);
  }
  /**
   * Sets the value for the given keys.
   *
   * @param {Array<Object>} keys - List of keys.
   * @param {any} value - The value to set.
   * @return {ChainMap} A reference to this Chain Map.
   */
  set(e, t) {
    let n = this._getWeakMap(e);
    for (let r = 0; r < e.length - 1; r++) {
      const s = e[r];
      n.has(s) === !1 && n.set(s, /* @__PURE__ */ new WeakMap()), n = n.get(s);
    }
    return n.set(e[e.length - 1], t), this;
  }
  /**
   * Deletes a value for the given keys.
   *
   * @param {Array<Object>} keys - The keys.
   * @return {boolean} Returns `true` if the value has been removed successfully and `false` if the value has not be found.
   */
  delete(e) {
    let t = this._getWeakMap(e);
    for (let n = 0; n < e.length - 1; n++)
      if (t = t.get(e[n]), t === void 0)
        return !1;
    return t.delete(e[e.length - 1]);
  }
}
let nO = 0;
function iO(i) {
  const e = Object.keys(i);
  let t = Object.getPrototypeOf(i);
  for (; t; ) {
    const n = Object.getOwnPropertyDescriptors(t);
    for (const r in n)
      if (n[r] !== void 0) {
        const s = n[r];
        s && typeof s.get == "function" && e.push(r);
      }
    t = Object.getPrototypeOf(t);
  }
  return e;
}
class rO {
  /**
   * Constructs a new render object.
   *
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   * @param {Geometries} geometries - Renderer component for managing geometries.
   * @param {Renderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The 3D object's material.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {LightsNode} lightsNode - The lights node.
   * @param {RenderContext} renderContext - The render context.
   * @param {ClippingContext} clippingContext - The clipping context.
   */
  constructor(e, t, n, r, s, a, o, l, c, u) {
    this.id = nO++, this._nodes = e, this._geometries = t, this.renderer = n, this.object = r, this.material = s, this.scene = a, this.camera = o, this.lightsNode = l, this.context = c, this.geometry = r.geometry, this.version = s.version, this.drawRange = null, this.attributes = null, this.attributesId = null, this.pipeline = null, this.group = null, this.vertexBuffers = null, this.drawParams = null, this.bundle = null, this.clippingContext = u, this.clippingContextCacheKey = u !== null ? u.cacheKey : "", this.initialNodesCacheKey = this.getDynamicCacheKey(), this.initialCacheKey = this.getCacheKey(), this._nodeBuilderState = null, this._bindings = null, this._monitor = null, this.onDispose = null, this.isRenderObject = !0, this.onMaterialDispose = () => {
      this.dispose();
    }, this.onGeometryDispose = () => {
      this.attributes = null, this.attributesId = null;
    }, this.material.addEventListener("dispose", this.onMaterialDispose), this.geometry.addEventListener("dispose", this.onGeometryDispose);
  }
  /**
   * Updates the clipping context.
   *
   * @param {ClippingContext} context - The clipping context to set.
   */
  updateClipping(e) {
    this.clippingContext = e;
  }
  /**
   * Whether the clipping requires an update or not.
   *
   * @type {boolean}
   * @readonly
   */
  get clippingNeedsUpdate() {
    return this.clippingContext === null || this.clippingContext.cacheKey === this.clippingContextCacheKey ? !1 : (this.clippingContextCacheKey = this.clippingContext.cacheKey, !0);
  }
  /**
   * The number of clipping planes defined in context of hardware clipping.
   *
   * @type {number}
   * @readonly
   */
  get hardwareClippingPlanes() {
    return this.material.hardwareClipping === !0 ? this.clippingContext.unionClippingCount : 0;
  }
  /**
   * Returns the node builder state of this render object.
   *
   * @return {NodeBuilderState} The node builder state.
   */
  getNodeBuilderState() {
    return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this));
  }
  /**
   * Returns the node material observer of this render object.
   *
   * @return {NodeMaterialObserver} The node material observer.
   */
  getMonitor() {
    return this._monitor || (this._monitor = this.getNodeBuilderState().observer);
  }
  /**
   * Returns an array of bind groups of this render object.
   *
   * @return {Array<BindGroup>} The bindings.
   */
  getBindings() {
    return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings());
  }
  /**
   * Returns a binding group by group name of this render object.
   *
   * @param {string} name - The name of the binding group.
   * @return {?BindGroup} The bindings.
   */
  getBindingGroup(e) {
    for (const t of this.getBindings())
      if (t.name === e)
        return t;
  }
  /**
   * Returns the index of the render object's geometry.
   *
   * @return {?BufferAttribute} The index. Returns `null` for non-indexed geometries.
   */
  getIndex() {
    return this._geometries.getIndex(this);
  }
  /**
   * Returns the indirect buffer attribute.
   *
   * @return {?BufferAttribute} The indirect attribute. `null` if no indirect drawing is used.
   */
  getIndirect() {
    return this._geometries.getIndirect(this);
  }
  /**
   * Returns the byte offset into the indirect attribute buffer.
   *
   * @return {number|Array<number>} The byte offset into the indirect attribute buffer.
   */
  getIndirectOffset() {
    return this._geometries.getIndirectOffset(this);
  }
  /**
   * Returns an array that acts as a key for identifying the render object in a chain map.
   *
   * @return {Array<Object>} An array with object references.
   */
  getChainArray() {
    return [this.object, this.material, this.context, this.lightsNode];
  }
  /**
   * This method is used when the geometry of a 3D object has been exchanged and the
   * respective render object now requires an update.
   *
   * @param {BufferGeometry} geometry - The geometry to set.
   */
  setGeometry(e) {
    this.geometry = e, this.attributes = null, this.attributesId = null;
  }
  /**
   * Returns the buffer attributes of the render object. The returned array holds
   * attribute definitions on geometry and node level.
   *
   * @return {Array<BufferAttribute>} An array with buffer attributes.
   */
  getAttributes() {
    if (this.attributes !== null)
      return this.attributes;
    const e = this.getNodeBuilderState().nodeAttributes, t = this.geometry, n = [], r = /* @__PURE__ */ new Set(), s = {};
    for (const a of e) {
      let o;
      if (a.node && a.node.attribute ? o = a.node.attribute : (o = t.getAttribute(a.name), s[a.name] = o.id), o === void 0)
        continue;
      n.push(o);
      const l = o.isInterleavedBufferAttribute ? o.data : o;
      r.add(l);
    }
    return this.attributes = n, this.attributesId = s, this.vertexBuffers = Array.from(r.values()), n;
  }
  /**
   * Returns the vertex buffers of the render object.
   *
   * @return {Array<BufferAttribute|InterleavedBuffer>} An array with buffer attribute or interleaved buffers.
   */
  getVertexBuffers() {
    return this.vertexBuffers === null && this.getAttributes(), this.vertexBuffers;
  }
  /**
   * Returns the draw parameters for the render object.
   *
   * @return {?{vertexCount: number, firstVertex: number, instanceCount: number, firstInstance: number}} The draw parameters.
   */
  getDrawParameters() {
    const { object: e, material: t, geometry: n, group: r, drawRange: s } = this, a = this.drawParams || (this.drawParams = {
      vertexCount: 0,
      firstVertex: 0,
      instanceCount: 0,
      firstInstance: 0
    }), o = this.getIndex(), l = o !== null;
    let c = 1;
    if (n.isInstancedBufferGeometry === !0 ? c = n.instanceCount : e.count !== void 0 && (c = Math.max(0, e.count)), c === 0)
      return null;
    if (a.instanceCount = c, e.isBatchedMesh === !0)
      return a;
    let u = 1;
    t.wireframe === !0 && !e.isPoints && !e.isLineSegments && !e.isLine && !e.isLineLoop && (u = 2);
    let h = s.start * u, d = (s.start + s.count) * u;
    r !== null && (h = Math.max(h, r.start * u), d = Math.min(d, (r.start + r.count) * u));
    const f = n.attributes.position;
    let p = 1 / 0;
    l ? p = o.count : f != null && (p = f.count), h = Math.max(h, 0), d = Math.min(d, p);
    const _ = d - h;
    return _ < 0 || _ === 1 / 0 ? null : (a.vertexCount = _, a.firstVertex = h, a);
  }
  /**
   * Returns the render object's geometry cache key.
   *
   * The geometry cache key is part of the material cache key.
   *
   * @return {string} The geometry cache key.
   */
  getGeometryCacheKey() {
    const { geometry: e } = this;
    let t = "";
    for (const n of Object.keys(e.attributes).sort()) {
      const r = e.attributes[n];
      t += n + ",", r.data && (t += r.data.stride + ","), r.offset && (t += r.offset + ","), r.itemSize && (t += r.itemSize + ","), r.normalized && (t += "n,");
    }
    for (const n of Object.keys(e.morphAttributes).sort()) {
      const r = e.morphAttributes[n];
      t += "morph-" + n + ",";
      for (let s = 0, a = r.length; s < a; s++) {
        const o = r[s];
        t += o.id + ",";
      }
    }
    return e.index && (t += "index,"), t;
  }
  /**
   * Returns the render object's material cache key.
   *
   * The material cache key is part of the render object cache key.
   *
   * @return {number} The material cache key.
   */
  getMaterialCacheKey() {
    const { object: e, material: t, renderer: n } = this;
    let r = t.customProgramCacheKey();
    for (const s of iO(t)) {
      if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(s))
        continue;
      const a = t[s];
      let o;
      if (a !== null) {
        const l = typeof a;
        l === "number" ? o = a !== 0 ? "1" : "0" : l === "object" ? (o = "{", a.isTexture && (o += a.mapping, n.backend.isWebGPUBackend === !0 && (o += a.magFilter, o += a.minFilter, o += a.wrapS, o += a.wrapT, o += a.wrapR)), o += "}") : o = String(a);
      } else
        o = String(a);
      r += /*property + ':' +*/
      o + ",";
    }
    return r += this.clippingContextCacheKey + ",", e.geometry && (r += this.getGeometryCacheKey()), e.skeleton && (r += e.skeleton.bones.length + ","), e.isBatchedMesh && (r += e._matricesTexture.uuid + ",", e._colorsTexture !== null && (r += e._colorsTexture.uuid + ",")), (e.isInstancedMesh || e.count > 1 || Array.isArray(e.morphTargetInfluences)) && (r += e.uuid + ","), r += this.context.id + ",", r += e.receiveShadow + ",", Ml(r);
  }
  /**
   * Whether the geometry requires an update or not.
   *
   * @type {boolean}
   * @readonly
   */
  get needsGeometryUpdate() {
    if (this.geometry.id !== this.object.geometry.id)
      return !0;
    if (this.attributes !== null) {
      const e = this.attributesId;
      for (const t in e) {
        const n = this.geometry.getAttribute(t);
        if (n === void 0 || e[t] !== n.id)
          return !0;
      }
    }
    return !1;
  }
  /**
   * Whether the render object requires an update or not.
   *
   * Note: There are two distinct places where render objects are checked for an update.
   *
   * 1. In `RenderObjects.get()` which is executed when the render object is request. This
   * method checks the `needsUpdate` flag and recreates the render object if necessary.
   * 2. In `Renderer._renderObjectDirect()` right after getting the render object via
   * `RenderObjects.get()`. The render object's NodeMaterialObserver is then used to detect
   * a need for a refresh due to material, geometry or object related value changes.
   *
   * TODO: Investigate if it's possible to merge both steps so there is only a single place
   * that performs the 'needsUpdate' check.
   *
   * @type {boolean}
   * @readonly
   */
  get needsUpdate() {
    return (
      /*this.object.static !== true &&*/
      this.initialNodesCacheKey !== this.getDynamicCacheKey() || this.clippingNeedsUpdate
    );
  }
  /**
   * Returns the dynamic cache key which represents a key that is computed per draw command.
   *
   * @return {number} The cache key.
   */
  getDynamicCacheKey() {
    let e = 0;
    return this.material.isShadowPassMaterial !== !0 && (e = this._nodes.getCacheKey(this.scene, this.lightsNode)), this.camera.isArrayCamera && (e = xc(e, this.camera.cameras.length)), this.object.receiveShadow && (e = xc(e, 1)), e = xc(e, this.renderer.contextNode.id, this.renderer.contextNode.version), e;
  }
  /**
   * Returns the render object's cache key.
   *
   * @return {number} The cache key.
   */
  getCacheKey() {
    return this.getMaterialCacheKey() + this.getDynamicCacheKey();
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this.material.removeEventListener("dispose", this.onMaterialDispose), this.geometry.removeEventListener("dispose", this.onGeometryDispose), this.onDispose();
  }
}
const dr = [];
class sO {
  /**
   * Constructs a new render object management component.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   * @param {Geometries} geometries - Renderer component for managing geometries.
   * @param {Pipelines} pipelines - Renderer component for managing pipelines.
   * @param {Bindings} bindings - Renderer component for managing bindings.
   * @param {Info} info - Renderer component for managing metrics and monitoring data.
   */
  constructor(e, t, n, r, s, a) {
    this.renderer = e, this.nodes = t, this.geometries = n, this.pipelines = r, this.bindings = s, this.info = a, this.chainMaps = {};
  }
  /**
   * Returns a render object for the given object and state data.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The 3D object's material.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the 3D object should be rendered with.
   * @param {LightsNode} lightsNode - The lights node.
   * @param {RenderContext} renderContext - The render context.
   * @param {ClippingContext} clippingContext - The clipping context.
   * @param {string} [passId] - An optional ID for identifying the pass.
   * @return {RenderObject} The render object.
   */
  get(e, t, n, r, s, a, o, l) {
    const c = this.getChainMap(l);
    dr[0] = e, dr[1] = t, dr[2] = a, dr[3] = s;
    let u = c.get(dr);
    return u === void 0 ? (u = this.createRenderObject(this.nodes, this.geometries, this.renderer, e, t, n, r, s, a, o, l), c.set(dr, u)) : (u.camera = r, u.updateClipping(o), u.needsGeometryUpdate && u.setGeometry(e.geometry), (u.version !== t.version || u.needsUpdate) && (u.initialCacheKey !== u.getCacheKey() ? (u.dispose(), u = this.get(e, t, n, r, s, a, o, l)) : u.version = t.version)), dr[0] = null, dr[1] = null, dr[2] = null, dr[3] = null, u;
  }
  /**
   * Returns a chain map for the given pass ID.
   *
   * @param {string} [passId='default'] - The pass ID.
   * @return {ChainMap} The chain map.
   */
  getChainMap(e = "default") {
    return this.chainMaps[e] || (this.chainMaps[e] = new qs());
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this.chainMaps = {};
  }
  /**
   * Factory method for creating render objects with the given list of parameters.
   *
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   * @param {Geometries} geometries - Renderer component for managing geometries.
   * @param {Renderer} renderer - The renderer.
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The object's material.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {LightsNode} lightsNode - The lights node.
   * @param {RenderContext} renderContext - The render context.
   * @param {ClippingContext} clippingContext - The clipping context.
   * @param {string} [passId] - An optional ID for identifying the pass.
   * @return {RenderObject} The render object.
   */
  createRenderObject(e, t, n, r, s, a, o, l, c, u, h) {
    const d = this.getChainMap(h), f = new rO(e, t, n, r, s, a, o, l, c, u);
    return f.onDispose = () => {
      this.pipelines.delete(f), this.bindings.deleteForRender(f), this.nodes.delete(f), d.delete(f.getChainArray());
    }, f;
  }
}
class Ks {
  /**
   * Constructs a new data map.
   */
  constructor() {
    this.data = /* @__PURE__ */ new WeakMap();
  }
  /**
   * Returns the dictionary for the given object.
   *
   * @param {Object} object - The object.
   * @return {Object} The dictionary.
   */
  get(e) {
    let t = this.data.get(e);
    return t === void 0 && (t = {}, this.data.set(e, t)), t;
  }
  /**
   * Deletes the dictionary for the given object.
   *
   * @param {Object} object - The object.
   * @return {?Object} The deleted dictionary.
   */
  delete(e) {
    let t = null;
    return this.data.has(e) && (t = this.data.get(e), this.data.delete(e)), t;
  }
  /**
   * Returns `true` if the given object has a dictionary defined.
   *
   * @param {Object} object - The object to test.
   * @return {boolean} Whether a dictionary is defined or not.
   */
  has(e) {
    return this.data.has(e);
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this.data = /* @__PURE__ */ new WeakMap();
  }
}
const Oi = {
  VERTEX: 1,
  INDEX: 2,
  STORAGE: 3,
  INDIRECT: 4
}, Cs = 16, aO = 211, oO = 212;
class lO extends Ks {
  /**
   * Constructs a new attribute management component.
   *
   * @param {Backend} backend - The renderer's backend.
   */
  constructor(e) {
    super(), this.backend = e;
  }
  /**
   * Deletes the data for the given attribute.
   *
   * @param {BufferAttribute} attribute - The attribute.
   * @return {?Object} The deleted attribute data.
   */
  delete(e) {
    const t = super.delete(e);
    return t !== null && this.backend.destroyAttribute(e), t;
  }
  /**
   * Updates the given attribute. This method creates attribute buffers
   * for new attributes and updates data for existing ones.
   *
   * @param {BufferAttribute} attribute - The attribute to update.
   * @param {number} type - The attribute type.
   */
  update(e, t) {
    const n = this.get(e);
    if (n.version === void 0)
      t === Oi.VERTEX ? this.backend.createAttribute(e) : t === Oi.INDEX ? this.backend.createIndexAttribute(e) : t === Oi.STORAGE ? this.backend.createStorageAttribute(e) : t === Oi.INDIRECT && this.backend.createIndirectStorageAttribute(e), n.version = this._getBufferAttribute(e).version;
    else {
      const r = this._getBufferAttribute(e);
      (n.version < r.version || r.usage === Dh) && (this.backend.updateAttribute(e), n.version = r.version);
    }
  }
  /**
   * Utility method for handling interleaved buffer attributes correctly.
   * To process them, their `InterleavedBuffer` is returned.
   *
   * @param {BufferAttribute} attribute - The attribute.
   * @return {BufferAttribute|InterleavedBuffer}
   */
  _getBufferAttribute(e) {
    return e.isInterleavedBufferAttribute && (e = e.data), e;
  }
}
function XS(i) {
  return i.index !== null ? i.index.version : i.attributes.position.version;
}
function jS(i) {
  return i.index !== null ? i.index.id : i.attributes.position.id;
}
function Ox(i) {
  const e = [], t = i.index, n = i.attributes.position;
  if (t !== null) {
    const s = t.array;
    for (let a = 0, o = s.length; a < o; a += 3) {
      const l = s[a + 0], c = s[a + 1], u = s[a + 2];
      e.push(l, c, c, u, u, l);
    }
  } else {
    const s = n.array;
    for (let a = 0, o = s.length / 3 - 1; a < o; a += 3) {
      const l = a + 0, c = a + 1, u = a + 2;
      e.push(l, c, c, u, u, l);
    }
  }
  const r = new (n.count >= 65535 ? Ym : jm)(e, 1);
  return r.version = XS(i), r.__id = jS(i), r;
}
class cO extends Ks {
  /**
   * Constructs a new geometry management component.
   *
   * @param {Attributes} attributes - Renderer component for managing attributes.
   * @param {Info} info - Renderer component for managing metrics and monitoring data.
   */
  constructor(e, t) {
    super(), this.attributes = e, this.info = t, this.wireframes = /* @__PURE__ */ new WeakMap(), this.attributeCall = /* @__PURE__ */ new WeakMap(), this._geometryDisposeListeners = /* @__PURE__ */ new Map();
  }
  /**
   * Returns `true` if the given render object has an initialized geometry.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether if the given render object has an initialized geometry or not.
   */
  has(e) {
    const t = e.geometry;
    return super.has(t) && this.get(t).initialized === !0;
  }
  /**
   * Prepares the geometry of the given render object for rendering.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateForRender(e) {
    this.has(e) === !1 && this.initGeometry(e), this.updateAttributes(e);
  }
  /**
   * Initializes the geometry of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  initGeometry(e) {
    const t = e.geometry, n = this.get(t);
    n.initialized = !0, this.info.memory.geometries++;
    const r = () => {
      this.info.memory.geometries--;
      const s = t.index, a = e.getAttributes();
      s !== null && this.attributes.delete(s);
      for (const l of a)
        this.attributes.delete(l);
      const o = this.wireframes.get(t);
      o !== void 0 && this.attributes.delete(o), t.removeEventListener("dispose", r), this._geometryDisposeListeners.delete(t);
    };
    t.addEventListener("dispose", r), this._geometryDisposeListeners.set(t, r);
  }
  /**
   * Updates the geometry attributes of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateAttributes(e) {
    const t = e.getAttributes();
    for (const s of t)
      s.isStorageBufferAttribute || s.isStorageInstancedBufferAttribute ? this.updateAttribute(s, Oi.STORAGE) : this.updateAttribute(s, Oi.VERTEX);
    const n = this.getIndex(e);
    n !== null && this.updateAttribute(n, Oi.INDEX);
    const r = e.geometry.indirect;
    r !== null && this.updateAttribute(r, Oi.INDIRECT);
  }
  /**
   * Updates the given attribute.
   *
   * @param {BufferAttribute} attribute - The attribute to update.
   * @param {number} type - The attribute type.
   */
  updateAttribute(e, t) {
    const n = this.info.render.calls;
    e.isInterleavedBufferAttribute ? this.attributeCall.get(e) === void 0 ? (this.attributes.update(e, t), this.attributeCall.set(e, n)) : this.attributeCall.get(e.data) !== n && (this.attributes.update(e, t), this.attributeCall.set(e.data, n), this.attributeCall.set(e, n)) : this.attributeCall.get(e) !== n && (this.attributes.update(e, t), this.attributeCall.set(e, n));
  }
  /**
   * Returns the indirect buffer attribute of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {?BufferAttribute} The indirect attribute. `null` if no indirect drawing is used.
   */
  getIndirect(e) {
    return e.geometry.indirect;
  }
  /**
   * Returns the byte offset into the indirect attribute buffer of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {number} The byte offset into the indirect attribute buffer.
   */
  getIndirectOffset(e) {
    return e.geometry.indirectOffset;
  }
  /**
   * Returns the index of the given render object's geometry. This is implemented
   * in a method to return a wireframe index if necessary.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {?BufferAttribute} The index. Returns `null` for non-indexed geometries.
   */
  getIndex(e) {
    const { geometry: t, material: n } = e;
    let r = t.index;
    if (n.wireframe === !0) {
      const s = this.wireframes;
      let a = s.get(t);
      a === void 0 ? (a = Ox(t), s.set(t, a)) : (a.version !== XS(t) || a.__id !== jS(t)) && (this.attributes.delete(a), a = Ox(t), s.set(t, a)), r = a;
    }
    return r;
  }
  dispose() {
    for (const [e, t] of this._geometryDisposeListeners.entries())
      e.removeEventListener("dispose", t);
    this._geometryDisposeListeners.clear();
  }
}
class uO {
  /**
   * Constructs a new info component.
   */
  constructor() {
    this.autoReset = !0, this.frame = 0, this.calls = 0, this.render = {
      calls: 0,
      frameCalls: 0,
      drawCalls: 0,
      triangles: 0,
      points: 0,
      lines: 0,
      timestamp: 0
    }, this.compute = {
      calls: 0,
      frameCalls: 0,
      timestamp: 0
    }, this.memory = {
      geometries: 0,
      textures: 0
    };
  }
  /**
   * This method should be executed per draw call and updates the corresponding metrics.
   *
   * @param {Object3D} object - The 3D object that is going to be rendered.
   * @param {number} count - The vertex or index count.
   * @param {number} instanceCount - The instance count.
   */
  update(e, t, n) {
    this.render.drawCalls++, e.isMesh || e.isSprite ? this.render.triangles += n * (t / 3) : e.isPoints ? this.render.points += n * t : e.isLineSegments ? this.render.lines += n * (t / 2) : e.isLine ? this.render.lines += n * (t - 1) : le("WebGPUInfo: Unknown object type.");
  }
  /**
   * Resets frame related metrics.
   */
  reset() {
    this.render.drawCalls = 0, this.render.frameCalls = 0, this.compute.frameCalls = 0, this.render.triangles = 0, this.render.points = 0, this.render.lines = 0;
  }
  /**
   * Performs a complete reset of the object.
   */
  dispose() {
    this.reset(), this.calls = 0, this.render.calls = 0, this.compute.calls = 0, this.render.timestamp = 0, this.compute.timestamp = 0, this.memory.geometries = 0, this.memory.textures = 0;
  }
}
class YS {
  /**
   * Constructs a new pipeline.
   *
   * @param {string} cacheKey - The pipeline's cache key.
   */
  constructor(e) {
    this.cacheKey = e, this.usedTimes = 0;
  }
}
class hO extends YS {
  /**
   * Constructs a new render object pipeline.
   *
   * @param {string} cacheKey - The pipeline's cache key.
   * @param {ProgrammableStage} vertexProgram - The pipeline's vertex shader.
   * @param {ProgrammableStage} fragmentProgram - The pipeline's fragment shader.
   */
  constructor(e, t, n) {
    super(e), this.vertexProgram = t, this.fragmentProgram = n;
  }
}
class dO extends YS {
  /**
   * Constructs a new render pipeline.
   *
   * @param {string} cacheKey - The pipeline's cache key.
   * @param {ProgrammableStage} computeProgram - The pipeline's compute shader.
   */
  constructor(e, t) {
    super(e), this.computeProgram = t, this.isComputePipeline = !0;
  }
}
let fO = 0;
class Zf {
  /**
   * Constructs a new programmable stage.
   *
   * @param {string} code - The shader code.
   * @param {('vertex'|'fragment'|'compute')} stage - The type of stage.
   * @param {string} name - The name of the shader.
   * @param {?Array<Object>} [transforms=null] - The transforms (only relevant for compute stages with WebGL 2 which uses Transform Feedback).
   * @param {?Array<Object>} [attributes=null] - The attributes (only relevant for compute stages with WebGL 2 which uses Transform Feedback).
   */
  constructor(e, t, n, r = null, s = null) {
    this.id = fO++, this.code = e, this.stage = t, this.name = n, this.transforms = r, this.attributes = s, this.usedTimes = 0;
  }
}
class pO extends Ks {
  /**
   * Constructs a new pipeline management component.
   *
   * @param {Backend} backend - The renderer's backend.
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   */
  constructor(e, t) {
    super(), this.backend = e, this.nodes = t, this.bindings = null, this.caches = /* @__PURE__ */ new Map(), this.programs = {
      vertex: /* @__PURE__ */ new Map(),
      fragment: /* @__PURE__ */ new Map(),
      compute: /* @__PURE__ */ new Map()
    };
  }
  /**
   * Returns a compute pipeline for the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   * @param {Array<BindGroup>} bindings - The bindings.
   * @return {ComputePipeline} The compute pipeline.
   */
  getForCompute(e, t) {
    const { backend: n } = this, r = this.get(e);
    if (this._needsComputeUpdate(e)) {
      const s = r.pipeline;
      s && (s.usedTimes--, s.computeProgram.usedTimes--);
      const a = this.nodes.getForCompute(e);
      let o = this.programs.compute.get(a.computeShader);
      o === void 0 && (s && s.computeProgram.usedTimes === 0 && this._releaseProgram(s.computeProgram), o = new Zf(a.computeShader, "compute", e.name, a.transforms, a.nodeAttributes), this.programs.compute.set(a.computeShader, o), n.createProgram(o));
      const l = this._getComputeCacheKey(e, o);
      let c = this.caches.get(l);
      c === void 0 && (s && s.usedTimes === 0 && this._releasePipeline(s), c = this._getComputePipeline(e, o, l, t)), c.usedTimes++, o.usedTimes++, r.version = e.version, r.pipeline = c;
    }
    return r.pipeline;
  }
  /**
   * Returns a render pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {?Array<Promise>} [promises=null] - An array of compilation promises which is only relevant in context of `Renderer.compileAsync()`.
   * @return {RenderObjectPipeline} The render pipeline.
   */
  getForRender(e, t = null) {
    const { backend: n } = this, r = this.get(e);
    if (this._needsRenderUpdate(e)) {
      const s = r.pipeline;
      s && (s.usedTimes--, s.vertexProgram.usedTimes--, s.fragmentProgram.usedTimes--);
      const a = e.getNodeBuilderState(), o = e.material ? e.material.name : "";
      let l = this.programs.vertex.get(a.vertexShader);
      l === void 0 && (s && s.vertexProgram.usedTimes === 0 && this._releaseProgram(s.vertexProgram), l = new Zf(a.vertexShader, "vertex", o), this.programs.vertex.set(a.vertexShader, l), n.createProgram(l));
      let c = this.programs.fragment.get(a.fragmentShader);
      c === void 0 && (s && s.fragmentProgram.usedTimes === 0 && this._releaseProgram(s.fragmentProgram), c = new Zf(a.fragmentShader, "fragment", o), this.programs.fragment.set(a.fragmentShader, c), n.createProgram(c));
      const u = this._getRenderCacheKey(e, l, c);
      let h = this.caches.get(u);
      h === void 0 ? (s && s.usedTimes === 0 && this._releasePipeline(s), h = this._getRenderPipeline(e, l, c, u, t)) : e.pipeline = h, h.usedTimes++, l.usedTimes++, c.usedTimes++, r.pipeline = h;
    }
    return r.pipeline;
  }
  /**
   * Deletes the pipeline for the given render object.
   *
   * @param {RenderObject} object - The render object.
   * @return {?Object} The deleted dictionary.
   */
  delete(e) {
    const t = this.get(e).pipeline;
    return t && (t.usedTimes--, t.usedTimes === 0 && this._releasePipeline(t), t.isComputePipeline ? (t.computeProgram.usedTimes--, t.computeProgram.usedTimes === 0 && this._releaseProgram(t.computeProgram)) : (t.fragmentProgram.usedTimes--, t.vertexProgram.usedTimes--, t.vertexProgram.usedTimes === 0 && this._releaseProgram(t.vertexProgram), t.fragmentProgram.usedTimes === 0 && this._releaseProgram(t.fragmentProgram))), super.delete(e);
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    super.dispose(), this.caches = /* @__PURE__ */ new Map(), this.programs = {
      vertex: /* @__PURE__ */ new Map(),
      fragment: /* @__PURE__ */ new Map(),
      compute: /* @__PURE__ */ new Map()
    };
  }
  /**
   * Updates the pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateForRender(e) {
    this.getForRender(e);
  }
  /**
   * Returns a compute pipeline for the given parameters.
   *
   * @private
   * @param {Node} computeNode - The compute node.
   * @param {ProgrammableStage} stageCompute - The programmable stage representing the compute shader.
   * @param {string} cacheKey - The cache key.
   * @param {Array<BindGroup>} bindings - The bindings.
   * @return {ComputePipeline} The compute pipeline.
   */
  _getComputePipeline(e, t, n, r) {
    n = n || this._getComputeCacheKey(e, t);
    let s = this.caches.get(n);
    return s === void 0 && (s = new dO(n, t), this.caches.set(n, s), this.backend.createComputePipeline(s, r)), s;
  }
  /**
   * Returns a render pipeline for the given parameters.
   *
   * @private
   * @param {RenderObject} renderObject - The render object.
   * @param {ProgrammableStage} stageVertex - The programmable stage representing the vertex shader.
   * @param {ProgrammableStage} stageFragment - The programmable stage representing the fragment shader.
   * @param {string} cacheKey - The cache key.
   * @param {?Array<Promise>} promises - An array of compilation promises which is only relevant in context of `Renderer.compileAsync()`.
   * @return {RenderObjectPipeline} The render pipeline.
   */
  _getRenderPipeline(e, t, n, r, s) {
    r = r || this._getRenderCacheKey(e, t, n);
    let a = this.caches.get(r);
    return a === void 0 && (a = new hO(r, t, n), this.caches.set(r, a), e.pipeline = a, this.backend.createRenderPipeline(e, s)), a;
  }
  /**
   * Computes a cache key representing a compute pipeline.
   *
   * @private
   * @param {Node} computeNode - The compute node.
   * @param {ProgrammableStage} stageCompute - The programmable stage representing the compute shader.
   * @return {string} The cache key.
   */
  _getComputeCacheKey(e, t) {
    return e.id + "," + t.id;
  }
  /**
   * Computes a cache key representing a render pipeline.
   *
   * @private
   * @param {RenderObject} renderObject - The render object.
   * @param {ProgrammableStage} stageVertex - The programmable stage representing the vertex shader.
   * @param {ProgrammableStage} stageFragment - The programmable stage representing the fragment shader.
   * @return {string} The cache key.
   */
  _getRenderCacheKey(e, t, n) {
    return t.id + "," + n.id + "," + this.backend.getRenderCacheKey(e);
  }
  /**
   * Releases the given pipeline.
   *
   * @private
   * @param {Pipeline} pipeline - The pipeline to release.
   */
  _releasePipeline(e) {
    this.caches.delete(e.cacheKey);
  }
  /**
   * Releases the shader program.
   *
   * @private
   * @param {Object} program - The shader program to release.
   */
  _releaseProgram(e) {
    const t = e.code, n = e.stage;
    this.programs[n].delete(t);
  }
  /**
   * Returns `true` if the compute pipeline for the given compute node requires an update.
   *
   * @private
   * @param {Node} computeNode - The compute node.
   * @return {boolean} Whether the compute pipeline for the given compute node requires an update or not.
   */
  _needsComputeUpdate(e) {
    const t = this.get(e);
    return t.pipeline === void 0 || t.version !== e.version;
  }
  /**
   * Returns `true` if the render pipeline for the given render object requires an update.
   *
   * @private
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the render object for the given render object requires an update or not.
   */
  _needsRenderUpdate(e) {
    return this.get(e).pipeline === void 0 || this.backend.needsRenderUpdate(e);
  }
}
class mO extends Ks {
  /**
   * Constructs a new bindings management component.
   *
   * @param {Backend} backend - The renderer's backend.
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   * @param {Textures} textures - Renderer component for managing textures.
   * @param {Attributes} attributes - Renderer component for managing attributes.
   * @param {Pipelines} pipelines - Renderer component for managing pipelines.
   * @param {Info} info - Renderer component for managing metrics and monitoring data.
   */
  constructor(e, t, n, r, s, a) {
    super(), this.backend = e, this.textures = n, this.pipelines = s, this.attributes = r, this.nodes = t, this.info = a, this.pipelines.bindings = this;
  }
  /**
   * Returns the bind groups for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {Array<BindGroup>} The bind groups.
   */
  getForRender(e) {
    const t = e.getBindings();
    for (const n of t) {
      const r = this.get(n);
      r.bindGroup === void 0 && (this._init(n), this.backend.createBindings(n, t, 0), r.bindGroup = n);
    }
    return t;
  }
  /**
   * Returns the bind groups for the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   * @return {Array<BindGroup>} The bind groups.
   */
  getForCompute(e) {
    const t = this.nodes.getForCompute(e).bindings;
    for (const n of t) {
      const r = this.get(n);
      r.bindGroup === void 0 && (this._init(n), this.backend.createBindings(n, t, 0), r.bindGroup = n);
    }
    return t;
  }
  /**
   * Updates the bindings for the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   */
  updateForCompute(e) {
    this._updateBindings(this.getForCompute(e));
  }
  /**
   * Updates the bindings for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateForRender(e) {
    this._updateBindings(this.getForRender(e));
  }
  /**
   * Deletes the bindings for the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   */
  deleteForCompute(e) {
    const t = this.nodes.getForCompute(e).bindings;
    for (const n of t)
      this.backend.deleteBindGroupData(n), this.delete(n);
  }
  /**
   * Deletes the bindings for the given renderObject node.
   *
   * @param {RenderObject} renderObject - The renderObject.
   */
  deleteForRender(e) {
    const t = e.getBindings();
    for (const n of t)
      this.backend.deleteBindGroupData(n), this.delete(n);
  }
  /**
   * Updates the given array of bindings.
   *
   * @param {Array<BindGroup>} bindings - The bind groups.
   */
  _updateBindings(e) {
    for (const t of e)
      this._update(t, e);
  }
  /**
   * Initializes the given bind group.
   *
   * @param {BindGroup} bindGroup - The bind group to initialize.
   */
  _init(e) {
    for (const t of e.bindings)
      if (t.isSampledTexture)
        this.textures.updateTexture(t.texture);
      else if (t.isSampler)
        this.textures.updateSampler(t.texture);
      else if (t.isStorageBuffer) {
        const n = t.attribute, r = n.isIndirectStorageBufferAttribute ? Oi.INDIRECT : Oi.STORAGE;
        this.attributes.update(n, r);
      }
  }
  /**
   * Updates the given bind group.
   *
   * @param {BindGroup} bindGroup - The bind group to update.
   * @param {Array<BindGroup>} bindings - The bind groups.
   */
  _update(e, t) {
    const { backend: n } = this;
    let r = !1, s = !0, a = 0, o = 0;
    for (const l of e.bindings)
      if (this.nodes.updateGroup(l) !== !1) {
        if (l.isStorageBuffer) {
          const u = l.attribute, h = u.isIndirectStorageBufferAttribute ? Oi.INDIRECT : Oi.STORAGE, d = n.get(l);
          this.attributes.update(u, h), d.attribute !== u && (d.attribute = u, r = !0);
        }
        if (l.isUniformBuffer)
          l.update() && n.updateBinding(l);
        else if (l.isSampledTexture) {
          const u = l.update(), h = l.texture, d = this.textures.get(h);
          if (u && (this.textures.updateTexture(h), l.generation !== d.generation && (l.generation = d.generation, r = !0), d.bindGroups.add(e)), n.get(h).externalTexture !== void 0 || d.isDefaultTexture ? s = !1 : (a = a * 10 + h.id, o += h.version), h.isStorageTexture === !0 && h.mipmapsAutoUpdate === !0) {
            const p = this.get(h);
            l.store === !0 ? p.needsMipmap = !0 : this.textures.needsMipmaps(h) && p.needsMipmap === !0 && (this.backend.generateMipmaps(h), p.needsMipmap = !1);
          }
        } else if (l.isSampler && l.update()) {
          const h = this.textures.updateSampler(l.texture);
          l.samplerKey !== h && (l.samplerKey = h, r = !0);
        }
        l.isBuffer && l.updateRanges.length > 0 && l.clearUpdateRanges();
      }
    r === !0 && this.backend.updateBindings(e, t, s ? a : 0, o);
  }
}
function gO(i, e) {
  return i.groupOrder !== e.groupOrder ? i.groupOrder - e.groupOrder : i.renderOrder !== e.renderOrder ? i.renderOrder - e.renderOrder : i.z !== e.z ? i.z - e.z : i.id - e.id;
}
function kx(i, e) {
  return i.groupOrder !== e.groupOrder ? i.groupOrder - e.groupOrder : i.renderOrder !== e.renderOrder ? i.renderOrder - e.renderOrder : i.z !== e.z ? e.z - i.z : i.id - e.id;
}
function Gx(i) {
  return (i.transmission > 0 || i.transmissionNode && i.transmissionNode.isNode) && i.side === Rn && i.forceSinglePass === !1;
}
class _O {
  /**
   * Constructs a render list.
   *
   * @param {Lighting} lighting - The lighting management component.
   * @param {Scene} scene - The scene.
   * @param {Camera} camera - The camera the scene is rendered with.
   */
  constructor(e, t, n) {
    this.renderItems = [], this.renderItemsIndex = 0, this.opaque = [], this.transparentDoublePass = [], this.transparent = [], this.bundles = [], this.lightsNode = e.getNode(t, n), this.lightsArray = [], this.scene = t, this.camera = n, this.occlusionQueryCount = 0;
  }
  /**
   * This method is called right at the beginning of a render call
   * before the scene is analyzed. It prepares the internal data
   * structures for the upcoming render lists generation.
   *
   * @return {RenderList} A reference to this render list.
   */
  begin() {
    return this.renderItemsIndex = 0, this.opaque.length = 0, this.transparentDoublePass.length = 0, this.transparent.length = 0, this.bundles.length = 0, this.lightsArray.length = 0, this.occlusionQueryCount = 0, this;
  }
  /**
   * Returns a render item for the giving render item state. The state is defined
   * by a series of object-related parameters.
   *
   * The method avoids object creation by holding render items and reusing them in
   * subsequent render calls (just with different property values).
   *
   * @param {Object3D} object - The 3D object.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} material - The 3D object's material.
   * @param {number} groupOrder - The current group order.
   * @param {number} z - Th 3D object's depth value (z value in clip space).
   * @param {?number} group - {?Object} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {ClippingContext} clippingContext - The current clipping context.
   * @return {Object} The render item.
   */
  getNextRenderItem(e, t, n, r, s, a, o) {
    let l = this.renderItems[this.renderItemsIndex];
    return l === void 0 ? (l = {
      id: e.id,
      object: e,
      geometry: t,
      material: n,
      groupOrder: r,
      renderOrder: e.renderOrder,
      z: s,
      group: a,
      clippingContext: o
    }, this.renderItems[this.renderItemsIndex] = l) : (l.id = e.id, l.object = e, l.geometry = t, l.material = n, l.groupOrder = r, l.renderOrder = e.renderOrder, l.z = s, l.group = a, l.clippingContext = o), this.renderItemsIndex++, l;
  }
  /**
   * Pushes the given object as a render item to the internal render lists.
   * The selected lists depend on the object properties.
   *
   * @param {Object3D} object - The 3D object.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} material - The 3D object's material.
   * @param {number} groupOrder - The current group order.
   * @param {number} z - Th 3D object's depth value (z value in clip space).
   * @param {?number} group - {?Object} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {ClippingContext} clippingContext - The current clipping context.
   */
  push(e, t, n, r, s, a, o) {
    const l = this.getNextRenderItem(e, t, n, r, s, a, o);
    e.occlusionTest === !0 && this.occlusionQueryCount++, n.transparent === !0 || n.transmission > 0 || n.transmissionNode && n.transmissionNode.isNode || n.backdropNode && n.backdropNode.isNode ? (Gx(n) && this.transparentDoublePass.push(l), this.transparent.push(l)) : this.opaque.push(l);
  }
  /**
   * Inserts the given object as a render item at the start of the internal render lists.
   * The selected lists depend on the object properties.
   *
   * @param {Object3D} object - The 3D object.
   * @param {BufferGeometry} geometry - The 3D object's geometry.
   * @param {Material} material - The 3D object's material.
   * @param {number} groupOrder - The current group order.
   * @param {number} z - Th 3D object's depth value (z value in clip space).
   * @param {?number} group - {?Object} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {ClippingContext} clippingContext - The current clipping context.
   */
  unshift(e, t, n, r, s, a, o) {
    const l = this.getNextRenderItem(e, t, n, r, s, a, o);
    n.transparent === !0 || n.transmission > 0 || n.transmissionNode && n.transmissionNode.isNode || n.backdropNode && n.backdropNode.isNode ? (Gx(n) && this.transparentDoublePass.unshift(l), this.transparent.unshift(l)) : this.opaque.unshift(l);
  }
  /**
   * Pushes render bundle group data into the render list.
   *
   * @param {Object} group - Bundle group data.
   */
  pushBundle(e) {
    this.bundles.push(e);
  }
  /**
   * Pushes a light into the render list.
   *
   * @param {Light} light - The light.
   */
  pushLight(e) {
    this.lightsArray.push(e);
  }
  /**
   * Sorts the internal render lists.
   *
   * @param {?function(any, any): number} customOpaqueSort - A custom sort function for opaque objects.
   * @param {?function(any, any): number} customTransparentSort -  A custom sort function for transparent objects.
   */
  sort(e, t) {
    this.opaque.length > 1 && this.opaque.sort(e || gO), this.transparentDoublePass.length > 1 && this.transparentDoublePass.sort(t || kx), this.transparent.length > 1 && this.transparent.sort(t || kx);
  }
  /**
   * This method performs finalizing tasks right after the render lists
   * have been generated.
   */
  finish() {
    this.lightsNode.setLights(this.lightsArray);
    for (let e = this.renderItemsIndex, t = this.renderItems.length; e < t; e++) {
      const n = this.renderItems[e];
      if (n.id === null)
        break;
      n.id = null, n.object = null, n.geometry = null, n.material = null, n.groupOrder = null, n.renderOrder = null, n.z = null, n.group = null, n.clippingContext = null;
    }
  }
}
const _o = [];
class xO {
  /**
   * Constructs a render lists management component.
   *
   * @param {Lighting} lighting - The lighting management component.
   */
  constructor(e) {
    this.lighting = e, this.lists = new qs();
  }
  /**
   * Returns a render list for the given scene and camera.
   *
   * @param {Scene} scene - The scene.
   * @param {Camera} camera - The camera.
   * @return {RenderList} The render list.
   */
  get(e, t) {
    const n = this.lists;
    _o[0] = e, _o[1] = t;
    let r = n.get(_o);
    return r === void 0 && (r = new _O(this.lighting, e, t), n.set(_o, r)), _o[0] = null, _o[1] = null, r;
  }
  /**
   * Frees all internal resources.
   */
  dispose() {
    this.lists = new qs();
  }
}
let vO = 0;
class yO {
  /**
   * Constructs a new render context.
   */
  constructor() {
    this.id = vO++, this.mrt = null, this.color = !0, this.clearColor = !0, this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }, this.depth = !0, this.clearDepth = !0, this.clearDepthValue = 1, this.stencil = !1, this.clearStencil = !0, this.clearStencilValue = 1, this.viewport = !1, this.viewportValue = new rt(), this.scissor = !1, this.scissorValue = new rt(), this.renderTarget = null, this.textures = null, this.depthTexture = null, this.activeCubeFace = 0, this.activeMipmapLevel = 0, this.sampleCount = 1, this.width = 0, this.height = 0, this.occlusionQueryCount = 0, this.clippingContext = null, this.camera = null, this.isRenderContext = !0;
  }
  /**
   * Returns the cache key of this render context.
   *
   * @return {number} The cache key.
   */
  getCacheKey() {
    return KS(this);
  }
}
function KS(i) {
  const { textures: e, activeCubeFace: t, activeMipmapLevel: n } = i, r = [t, n];
  for (const s of e)
    r.push(s.id);
  return ou(r);
}
class bO {
  /**
   * Constructs a new render context management component.
   *
   * @param {Renderer} renderer - The renderer.
   */
  constructor(e) {
    this.renderer = e, this._renderContexts = {};
  }
  /**
   * Returns a render context for the given scene, camera and render target.
   *
   * @param {?RenderTarget} [renderTarget=null] - The active render target.
   * @param {?MRTNode} [mrt=null] - The MRT configuration
   * @param {?number} [callDepth=0] - The call depth of the renderer.
   * @return {RenderContext} The render context.
   */
  get(e = null, t = null, n = 0) {
    let r;
    if (e === null)
      r = "default";
    else {
      const l = e.texture.format, c = e.texture.type;
      r = `${e.textures.length}:${l}:${c}:${e.samples}:${e.depthBuffer}:${e.stencilBuffer}`;
    }
    const s = t !== null ? t.id : "default", a = r + "-" + s + "-" + n;
    let o = this._renderContexts[a];
    return o === void 0 && (o = new yO(), o.mrt = t, this._renderContexts[a] = o), e !== null && (o.sampleCount = e.samples === 0 ? 1 : e.samples), o.clearDepthValue = this.renderer.getClearDepth(), o.clearStencilValue = this.renderer.getClearStencil(), o;
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this._renderContexts = {};
  }
}
const SO = /* @__PURE__ */ new P();
class TO extends Ks {
  /**
   * Constructs a new texture management component.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {Backend} backend - The renderer's backend.
   * @param {Info} info - Renderer component for managing metrics and monitoring data.
   */
  constructor(e, t, n) {
    super(), this.renderer = e, this.backend = t, this.info = n;
  }
  /**
   * Updates the given render target. Based on the given render target configuration,
   * it updates the texture states representing the attachments of the framebuffer.
   *
   * @param {RenderTarget} renderTarget - The render target to update.
   * @param {number} [activeMipmapLevel=0] - The active mipmap level.
   */
  updateRenderTarget(e, t = 0) {
    const n = this.get(e), r = e.samples === 0 ? 1 : e.samples, s = n.depthTextureMips || (n.depthTextureMips = {}), a = e.textures, o = this.getSize(a[0]), l = o.width >> t, c = o.height >> t;
    let u = e.depthTexture || s[t];
    const h = e.depthBuffer === !0 || e.stencilBuffer === !0;
    let d = !1;
    u === void 0 && h && (u = new oi(), u.format = e.stencilBuffer ? ii : Un, u.type = e.stencilBuffer ? Ci : Dt, u.image.width = l, u.image.height = c, u.image.depth = o.depth, u.renderTarget = e, u.isArrayTexture = e.multiview === !0 && o.depth > 1, s[t] = u), (n.width !== o.width || o.height !== n.height) && (d = !0, u && (u.needsUpdate = !0, u.image.width = l, u.image.height = c, u.image.depth = u.isArrayTexture ? u.image.depth : 1)), n.width = o.width, n.height = o.height, n.textures = a, n.depthTexture = u || null, n.depth = e.depthBuffer, n.stencil = e.stencilBuffer, n.renderTarget = e, n.sampleCount !== r && (d = !0, u && (u.needsUpdate = !0), n.sampleCount = r);
    const f = { sampleCount: r };
    if (e.isXRRenderTarget !== !0) {
      for (let p = 0; p < a.length; p++) {
        const _ = a[p];
        d && (_.needsUpdate = !0), this.updateTexture(_, f);
      }
      u && this.updateTexture(u, f);
    }
    n.initialized !== !0 && (n.initialized = !0, n.onDispose = () => {
      this._destroyRenderTarget(e);
    }, e.addEventListener("dispose", n.onDispose));
  }
  /**
   * Updates the given texture. Depending on the texture state, this method
   * triggers the upload of texture data to the GPU memory. If the texture data are
   * not yet ready for the upload, it uses default texture data for as a placeholder.
   *
   * @param {Texture} texture - The texture to update.
   * @param {Object} [options={}] - The options.
   */
  updateTexture(e, t = {}) {
    const n = this.get(e);
    if (n.initialized === !0 && n.version === e.version)
      return;
    const r = e.isRenderTargetTexture || e.isDepthTexture || e.isFramebufferTexture, s = this.backend;
    if (r && n.initialized === !0 && s.destroyTexture(e), e.isFramebufferTexture) {
      const c = this.renderer.getRenderTarget();
      c ? e.type = c.texture.type : e.type = Zt;
    }
    const { width: a, height: o, depth: l } = this.getSize(e);
    if (t.width = a, t.height = o, t.depth = l, t.needsMipmaps = this.needsMipmaps(e), t.levels = t.needsMipmaps ? this.getMipLevels(e, a, o) : 1, e.isCubeTexture && e.mipmaps.length > 0 && t.levels++, r || e.isStorageTexture === !0 || e.isExternalTexture === !0)
      s.createTexture(e, t), n.generation = e.version;
    else if (e.version > 0) {
      const c = e.image;
      if (c === void 0)
        oe("Renderer: Texture marked for update but image is undefined.");
      else if (c.complete === !1)
        oe("Renderer: Texture marked for update but image is incomplete.");
      else {
        if (e.images) {
          const h = [];
          for (const d of e.images)
            h.push(d);
          t.images = h;
        } else
          t.image = c;
        (n.isDefaultTexture === void 0 || n.isDefaultTexture === !0) && (s.createTexture(e, t), n.isDefaultTexture = !1, n.generation = e.version), e.source.dataReady === !0 && s.updateTexture(e, t);
        const u = e.isStorageTexture === !0 && e.mipmapsAutoUpdate === !1;
        t.needsMipmaps && e.mipmaps.length === 0 && !u && s.generateMipmaps(e), e.onUpdate && e.onUpdate(e);
      }
    } else
      s.createDefaultTexture(e), n.isDefaultTexture = !0, n.generation = e.version;
    n.initialized !== !0 && (n.initialized = !0, n.generation = e.version, n.bindGroups = /* @__PURE__ */ new Set(), this.info.memory.textures++, e.isVideoTexture && Ke.enabled === !0 && Ke.getTransfer(e.colorSpace) !== Te && oe("WebGPURenderer: Video textures must use a color space with a sRGB transfer function, e.g. SRGBColorSpace."), n.onDispose = () => {
      this._destroyTexture(e);
    }, e.addEventListener("dispose", n.onDispose)), n.version = e.version;
  }
  /**
   * Updates the sampler for the given texture. This method has no effect
   * for the WebGL backend since it has no concept of samplers. Texture
   * parameters are configured with the `texParameter()` command for each
   * texture.
   *
   * In WebGPU, samplers are objects like textures and it's possible to share
   * them when the texture parameters match.
   *
   * @param {Texture} texture - The texture to update the sampler for.
   * @return {string} The current sampler key.
   */
  updateSampler(e) {
    return this.backend.updateSampler(e);
  }
  /**
   * Computes the size of the given texture and writes the result
   * into the target vector. This vector is also returned by the
   * method.
   *
   * If no texture data are available for the compute yet, the method
   * returns default size values.
   *
   * @param {Texture} texture - The texture to compute the size for.
   * @param {Vector3} target - The target vector.
   * @return {Vector3} The target vector.
   */
  getSize(e, t = SO) {
    let n = e.images ? e.images[0] : e.image;
    return n ? (n.image !== void 0 && (n = n.image), typeof HTMLVideoElement < "u" && n instanceof HTMLVideoElement ? (t.width = n.videoWidth || 1, t.height = n.videoHeight || 1, t.depth = 1) : typeof VideoFrame < "u" && n instanceof VideoFrame ? (t.width = n.displayWidth || 1, t.height = n.displayHeight || 1, t.depth = 1) : (t.width = n.width || 1, t.height = n.height || 1, t.depth = e.isCubeTexture ? 6 : n.depth || 1)) : t.width = t.height = t.depth = 1, t;
  }
  /**
   * Computes the number of mipmap levels for the given texture.
   *
   * @param {Texture} texture - The texture.
   * @param {number} width - The texture's width.
   * @param {number} height - The texture's height.
   * @return {number} The number of mipmap levels.
   */
  getMipLevels(e, t, n) {
    let r;
    return e.mipmaps.length > 0 ? r = e.mipmaps.length : e.isCompressedTexture === !0 ? r = 1 : r = Math.floor(Math.log2(Math.max(t, n))) + 1, r;
  }
  /**
   * Returns `true` if the given texture makes use of mipmapping.
   *
   * @param {Texture} texture - The texture.
   * @return {boolean} Whether mipmaps are required or not.
   */
  needsMipmaps(e) {
    return e.generateMipmaps === !0 || e.mipmaps.length > 0;
  }
  /**
   * Frees internal resources when the given render target isn't
   * required anymore.
   *
   * @param {RenderTarget} renderTarget - The render target to destroy.
   */
  _destroyRenderTarget(e) {
    if (this.has(e) === !0) {
      const t = this.get(e), n = t.textures, r = t.depthTexture;
      e.removeEventListener("dispose", t.onDispose);
      for (let s = 0; s < n.length; s++)
        this._destroyTexture(n[s]);
      r && this._destroyTexture(r), this.delete(e), this.backend.delete(e);
    }
  }
  /**
   * Frees internal resource when the given texture isn't
   * required anymore.
   *
   * @param {Texture} texture - The texture to destroy.
   */
  _destroyTexture(e) {
    if (this.has(e) === !0) {
      const t = this.get(e);
      e.removeEventListener("dispose", t.onDispose);
      const n = t.isDefaultTexture;
      if (this.backend.destroyTexture(e, n), t.bindGroups)
        for (const r of t.bindGroups) {
          const s = this.backend.get(r);
          s.groups = void 0, s.versions = void 0;
        }
      this.delete(e), this.info.memory.textures--;
    }
  }
}
class Og extends He {
  /**
   * Constructs a new four-component color.
   * You can also pass a single THREE.Color, hex or
   * string argument to this constructor.
   *
   * @param {number|string} [r=1] - The red value.
   * @param {number} [g=1] - The green value.
   * @param {number} [b=1] - The blue value.
   * @param {number} [a=1] - The alpha value.
   */
  constructor(e, t, n, r = 1) {
    super(e, t, n), this.a = r;
  }
  /**
   * Overwrites the default to honor alpha.
   * You can also pass a single THREE.Color, hex or
   * string argument to this method.
   *
   * @param {number|string|Color} r - The red value.
   * @param {number} [g] - The green value.
   * @param {number} [b] - The blue value.
   * @param {number} [a=1] - The alpha value.
   * @return {Color4} A reference to this object.
   */
  set(e, t, n, r = 1) {
    return this.a = r, super.set(e, t, n);
  }
  /**
   * Overwrites the default to honor alpha.
   *
   * @param {Color4} color - The color to copy.
   * @return {Color4} A reference to this object.
   */
  copy(e) {
    return e.a !== void 0 && (this.a = e.a), super.copy(e);
  }
  /**
   * Overwrites the default to honor alpha.
   *
   * @return {Color4} The cloned color.
   */
  clone() {
    return new this.constructor(this.r, this.g, this.b, this.a);
  }
}
class MO extends Et {
  static get type() {
    return "ParameterNode";
  }
  /**
   * Constructs a new parameter node.
   *
   * @param {string} nodeType - The type of the node.
   * @param {?string} [name=null] - The name of the parameter in the shader.
   */
  constructor(e, t = null) {
    super(e, t), this.isParameterNode = !0;
  }
  /**
   * Gets the type of a member variable in the parameter node.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @param {string} name - The name of the member variable.
   * @returns {string}
   */
  getMemberType(e, t) {
    const n = this.getNodeType(e), r = e.getStructTypeNode(n);
    let s;
    return r !== null ? s = r.getMemberType(e, t) : (le(`TSL: Member "${t}" not found in struct "${n}".`, new Yn()), s = "float"), s;
  }
  getHash() {
    return this.uuid;
  }
  generate() {
    return this.name;
  }
}
class EO extends Fe {
  static get type() {
    return "StackNode";
  }
  /**
   * Constructs a new stack node.
   *
   * @param {?StackNode} [parent=null] - The parent stack node.
   */
  constructor(e = null) {
    super(), this.nodes = [], this.outputNode = null, this.parent = e, this._currentCond = null, this._expressionNode = null, this._currentNode = null, this.isStackNode = !0;
  }
  getElementType(e) {
    return this.hasOutput(e) ? this.outputNode.getElementType(e) : "void";
  }
  getNodeType(e) {
    return this.hasOutput(e) ? this.outputNode.getNodeType(e) : "void";
  }
  getMemberType(e, t) {
    return this.hasOutput(e) ? this.outputNode.getMemberType(e, t) : "void";
  }
  /**
   * Adds a node to this stack.
   *
   * @param {Node} node - The node to add.
   * @param {number} [index=this.nodes.length] - The index where the node should be added.
   * @return {StackNode} A reference to this stack node.
   */
  addToStack(e, t = this.nodes.length) {
    return e.isNode !== !0 ? (le("TSL: Invalid node added to stack.", new Yn()), this) : (this.nodes.splice(t, 0, e), this);
  }
  /**
   * Adds a node to the stack before the current node.
   *
   * @param {Node} node - The node to add.
   * @return {StackNode} A reference to this stack node.
   */
  addToStackBefore(e) {
    const t = this._currentNode ? this.nodes.indexOf(this._currentNode) : 0;
    return this.addToStack(e, t);
  }
  /**
   * Represent an `if` statement in TSL.
   *
   * @param {Node} boolNode - Represents the condition.
   * @param {Function} method - TSL code which is executed if the condition evaluates to `true`.
   * @return {StackNode} A reference to this stack node.
   */
  If(e, t) {
    const n = new cc(t);
    return this._currentCond = Ri(e, n), this.addToStack(this._currentCond);
  }
  /**
   * Represent an `elseif` statement in TSL.
   *
   * @param {Node} boolNode - Represents the condition.
   * @param {Function} method - TSL code which is executed if the condition evaluates to `true`.
   * @return {StackNode} A reference to this stack node.
   */
  ElseIf(e, t) {
    const n = new cc(t), r = Ri(e, n);
    return this._currentCond.elseNode = r, this._currentCond = r, this;
  }
  /**
   * Represent an `else` statement in TSL.
   *
   * @param {Function} method - TSL code which is executed in the `else` case.
   * @return {StackNode} A reference to this stack node.
   */
  Else(e) {
    return this._currentCond.elseNode = new cc(e), this;
  }
  /**
   * Represents a `switch` statement in TSL.
   *
   * @param {any} expression - Represents the expression.
   * @param {Function} method - TSL code which is executed if the condition evaluates to `true`.
   * @return {StackNode} A reference to this stack node.
   */
  Switch(e) {
    return this._expressionNode = Le(e), this;
  }
  /**
   * Represents a `case` statement in TSL. The TSL version accepts an arbitrary numbers of values.
   * The last parameter must be the callback method that should be executed in the `true` case.
   *
   * @param {...any} params - The values of the `Case()` statement as well as the callback method.
   * @return {StackNode} A reference to this stack node.
   */
  Case(...e) {
    const t = [];
    if (e.length >= 2)
      for (let o = 0; o < e.length - 1; o++)
        t.push(this._expressionNode.equal(Le(e[o])));
    else
      le("TSL: Invalid parameter length. Case() requires at least two parameters.", new Yn());
    const n = e[e.length - 1], r = new cc(n);
    let s = t[0];
    for (let o = 1; o < t.length; o++)
      s = s.or(t[o]);
    const a = Ri(s, r);
    return this._currentCond === null ? (this._currentCond = a, this.addToStack(this._currentCond)) : (this._currentCond.elseNode = a, this._currentCond = a, this);
  }
  /**
   * Represents the default code block of a Switch/Case statement.
   *
   * @param {Function} method - TSL code which is executed in the `else` case.
   * @return {StackNode} A reference to this stack node.
   */
  Default(e) {
    return this.Else(e), this;
  }
  setup(e) {
    const t = e.getNodeProperties(this);
    let n = 0;
    for (const r of this.getChildren())
      r.isVarNode && r.isIntent(e) && r.isAssign(e) !== !0 || (t["node" + n++] = r);
    return t.outputNode || null;
  }
  hasOutput(e) {
    return this.outputNode && this.outputNode.isNode && this.outputNode.getNodeType(e) !== "void";
  }
  build(e, ...t) {
    const n = Mb(), r = e.buildStage;
    Hh(this), e.setActiveStack(this);
    const s = (c) => {
      if (this._currentNode = c, !(c.isVarNode && c.isIntent(e) && c.isAssign(e) !== !0)) {
        if (r === "setup")
          c.build(e);
        else if (r === "analyze")
          c.build(e, this);
        else if (r === "generate") {
          const u = e.getDataFromNode(c, "any").stages, h = u && u[e.shaderStage];
          if (c.isVarNode && h && h.length === 1 && h[0] && h[0].isStackNode)
            return;
          c.build(e, "void");
        }
      }
    }, a = [...this.nodes];
    for (const c of a)
      s(c);
    this._currentNode = null;
    const o = this.nodes.filter((c) => a.indexOf(c) === -1);
    for (const c of o)
      s(c);
    let l;
    return this.hasOutput(e) ? l = this.outputNode.build(e, ...t) : l = super.build(e, ...t), Hh(n), e.removeActiveStack(this), l;
  }
}
const Qf = /* @__PURE__ */ Mt(EO).setParameterLength(0, 1);
class ZS extends xn {
  static get type() {
    return "BitcastNode";
  }
  /**
   * Constructs a new bitcast node.
   *
   * @param {Node} valueNode - The value to convert.
   * @param {string} conversionType - The type to convert to.
   * @param {?string} [inputType = null] - The expected input data type of the bitcast operation.
   */
  constructor(e, t, n = null) {
    super(), this.valueNode = e, this.conversionType = t, this.inputType = n, this.isBitcastNode = !0;
  }
  getNodeType(e) {
    if (this.inputType !== null) {
      const t = this.valueNode.getNodeType(e), n = e.getTypeLength(t);
      return e.getTypeFromLength(n, this.conversionType);
    }
    return this.conversionType;
  }
  generate(e) {
    const t = this.getNodeType(e);
    let n = "";
    if (this.inputType !== null) {
      const r = this.valueNode.getNodeType(e);
      n = e.getTypeLength(r) === 1 ? this.inputType : e.changeComponentType(r, this.inputType);
    } else
      n = this.valueNode.getNodeType(e);
    return `${e.getBitcastMethod(t, n)}( ${this.valueNode.build(e, n)} )`;
  }
}
const wO = /* @__PURE__ */ Ae(ZS).setParameterLength(2), AO = (i) => new ZS(i, "uint", "float"), ih = {};
class wa extends $ {
  static get type() {
    return "BitcountNode";
  }
  /**
   * Constructs a new math node.
   *
   * @param {'countTrailingZeros'|'countLeadingZeros'|'countOneBits'} method - The method name.
   * @param {Node} aNode - The first input.
   */
  constructor(e, t) {
    super(e, t), this.isBitcountNode = !0;
  }
  /**
   * Casts the input value of the function to an integer if necessary.
   *
   * @private
   * @param {Node<uint>|Node<int>} inputNode - The input value.
   * @param {Node<uint>} outputNode - The output value.
   * @param {string} elementType - The type of the input value.
   */
  _resolveElementType(e, t, n) {
    n === "int" ? t.assign(wO(e, "uint")) : t.assign(e);
  }
  _returnDataNode(e) {
    switch (e) {
      case "uint":
        return gt;
      case "int":
        return Kt;
      case "uvec2":
        return wb;
      case "uvec3":
        return Rb;
      case "uvec4":
        return Nb;
      case "ivec2":
        return gr;
      case "ivec3":
        return Ab;
      case "ivec4":
        return Cb;
    }
  }
  /**
   * Creates and registers a reusable GLSL function that emulates the behavior of countTrailingZeros.
   *
   * @private
   * @param {string} method - The name of the function to create.
   * @param {string} elementType - The type of the input value.
   * @returns {Function} - The generated function
   */
  _createTrailingZerosBaseLayout(e, t) {
    const n = this._returnDataNode(t);
    return ee(([s]) => {
      const a = gt(0);
      this._resolveElementType(s, a, t);
      const o = K(a.bitAnd(zb(a))), c = AO(o).shiftRight(23).sub(127);
      return n(c);
    }).setLayout({
      name: e,
      type: t,
      inputs: [
        { name: "value", type: t }
      ]
    });
  }
  /**
   * Creates and registers a reusable GLSL function that emulates the behavior of countLeadingZeros.
   *
   * @private
   * @param {string} method - The name of the function to create.
   * @param {string} elementType - The type of the input value.
   * @returns {Function} - The generated function
   */
  _createLeadingZerosBaseLayout(e, t) {
    const n = this._returnDataNode(t);
    return ee(([s]) => {
      Bt(s.equal(gt(0)), () => gt(32));
      const a = gt(0), o = gt(0);
      return this._resolveElementType(s, a, t), Bt(a.shiftRight(16).equal(0), () => {
        o.addAssign(16), a.shiftLeftAssign(16);
      }), Bt(a.shiftRight(24).equal(0), () => {
        o.addAssign(8), a.shiftLeftAssign(8);
      }), Bt(a.shiftRight(28).equal(0), () => {
        o.addAssign(4), a.shiftLeftAssign(4);
      }), Bt(a.shiftRight(30).equal(0), () => {
        o.addAssign(2), a.shiftLeftAssign(2);
      }), Bt(a.shiftRight(31).equal(0), () => {
        o.addAssign(1);
      }), n(o);
    }).setLayout({
      name: e,
      type: t,
      inputs: [
        { name: "value", type: t }
      ]
    });
  }
  /**
   * Creates and registers a reusable GLSL function that emulates the behavior of countOneBits.
   *
   * @private
   * @param {string} method - The name of the function to create.
   * @param {string} elementType - The type of the input value.
   * @returns {Function} - The generated function
   */
  _createOneBitsBaseLayout(e, t) {
    const n = this._returnDataNode(t);
    return ee(([s]) => {
      const a = gt(0);
      this._resolveElementType(s, a, t), a.assign(a.sub(a.shiftRight(gt(1)).bitAnd(gt(1431655765)))), a.assign(a.bitAnd(gt(858993459)).add(a.shiftRight(gt(2)).bitAnd(gt(858993459))));
      const o = a.add(a.shiftRight(gt(4))).bitAnd(gt(252645135)).mul(gt(16843009)).shiftRight(gt(24));
      return n(o);
    }).setLayout({
      name: e,
      type: t,
      inputs: [
        { name: "value", type: t }
      ]
    });
  }
  /**
   * Creates and registers a reusable GLSL function that emulates the behavior of the specified bitcount function.
   * including considerations for component-wise bitcounts on vector type inputs.
   *
   * @private
   * @param {string} method - The name of the function to create.
   * @param {string} inputType - The type of the input value.
   * @param {number} typeLength - The vec length of the input value.
   * @param {Function} baseFn - The base function that operates on an individual component of the vector.
   * @returns {Function} - The alias function for the specified bitcount method.
   */
  _createMainLayout(e, t, n, r) {
    const s = this._returnDataNode(t);
    return ee(([o]) => {
      if (n === 1)
        return s(r(o));
      {
        const l = s(0), c = ["x", "y", "z", "w"];
        for (let u = 0; u < n; u++) {
          const h = c[u];
          l[h].assign(r(o[h]));
        }
        return l;
      }
    }).setLayout({
      name: e,
      type: t,
      inputs: [
        { name: "value", type: t }
      ]
    });
  }
  setup(e) {
    const { method: t, aNode: n } = this, { renderer: r } = e;
    if (r.backend.isWebGPUBackend)
      return super.setup(e);
    const s = this.getInputType(e), a = e.getElementType(s), o = e.getTypeLength(s), l = `${t}_base_${a}`, c = `${t}_${s}`;
    let u = ih[l];
    if (u === void 0) {
      switch (t) {
        case wa.COUNT_LEADING_ZEROS: {
          u = this._createLeadingZerosBaseLayout(l, a);
          break;
        }
        case wa.COUNT_TRAILING_ZEROS: {
          u = this._createTrailingZerosBaseLayout(l, a);
          break;
        }
        case wa.COUNT_ONE_BITS: {
          u = this._createOneBitsBaseLayout(l, a);
          break;
        }
      }
      ih[l] = u;
    }
    let h = ih[c];
    return h === void 0 && (h = this._createMainLayout(c, s, o, u), ih[c] = h), ee(() => h(
      n
    ))();
  }
}
wa.COUNT_TRAILING_ZEROS = "countTrailingZeros";
wa.COUNT_LEADING_ZEROS = "countLeadingZeros";
wa.COUNT_ONE_BITS = "countOneBits";
new Zi();
new P();
new P();
new P();
new pt();
new P(0, 0, -1);
new rt();
new P();
new P();
new rt();
new de();
const RO = new js();
Ea.flipX();
RO.depthTexture = new oi(1, 1);
const Jf = /* @__PURE__ */ new bl(-1, 1, 1, -1, 0, 1);
class CO extends Pn {
  /**
   * Constructs a new quad geometry.
   *
   * @param {boolean} [flipY=false] - Whether the uv coordinates should be flipped along the vertical axis or not.
   */
  constructor(e = !1) {
    super();
    const t = e === !1 ? [0, -1, 0, 1, 2, 1] : [0, 2, 0, 0, 2, 0];
    this.setAttribute("position", new an([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)), this.setAttribute("uv", new an(t, 2));
  }
}
const NO = /* @__PURE__ */ new CO();
class kg extends _n {
  /**
   * Constructs a new quad mesh.
   *
   * @param {?Material} [material=null] - The material to render the quad mesh with.
   */
  constructor(e = null) {
    super(NO, e), this.camera = Jf, this.isQuadMesh = !0;
  }
  /**
   * Async version of `render()`.
   *
   * @async
   * @deprecated
   * @param {Renderer} renderer - The renderer.
   * @return {Promise} A Promise that resolves when the render has been finished.
   */
  async renderAsync(e) {
    Pt('QuadMesh: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'), await e.init(), e.render(this, Jf);
  }
  /**
   * Renders the quad mesh
   *
   * @param {Renderer} renderer - The renderer.
   */
  render(e) {
    e.render(this, Jf);
  }
}
const QS = ee(([i]) => Pr(K(52.9829189).mul(Pr(Oa(i, Pe(0.06711056, 583715e-8)))))).setLayout({
  name: "interleavedGradientNoise",
  type: "float",
  inputs: [
    { name: "position", type: "vec2" }
  ]
}), yr = ee(([i, e, t]) => {
  const n = K(2.399963229728653), r = zs(K(i).add(0.5).div(K(e))), s = K(i).mul(n).add(t);
  return Pe(_r(s), wi(s)).mul(r);
}).setLayout({
  name: "vogelDiskSample",
  type: "vec2",
  inputs: [
    { name: "sampleIndex", type: "int" },
    { name: "samplesCount", type: "int" },
    { name: "phi", type: "float" }
  ]
});
class is extends Fe {
  static get type() {
    return "EventNode";
  }
  /**
   * Creates an EventNode.
   *
   * @param {string} eventType - The type of event
   * @param {Function} callback - The callback to execute on update.
   */
  constructor(e, t) {
    super("void"), this.eventType = e, this.callback = t, e === is.OBJECT ? this.updateType = it.OBJECT : e === is.MATERIAL ? this.updateType = it.RENDER : e === is.BEFORE_OBJECT ? this.updateBeforeType = it.OBJECT : e === is.BEFORE_MATERIAL && (this.updateBeforeType = it.RENDER);
  }
  update(e) {
    this.callback(e);
  }
  updateBefore(e) {
    this.callback(e);
  }
}
is.OBJECT = "object";
is.MATERIAL = "material";
is.BEFORE_OBJECT = "beforeObject";
is.BEFORE_MATERIAL = "beforeMaterial";
const Jl = /* @__PURE__ */ new gi(), ep = /* @__PURE__ */ new pt(), PO = /* @__PURE__ */ je(0).setGroup(Xe).onRenderUpdate(({ scene: i }) => i.backgroundBlurriness), Vx = /* @__PURE__ */ je(1).setGroup(Xe).onRenderUpdate(({ scene: i }) => i.backgroundIntensity), DO = /* @__PURE__ */ je(new pt()).setGroup(Xe).onRenderUpdate(({ scene: i }) => {
  const e = i.background;
  return e !== null && e.isTexture && e.mapping !== Im ? (Jl.copy(i.backgroundRotation), Jl.x *= -1, Jl.y *= -1, Jl.z *= -1, ep.makeRotationFromEuler(Jl)) : ep.identity(), ep;
}), LO = ee(({ texture: i, uv: e }) => {
  const n = Y().toVar();
  return Bt(e.x.lessThan(1e-4), () => {
    n.assign(Y(1, 0, 0));
  }).ElseIf(e.y.lessThan(1e-4), () => {
    n.assign(Y(0, 1, 0));
  }).ElseIf(e.z.lessThan(1e-4), () => {
    n.assign(Y(0, 0, 1));
  }).ElseIf(e.x.greaterThan(1 - 1e-4), () => {
    n.assign(Y(-1, 0, 0));
  }).ElseIf(e.y.greaterThan(1 - 1e-4), () => {
    n.assign(Y(0, -1, 0));
  }).ElseIf(e.z.greaterThan(1 - 1e-4), () => {
    n.assign(Y(0, 0, -1));
  }).Else(() => {
    const s = i.sample(e.add(Y(-0.01, 0, 0))).r.sub(i.sample(e.add(Y(0.01, 0, 0))).r), a = i.sample(e.add(Y(0, -0.01, 0))).r.sub(i.sample(e.add(Y(0, 0.01, 0))).r), o = i.sample(e.add(Y(0, 0, -0.01))).r.sub(i.sample(e.add(Y(0, 0, 0.01))).r);
    n.assign(Y(s, a, o));
  }), n.normalize();
});
class FO extends Rl {
  static get type() {
    return "Texture3DNode";
  }
  /**
   * Constructs a new 3D texture node.
   *
   * @param {Data3DTexture} value - The 3D texture.
   * @param {?Node<vec2|vec3>} [uvNode=null] - The uv node.
   * @param {?Node<int>} [levelNode=null] - The level node.
   */
  constructor(e, t = null, n = null) {
    super(e, t, n), this.isTexture3DNode = !0;
  }
  /**
   * Overwrites the default implementation to return a fixed value `'texture3D'`.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType() {
    return "texture3D";
  }
  /**
   * Returns a default uv node which is in context of 3D textures a three-dimensional
   * uv node.
   *
   * @return {Node<vec3>} The default uv node.
   */
  getDefaultUV() {
    return Y(0.5, 0.5, 0.5);
  }
  /**
   * Overwritten with an empty implementation since the `updateMatrix` flag is ignored
   * for 3D textures. The uv transformation matrix is not applied to 3D textures.
   *
   * @param {boolean} value - The update toggle.
   */
  setUpdateMatrix() {
  }
  // Ignore .updateMatrix for 3d TextureNode
  /**
   * Generates the uv code snippet.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} uvNode - The uv node to generate code for.
   * @return {string} The generated code snippet.
   */
  generateUV(e, t) {
    return t.build(e, this.sampler === !0 ? "vec3" : "ivec3");
  }
  /**
   * Generates the offset code snippet.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {Node} offsetNode - The offset node to generate code for.
   * @return {string} The generated code snippet.
   */
  generateOffset(e, t) {
    return t.build(e, "ivec3");
  }
  /**
   * Computes the normal for the given uv. These texture coordiantes represent a
   * position inside the 3D texture. Unlike geometric normals, this normal
   * represents a slope or gradient of scalar data inside the 3D texture.
   *
   * @param {Node<vec3>} uvNode - The uv node that defines a position in the 3D texture.
   * @return {Node<vec3>} The normal representing the slope/gradient in the data.
   */
  normal(e) {
    return LO({ texture: this, uv: e });
  }
}
const IO = /* @__PURE__ */ Mt(FO).setParameterLength(1, 3);
ee(([i, e]) => i.mul(e).floor().div(e));
const rh = /* @__PURE__ */ new de();
class UO extends Rl {
  static get type() {
    return "PassTextureNode";
  }
  /**
   * Constructs a new pass texture node.
   *
   * @param {PassNode} passNode - The pass node.
   * @param {Texture} texture - The output texture.
   */
  constructor(e, t) {
    super(t), this.passNode = e, this.isPassTextureNode = !0, this.setUpdateMatrix(!1);
  }
  setup(e) {
    const t = e.getNodeProperties(this);
    return t.passNode = this.passNode, super.setup(e);
  }
  clone() {
    return new this.constructor(this.passNode, this.value);
  }
}
class zx extends UO {
  static get type() {
    return "PassMultipleTextureNode";
  }
  /**
   * Constructs a new pass texture node.
   *
   * @param {PassNode} passNode - The pass node.
   * @param {string} textureName - The output texture name.
   * @param {boolean} [previousTexture=false] - Whether previous frame data should be used or not.
   */
  constructor(e, t, n = !1) {
    super(e, null), this.textureName = t, this.previousTexture = n, this.isPassMultipleTextureNode = !0;
  }
  /**
   * Updates the texture reference of this node.
   */
  updateTexture() {
    this.value = this.previousTexture ? this.passNode.getPreviousTexture(this.textureName) : this.passNode.getTexture(this.textureName);
  }
  setup(e) {
    return this.updateTexture(), super.setup(e);
  }
  clone() {
    const e = new this.constructor(this.passNode, this.textureName, this.previousTexture);
    return e.uvNode = this.uvNode, e.levelNode = this.levelNode, e.biasNode = this.biasNode, e.sampler = this.sampler, e.depthNode = this.depthNode, e.compareNode = this.compareNode, e.gradNode = this.gradNode, e.offsetNode = this.offsetNode, e;
  }
}
class Rd extends xn {
  static get type() {
    return "PassNode";
  }
  /**
   * Constructs a new pass node.
   *
   * @param {('color'|'depth')} scope - The scope of the pass. The scope determines whether the node outputs color or depth.
   * @param {Scene} scene - A reference to the scene.
   * @param {Camera} camera - A reference to the camera.
   * @param {Object} options - Options for the internal render target.
   */
  constructor(e, t, n, r = {}) {
    super("vec4"), this.scope = e, this.scene = t, this.camera = n, this.options = r, this._pixelRatio = 1, this._width = 1, this._height = 1;
    const s = new oi();
    s.isRenderTargetTexture = !0, s.name = "depth";
    const a = new js(this._width * this._pixelRatio, this._height * this._pixelRatio, { type: nn, ...r });
    a.texture.name = "output", a.depthTexture = s, this.renderTarget = a, this.overrideMaterial = null, this.transparent = !0, this.opaque = !0, this.contextNode = null, this._contextNodeCache = null, this._textures = {
      output: a.texture,
      depth: s
    }, this._textureNodes = {}, this._linearDepthNodes = {}, this._viewZNodes = {}, this._previousTextures = {}, this._previousTextureNodes = {}, this._cameraNear = je(0), this._cameraFar = je(0), this._mrt = null, this._layers = null, this._resolutionScale = 1, this._viewport = null, this._scissor = null, this.isPassNode = !0, this.updateBeforeType = it.FRAME, this.global = !0;
  }
  /**
   * Sets the resolution scale for the pass.
   * The resolution scale is a factor that is multiplied with the renderer's width and height.
   *
   * @param {number} resolutionScale - The resolution scale to set. A value of `1` means full resolution.
   * @return {PassNode} A reference to this pass.
   */
  setResolutionScale(e) {
    return this._resolutionScale = e, this;
  }
  /**
   * Gets the current resolution scale of the pass.
   *
   * @return {number} The current resolution scale. A value of `1` means full resolution.
   */
  getResolutionScale() {
    return this._resolutionScale;
  }
  /**
   * Sets the resolution for the pass.
   * The resolution is a factor that is multiplied with the renderer's width and height.
   *
   * @param {number} resolution - The resolution to set. A value of `1` means full resolution.
   * @return {PassNode} A reference to this pass.
   * @deprecated since r181. Use {@link PassNode#setResolutionScale `setResolutionScale()`} instead.
   */
  setResolution(e) {
    return oe("PassNode: .setResolution() is deprecated. Use .setResolutionScale() instead."), this.setResolutionScale(e);
  }
  /**
   * Gets the current resolution of the pass.
   *
   * @return {number} The current resolution. A value of `1` means full resolution.
   * @deprecated since r181. Use {@link PassNode#getResolutionScale `getResolutionScale()`} instead.
   */
  getResolution() {
    return oe("PassNode: .getResolution() is deprecated. Use .getResolutionScale() instead."), this.getResolutionScale();
  }
  /**
   * Sets the layer configuration that should be used when rendering the pass.
   *
   * @param {Layers} layers - The layers object to set.
   * @return {PassNode} A reference to this pass.
   */
  setLayers(e) {
    return this._layers = e, this;
  }
  /**
   * Gets the current layer configuration of the pass.
   *
   * @return {?Layers} .
   */
  getLayers() {
    return this._layers;
  }
  /**
   * Sets the given MRT node to setup MRT for this pass.
   *
   * @param {MRTNode} mrt - The MRT object.
   * @return {PassNode} A reference to this pass.
   */
  setMRT(e) {
    return this._mrt = e, this;
  }
  /**
   * Returns the current MRT node.
   *
   * @return {MRTNode} The current MRT node.
   */
  getMRT() {
    return this._mrt;
  }
  /**
   * Returns the texture for the given output name.
   *
   * @param {string} name - The output name to get the texture for.
   * @return {Texture} The texture.
   */
  getTexture(e) {
    let t = this._textures[e];
    return t === void 0 && (t = this.renderTarget.texture.clone(), t.name = e, this._textures[e] = t, this.renderTarget.textures.push(t)), t;
  }
  /**
   * Returns the texture holding the data of the previous frame for the given output name.
   *
   * @param {string} name - The output name to get the texture for.
   * @return {Texture} The texture holding the data of the previous frame.
   */
  getPreviousTexture(e) {
    let t = this._previousTextures[e];
    return t === void 0 && (t = this.getTexture(e).clone(), this._previousTextures[e] = t), t;
  }
  /**
   * Switches current and previous textures for the given output name.
   *
   * @param {string} name - The output name.
   */
  toggleTexture(e) {
    const t = this._previousTextures[e];
    if (t !== void 0) {
      const n = this._textures[e], r = this.renderTarget.textures.indexOf(n);
      this.renderTarget.textures[r] = t, this._textures[e] = t, this._previousTextures[e] = n, this._textureNodes[e].updateTexture(), this._previousTextureNodes[e].updateTexture();
    }
  }
  /**
   * Returns the texture node for the given output name.
   *
   * @param {string} [name='output'] - The output name to get the texture node for.
   * @return {TextureNode} The texture node.
   */
  getTextureNode(e = "output") {
    let t = this._textureNodes[e];
    return t === void 0 && (t = new zx(this, e), t.updateTexture(), this._textureNodes[e] = t), t;
  }
  /**
   * Returns the previous texture node for the given output name.
   *
   * @param {string} [name='output'] - The output name to get the previous texture node for.
   * @return {TextureNode} The previous texture node.
   */
  getPreviousTextureNode(e = "output") {
    let t = this._previousTextureNodes[e];
    return t === void 0 && (this._textureNodes[e] === void 0 && this.getTextureNode(e), t = new zx(this, e, !0), t.updateTexture(), this._previousTextureNodes[e] = t), t;
  }
  /**
   * Returns a viewZ node of this pass.
   *
   * @param {string} [name='depth'] - The output name to get the viewZ node for. In most cases the default `'depth'` can be used however the parameter exists for custom depth outputs.
   * @return {Node} The viewZ node.
   */
  getViewZNode(e = "depth") {
    let t = this._viewZNodes[e];
    if (t === void 0) {
      const n = this._cameraNear, r = this._cameraFar;
      this._viewZNodes[e] = t = AS(this.getTextureNode(e), n, r);
    }
    return t;
  }
  /**
   * Returns a linear depth node of this pass.
   *
   * @param {string} [name='depth'] - The output name to get the linear depth node for. In most cases the default `'depth'` can be used however the parameter exists for custom depth outputs.
   * @return {Node} The linear depth node.
   */
  getLinearDepthNode(e = "depth") {
    let t = this._linearDepthNodes[e];
    if (t === void 0) {
      const n = this._cameraNear, r = this._cameraFar, s = this.getViewZNode(e);
      this._linearDepthNodes[e] = t = Ec(s, n, r);
    }
    return t;
  }
  /**
   * Precompiles the pass.
   *
   * Note that this method must be called after the pass configuration is complete.
   * So calls like `setMRT()` and `getTextureNode()` must proceed the precompilation.
   *
   * @async
   * @param {Renderer} renderer - The renderer.
   * @return {Promise} A Promise that resolves when the compile has been finished.
   * @see {@link Renderer#compileAsync}
   */
  async compileAsync(e) {
    const t = e.getRenderTarget(), n = e.getMRT();
    e.setRenderTarget(this.renderTarget), e.setMRT(this._mrt), await e.compileAsync(this.scene, this.camera), e.setRenderTarget(t), e.setMRT(n);
  }
  setup({ renderer: e }) {
    return this.renderTarget.samples = this.options.samples === void 0 ? e.samples : this.options.samples, this.renderTarget.texture.type = e.getOutputBufferType(), this.scope === Rd.COLOR ? this.getTextureNode() : this.getLinearDepthNode();
  }
  updateBefore(e) {
    const { renderer: t } = e, { scene: n } = this;
    let r, s;
    const a = t.getOutputRenderTarget();
    a && a.isXRRenderTarget === !0 ? (s = 1, r = t.xr.getCamera(), t.xr.updateCamera(r), rh.set(a.width, a.height)) : (r = this.camera, s = t.getPixelRatio(), t.getSize(rh)), this._pixelRatio = s, this.setSize(rh.width, rh.height);
    const o = t.getRenderTarget(), l = t.getMRT(), c = t.autoClear, u = t.transparent, h = t.opaque, d = r.layers.mask, f = t.contextNode, p = n.overrideMaterial;
    this._cameraNear.value = r.near, this._cameraFar.value = r.far, this._layers !== null && (r.layers.mask = this._layers.mask);
    for (const g in this._previousTextures)
      this.toggleTexture(g);
    this.overrideMaterial !== null && (n.overrideMaterial = this.overrideMaterial), t.setRenderTarget(this.renderTarget), t.setMRT(this._mrt), t.autoClear = !0, t.transparent = this.transparent, t.opaque = this.opaque, this.contextNode !== null && ((this._contextNodeCache === null || this._contextNodeCache.version !== this.version) && (this._contextNodeCache = {
      version: this.version,
      context: qa({ ...t.contextNode.getFlowContextData(), ...this.contextNode.getFlowContextData() })
    }), t.contextNode = this._contextNodeCache.context);
    const _ = n.name;
    n.name = this.name ? this.name : n.name, t.render(n, r), n.name = _, n.overrideMaterial = p, t.setRenderTarget(o), t.setMRT(l), t.autoClear = c, t.transparent = u, t.opaque = h, t.contextNode = f, r.layers.mask = d;
  }
  /**
   * Sets the size of the pass's render target. Honors the pixel ratio.
   *
   * @param {number} width - The width to set.
   * @param {number} height - The height to set.
   */
  setSize(e, t) {
    this._width = e, this._height = t;
    const n = Math.floor(this._width * this._pixelRatio * this._resolutionScale), r = Math.floor(this._height * this._pixelRatio * this._resolutionScale);
    this.renderTarget.setSize(n, r), this._scissor !== null && this.renderTarget.scissor.copy(this._scissor), this._viewport !== null && this.renderTarget.viewport.copy(this._viewport);
  }
  /**
   * This method allows to define the pass's scissor rectangle. By default, the scissor rectangle is kept
   * in sync with the pass's dimensions. To reverse the process and use auto-sizing again, call the method
   * with `null` as the single argument.
   *
   * @param {?(number | Vector4)} x - The horizontal coordinate for the lower left corner of the box in logical pixel unit.
   * Instead of passing four arguments, the method also works with a single four-dimensional vector.
   * @param {number} y - The vertical coordinate for the lower left corner of the box in logical pixel unit.
   * @param {number} width - The width of the scissor box in logical pixel unit.
   * @param {number} height - The height of the scissor box in logical pixel unit.
   */
  setScissor(e, t, n, r) {
    e === null ? this._scissor = null : (this._scissor === null && (this._scissor = new rt()), e.isVector4 ? this._scissor.copy(e) : this._scissor.set(e, t, n, r), this._scissor.multiplyScalar(this._pixelRatio * this._resolutionScale).floor());
  }
  /**
   * This method allows to define the pass's viewport. By default, the viewport is kept in sync
   * with the pass's dimensions. To reverse the process and use auto-sizing again, call the method
   * with `null` as the single argument.
   *
   * @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the viewport origin in logical pixel unit.
   * @param {number} y - The vertical coordinate for the lower left corner of the viewport origin  in logical pixel unit.
   * @param {number} width - The width of the viewport in logical pixel unit.
   * @param {number} height - The height of the viewport in logical pixel unit.
   */
  setViewport(e, t, n, r) {
    e === null ? this._viewport = null : (this._viewport === null && (this._viewport = new rt()), e.isVector4 ? this._viewport.copy(e) : this._viewport.set(e, t, n, r), this._viewport.multiplyScalar(this._pixelRatio * this._resolutionScale).floor());
  }
  /**
   * Sets the pixel ratio the pass's render target and updates the size.
   *
   * @param {number} pixelRatio - The pixel ratio to set.
   */
  setPixelRatio(e) {
    this._pixelRatio = e, this.setSize(this._width, this._height);
  }
  /**
   * Frees internal resources. Should be called when the node is no longer in use.
   */
  dispose() {
    this.renderTarget.dispose();
  }
}
Rd.COLOR = "color";
Rd.DEPTH = "depth";
const BO = /* @__PURE__ */ ee(([i, e]) => i.mul(e).clamp()).setLayout({
  name: "linearToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
}), OO = /* @__PURE__ */ ee(([i, e]) => (i = i.mul(e), i.div(i.add(1)).clamp())).setLayout({
  name: "reinhardToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
}), kO = /* @__PURE__ */ ee(([i, e]) => {
  i = i.mul(e), i = i.sub(4e-3).max(0);
  const t = i.mul(i.mul(6.2).add(0.5)), n = i.mul(i.mul(6.2).add(1.7)).add(0.06);
  return t.div(n).pow(2.2);
}).setLayout({
  name: "cineonToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
}), GO = /* @__PURE__ */ ee(([i]) => {
  const e = i.mul(i.add(0.0245786)).sub(90537e-9), t = i.mul(i.add(0.432951).mul(0.983729)).add(0.238081);
  return e.div(t);
}), VO = /* @__PURE__ */ ee(([i, e]) => {
  const t = On(
    0.59719,
    0.35458,
    0.04823,
    0.076,
    0.90834,
    0.01566,
    0.0284,
    0.13383,
    0.83777
  ), n = On(
    1.60475,
    -0.53108,
    -0.07367,
    -0.10208,
    1.10813,
    -605e-5,
    -327e-5,
    -0.07276,
    1.07602
  );
  return i = i.mul(e).div(0.6), i = t.mul(i), i = GO(i), i = n.mul(i), i.clamp();
}).setLayout({
  name: "acesFilmicToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
}), zO = /* @__PURE__ */ On(Y(1.6605, -0.1246, -0.0182), Y(-0.5876, 1.1329, -0.1006), Y(-0.0728, -83e-4, 1.1187)), HO = /* @__PURE__ */ On(Y(0.6274, 0.0691, 0.0164), Y(0.3293, 0.9195, 0.088), Y(0.0433, 0.0113, 0.8956)), $O = /* @__PURE__ */ ee(([i]) => {
  const e = Y(i).toVar(), t = Y(e.mul(e)).toVar(), n = Y(t.mul(t)).toVar();
  return K(15.5).mul(n.mul(t)).sub(at(40.14, n.mul(e))).add(at(31.96, n).sub(at(6.868, t.mul(e))).add(at(0.4298, t).add(at(0.1191, e).sub(232e-5))));
}), WO = /* @__PURE__ */ ee(([i, e]) => {
  const t = Y(i).toVar(), n = On(Y(0.856627153315983, 0.137318972929847, 0.11189821299995), Y(0.0951212405381588, 0.761241990602591, 0.0767994186031903), Y(0.0482516061458583, 0.101439036467562, 0.811302368396859)), r = On(Y(1.1271005818144368, -0.1413297634984383, -0.14132976349843826), Y(-0.11060664309660323, 1.157823702216272, -0.11060664309660294), Y(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)), s = K(-12.47393), a = K(4.026069);
  return t.mulAssign(e), t.assign(HO.mul(t)), t.assign(n.mul(t)), t.assign(kn(t, 1e-10)), t.assign(ls(t)), t.assign(t.sub(s).div(a.sub(s))), t.assign($s(t, 0, 1)), t.assign($O(t)), t.assign(r.mul(t)), t.assign(bd(kn(Y(0), t), Y(2.2))), t.assign(zO.mul(t)), t.assign($s(t, 0, 1)), t;
}).setLayout({
  name: "agxToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
}), qO = /* @__PURE__ */ ee(([i, e]) => {
  const t = K(0.76), n = K(0.15);
  i = i.mul(e);
  const r = fl(i.r, fl(i.g, i.b)), s = Ri(r.lessThan(0.08), r.sub(at(6.25, r.mul(r))), 0.04);
  i.subAssign(s);
  const a = kn(i.r, kn(i.g, i.b));
  Bt(a.lessThan(t), () => i);
  const o = ui(1, t), l = ui(1, o.mul(o).div(a.add(o.sub(t))));
  i.mulAssign(l.div(a));
  const c = ui(1, Nr(1, n.mul(a.sub(l)).add(1)));
  return Lt(i, Y(l), c);
}).setLayout({
  name: "neutralToneMapping",
  type: "vec3",
  inputs: [
    { name: "color", type: "vec3" },
    { name: "exposure", type: "float" }
  ]
});
class En extends Fe {
  static get type() {
    return "CodeNode";
  }
  /**
   * Constructs a new code node.
   *
   * @param {string} [code=''] - The native code.
   * @param {Array<Node>} [includes=[]] - An array of includes.
   * @param {('js'|'wgsl'|'glsl')} [language=''] - The used language.
   */
  constructor(e = "", t = [], n = "") {
    super("code"), this.isCodeNode = !0, this.global = !0, this.code = e, this.includes = t, this.language = n;
  }
  /**
   * Sets the includes of this code node.
   *
   * @param {Array<Node>} includes - The includes to set.
   * @return {CodeNode} A reference to this node.
   */
  setIncludes(e) {
    return this.includes = e, this;
  }
  /**
   * Returns the includes of this code node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Array<Node>} The includes.
   */
  getIncludes() {
    return this.includes;
  }
  generate(e) {
    const t = this.getIncludes(e);
    for (const r of t)
      r.build(e);
    const n = e.getCodeFromNode(this, this.getNodeType(e));
    return n.code = this.code, n.code;
  }
  serialize(e) {
    super.serialize(e), e.code = this.code, e.language = this.language;
  }
  deserialize(e) {
    super.deserialize(e), this.code = e.code, this.language = e.language;
  }
}
class XO extends En {
  static get type() {
    return "FunctionNode";
  }
  /**
   * Constructs a new function node.
   *
   * @param {string} [code=''] - The native code.
   * @param {Array<Node>} [includes=[]] - An array of includes.
   * @param {('js'|'wgsl'|'glsl')} [language=''] - The used language.
   */
  constructor(e = "", t = [], n = "") {
    super(e, t, n);
  }
  /**
   * Returns the type of this function node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The type.
   */
  getNodeType(e) {
    return this.getNodeFunction(e).type;
  }
  /**
   * Returns the type of a member of this function node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @param {string} name - The name of the member.
   * @return {string} The type of the member.
   */
  getMemberType(e, t) {
    const n = this.getNodeType(e);
    return e.getStructTypeNode(n).getMemberType(e, t);
  }
  /**
   * Returns the inputs of this function node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {Array<NodeFunctionInput>} The inputs.
   */
  getInputs(e) {
    return this.getNodeFunction(e).inputs;
  }
  /**
   * Returns the node function for this function node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {NodeFunction} The node function.
   */
  getNodeFunction(e) {
    const t = e.getDataFromNode(this);
    let n = t.nodeFunction;
    return n === void 0 && (n = e.parser.parseFunction(this.code), t.nodeFunction = n), n;
  }
  generate(e, t) {
    super.generate(e);
    const n = this.getNodeFunction(e), r = n.name, s = n.type, a = e.getCodeFromNode(this, s);
    r !== "" && (a.name = r);
    const o = e.getPropertyName(a), l = this.getNodeFunction(e).getCode(o);
    return a.code = l + `
`, t === "property" ? o : e.format(`${o}()`, s, t);
  }
}
function Gg(i) {
  let e;
  const t = i.context.getViewZ;
  return t !== void 0 && (e = t(this)), (e || hn.z).negate();
}
const jO = ee(([i, e], t) => {
  const n = Gg(t);
  return hs(i, e, n);
}), YO = ee(([i], e) => {
  const t = Gg(e);
  return i.mul(i, t, t).negate().exp().oneMinus();
});
ee(([i, e], t) => {
  const n = Gg(t), s = e.sub(pl.y).max(0).toConst().mul(n).toConst();
  return i.mul(i, s, s).negate().exp().oneMinus();
});
const Hx = ee(([i, e]) => et(e.toFloat().mix(bc.rgb, i.toVec3()), bc.a));
class KO extends Fe {
  /**
   * Constructs a new barrier node.
   *
   * @param {string} scope - The scope defines the behavior of the node.
   */
  constructor(e) {
    super(), this.scope = e;
  }
  generate(e) {
    const { scope: t } = this, { renderer: n } = e;
    n.backend.isWebGLBackend === !0 ? e.addFlowCode(`	// ${t}Barrier 
`) : e.addLineFlowCode(`${t}Barrier()`, this);
  }
}
Mt(KO);
class Ur extends Fe {
  static get type() {
    return "AtomicFunctionNode";
  }
  /**
   * Constructs a new atomic function node.
   *
   * @param {string} method - The signature of the atomic function to construct.
   * @param {Node} pointerNode - An atomic variable or element of an atomic buffer.
   * @param {Node} valueNode - The value that mutates the atomic variable.
   */
  constructor(e, t, n) {
    super("uint"), this.method = e, this.pointerNode = t, this.valueNode = n, this.parents = !0;
  }
  /**
   * Overwrites the default implementation to return the type of
   * the pointer node.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The input type.
   */
  getInputType(e) {
    return this.pointerNode.getNodeType(e);
  }
  /**
   * Overwritten since the node type is inferred from the input type.
   *
   * @param {NodeBuilder} builder - The current node builder.
   * @return {string} The node type.
   */
  getNodeType(e) {
    return this.getInputType(e);
  }
  generate(e) {
    const t = e.getNodeProperties(this), n = t.parents, r = this.method, s = this.getNodeType(e), a = this.getInputType(e), o = this.pointerNode, l = this.valueNode, c = [];
    c.push(`&${o.build(e, a)}`), l !== null && c.push(l.build(e, a));
    const u = `${e.getMethod(r, s)}( ${c.join(", ")} )`;
    if (n ? n.length === 1 && n[0].isStackNode === !0 : !1)
      e.addLineFlowCode(u, this);
    else
      return t.constNode === void 0 && (t.constNode = vr(u, s).toConst()), t.constNode.build(e);
  }
}
Ur.ATOMIC_LOAD = "atomicLoad";
Ur.ATOMIC_STORE = "atomicStore";
Ur.ATOMIC_ADD = "atomicAdd";
Ur.ATOMIC_SUB = "atomicSub";
Ur.ATOMIC_MAX = "atomicMax";
Ur.ATOMIC_MIN = "atomicMin";
Ur.ATOMIC_AND = "atomicAnd";
Ur.ATOMIC_OR = "atomicOr";
Ur.ATOMIC_XOR = "atomicXor";
Mt(Ur);
class yt extends xn {
  static get type() {
    return "SubgroupFunctionNode";
  }
  /**
   * Constructs a new function node.
   *
   * @param {string} method - The subgroup/wave intrinsic method to construct.
   * @param {Node} [aNode=null] - The method's first argument.
   * @param {Node} [bNode=null] - The method's second argument.
   */
  constructor(e, t = null, n = null) {
    super(), this.method = e, this.aNode = t, this.bNode = n;
  }
  getInputType(e) {
    const t = this.aNode ? this.aNode.getNodeType(e) : null, n = this.bNode ? this.bNode.getNodeType(e) : null, r = e.isMatrix(t) ? 0 : e.getTypeLength(t), s = e.isMatrix(n) ? 0 : e.getTypeLength(n);
    return r > s ? t : n;
  }
  getNodeType(e) {
    const t = this.method;
    return t === yt.SUBGROUP_ELECT ? "bool" : t === yt.SUBGROUP_BALLOT ? "uvec4" : this.getInputType(e);
  }
  generate(e, t) {
    const n = this.method, r = this.getNodeType(e), s = this.getInputType(e), a = this.aNode, o = this.bNode, l = [];
    if (n === yt.SUBGROUP_BROADCAST || n === yt.SUBGROUP_SHUFFLE || n === yt.QUAD_BROADCAST) {
      const u = o.getNodeType(e);
      l.push(
        a.build(e, r),
        o.build(e, u === "float" ? "int" : r)
      );
    } else
      n === yt.SUBGROUP_SHUFFLE_XOR || n === yt.SUBGROUP_SHUFFLE_DOWN || n === yt.SUBGROUP_SHUFFLE_UP ? l.push(
        a.build(e, r),
        o.build(e, "uint")
      ) : (a !== null && l.push(a.build(e, s)), o !== null && l.push(o.build(e, s)));
    const c = l.length === 0 ? "()" : `( ${l.join(", ")} )`;
    return e.format(`${e.getMethod(n, r)}${c}`, r, t);
  }
  serialize(e) {
    super.serialize(e), e.method = this.method;
  }
  deserialize(e) {
    super.deserialize(e), this.method = e.method;
  }
}
yt.SUBGROUP_ELECT = "subgroupElect";
yt.SUBGROUP_BALLOT = "subgroupBallot";
yt.SUBGROUP_ADD = "subgroupAdd";
yt.SUBGROUP_INCLUSIVE_ADD = "subgroupInclusiveAdd";
yt.SUBGROUP_EXCLUSIVE_AND = "subgroupExclusiveAdd";
yt.SUBGROUP_MUL = "subgroupMul";
yt.SUBGROUP_INCLUSIVE_MUL = "subgroupInclusiveMul";
yt.SUBGROUP_EXCLUSIVE_MUL = "subgroupExclusiveMul";
yt.SUBGROUP_AND = "subgroupAnd";
yt.SUBGROUP_OR = "subgroupOr";
yt.SUBGROUP_XOR = "subgroupXor";
yt.SUBGROUP_MIN = "subgroupMin";
yt.SUBGROUP_MAX = "subgroupMax";
yt.SUBGROUP_ALL = "subgroupAll";
yt.SUBGROUP_ANY = "subgroupAny";
yt.SUBGROUP_BROADCAST_FIRST = "subgroupBroadcastFirst";
yt.QUAD_SWAP_X = "quadSwapX";
yt.QUAD_SWAP_Y = "quadSwapY";
yt.QUAD_SWAP_DIAGONAL = "quadSwapDiagonal";
yt.SUBGROUP_BROADCAST = "subgroupBroadcast";
yt.SUBGROUP_SHUFFLE = "subgroupShuffle";
yt.SUBGROUP_SHUFFLE_XOR = "subgroupShuffleXor";
yt.SUBGROUP_SHUFFLE_UP = "subgroupShuffleUp";
yt.SUBGROUP_SHUFFLE_DOWN = "subgroupShuffleDown";
yt.QUAD_BROADCAST = "quadBroadcast";
let sh;
function Cd(i) {
  sh = sh || /* @__PURE__ */ new WeakMap();
  let e = sh.get(i);
  return e === void 0 && sh.set(i, e = {}), e;
}
function Vg(i) {
  const e = Cd(i);
  return e.shadowMatrix || (e.shadowMatrix = je("mat4").setGroup(Xe).onRenderUpdate((t) => ((i.castShadow !== !0 || t.renderer.shadowMap.enabled === !1) && (i.shadow.camera.coordinateSystem !== t.camera.coordinateSystem && (i.shadow.camera.coordinateSystem = t.camera.coordinateSystem, i.shadow.camera.updateProjectionMatrix()), i.shadow.updateMatrices(i)), i.shadow.matrix)));
}
function ZO(i, e = pl) {
  const t = Vg(i).mul(e);
  return t.xyz.div(t.w);
}
function JS(i) {
  const e = Cd(i);
  return e.position || (e.position = je(new P()).setGroup(Xe).onRenderUpdate((t, n) => n.value.setFromMatrixPosition(i.matrixWorld)));
}
function QO(i) {
  const e = Cd(i);
  return e.targetPosition || (e.targetPosition = je(new P()).setGroup(Xe).onRenderUpdate((t, n) => n.value.setFromMatrixPosition(i.target.matrixWorld)));
}
function eT(i) {
  const e = Cd(i);
  return e.viewPosition || (e.viewPosition = je(new P()).setGroup(Xe).onRenderUpdate(({ camera: t }, n) => {
    n.value = n.value || new P(), n.value.setFromMatrixPosition(i.matrixWorld), n.value.applyMatrix4(t.matrixWorldInverse);
  }));
}
const tT = (i) => fs.transformDirection(JS(i).sub(QO(i))), JO = (i) => i.sort((e, t) => e.id - t.id), ek = (i, e) => {
  for (const t of e)
    if (t.isAnalyticLightNode && t.light.id === i)
      return t;
  return null;
}, tp = /* @__PURE__ */ new WeakMap(), ec = [];
class nT extends Fe {
  static get type() {
    return "LightsNode";
  }
  /**
   * Constructs a new lights node.
   */
  constructor() {
    super("vec3"), this.totalDiffuseNode = Vs("vec3", "totalDiffuse"), this.totalSpecularNode = Vs("vec3", "totalSpecular"), this.outgoingLightNode = Vs("vec3", "outgoingLight"), this._lights = [], this._lightNodes = null, this._lightNodesHash = null, this.global = !0;
  }
  /**
   * Overwrites the default {@link Node#customCacheKey} implementation by including
   * light data into the cache key.
   *
   * @return {number} The custom cache key.
   */
  customCacheKey() {
    const e = this._lights;
    for (let n = 0; n < e.length; n++) {
      const r = e[n];
      if (ec.push(r.id), ec.push(r.castShadow ? 1 : 0), r.isSpotLight === !0) {
        const s = r.map !== null ? r.map.id : -1, a = r.colorNode ? r.colorNode.getCacheKey() : -1;
        ec.push(s, a);
      }
    }
    const t = ou(ec);
    return ec.length = 0, t;
  }
  /**
   * Computes a hash value for identifying the current light nodes setup.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {string} The computed hash.
   */
  getHash(e) {
    if (this._lightNodesHash === null) {
      this._lightNodes === null && this.setupLightsNode(e);
      const t = [];
      for (const n of this._lightNodes)
        t.push(n.getHash());
      this._lightNodesHash = "lights-" + t.join(",");
    }
    return this._lightNodesHash;
  }
  analyze(e) {
    const t = e.getNodeProperties(this);
    for (const n of t.nodes)
      n.build(e);
    t.outputNode.build(e);
  }
  /**
   * Creates lighting nodes for each scene light. This makes it possible to further
   * process lights in the node system.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   */
  setupLightsNode(e) {
    const t = [], n = this._lightNodes, r = JO(this._lights), s = e.renderer.library;
    for (const a of r)
      if (a.isNode)
        t.push(Le(a));
      else {
        let o = null;
        if (n !== null && (o = ek(a.id, n)), o === null) {
          const l = s.getLightNodeClass(a.constructor);
          if (l === null) {
            oe(`LightsNode.setupNodeLights: Light node not found for ${a.constructor.name}`);
            continue;
          }
          let c = null;
          tp.has(a) ? c = tp.get(a) : (c = new l(a), tp.set(a, c)), t.push(c);
        }
      }
    this._lightNodes = t;
  }
  /**
   * Sets up a direct light in the lighting model.
   *
   * @param {Object} builder - The builder object containing the context and stack.
   * @param {Object} lightNode - The light node.
   * @param {Object} lightData - The light object containing color and direction properties.
   */
  setupDirectLight(e, t, n) {
    const { lightingModel: r, reflectedLight: s } = e.context;
    r.direct({
      ...n,
      lightNode: t,
      reflectedLight: s
    }, e);
  }
  setupDirectRectAreaLight(e, t, n) {
    const { lightingModel: r, reflectedLight: s } = e.context;
    r.directRectArea({
      ...n,
      lightNode: t,
      reflectedLight: s
    }, e);
  }
  /**
   * Setups the internal lights by building all respective
   * light nodes.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @param {Array<LightingNode>} lightNodes - An array of lighting nodes.
   */
  setupLights(e, t) {
    for (const n of t)
      n.build(e);
  }
  getLightNodes(e) {
    return this._lightNodes === null && this.setupLightsNode(e), this._lightNodes;
  }
  /**
   * The implementation makes sure that for each light in the scene
   * there is a corresponding light node. By building the light nodes
   * and evaluating the lighting model the outgoing light is computed.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {Node<vec3>} A node representing the outgoing light.
   */
  setup(e) {
    const t = e.lightsNode;
    e.lightsNode = this;
    let n = this.outgoingLightNode;
    const r = e.context, s = r.lightingModel, a = e.getNodeProperties(this);
    if (s) {
      const { totalDiffuseNode: o, totalSpecularNode: l } = this;
      r.outgoingLight = n;
      const c = e.addStack();
      a.nodes = c.nodes, s.start(e);
      const { backdrop: u, backdropAlpha: h } = r, { directDiffuse: d, directSpecular: f, indirectDiffuse: p, indirectSpecular: _ } = r.reflectedLight;
      let g = d.add(p);
      u !== null && (h !== null ? g = Y(h.mix(g, u)) : g = Y(u)), o.assign(g), l.assign(f.add(_)), n.assign(o.add(l)), s.finish(e), n = n.bypass(e.removeStack());
    } else
      a.nodes = [];
    return e.lightsNode = t, n;
  }
  /**
   * Configures this node with an array of lights.
   *
   * @param {Array<Light>} lights - An array of lights.
   * @return {LightsNode} A reference to this node.
   */
  setLights(e) {
    return this._lights = e, this._lightNodes = null, this._lightNodesHash = null, this;
  }
  /**
   * Returns an array of the scene's lights.
   *
   * @return {Array<Light>} The scene's lights.
   */
  getLights() {
    return this._lights;
  }
  /**
   * Whether the scene has lights or not.
   *
   * @type {boolean}
   */
  get hasLights() {
    return this._lights.length > 0;
  }
}
class tk extends Fe {
  static get type() {
    return "ShadowBaseNode";
  }
  /**
   * Constructs a new shadow base node.
   *
   * @param {Light} light - The shadow casting light.
   */
  constructor(e) {
    super(), this.light = e, this.updateBeforeType = it.RENDER, this.isShadowBaseNode = !0;
  }
  /**
   * Setups the shadow position node which is by default the predefined TSL node object `shadowPositionWorld`.
   *
   * @param {NodeBuilder} object - A configuration object that must at least hold a material reference.
   */
  setupShadowPosition({ context: e, material: t }) {
    iT.assign(t.receivedShadowPositionNode || e.shadowPositionWorld || pl);
  }
}
const iT = /* @__PURE__ */ Vs("vec3", "shadowPositionWorld");
function nk(i, e = {}) {
  return e.toneMapping = i.toneMapping, e.toneMappingExposure = i.toneMappingExposure, e.outputColorSpace = i.outputColorSpace, e.renderTarget = i.getRenderTarget(), e.activeCubeFace = i.getActiveCubeFace(), e.activeMipmapLevel = i.getActiveMipmapLevel(), e.renderObjectFunction = i.getRenderObjectFunction(), e.pixelRatio = i.getPixelRatio(), e.mrt = i.getMRT(), e.clearColor = i.getClearColor(e.clearColor || new He()), e.clearAlpha = i.getClearAlpha(), e.autoClear = i.autoClear, e.scissorTest = i.getScissorTest(), e;
}
function ik(i, e) {
  return e = nk(i, e), i.setMRT(null), i.setRenderObjectFunction(null), i.setClearColor(0, 1), i.autoClear = !0, e;
}
function rk(i, e) {
  i.toneMapping = e.toneMapping, i.toneMappingExposure = e.toneMappingExposure, i.outputColorSpace = e.outputColorSpace, i.setRenderTarget(e.renderTarget, e.activeCubeFace, e.activeMipmapLevel), i.setRenderObjectFunction(e.renderObjectFunction), i.setPixelRatio(e.pixelRatio), i.setMRT(e.mrt), i.setClearColor(e.clearColor, e.clearAlpha), i.autoClear = e.autoClear, i.setScissorTest(e.scissorTest);
}
function sk(i, e = {}) {
  return e.background = i.background, e.backgroundNode = i.backgroundNode, e.overrideMaterial = i.overrideMaterial, e;
}
function ak(i, e) {
  return e = sk(i, e), i.background = null, i.backgroundNode = null, i.overrideMaterial = null, e;
}
function ok(i, e) {
  i.background = e.background, i.backgroundNode = e.backgroundNode, i.overrideMaterial = e.overrideMaterial;
}
function lk(i, e, t) {
  return t = ik(i, t), t = ak(e, t), t;
}
function ck(i, e, t) {
  rk(i, t), ok(e, t);
}
const Yh = /* @__PURE__ */ new WeakMap(), uk = /* @__PURE__ */ ee(({ depthTexture: i, shadowCoord: e, depthLayer: t }) => {
  let n = qt(i, e.xy).setName("t_basic");
  return i.isArrayTexture && (n = n.depth(t)), n.compare(e.z);
}), hk = /* @__PURE__ */ ee(({ depthTexture: i, shadowCoord: e, shadow: t, depthLayer: n }) => {
  const r = (u, h) => {
    let d = qt(i, u);
    return i.isArrayTexture && (d = d.depth(n)), d.compare(h);
  }, s = Qt("mapSize", "vec2", t).setGroup(Xe), a = Qt("radius", "float", t).setGroup(Xe), o = Pe(1).div(s), l = a.mul(o.x), c = QS(Nl.xy).mul(6.28318530718);
  return _i(
    r(e.xy.add(yr(0, 5, c).mul(l)), e.z),
    r(e.xy.add(yr(1, 5, c).mul(l)), e.z),
    r(e.xy.add(yr(2, 5, c).mul(l)), e.z),
    r(e.xy.add(yr(3, 5, c).mul(l)), e.z),
    r(e.xy.add(yr(4, 5, c).mul(l)), e.z)
  ).mul(1 / 5);
}), dk = /* @__PURE__ */ ee(({ depthTexture: i, shadowCoord: e, shadow: t, depthLayer: n }) => {
  const r = (h, d) => {
    let f = qt(i, h);
    return i.isArrayTexture && (f = f.depth(n)), f.compare(d);
  }, s = Qt("mapSize", "vec2", t).setGroup(Xe), a = Pe(1).div(s), o = a.x, l = a.y, c = e.xy, u = Pr(c.mul(s).add(0.5));
  return c.subAssign(u.mul(a)), _i(
    r(c, e.z),
    r(c.add(Pe(o, 0)), e.z),
    r(c.add(Pe(0, l)), e.z),
    r(c.add(a), e.z),
    Lt(
      r(c.add(Pe(o.negate(), 0)), e.z),
      r(c.add(Pe(o.mul(2), 0)), e.z),
      u.x
    ),
    Lt(
      r(c.add(Pe(o.negate(), l)), e.z),
      r(c.add(Pe(o.mul(2), l)), e.z),
      u.x
    ),
    Lt(
      r(c.add(Pe(0, l.negate())), e.z),
      r(c.add(Pe(0, l.mul(2))), e.z),
      u.y
    ),
    Lt(
      r(c.add(Pe(o, l.negate())), e.z),
      r(c.add(Pe(o, l.mul(2))), e.z),
      u.y
    ),
    Lt(
      Lt(
        r(c.add(Pe(o.negate(), l.negate())), e.z),
        r(c.add(Pe(o.mul(2), l.negate())), e.z),
        u.x
      ),
      Lt(
        r(c.add(Pe(o.negate(), l.mul(2))), e.z),
        r(c.add(Pe(o.mul(2), l.mul(2))), e.z),
        u.x
      ),
      u.y
    )
  ).mul(1 / 9);
}), fk = /* @__PURE__ */ ee(({ depthTexture: i, shadowCoord: e, depthLayer: t }, n) => {
  let r = qt(i).sample(e.xy);
  i.isArrayTexture && (r = r.depth(t)), r = r.rg;
  const s = r.x, a = kn(1e-7, r.y.mul(r.y)), o = n.renderer.reversedDepthBuffer ? qc(s, e.z) : qc(e.z, s), l = K(1).toVar();
  return Bt(o.notEqual(1), () => {
    const c = e.z.sub(s);
    let u = a.div(a.add(c.mul(c)));
    u = $s(ui(u, 0.3).div(0.65)), l.assign(kn(o, u));
  }), l;
}), pk = (i) => {
  let e = Yh.get(i);
  return e === void 0 && (e = new dn(), e.colorNode = et(0, 0, 0, 1), e.isShadowPassMaterial = !0, e.name = "ShadowMaterial", e.blending = Nn, e.fog = !1, Yh.set(i, e)), e;
}, mk = (i) => {
  const e = Yh.get(i);
  e !== void 0 && (e.dispose(), Yh.delete(i));
}, $x = /* @__PURE__ */ new qs(), xo = [], gk = (i, e, t, n) => {
  xo[0] = i, xo[1] = e;
  let r = $x.get(xo);
  return (r === void 0 || r.shadowType !== t || r.useVelocity !== n) && (r = (s, a, o, l, c, u, ...h) => {
    (s.castShadow === !0 || s.receiveShadow && t === br) && (n && (yb(s).useVelocity = !0), s.onBeforeShadow(i, s, o, e.camera, l, a.overrideMaterial, u), i.renderObject(s, a, o, l, c, u, ...h), s.onAfterShadow(i, s, o, e.camera, l, a.overrideMaterial, u));
  }, r.shadowType = t, r.useVelocity = n, $x.set(xo, r)), xo[0] = null, xo[1] = null, r;
}, _k = /* @__PURE__ */ ee(({ samples: i, radius: e, size: t, shadowPass: n, depthLayer: r }) => {
  const s = K(0).toVar("meanVertical"), a = K(0).toVar("squareMeanVertical"), o = i.lessThanEqual(K(1)).select(K(0), K(2).div(i.sub(1))), l = i.lessThanEqual(K(1)).select(K(0), K(-1));
  Ui({ start: Kt(0), end: Kt(i), type: "int", condition: "<" }, ({ i: u }) => {
    const h = l.add(K(u).mul(o));
    let d = n.sample(_i(Nl.xy, Pe(0, h).mul(e)).div(t));
    n.value.isArrayTexture && (d = d.depth(r)), d = d.x, s.addAssign(d), a.addAssign(d.mul(d));
  }), s.divAssign(i), a.divAssign(i);
  const c = zs(a.sub(s.mul(s)).max(0));
  return Pe(s, c);
}), xk = /* @__PURE__ */ ee(({ samples: i, radius: e, size: t, shadowPass: n, depthLayer: r }) => {
  const s = K(0).toVar("meanHorizontal"), a = K(0).toVar("squareMeanHorizontal"), o = i.lessThanEqual(K(1)).select(K(0), K(2).div(i.sub(1))), l = i.lessThanEqual(K(1)).select(K(0), K(-1));
  Ui({ start: Kt(0), end: Kt(i), type: "int", condition: "<" }, ({ i: u }) => {
    const h = l.add(K(u).mul(o));
    let d = n.sample(_i(Nl.xy, Pe(h, 0).mul(e)).div(t));
    n.value.isArrayTexture && (d = d.depth(r)), s.addAssign(d.x), a.addAssign(_i(d.y.mul(d.y), d.x.mul(d.x)));
  }), s.divAssign(i), a.divAssign(i);
  const c = zs(a.sub(s.mul(s)).max(0));
  return Pe(s, c);
}), vk = [uk, hk, dk, fk];
let np;
const ah = /* @__PURE__ */ new kg();
class rT extends tk {
  static get type() {
    return "ShadowNode";
  }
  /**
   * Constructs a new shadow node.
   *
   * @param {Light} light - The shadow casting light.
   * @param {?LightShadow} [shadow=null] - An optional light shadow.
   */
  constructor(e, t = null) {
    super(e), this.shadow = t || e.shadow, this.shadowMap = null, this.vsmShadowMapVertical = null, this.vsmShadowMapHorizontal = null, this.vsmMaterialVertical = null, this.vsmMaterialHorizontal = null, this._node = null, this._currentShadowType = null, this._cameraFrameId = /* @__PURE__ */ new WeakMap(), this.isShadowNode = !0, this.depthLayer = 0;
  }
  /**
   * Setups the shadow filtering.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @param {Object} inputs - A configuration object that defines the shadow filtering.
   * @param {Function} inputs.filterFn - This function defines the filtering type of the shadow map e.g. PCF.
   * @param {DepthTexture} inputs.depthTexture - A reference to the shadow map's texture data.
   * @param {Node<vec3>} inputs.shadowCoord - Shadow coordinates which are used to sample from the shadow map.
   * @param {LightShadow} inputs.shadow - The light shadow.
   * @return {Node<float>} The result node of the shadow filtering.
   */
  setupShadowFilter(e, { filterFn: t, depthTexture: n, shadowCoord: r, shadow: s, depthLayer: a }) {
    const o = r.x.greaterThanEqual(0).and(r.x.lessThanEqual(1)).and(r.y.greaterThanEqual(0)).and(r.y.lessThanEqual(1)).and(r.z.lessThanEqual(1)), l = t({ depthTexture: n, shadowCoord: r, shadow: s, depthLayer: a });
    return o.select(l, K(1));
  }
  /**
   * Setups the shadow coordinates.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @param {Node<vec3>} shadowPosition - A node representing the shadow position.
   * @return {Node<vec3>} The shadow coordinates.
   */
  setupShadowCoord(e, t) {
    const { shadow: n } = this, { renderer: r } = e, s = n.biasNode || Qt("bias", "float", n).setGroup(Xe);
    let a = t, o;
    if (n.camera.isOrthographicCamera || r.logarithmicDepthBuffer !== !0)
      a = a.xyz.div(a.w), o = a.z;
    else {
      const l = a.w;
      a = a.xy.div(l);
      const c = Qt("near", "float", n.camera).setGroup(Xe), u = Qt("far", "float", n.camera).setGroup(Xe);
      o = RS(l.negate(), c, u);
    }
    return a = Y(
      a.x,
      a.y.oneMinus(),
      // follow webgpu standards
      r.reversedDepthBuffer ? o.sub(s) : o.add(s)
    ), a;
  }
  /**
   * Returns the shadow filtering function for the given shadow type.
   *
   * @param {number} type - The shadow type.
   * @return {Function} The filtering function.
   */
  getShadowFilterFn(e) {
    return vk[e];
  }
  setupRenderTarget(e, t) {
    const n = new oi(e.mapSize.width, e.mapSize.height);
    n.name = "ShadowDepthTexture", n.compareFunction = t.renderer.reversedDepthBuffer ? us : Xs;
    const r = t.createRenderTarget(e.mapSize.width, e.mapSize.height);
    return r.texture.name = "ShadowMap", r.texture.type = e.mapType, r.depthTexture = n, { shadowMap: r, depthTexture: n };
  }
  /**
   * Setups the shadow output node.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {Node<vec3>} The shadow output node.
   */
  setupShadow(e) {
    const { renderer: t, camera: n } = e, { light: r, shadow: s } = this, { depthTexture: a, shadowMap: o } = this.setupRenderTarget(s, e), l = t.shadowMap.type, c = t.hasCompatibility(rs.TEXTURE_COMPARE);
    if ((l === Ro || l === zv) && c ? (a.minFilter = Ot, a.magFilter = Ot) : (a.minFilter = Tt, a.magFilter = Tt), s.camera.coordinateSystem = n.coordinateSystem, s.camera.updateProjectionMatrix(), l === br && s.isPointLightShadow !== !0) {
      a.compareFunction = null, o.depth > 1 ? (o._vsmShadowMapVertical || (o._vsmShadowMapVertical = e.createRenderTarget(s.mapSize.width, s.mapSize.height, { format: ri, type: nn, depth: o.depth, depthBuffer: !1 }), o._vsmShadowMapVertical.texture.name = "VSMVertical"), this.vsmShadowMapVertical = o._vsmShadowMapVertical, o._vsmShadowMapHorizontal || (o._vsmShadowMapHorizontal = e.createRenderTarget(s.mapSize.width, s.mapSize.height, { format: ri, type: nn, depth: o.depth, depthBuffer: !1 }), o._vsmShadowMapHorizontal.texture.name = "VSMHorizontal"), this.vsmShadowMapHorizontal = o._vsmShadowMapHorizontal) : (this.vsmShadowMapVertical = e.createRenderTarget(s.mapSize.width, s.mapSize.height, { format: ri, type: nn, depthBuffer: !1 }), this.vsmShadowMapHorizontal = e.createRenderTarget(s.mapSize.width, s.mapSize.height, { format: ri, type: nn, depthBuffer: !1 }));
      let b = qt(a);
      a.isArrayTexture && (b = b.depth(this.depthLayer));
      let T = qt(this.vsmShadowMapVertical.texture);
      a.isArrayTexture && (T = T.depth(this.depthLayer));
      const S = Qt("blurSamples", "float", s).setGroup(Xe), E = Qt("radius", "float", s).setGroup(Xe), v = Qt("mapSize", "vec2", s).setGroup(Xe);
      let M = this.vsmMaterialVertical || (this.vsmMaterialVertical = new dn());
      M.fragmentNode = _k({ samples: S, radius: E, size: v, shadowPass: b, depthLayer: this.depthLayer }).context(e.getSharedContext()), M.name = "VSMVertical", M = this.vsmMaterialHorizontal || (this.vsmMaterialHorizontal = new dn()), M.fragmentNode = xk({ samples: S, radius: E, size: v, shadowPass: T, depthLayer: this.depthLayer }).context(e.getSharedContext()), M.name = "VSMHorizontal";
    }
    const u = Qt("intensity", "float", s).setGroup(Xe), h = Qt("normalBias", "float", s).setGroup(Xe), d = Vg(r).mul(iT.add(Pl.mul(h))), f = this.setupShadowCoord(e, d), p = s.filterNode || this.getShadowFilterFn(t.shadowMap.type) || null;
    if (p === null)
      throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet.");
    const _ = l === br && s.isPointLightShadow !== !0 ? this.vsmShadowMapHorizontal.texture : a, g = this.setupShadowFilter(e, { filterFn: p, shadowTexture: o.texture, depthTexture: _, shadowCoord: f, shadow: s, depthLayer: this.depthLayer });
    let m;
    t.shadowMap.transmitted === !0 && (o.texture.isCubeTexture ? m = di(o.texture, f.xyz) : (m = qt(o.texture, f), a.isArrayTexture && (m = m.depth(this.depthLayer))));
    let x;
    m ? x = Lt(1, g.rgb.mix(m, 1), u.mul(m.a)).toVar() : x = Lt(1, g, u).toVar(), this.shadowMap = o, this.shadow.map = o;
    const y = `${this.light.type} Shadow [ ${this.light.name || "ID: " + this.light.id} ]`;
    return m && x.toInspector(`${y} / Color`, () => this.shadowMap.texture.isCubeTexture ? di(this.shadowMap.texture) : qt(this.shadowMap.texture)), x.toInspector(`${y} / Depth`, () => this.shadowMap.texture.isCubeTexture ? di(this.shadowMap.texture).r.oneMinus() : Fi(this.shadowMap.depthTexture, Al().mul(Bo(qt(this.shadowMap.depthTexture)))).r.oneMinus());
  }
  /**
   * The implementation performs the setup of the output node. An output is only
   * produces if shadow mapping is globally enabled in the renderer.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {ShaderCallNodeInternal} The output node.
   */
  setup(e) {
    if (e.renderer.shadowMap.enabled !== !1)
      return ee(() => {
        const t = e.renderer.shadowMap.type;
        this._currentShadowType !== t && (this._reset(), this._node = null);
        let n = this._node;
        return this.setupShadowPosition(e), n === null && (this._node = n = this.setupShadow(e), this._currentShadowType = t), e.material.receivedShadowNode && (n = e.material.receivedShadowNode(n)), n;
      })();
  }
  /**
   * Renders the shadow. The logic of this function could be included
   * into {@link ShadowNode#updateShadow} however more specialized shadow
   * nodes might require a custom shadow map rendering. By having a
   * dedicated method, it's easier to overwrite the default behavior.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  renderShadow(e) {
    const { shadow: t, shadowMap: n, light: r } = this, { renderer: s, scene: a } = e;
    t.updateMatrices(r), n.setSize(t.mapSize.width, t.mapSize.height, n.depth);
    const o = a.name;
    a.name = `Shadow Map [ ${r.name || "ID: " + r.id} ]`, s.render(a, t.camera), a.name = o;
  }
  /**
   * Updates the shadow.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  updateShadow(e) {
    const { shadowMap: t, light: n, shadow: r } = this, { renderer: s, scene: a, camera: o } = e, l = s.shadowMap.type, c = t.depthTexture.version;
    this._depthVersionCached = c;
    const u = r.camera.layers.mask;
    r.camera.layers.mask & 4294967294 || (r.camera.layers.mask = o.layers.mask);
    const h = s.getRenderObjectFunction(), d = s.getMRT(), f = d ? d.has("velocity") : !1;
    np = lk(s, a, np), a.overrideMaterial = pk(n), s.setRenderObjectFunction(gk(s, r, l, f)), s.setClearColor(0, 0), s.setRenderTarget(t), this.renderShadow(e), s.setRenderObjectFunction(h), l === br && r.isPointLightShadow !== !0 && this.vsmPass(s), r.camera.layers.mask = u, ck(s, a, np);
  }
  /**
   * For VSM additional render passes are required.
   *
   * @param {Renderer} renderer - A reference to the current renderer.
   */
  vsmPass(e) {
    const { shadow: t } = this, n = this.shadowMap.depth;
    this.vsmShadowMapVertical.setSize(t.mapSize.width, t.mapSize.height, n), this.vsmShadowMapHorizontal.setSize(t.mapSize.width, t.mapSize.height, n), e.setRenderTarget(this.vsmShadowMapVertical), ah.material = this.vsmMaterialVertical, ah.render(e), e.setRenderTarget(this.vsmShadowMapHorizontal), ah.material = this.vsmMaterialHorizontal, ah.render(e);
  }
  /**
   * Frees the internal resources of this shadow node.
   */
  dispose() {
    this._reset(), super.dispose();
  }
  /**
   * Resets the resouce state of this shadow node.
   *
   * @private
   */
  _reset() {
    this._currentShadowType = null, mk(this.light), this.shadowMap && (this.shadowMap.dispose(), this.shadowMap = null), this.vsmShadowMapVertical !== null && (this.vsmShadowMapVertical.dispose(), this.vsmShadowMapVertical = null, this.vsmMaterialVertical.dispose(), this.vsmMaterialVertical = null), this.vsmShadowMapHorizontal !== null && (this.vsmShadowMapHorizontal.dispose(), this.vsmShadowMapHorizontal = null, this.vsmMaterialHorizontal.dispose(), this.vsmMaterialHorizontal = null);
  }
  /**
   * The implementation performs the update of the shadow map if necessary.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  updateBefore(e) {
    const { shadow: t } = this;
    let n = t.needsUpdate || t.autoUpdate;
    n && (this._cameraFrameId[e.camera] === e.frameId && (n = !1), this._cameraFrameId[e.camera] = e.frameId), n && (this.updateShadow(e), this.shadowMap.depthTexture.version === this._depthVersionCached && (t.needsUpdate = !1));
  }
}
const yk = (i, e) => new rT(i, e), bk = /* @__PURE__ */ new He(), Wx = /* @__PURE__ */ new pt(), tc = /* @__PURE__ */ new P(), ip = /* @__PURE__ */ new P(), Sk = [
  /* @__PURE__ */ new P(1, 0, 0),
  /* @__PURE__ */ new P(-1, 0, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 1, 0),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, 0, -1)
], Tk = [
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 0, -1),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0)
], Mk = [
  /* @__PURE__ */ new P(1, 0, 0),
  /* @__PURE__ */ new P(-1, 0, 0),
  /* @__PURE__ */ new P(0, 1, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, 0, -1)
], Ek = [
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, 0, 1),
  /* @__PURE__ */ new P(0, 0, -1),
  /* @__PURE__ */ new P(0, -1, 0),
  /* @__PURE__ */ new P(0, -1, 0)
], wk = /* @__PURE__ */ ee(({ depthTexture: i, bd3D: e, dp: t }) => di(i, e).compare(t)), Ak = /* @__PURE__ */ ee(({ depthTexture: i, bd3D: e, dp: t, shadow: n }) => {
  const r = Qt("radius", "float", n).setGroup(Xe), s = Qt("mapSize", "vec2", n).setGroup(Xe), a = r.div(s.x), o = Ai(e), l = Ar(ka(e, o.x.greaterThan(o.z).select(Y(0, 1, 0), Y(1, 0, 0)))), c = ka(e, l), u = QS(Nl.xy).mul(6.28318530718), h = yr(0, 5, u), d = yr(1, 5, u), f = yr(2, 5, u), p = yr(3, 5, u), _ = yr(4, 5, u);
  return di(i, e.add(l.mul(h.x).add(c.mul(h.y)).mul(a))).compare(t).add(di(i, e.add(l.mul(d.x).add(c.mul(d.y)).mul(a))).compare(t)).add(di(i, e.add(l.mul(f.x).add(c.mul(f.y)).mul(a))).compare(t)).add(di(i, e.add(l.mul(p.x).add(c.mul(p.y)).mul(a))).compare(t)).add(di(i, e.add(l.mul(_.x).add(c.mul(_.y)).mul(a))).compare(t)).mul(1 / 5);
}), Rk = /* @__PURE__ */ ee(({ filterFn: i, depthTexture: e, shadowCoord: t, shadow: n }, r) => {
  const s = t.xyz.toConst(), a = s.abs().toConst(), o = a.x.max(a.y).max(a.z), l = je("float").setGroup(Xe).onRenderUpdate(() => n.camera.near), c = je("float").setGroup(Xe).onRenderUpdate(() => n.camera.far), u = Qt("bias", "float", n).setGroup(Xe), h = K(1).toVar();
  return Bt(o.sub(c).lessThanEqual(0).and(o.sub(l).greaterThanEqual(0)), () => {
    let d;
    r.renderer.reversedDepthBuffer ? (d = p3(o.negate(), l, c), d.subAssign(u)) : (d = wS(o.negate(), l, c), d.addAssign(u));
    const f = s.normalize();
    h.assign(i({ depthTexture: e, bd3D: f, dp: d, shadow: n }));
  }), h;
});
class Ck extends rT {
  static get type() {
    return "PointShadowNode";
  }
  /**
   * Constructs a new point shadow node.
   *
   * @param {PointLight} light - The shadow casting point light.
   * @param {?PointLightShadow} [shadow=null] - An optional point light shadow.
   */
  constructor(e, t = null) {
    super(e, t);
  }
  /**
   * Overwrites the default implementation to return point light shadow specific
   * filtering functions.
   *
   * @param {number} type - The shadow type.
   * @return {Function} The filtering function.
   */
  getShadowFilterFn(e) {
    return e === aM ? wk : Ak;
  }
  /**
   * Overwrites the default implementation so the unaltered shadow position is used.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @param {Node<vec3>} shadowPosition - A node representing the shadow position.
   * @return {Node<vec3>} The shadow coordinates.
   */
  setupShadowCoord(e, t) {
    return t;
  }
  /**
   * Overwrites the default implementation to only use point light specific
   * shadow filter functions.
   *
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @param {Object} inputs - A configuration object that defines the shadow filtering.
   * @param {Function} inputs.filterFn - This function defines the filtering type of the shadow map e.g. PCF.
   * @param {DepthTexture} inputs.depthTexture - A reference to the shadow map's depth texture.
   * @param {Node<vec3>} inputs.shadowCoord - Shadow coordinates which are used to sample from the shadow map.
   * @param {LightShadow} inputs.shadow - The light shadow.
   * @return {Node<float>} The result node of the shadow filtering.
   */
  setupShadowFilter(e, { filterFn: t, depthTexture: n, shadowCoord: r, shadow: s }) {
    return Rk({ filterFn: t, depthTexture: n, shadowCoord: r, shadow: s });
  }
  /**
   * Overwrites the default implementation to create a CubeRenderTarget with CubeDepthTexture.
   *
   * @param {LightShadow} shadow - The light shadow object.
   * @param {NodeBuilder} builder - A reference to the current node builder.
   * @return {Object} An object containing the shadow map and depth texture.
   */
  setupRenderTarget(e, t) {
    const n = new iy(e.mapSize.width);
    n.name = "PointShadowDepthTexture", n.compareFunction = t.renderer.reversedDepthBuffer ? us : Xs;
    const r = t.createCubeRenderTarget(e.mapSize.width);
    return r.texture.name = "PointShadowMap", r.depthTexture = n, { shadowMap: r, depthTexture: n };
  }
  /**
   * Overwrites the default implementation with point light specific
   * rendering code.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  renderShadow(e) {
    const { shadow: t, shadowMap: n, light: r } = this, { renderer: s, scene: a } = e, o = t.camera, l = t.matrix, c = s.coordinateSystem === Cr, u = c ? Sk : Mk, h = c ? Tk : Ek;
    n.setSize(t.mapSize.width, t.mapSize.width);
    const d = s.autoClear, f = s.getClearColor(bk), p = s.getClearAlpha();
    s.autoClear = !1, s.setClearColor(t.clearColor, t.clearAlpha);
    for (let _ = 0; _ < 6; _++) {
      s.setRenderTarget(n, _), s.clear();
      const g = r.distance || o.far;
      g !== o.far && (o.far = g, o.updateProjectionMatrix()), tc.setFromMatrixPosition(r.matrixWorld), o.position.copy(tc), ip.copy(o.position), ip.add(u[_]), o.up.copy(h[_]), o.lookAt(ip), o.updateMatrixWorld(), l.makeTranslation(-tc.x, -tc.y, -tc.z), Wx.multiplyMatrices(o.projectionMatrix, o.matrixWorldInverse), t._frustum.setFromProjectionMatrix(Wx, o.coordinateSystem, o.reversedDepth);
      const m = a.name;
      a.name = `Point Light Shadow [ ${r.name || "ID: " + r.id} ] - Face ${_ + 1}`, s.render(a, o), a.name = m;
    }
    s.autoClear = d, s.setClearColor(f, p);
  }
}
const Nk = (i, e) => new Ck(i, e);
class ja extends Dl {
  static get type() {
    return "AnalyticLightNode";
  }
  /**
   * Constructs a new analytic light node.
   *
   * @param {?Light} [light=null] - The light source.
   */
  constructor(e = null) {
    super(), this.light = e, this.color = new He(), this.colorNode = e && e.colorNode || je(this.color).setGroup(Xe), this.baseColorNode = null, this.shadowNode = null, this.shadowColorNode = null, this.isAnalyticLightNode = !0, this.updateType = it.FRAME, e && e.shadow && (this._shadowDisposeListener = () => {
      this.disposeShadow();
    }, e.addEventListener("dispose", this._shadowDisposeListener));
  }
  dispose() {
    this._shadowDisposeListener && this.light.removeEventListener("dispose", this._shadowDisposeListener), super.dispose();
  }
  /**
   * Frees internal resources related to shadows.
   */
  disposeShadow() {
    this.shadowNode !== null && (this.shadowNode.dispose(), this.shadowNode = null), this.shadowColorNode = null, this.baseColorNode !== null && (this.colorNode = this.baseColorNode, this.baseColorNode = null);
  }
  getHash() {
    return this.light.uuid;
  }
  /**
   * Returns a node representing a direction vector which points from the current
   * position in view space to the light's position in view space.
   *
   * @param {NodeBuilder} builder - The builder object used for setting up the light.
   * @return {Node<vec3>} The light vector node.
   */
  getLightVector(e) {
    return eT(this.light).sub(e.context.positionView || hn);
  }
  /**
   * Sets up the direct lighting for the analytic light node.
   *
   * @abstract
   * @param {NodeBuilder} builder - The builder object used for setting up the light.
   * @return {Object|undefined} The direct light data (color and direction).
   */
  setupDirect() {
  }
  /**
   * Sets up the direct rect area lighting for the analytic light node.
   *
   * @abstract
   * @param {NodeBuilder} builder - The builder object used for setting up the light.
   * @return {Object|undefined} The direct rect area light data.
   */
  setupDirectRectArea() {
  }
  /**
   * Setups the shadow node for this light. The method exists so concrete light classes
   * can setup different types of shadow nodes.
   *
   * @return {ShadowNode} The created shadow node.
   */
  setupShadowNode() {
    return yk(this.light);
  }
  /**
   * Setups the shadow for this light. This method is only executed if the light
   * cast shadows and the current build object receives shadows. It incorporates
   * shadows into the lighting computation.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setupShadow(e) {
    const { renderer: t } = e;
    if (t.shadowMap.enabled === !1)
      return;
    let n = this.shadowColorNode;
    if (n === null) {
      const r = this.light.shadow.shadowNode;
      let s;
      r !== void 0 ? s = Le(r) : s = this.setupShadowNode(), this.shadowNode = s, this.shadowColorNode = n = this.colorNode.mul(s), this.baseColorNode = this.colorNode;
    }
    e.context.getShadow && (n = e.context.getShadow(this, e)), this.colorNode = n;
  }
  /**
   * Unlike most other nodes, lighting nodes do not return a output node in {@link Node#setup}.
   * The main purpose of lighting nodes is to configure the current {@link LightingModel} and/or
   * invocate the respective interface methods.
   *
   * @param {NodeBuilder} builder - The current node builder.
   */
  setup(e) {
    this.colorNode = this.baseColorNode || this.colorNode, this.light.castShadow ? e.object.receiveShadow && this.setupShadow(e) : this.shadowNode !== null && (this.shadowNode.dispose(), this.shadowNode = null, this.shadowColorNode = null);
    const t = this.setupDirect(e), n = this.setupDirectRectArea(e);
    t && e.lightsNode.setupDirectLight(e, this, t), n && e.lightsNode.setupDirectRectAreaLight(e, this, n);
  }
  /**
   * The update method is used to update light uniforms per frame.
   * Potentially overwritten in concrete light nodes to update light
   * specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update() {
    const { light: e } = this;
    this.color.copy(e.color).multiplyScalar(e.intensity);
  }
}
const sT = /* @__PURE__ */ ee(({ lightDistance: i, cutoffDistance: e, decayExponent: t }) => {
  const n = i.pow(t).max(0.01).reciprocal();
  return e.greaterThan(0).select(
    n.mul(i.div(e).pow4().oneMinus().clamp().pow2()),
    n
  );
}), Pk = ({ color: i, lightVector: e, cutoffDistance: t, decayExponent: n }) => {
  const r = e.normalize(), s = e.length(), a = sT({
    lightDistance: s,
    cutoffDistance: t,
    decayExponent: n
  }), o = i.mul(a);
  return { lightDirection: r, lightColor: o };
};
class Dk extends ja {
  static get type() {
    return "PointLightNode";
  }
  /**
   * Constructs a new point light node.
   *
   * @param {?PointLight} [light=null] - The point light source.
   */
  constructor(e = null) {
    super(e), this.cutoffDistanceNode = je(0).setGroup(Xe), this.decayExponentNode = je(2).setGroup(Xe);
  }
  /**
   * Overwritten to updated point light specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    const { light: t } = this;
    super.update(e), this.cutoffDistanceNode.value = t.distance, this.decayExponentNode.value = t.decay;
  }
  /**
   * Overwritten to setup point light specific shadow.
   *
   * @return {PointShadowNode}
   */
  setupShadowNode() {
    return Nk(this.light);
  }
  setupDirect(e) {
    return Pk({
      color: this.colorNode,
      lightVector: this.getLightVector(e),
      cutoffDistance: this.cutoffDistanceNode,
      decayExponent: this.decayExponentNode
    });
  }
}
ee(([i = Al()], { renderer: e, material: t }) => {
  const n = jb(i.mul(2).sub(1));
  let r;
  if (t.alphaToCoverage && e.currentSamples > 0) {
    const s = K(n.fwidth()).toVar();
    r = hs(s.oneMinus(), s.add(1), n).oneMinus();
  } else
    r = Ri(n.greaterThan(1), 0, 1);
  return r;
});
const Lk = /* @__PURE__ */ ee(([i, e]) => {
  const t = i.x, n = i.y, r = i.z;
  let s = e.element(0).mul(0.886227);
  return s = s.add(e.element(1).mul(2 * 0.511664).mul(n)), s = s.add(e.element(2).mul(2 * 0.511664).mul(r)), s = s.add(e.element(3).mul(2 * 0.511664).mul(t)), s = s.add(e.element(4).mul(2 * 0.429043).mul(t).mul(n)), s = s.add(e.element(5).mul(2 * 0.429043).mul(n).mul(r)), s = s.add(e.element(6).mul(r.mul(r).mul(0.743125).sub(0.247708))), s = s.add(e.element(7).mul(2 * 0.429043).mul(t).mul(r)), s = s.add(e.element(8).mul(0.429043).mul(at(t, t).sub(at(n, n)))), s;
}), ji = /* @__PURE__ */ new Og();
class Fk extends Ks {
  /**
   * Constructs a new background management component.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {Nodes} nodes - Renderer component for managing nodes related logic.
   */
  constructor(e, t) {
    super(), this.renderer = e, this.nodes = t;
  }
  /**
   * Updates the background for the given scene. Depending on how `Scene.background`
   * or `Scene.backgroundNode` are configured, this method might configure a simple clear
   * or add a mesh to the render list for rendering the background as a textured plane
   * or skybox.
   *
   * @param {Scene} scene - The scene.
   * @param {RenderList} renderList - The current render list.
   * @param {RenderContext} renderContext - The current render context.
   */
  update(e, t, n) {
    const r = this.renderer, s = this.nodes.getBackgroundNode(e) || e.background;
    let a = !1;
    if (s === null)
      r._clearColor.getRGB(ji), ji.a = r._clearColor.a;
    else if (s.isColor === !0)
      s.getRGB(ji), ji.a = 1, a = !0;
    else if (s.isNode === !0) {
      const l = this.get(e), c = s;
      ji.copy(r._clearColor);
      let u = l.backgroundMesh;
      if (u === void 0) {
        let y = function() {
          s.removeEventListener("dispose", y), u.material.dispose(), u.geometry.dispose();
        };
        const d = et(c).mul(Vx).context({
          // @TODO: Add Texture2D support using node context
          getUV: () => DO.mul(GI),
          getTextureLevel: () => PO
        }), f = Tc.element(3).element(3).equal(1), p = Nr(1, Tc.element(1).element(1)).mul(3), _ = f.select(Cn.mul(p), Cn), g = cu.mul(et(_, 0));
        let m = Tc.mul(et(g.xyz, 1));
        m = m.setZ(m.w);
        const x = new dn();
        x.name = "Background.material", x.side = Ft, x.depthTest = !1, x.depthWrite = !1, x.allowOverride = !1, x.fog = !1, x.lights = !1, x.vertexNode = m, x.colorNode = d, l.backgroundMeshNode = d, l.backgroundMesh = u = new _n(new su(1, 32, 32), x), u.frustumCulled = !1, u.name = "Background.mesh", s.addEventListener("dispose", y);
      }
      const h = c.getCacheKey();
      l.backgroundCacheKey !== h && (l.backgroundMeshNode.node = et(c).mul(Vx), l.backgroundMeshNode.needsUpdate = !0, u.material.needsUpdate = !0, l.backgroundCacheKey = h), t.unshift(u, u.geometry, u.material, 0, 0, null, null);
    } else
      le("Renderer: Unsupported background configuration.", s);
    const o = r.xr.getEnvironmentBlendMode();
    if (o === "additive" ? ji.set(0, 0, 0, 1) : o === "alpha-blend" && ji.set(0, 0, 0, 0), r.autoClear === !0 || a === !0) {
      const l = n.clearColorValue;
      l.r = ji.r, l.g = ji.g, l.b = ji.b, l.a = ji.a, (r.backend.isWebGLBackend === !0 || r.alpha === !0) && (l.r *= l.a, l.g *= l.a, l.b *= l.a), n.depthClearValue = r.getClearDepth(), n.stencilClearValue = r.getClearStencil(), n.clearColor = r.autoClearColor === !0, n.clearDepth = r.autoClearDepth === !0, n.clearStencil = r.autoClearStencil === !0;
    } else
      n.clearColor = !1, n.clearDepth = !1, n.clearStencil = !1;
  }
}
let Ik = 0;
class im {
  /**
   * Constructs a new bind group.
   *
   * @param {string} name - The bind group's name.
   * @param {Array<Binding>} bindings - An array of bindings.
   * @param {number} index - The group index.
   */
  constructor(e = "", t = [], n = 0) {
    this.name = e, this.bindings = t, this.index = n, this.id = Ik++;
  }
}
class Uk {
  /**
   * Constructs a new node builder state.
   *
   * @param {string} vertexShader - The native vertex shader code.
   * @param {string} fragmentShader - The native fragment shader code.
   * @param {string} computeShader - The native compute shader code.
   * @param {Array<NodeAttribute>} nodeAttributes - An array of node attributes.
   * @param {Array<BindGroup>} bindings - An array of bind groups.
   * @param {Array<Node>} updateNodes - An array of nodes that implement their `update()` method.
   * @param {Array<Node>} updateBeforeNodes - An array of nodes that implement their `updateBefore()` method.
   * @param {Array<Node>} updateAfterNodes - An array of nodes that implement their `updateAfter()` method.
   * @param {NodeMaterialObserver} observer - A node material observer.
   * @param {Array<Object>} transforms - An array with transform attribute objects. Only relevant when using compute shaders with WebGL 2.
   */
  constructor(e, t, n, r, s, a, o, l, c, u = []) {
    this.vertexShader = e, this.fragmentShader = t, this.computeShader = n, this.transforms = u, this.nodeAttributes = r, this.bindings = s, this.updateNodes = a, this.updateBeforeNodes = o, this.updateAfterNodes = l, this.observer = c, this.usedTimes = 0;
  }
  /**
   * This method is used to create a array of bind groups based
   * on the existing bind groups of this state. Shared groups are
   * not cloned.
   *
   * @return {Array<BindGroup>} A array of bind groups.
   */
  createBindings() {
    const e = [];
    for (const t of this.bindings)
      if (t.bindings[0].groupNode.shared !== !0) {
        const r = new im(t.name, [], t.index);
        e.push(r);
        for (const s of t.bindings)
          r.bindings.push(s.clone());
      } else
        e.push(t);
    return e;
  }
}
class qx {
  /**
   * Constructs a new node attribute.
   *
   * @param {string} name - The name of the attribute.
   * @param {string} type - The type of the attribute.
   * @param {?Node} node - An optional reference to the node.
   */
  constructor(e, t, n = null) {
    this.isNodeAttribute = !0, this.name = e, this.type = t, this.node = n;
  }
}
class Bk {
  /**
   * Constructs a new node uniform.
   *
   * @param {string} name - The name of the uniform.
   * @param {string} type - The type of the uniform.
   * @param {UniformNode} node - An reference to the node.
   */
  constructor(e, t, n) {
    this.isNodeUniform = !0, this.name = e, this.type = t, this.node = n;
  }
  /**
   * The value of the uniform node.
   *
   * @type {any}
   */
  get value() {
    return this.node.value;
  }
  set value(e) {
    this.node.value = e;
  }
  /**
   * The id of the uniform node.
   *
   * @type {number}
   */
  get id() {
    return this.node.id;
  }
  /**
   * The uniform node's group.
   *
   * @type {UniformGroupNode}
   */
  get groupNode() {
    return this.node.groupNode;
  }
}
class aT {
  /**
   * Constructs a new node variable.
   *
   * @param {string} name - The name of the variable.
   * @param {string} type - The type of the variable.
   * @param {boolean} [readOnly=false] - The read-only flag.
   * @param {?number} [count=null] - The size.
   */
  constructor(e, t, n = !1, r = null) {
    this.isNodeVar = !0, this.name = e, this.type = t, this.readOnly = n, this.count = r;
  }
}
class Ok extends aT {
  /**
   * Constructs a new node varying.
   *
   * @param {string} name - The name of the varying.
   * @param {string} type - The type of the varying.
   * @param {?string} interpolationType - The interpolation type of the varying.
   * @param {?string} interpolationSampling - The interpolation sampling type of the varying.
   */
  constructor(e, t, n = null, r = null) {
    super(e, t), this.needsInterpolation = !1, this.isNodeVarying = !0, this.interpolationType = n, this.interpolationSampling = r;
  }
}
class kk {
  /**
   * Constructs a new code node.
   *
   * @param {string} name - The name of the code.
   * @param {string} type - The node type.
   * @param {string} [code=''] - The native shader code.
   */
  constructor(e, t, n = "") {
    this.name = e, this.type = t, this.code = n, Object.defineProperty(this, "isNodeCode", { value: !0 });
  }
}
let Gk = 0;
class rp {
  /**
   * Constructs a new node cache.
   *
   * @param {?NodeCache} parent - A reference to a parent cache.
   */
  constructor(e = null) {
    this.id = Gk++, this.nodesData = /* @__PURE__ */ new WeakMap(), this.parent = e;
  }
  /**
   * Returns the data for the given node.
   *
   * @param {Node} node - The node.
   * @return {?Object} The data for the node.
   */
  getData(e) {
    let t = this.nodesData.get(e);
    return t === void 0 && this.parent !== null && (t = this.parent.getData(e)), t;
  }
  /**
   * Sets the data for a given node.
   *
   * @param {Node} node - The node.
   * @param {Object} data - The data that should be cached.
   */
  setData(e, t) {
    this.nodesData.set(e, t);
  }
}
class Vk {
  constructor(e, t) {
    this.name = e, this.members = t, this.output = !1;
  }
}
class Zs {
  /**
   * Constructs a new uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {any} value - The uniform's value.
   */
  constructor(e, t) {
    this.name = e, this.value = t, this.boundary = 0, this.itemSize = 0, this.offset = 0, this.index = -1;
  }
  /**
   * Sets the uniform's value.
   *
   * @param {any} value - The value to set.
   */
  setValue(e) {
    this.value = e;
  }
  /**
   * Returns the uniform's value.
   *
   * @return {any} The value.
   */
  getValue() {
    return this.value;
  }
}
class zk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {number} value - The uniform's value.
   */
  constructor(e, t = 0) {
    super(e, t), this.isNumberUniform = !0, this.boundary = 4, this.itemSize = 1;
  }
}
class Hk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Vector2} value - The uniform's value.
   */
  constructor(e, t = new de()) {
    super(e, t), this.isVector2Uniform = !0, this.boundary = 8, this.itemSize = 2;
  }
}
class $k extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Vector3} value - The uniform's value.
   */
  constructor(e, t = new P()) {
    super(e, t), this.isVector3Uniform = !0, this.boundary = 16, this.itemSize = 3;
  }
}
class Wk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Vector4} value - The uniform's value.
   */
  constructor(e, t = new rt()) {
    super(e, t), this.isVector4Uniform = !0, this.boundary = 16, this.itemSize = 4;
  }
}
class qk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Color} value - The uniform's value.
   */
  constructor(e, t = new He()) {
    super(e, t), this.isColorUniform = !0, this.boundary = 16, this.itemSize = 3;
  }
}
class Xk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Matrix2} value - The uniform's value.
   */
  constructor(e, t = new hd()) {
    super(e, t), this.isMatrix2Uniform = !0, this.boundary = 8, this.itemSize = 4;
  }
}
class jk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Matrix3} value - The uniform's value.
   */
  constructor(e, t = new nt()) {
    super(e, t), this.isMatrix3Uniform = !0, this.boundary = 48, this.itemSize = 12;
  }
}
class Yk extends Zs {
  /**
   * Constructs a new Number uniform.
   *
   * @param {string} name - The uniform's name.
   * @param {Matrix4} value - The uniform's value.
   */
  constructor(e, t = new pt()) {
    super(e, t), this.isMatrix4Uniform = !0, this.boundary = 64, this.itemSize = 16;
  }
}
class Kk extends zk {
  /**
   * Constructs a new node-based Number uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {number} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class Zk extends Hk {
  /**
   * Constructs a new node-based Vector2 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Vector2} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class Qk extends $k {
  /**
   * Constructs a new node-based Vector3 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Vector3} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class Jk extends Wk {
  /**
   * Constructs a new node-based Vector4 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Vector4} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class eG extends qk {
  /**
   * Constructs a new node-based Color uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Color} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class tG extends Xk {
  /**
   * Constructs a new node-based Matrix2 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Matrix2} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class nG extends jk {
  /**
   * Constructs a new node-based Matrix3 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Matrix3} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
class iG extends Yk {
  /**
   * Constructs a new node-based Matrix4 uniform.
   *
   * @param {NodeUniform} nodeUniform - The node uniform.
   */
  constructor(e) {
    super(e.name, e.value), this.nodeUniform = e;
  }
  /**
   * Overwritten to return the value of the node uniform.
   *
   * @return {Matrix4} The value.
   */
  getValue() {
    return this.nodeUniform.value;
  }
  /**
   * Returns the node uniform data type.
   *
   * @return {string} The data type.
   */
  getType() {
    return this.nodeUniform.type;
  }
}
let rG = 0;
const Xx = /* @__PURE__ */ new WeakMap(), sG = /* @__PURE__ */ new WeakMap(), aG = /* @__PURE__ */ new Map([
  [Int8Array, "int"],
  [Int16Array, "int"],
  [Int32Array, "int"],
  [Uint8Array, "uint"],
  [Uint16Array, "uint"],
  [Uint32Array, "uint"],
  [Float32Array, "float"]
]), oh = (i) => /e/g.test(i) ? String(i).replace(/\+/g, "") : (i = Number(i), i + (i % 1 ? "" : ".0"));
class oT {
  /**
   * Constructs a new node builder.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Renderer} renderer - The current renderer.
   * @param {NodeParser} parser - A reference to a node parser.
   */
  constructor(e, t, n) {
    this.object = e, this.material = e && e.material || null, this.geometry = e && e.geometry || null, this.renderer = t, this.parser = n, this.scene = null, this.camera = null, this.nodes = [], this.sequentialNodes = [], this.updateNodes = [], this.updateBeforeNodes = [], this.updateAfterNodes = [], this.hashNodes = {}, this.observer = null, this.lightsNode = null, this.environmentNode = null, this.fogNode = null, this.clippingContext = null, this.vertexShader = null, this.fragmentShader = null, this.computeShader = null, this.flowNodes = { vertex: [], fragment: [], compute: [] }, this.flowCode = { vertex: "", fragment: "", compute: "" }, this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }, this.structs = { vertex: [], fragment: [], compute: [], index: 0 }, this.types = { vertex: [], fragment: [], compute: [], index: 0 }, this.bindings = { vertex: {}, fragment: {}, compute: {} }, this.bindingsIndexes = {}, this.bindGroups = null, this.attributes = [], this.bufferAttributes = [], this.varyings = [], this.codes = {}, this.vars = {}, this.declarations = {}, this.flow = { code: "" }, this.chaining = [], this.stack = Qf(), this.stacks = [], this.tab = "	", this.currentFunctionNode = null, this.context = {
      material: this.material
    }, this.cache = new rp(), this.globalCache = this.cache, this.flowsData = /* @__PURE__ */ new WeakMap(), this.shaderStage = null, this.buildStage = null, this.subBuildLayers = [], this.activeStacks = [], this.subBuildFn = null, this.fnCall = null, Object.defineProperty(this, "id", { value: rG++ });
  }
  /**
   * Whether the material is using flat shading or not.
   *
   * @returns {boolean} Whether the material is using flat shading or not.
   */
  isFlatShading() {
    return this.material.flatShading === !0 || this.geometry.hasAttribute("normal") === !1;
  }
  /**
   * Whether the material is opaque or not.
   *
   * @return {boolean} Whether the material is opaque or not.
   */
  isOpaque() {
    const e = this.material;
    return e.transparent === !1 && e.blending === ei && e.alphaToCoverage === !1;
  }
  /**
   * Factory method for creating an instance of {@link RenderTarget} with the given
   * dimensions and options.
   *
   * @param {number} width - The width of the render target.
   * @param {number} height - The height of the render target.
   * @param {Object} options - The options of the render target.
   * @return {RenderTarget} The render target.
   */
  createRenderTarget(e, t, n) {
    return new js(e, t, n);
  }
  /**
   * Factory method for creating an instance of {@link CubeRenderTarget} with the given
   * dimensions and options.
   *
   * @param {number} size - The size of the cube render target.
   * @param {Object} options - The options of the cube render target.
   * @return {CubeRenderTarget} The cube render target.
   */
  createCubeRenderTarget(e, t) {
    return new DS(e, t);
  }
  /**
   * Whether the given node is included in the internal array of nodes or not.
   *
   * @param {Node} node - The node to test.
   * @return {boolean} Whether the given node is included in the internal array of nodes or not.
   */
  includes(e) {
    return this.nodes.includes(e);
  }
  /**
   * Returns the output struct name which is required by
   * {@link OutputStructNode}.
   *
   * @abstract
   * @return {string} The name of the output struct.
   */
  getOutputStructName() {
  }
  /**
   * Returns a bind group for the given group name and binding.
   *
   * @private
   * @param {string} groupName - The group name.
   * @param {Array<NodeUniformsGroup>} bindings - List of bindings.
   * @return {BindGroup} The bind group
   */
  _getBindGroup(e, t) {
    const n = t[0].groupNode;
    let r = n.shared;
    if (r)
      for (let a = 1; a < t.length; a++)
        n !== t[a].groupNode && (r = !1);
    let s;
    if (r) {
      let a = "";
      for (const u of t)
        if (u.isNodeUniformsGroup) {
          u.uniforms.sort((h, d) => h.nodeUniform.node.id - d.nodeUniform.node.id);
          for (const h of u.uniforms)
            a += h.nodeUniform.node.id;
        } else
          a += u.nodeUniform.id;
      const o = this.renderer._currentRenderContext || this.renderer;
      let l = Xx.get(o);
      l === void 0 && (l = /* @__PURE__ */ new Map(), Xx.set(o, l));
      const c = Ml(a);
      s = l.get(c), s === void 0 && (s = new im(e, t, this.bindingsIndexes[e].group), l.set(c, s));
    } else
      s = new im(e, t, this.bindingsIndexes[e].group);
    return s;
  }
  /**
   * Returns an array of node uniform groups for the given group name and shader stage.
   *
   * @param {string} groupName - The group name.
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {Array<NodeUniformsGroup>} The array of node uniform groups.
   */
  getBindGroupArray(e, t) {
    const n = this.bindings[t];
    let r = n[e];
    return r === void 0 && (this.bindingsIndexes[e] === void 0 && (this.bindingsIndexes[e] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }), n[e] = r = []), r;
  }
  /**
   * Returns a list bindings of all shader stages separated by groups.
   *
   * @return {Array<BindGroup>} The list of bindings.
   */
  getBindings() {
    let e = this.bindGroups;
    if (e === null) {
      const t = {}, n = this.bindings;
      for (const r of G0)
        for (const s in n[r]) {
          const a = n[r][s], o = t[s] || (t[s] = []);
          for (const l of a)
            o.includes(l) === !1 && o.push(l);
        }
      e = [];
      for (const r in t) {
        const s = t[r], a = this._getBindGroup(r, s);
        e.push(a);
      }
      this.bindGroups = e;
    }
    return e;
  }
  /**
   * Sorts the bind groups and updates {@link NodeBuilder#bindingsIndexes}.
   */
  sortBindingGroups() {
    const e = this.getBindings();
    e.sort((t, n) => t.bindings[0].groupNode.order - n.bindings[0].groupNode.order);
    for (let t = 0; t < e.length; t++) {
      const n = e[t];
      this.bindingsIndexes[n.name].group = t, n.index = t;
    }
  }
  /**
   * The builder maintains each node in a hash-based dictionary.
   * This method sets the given node (value) with the given hash (key) into this dictionary.
   *
   * @param {Node} node - The node to add.
   * @param {number} hash - The hash of the node.
   */
  setHashNode(e, t) {
    this.hashNodes[t] = e;
  }
  /**
   * Adds a node to this builder.
   *
   * @param {Node} node - The node to add.
   */
  addNode(e) {
    this.nodes.includes(e) === !1 && (this.nodes.push(e), this.setHashNode(e, e.getHash(this)));
  }
  /**
   * It is used to add Nodes that will be used as FRAME and RENDER events,
   * and need to follow a certain sequence in the calls to work correctly.
   * This function should be called after 'setup()' in the 'build()' process to ensure that the child nodes are processed first.
   *
   * @param {Node} node - The node to add.
   */
  addSequentialNode(e) {
    const t = e.getUpdateBeforeType(), n = e.getUpdateAfterType();
    (t !== it.NONE || n !== it.NONE) && this.sequentialNodes.includes(e) === !1 && this.sequentialNodes.push(e);
  }
  /**
   * Checks the update types of nodes
   */
  buildUpdateNodes() {
    for (const e of this.nodes)
      e.getUpdateType() !== it.NONE && this.updateNodes.push(e);
    for (const e of this.sequentialNodes) {
      const t = e.getUpdateBeforeType(), n = e.getUpdateAfterType();
      t !== it.NONE && this.updateBeforeNodes.push(e), n !== it.NONE && this.updateAfterNodes.push(e);
    }
  }
  /**
   * A reference the current node which is the
   * last node in the chain of nodes.
   *
   * @type {Node}
   */
  get currentNode() {
    return this.chaining[this.chaining.length - 1];
  }
  /**
   * Whether the given texture is filtered or not.
   *
   * @param {Texture} texture - The texture to check.
   * @return {boolean} Whether the given texture is filtered or not.
   */
  isFilteredTexture(e) {
    return e.magFilter === Ot || e.magFilter === Po || e.magFilter === ts || e.magFilter === pi || e.minFilter === Ot || e.minFilter === Po || e.minFilter === ts || e.minFilter === pi;
  }
  /**
   * Returns the maximum number of bytes available for uniform buffers.
   *
   * @return {number} The maximum number of bytes available for uniform buffers.
   */
  getUniformBufferLimit() {
    return 16384;
  }
  /**
   * Adds the given node to the internal node chain.
   * This is used to check recursive calls in node-graph.
   *
   * @param {Node} node - The node to add.
   */
  addChain(e) {
    this.chaining.push(e);
  }
  /**
   * Removes the given node from the internal node chain.
   *
   * @param {Node} node - The node to remove.
   */
  removeChain(e) {
    if (this.chaining.pop() !== e)
      throw new Error("NodeBuilder: Invalid node chaining!");
  }
  /**
   * Returns the native shader method name for a given generic name. E.g.
   * the method name `textureDimensions` matches the WGSL name but must be
   * resolved to `textureSize` in GLSL.
   *
   * @abstract
   * @param {string} method - The method name to resolve.
   * @return {string} The resolved method name.
   */
  getMethod(e) {
    return e;
  }
  /**
   * Returns the native snippet for a ternary operation. E.g. GLSL would output
   * a ternary op as `cond ? x : y` whereas WGSL would output it as `select(y, x, cond)`
   *
   * @abstract
   * @param {string} condSnippet - The condition determining which expression gets resolved.
   * @param {string} ifSnippet - The expression to resolve to if the condition is true.
   * @param {string} elseSnippet - The expression to resolve to if the condition is false.
   * @return {string} The resolved method name.
   */
  getTernary() {
    return null;
  }
  /**
   * Returns a node for the given hash, see {@link NodeBuilder#setHashNode}.
   *
   * @param {number} hash - The hash of the node.
   * @return {Node} The found node.
   */
  getNodeFromHash(e) {
    return this.hashNodes[e];
  }
  /**
   * Adds the Node to a target flow so that it can generate code in the 'generate' process.
   *
   * @param {('vertex'|'fragment'|'compute')} shaderStage - The shader stage.
   * @param {Node} node - The node to add.
   * @return {Node} The node.
   */
  addFlow(e, t) {
    return this.flowNodes[e].push(t), t;
  }
  /**
   * Sets builder's context.
   *
   * @param {Object} context - The context to set.
   */
  setContext(e) {
    this.context = e;
  }
  /**
   * Returns the builder's current context.
   *
   * @return {Object} The builder's current context.
   */
  getContext() {
    return this.context;
  }
  /**
   * Adds context data to the builder's current context.
   *
   * @param {Object} context - The context to add.
   * @return {Object} The previous context.
   */
  addContext(e) {
    const t = this.getContext();
    return this.setContext({ ...this.context, ...e }), t;
  }
  /**
   * Gets a context used in shader construction that can be shared across different materials.
   * This is necessary since the renderer cache can reuse shaders generated in one material and use them in another.
   *
   * @return {Object} The builder's current context without material.
   */
  getSharedContext() {
    const e = { ...this.context };
    return delete e.material, delete e.getUV, delete e.getOutput, delete e.getTextureLevel, delete e.getAO, delete e.getShadow, e;
  }
  /**
   * Sets builder's cache.
   *
   * @param {NodeCache} cache - The cache to set.
   */
  setCache(e) {
    this.cache = e;
  }
  /**
   * Returns the builder's current cache.
   *
   * @return {NodeCache} The builder's current cache.
   */
  getCache() {
    return this.cache;
  }
  /**
   * Returns a cache for the given node.
   *
   * @param {Node} node - The node.
   * @param {boolean} [parent=true] - Whether this node refers to a shared parent cache or not.
   * @return {NodeCache} The cache.
   */
  getCacheFromNode(e, t = !0) {
    const n = this.getDataFromNode(e);
    return n.cache === void 0 && (n.cache = new rp(t ? this.getCache() : null)), n.cache;
  }
  /**
   * Whether the requested feature is available or not.
   *
   * @abstract
   * @param {string} name - The requested feature.
   * @return {boolean} Whether the requested feature is supported or not.
   */
  isAvailable() {
    return !1;
  }
  /**
   * Returns the vertexIndex input variable as a native shader string.
   *
   * @abstract
   * @return {string} The instanceIndex shader string.
   */
  getVertexIndex() {
    oe("Abstract function.");
  }
  /**
   * Contextually returns either the vertex stage instance index builtin
   * or the linearized index of an compute invocation within a grid of workgroups.
   *
   * @abstract
   * @return {string} The instanceIndex shader string.
   */
  getInstanceIndex() {
    oe("Abstract function.");
  }
  /**
   * Returns the drawIndex input variable as a native shader string.
   * Only relevant for WebGL and its `WEBGL_multi_draw` extension.
   *
   * @abstract
   * @return {?string} The drawIndex shader string.
   */
  getDrawIndex() {
    oe("Abstract function.");
  }
  /**
   * Returns the frontFacing input variable as a native shader string.
   *
   * @abstract
   * @return {string} The frontFacing shader string.
   */
  getFrontFacing() {
    oe("Abstract function.");
  }
  /**
   * Returns the fragCoord input variable as a native shader string.
   *
   * @abstract
   * @return {string} The fragCoord shader string.
   */
  getFragCoord() {
    oe("Abstract function.");
  }
  /**
   * Whether to flip texture data along its vertical axis or not. WebGL needs
   * this method evaluate to `true`, WebGPU to `false`.
   *
   * @abstract
   * @return {boolean} Whether to flip texture data along its vertical axis or not.
   */
  isFlipY() {
    return !1;
  }
  /**
   * Calling this method increases the usage count for the given node by one.
   *
   * @param {Node} node - The node to increase the usage count for.
   * @return {number} The updated usage count.
   */
  increaseUsage(e) {
    const t = this.getDataFromNode(e);
    return t.usageCount = t.usageCount === void 0 ? 1 : t.usageCount + 1, t.usageCount;
  }
  /**
   * Generates a texture sample shader string for the given texture data.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The texture property name.
   * @param {string} uvSnippet - Snippet defining the texture coordinates.
   * @return {string} The generated shader string.
   */
  generateTexture() {
    oe("Abstract function.");
  }
  /**
   * Generates a texture LOD shader string for the given texture data.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The texture property name.
   * @param {string} uvSnippet - Snippet defining the texture coordinates.
   * @param {?string} depthSnippet - Snippet defining the 0-based texture array index to sample.
   * @param {string} levelSnippet - Snippet defining the mip level.
   * @return {string} The generated shader string.
   */
  generateTextureLod() {
    oe("Abstract function.");
  }
  /**
   * Generates the array declaration string.
   *
   * @param {string} type - The type.
   * @param {?number} [count] - The count.
   * @return {string} The generated value as a shader string.
   */
  generateArrayDeclaration(e, t) {
    return this.getType(e) + "[ " + t + " ]";
  }
  /**
   * Generates the array shader string for the given type and value.
   *
   * @param {string} type - The type.
   * @param {?number} [count] - The count.
   * @param {?Array<Node>} [values=null] - The default values.
   * @return {string} The generated value as a shader string.
   */
  generateArray(e, t, n = null) {
    let r = this.generateArrayDeclaration(e, t) + "( ";
    for (let s = 0; s < t; s++) {
      const a = n ? n[s] : null;
      a !== null ? r += a.build(this, e) : r += this.generateConst(e), s < t - 1 && (r += ", ");
    }
    return r += " )", r;
  }
  /**
   * Generates the struct shader string.
   *
   * @param {string} type - The type.
   * @param {Array<Object>} [membersLayout] - The count.
   * @param {?Array<Node>} [values=null] - The default values.
   * @return {string} The generated value as a shader string.
   */
  generateStruct(e, t, n = null) {
    const r = [];
    for (const s of t) {
      const { name: a, type: o } = s;
      n && n[a] && n[a].isNode ? r.push(n[a].build(this, o)) : r.push(this.generateConst(o));
    }
    return e + "( " + r.join(", ") + " )";
  }
  /**
   * Generates the shader string for the given type and value.
   *
   * @param {string} type - The type.
   * @param {?any} [value=null] - The value.
   * @return {string} The generated value as a shader string.
   */
  generateConst(e, t = null) {
    if (t === null && (e === "float" || e === "int" || e === "uint" ? t = 0 : e === "bool" ? t = !1 : e === "color" ? t = new He() : e === "vec2" || e === "uvec2" || e === "ivec2" ? t = new de() : e === "vec3" || e === "uvec3" || e === "ivec3" ? t = new P() : (e === "vec4" || e === "uvec4" || e === "ivec4") && (t = new rt())), e === "float")
      return oh(t);
    if (e === "int")
      return `${Math.round(t)}`;
    if (e === "uint")
      return t >= 0 ? `${Math.round(t)}u` : "0u";
    if (e === "bool")
      return t ? "true" : "false";
    if (e === "color")
      return `${this.getType("vec3")}( ${oh(t.r)}, ${oh(t.g)}, ${oh(t.b)} )`;
    const n = this.getTypeLength(e), r = this.getComponentType(e), s = (a) => this.generateConst(r, a);
    if (n === 2)
      return `${this.getType(e)}( ${s(t.x)}, ${s(t.y)} )`;
    if (n === 3)
      return `${this.getType(e)}( ${s(t.x)}, ${s(t.y)}, ${s(t.z)} )`;
    if (n === 4 && e !== "mat2")
      return `${this.getType(e)}( ${s(t.x)}, ${s(t.y)}, ${s(t.z)}, ${s(t.w)} )`;
    if (n >= 4 && t && (t.isMatrix2 || t.isMatrix3 || t.isMatrix4))
      return `${this.getType(e)}( ${t.elements.map(s).join(", ")} )`;
    if (n > 4)
      return `${this.getType(e)}()`;
    throw new Error(`NodeBuilder: Type '${e}' not found in generate constant attempt.`);
  }
  /**
   * It might be necessary to convert certain data types to different ones
   * so this method can be used to hide the conversion.
   *
   * @param {string} type - The type.
   * @return {string} The updated type.
   */
  getType(e) {
    return e === "color" ? "vec3" : e;
  }
  /**
   * Whether the given attribute name is defined in the geometry or not.
   *
   * @param {string} name - The attribute name.
   * @return {boolean} Whether the given attribute name is defined in the geometry.
   */
  hasGeometryAttribute(e) {
    return this.geometry && this.geometry.getAttribute(e) !== void 0;
  }
  /**
   * Returns a node attribute for the given name and type.
   *
   * @param {string} name - The attribute's name.
   * @param {string} type - The attribute's type.
   * @return {NodeAttribute} The node attribute.
   */
  getAttribute(e, t) {
    const n = this.attributes;
    for (const s of n)
      if (s.name === e)
        return s;
    const r = new qx(e, t);
    return this.registerDeclaration(r), n.push(r), r;
  }
  /**
   * Returns for the given node and shader stage the property name for the shader.
   *
   * @param {Node} node - The node.
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The property name.
   */
  getPropertyName(e) {
    return e.name;
  }
  /**
   * Whether the given type is a vector type or not.
   *
   * @param {string} type - The type to check.
   * @return {boolean} Whether the given type is a vector type or not.
   */
  isVector(e) {
    return /vec\d/.test(e);
  }
  /**
   * Whether the given type is a matrix type or not.
   *
   * @param {string} type - The type to check.
   * @return {boolean} Whether the given type is a matrix type or not.
   */
  isMatrix(e) {
    return /mat\d/.test(e);
  }
  /**
   * Whether the given type is a reference type or not.
   *
   * @param {string} type - The type to check.
   * @return {boolean} Whether the given type is a reference type or not.
   */
  isReference(e) {
    return e === "void" || e === "property" || e === "sampler" || e === "samplerComparison" || e === "texture" || e === "cubeTexture" || e === "storageTexture" || e === "depthTexture" || e === "texture3D";
  }
  /**
   * Checks if the given texture requires a manual conversion to the working color space.
   *
   * @abstract
   * @param {Texture} texture - The texture to check.
   * @return {boolean} Whether the given texture requires a conversion to working color space or not.
   */
  needsToWorkingColorSpace() {
    return !1;
  }
  /**
   * Returns the component type of a given texture.
   *
   * @param {Texture} texture - The texture.
   * @return {string} The component type.
   */
  getComponentTypeFromTexture(e) {
    const t = e.type;
    if (e.isDataTexture) {
      if (t === wn)
        return "int";
      if (t === Dt)
        return "uint";
    }
    return "float";
  }
  /**
   * Returns the element type for a given type.
   *
   * @param {string} type - The type.
   * @return {string} The element type.
   */
  getElementType(e) {
    return e === "mat2" ? "vec2" : e === "mat3" ? "vec3" : e === "mat4" ? "vec4" : this.getComponentType(e);
  }
  /**
   * Returns the component type for a given type.
   *
   * @param {string} type - The type.
   * @return {string} The component type.
   */
  getComponentType(e) {
    if (e = this.getVectorType(e), e === "float" || e === "bool" || e === "int" || e === "uint")
      return e;
    const t = /(b|i|u|)(vec|mat)([2-4])/.exec(e);
    return t === null ? null : t[1] === "b" ? "bool" : t[1] === "i" ? "int" : t[1] === "u" ? "uint" : "float";
  }
  /**
   * Returns the vector type for a given type.
   *
   * @param {string} type - The type.
   * @return {string} The vector type.
   */
  getVectorType(e) {
    return e === "color" ? "vec3" : e === "texture" || e === "cubeTexture" || e === "storageTexture" || e === "texture3D" ? "vec4" : e;
  }
  /**
   * Returns the data type for the given the length and component type.
   *
   * @param {number} length - The length.
   * @param {string} [componentType='float'] - The component type.
   * @return {string} The type.
   */
  getTypeFromLength(e, t = "float") {
    if (e === 1)
      return t;
    let n = vb(e);
    const r = t === "float" ? "" : t[0];
    return /mat2/.test(t) === !0 && (n = n.replace("vec", "mat")), r + n;
  }
  /**
   * Returns the type for a given typed array.
   *
   * @param {TypedArray} array - The typed array.
   * @return {string} The type.
   */
  getTypeFromArray(e) {
    return aG.get(e.constructor);
  }
  /**
   * Returns the type is an integer type.
   *
   * @param {string} type - The type.
   * @return {boolean} Whether the type is an integer type or not.
   */
  isInteger(e) {
    return /int|uint|(i|u)vec/.test(e);
  }
  /**
   * Returns the type for a given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   * @return {string} The type.
   */
  getTypeFromAttribute(e) {
    let t = e;
    e.isInterleavedBufferAttribute && (t = e.data);
    const n = t.array, r = e.itemSize, s = e.normalized;
    let a;
    return !(e instanceof ey) && s !== !0 && (a = this.getTypeFromArray(n)), this.getTypeFromLength(r, a);
  }
  /**
   * Returns the length for the given data type.
   *
   * @param {string} type - The data type.
   * @return {number} The length.
   */
  getTypeLength(e) {
    const t = this.getVectorType(e), n = /vec([2-4])/.exec(t);
    return n !== null ? Number(n[1]) : t === "float" || t === "bool" || t === "int" || t === "uint" ? 1 : /mat2/.test(e) === !0 ? 4 : /mat3/.test(e) === !0 ? 9 : /mat4/.test(e) === !0 ? 16 : 0;
  }
  /**
   * Returns the vector type for a given matrix type.
   *
   * @param {string} type - The matrix type.
   * @return {string} The vector type.
   */
  getVectorFromMatrix(e) {
    return e.replace("mat", "vec");
  }
  /**
   * For a given type this method changes the component type to the
   * given value. E.g. `vec4` should be changed to the new component type
   * `uint` which results in `uvec4`.
   *
   * @param {string} type - The type.
   * @param {string} newComponentType - The new component type.
   * @return {string} The new type.
   */
  changeComponentType(e, t) {
    return this.getTypeFromLength(this.getTypeLength(e), t);
  }
  /**
   * Returns the integer type pendant for the given type.
   *
   * @param {string} type - The type.
   * @return {string} The integer type.
   */
  getIntegerType(e) {
    const t = this.getComponentType(e);
    return t === "int" || t === "uint" ? e : this.changeComponentType(e, "int");
  }
  /**
   * Adds an active stack to the internal stack.
   *
   * @param {StackNode} stack - The stack node to add.
   */
  setActiveStack(e) {
    this.activeStacks.push(e);
  }
  /**
   * Removes the active stack from the internal stack.
   *
   * @param {StackNode} stack - The stack node to remove.
   */
  removeActiveStack(e) {
    if (this.activeStacks[this.activeStacks.length - 1] === e)
      this.activeStacks.pop();
    else
      throw new Error("NodeBuilder: Invalid active stack removal.");
  }
  /**
   * Returns the active stack.
   *
   * @return {StackNode} The active stack.
   */
  getActiveStack() {
    return this.activeStacks[this.activeStacks.length - 1];
  }
  /**
   * Returns the base stack.
   *
   * @return {StackNode} The base stack.
   */
  getBaseStack() {
    return this.activeStacks[0];
  }
  /**
   * Adds a stack node to the internal stack.
   *
   * @return {StackNode} The added stack node.
   */
  addStack() {
    this.stack = Qf(this.stack);
    const e = Mb();
    return this.stacks.push(e), Hh(this.stack), this.stack;
  }
  /**
   * Removes the last stack node from the internal stack.
   *
   * @return {StackNode} The removed stack node.
   */
  removeStack() {
    const e = this.stack;
    for (const t of e.nodes) {
      const n = this.getDataFromNode(t);
      n.stack = e;
    }
    return this.stack = e.parent, Hh(this.stacks.pop()), e;
  }
  /**
   * The builder maintains (cached) data for each node during the building process. This method
   * can be used to get these data for a specific shader stage and cache.
   *
   * @param {Node} node - The node to get the data for.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @param {?NodeCache} cache - An optional cache.
   * @return {Object} The node data.
   */
  getDataFromNode(e, t = this.shaderStage, n = null) {
    n = n === null ? e.isGlobal(this) ? this.globalCache : this.cache : n;
    let r = n.getData(e);
    r === void 0 && (r = {}, n.setData(e, r)), r[t] === void 0 && (r[t] = {});
    let s = r[t];
    const a = r.any ? r.any.subBuilds : null, o = this.getClosestSubBuild(a);
    return o && (s.subBuildsCache === void 0 && (s.subBuildsCache = {}), s = s.subBuildsCache[o] || (s.subBuildsCache[o] = {}), s.subBuilds = a), s;
  }
  /**
   * Returns the properties for the given node and shader stage.
   *
   * Properties are typically used within a build stage to reference a node's
   * child node or nodes manually assigned to the properties in a separate build stage.
   * A typical usage pattern for defining nodes manually would be assigning dependency nodes
   * to the current node's properties in the setup stage and building those properties in the generate stage.
   *
   * @param {Node} node - The node to get the properties for.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage='any'] - The shader stage.
   * @return {Object} The node properties.
   */
  getNodeProperties(e, t = "any") {
    const n = this.getDataFromNode(e, t);
    return n.properties || (n.properties = { outputNode: null });
  }
  /**
   * Returns an instance of {@link NodeAttribute} for the given buffer attribute node.
   *
   * @param {BufferAttributeNode} node - The buffer attribute node.
   * @param {string} type - The node type.
   * @return {NodeAttribute} The node attribute.
   */
  getBufferAttributeFromNode(e, t) {
    const n = this.getDataFromNode(e, "vertex");
    let r = n.bufferAttribute;
    if (r === void 0) {
      const s = this.uniforms.index++;
      r = new qx("nodeAttribute" + s, t, e), this.bufferAttributes.push(r), n.bufferAttribute = r;
    }
    return r;
  }
  /**
   * Returns an instance of {@link StructType} for the given struct name and shader stage
   * or null if not found.
   *
   * @param {string} name - The name of the struct.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @return {?StructType} The struct type or null if not found.
   */
  getStructTypeNode(e, t = this.shaderStage) {
    return this.types[t][e] || null;
  }
  /**
   * Returns an instance of {@link StructType} for the given output struct node.
   *
   * @param {OutputStructNode} node - The output struct node.
   * @param {Array<Object>} membersLayout - The output struct types.
   * @param {?string} [name=null] - The name of the struct.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @return {StructType} The struct type attribute.
   */
  getStructTypeFromNode(e, t, n = null, r = this.shaderStage) {
    const s = this.getDataFromNode(e, r, this.globalCache);
    let a = s.structType;
    if (a === void 0) {
      const o = this.structs.index++;
      n === null && (n = "StructType" + o), a = new Vk(n, t), this.structs[r].push(a), this.types[r][n] = e, s.structType = a;
    }
    return a;
  }
  /**
   * Returns an instance of {@link StructType} for the given output struct node.
   *
   * @param {OutputStructNode} node - The output struct node.
   * @param {Array<Object>} membersLayout - The output struct types.
   * @return {StructType} The struct type attribute.
   */
  getOutputStructTypeFromNode(e, t) {
    const n = this.getStructTypeFromNode(e, t, "OutputType", "fragment");
    return n.output = !0, n;
  }
  /**
   * Returns an instance of {@link NodeUniform} for the given uniform node.
   *
   * @param {UniformNode} node - The uniform node.
   * @param {string} type - The uniform type.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @param {?string} name - The name of the uniform.
   * @return {NodeUniform} The node uniform.
   */
  getUniformFromNode(e, t, n = this.shaderStage, r = null) {
    const s = this.getDataFromNode(e, n, this.globalCache);
    let a = s.uniform;
    if (a === void 0) {
      const o = this.uniforms.index++;
      a = new Bk(r || "nodeUniform" + o, t, e), this.uniforms[n].push(a), this.registerDeclaration(a), s.uniform = a;
    }
    return a;
  }
  /**
   * Returns an instance of {@link NodeVar} for the given variable node.
   *
   * @param {VarNode} node - The variable node.
   * @param {?string} name - The variable's name.
   * @param {string} [type=node.getNodeType( this )] - The variable's type.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @param {boolean} [readOnly=false] - Whether the variable is read-only or not.
   *
   * @return {NodeVar} The node variable.
   */
  getVarFromNode(e, t = null, n = e.getNodeType(this), r = this.shaderStage, s = !1) {
    const a = this.getDataFromNode(e, r), o = this.getSubBuildProperty("variable", a.subBuilds);
    let l = a[o];
    if (l === void 0) {
      const c = s ? "_const" : "_var", u = this.vars[r] || (this.vars[r] = []), h = this.vars[c] || (this.vars[c] = 0);
      t === null && (t = (s ? "nodeConst" : "nodeVar") + h, this.vars[c]++), o !== "variable" && (t = this.getSubBuildProperty(t, a.subBuilds));
      const d = e.getArrayCount(this);
      l = new aT(t, n, s, d), s || u.push(l), this.registerDeclaration(l), a[o] = l;
    }
    return l;
  }
  /**
   * Returns whether a Node or its flow is deterministic, useful for use in `const`.
   *
   * @param {Node} node - The varying node.
   * @return {boolean} Returns true if deterministic.
   */
  isDeterministic(e) {
    if (e.isMathNode)
      return this.isDeterministic(e.aNode) && (e.bNode ? this.isDeterministic(e.bNode) : !0) && (e.cNode ? this.isDeterministic(e.cNode) : !0);
    if (e.isOperatorNode)
      return this.isDeterministic(e.aNode) && (e.bNode ? this.isDeterministic(e.bNode) : !0);
    if (e.isArrayNode) {
      if (e.values !== null) {
        for (const t of e.values)
          if (!this.isDeterministic(t))
            return !1;
      }
      return !0;
    } else if (e.isConstNode)
      return !0;
    return !1;
  }
  /**
   * Returns an instance of {@link NodeVarying} for the given varying node.
   *
   * @param {(VaryingNode|PropertyNode)} node - The varying node.
   * @param {?string} name - The varying's name.
   * @param {string} [type=node.getNodeType( this )] - The varying's type.
   * @param {?string} interpolationType - The interpolation type of the varying.
   * @param {?string} interpolationSampling - The interpolation sampling type of the varying.
   * @return {NodeVar} The node varying.
   */
  getVaryingFromNode(e, t = null, n = e.getNodeType(this), r = null, s = null) {
    const a = this.getDataFromNode(e, "any"), o = this.getSubBuildProperty("varying", a.subBuilds);
    let l = a[o];
    if (l === void 0) {
      const c = this.varyings, u = c.length;
      t === null && (t = "nodeVarying" + u), o !== "varying" && (t = this.getSubBuildProperty(t, a.subBuilds)), l = new Ok(t, n, r, s), c.push(l), this.registerDeclaration(l), a[o] = l;
    }
    return l;
  }
  /**
   * Registers a node declaration in the current shader stage.
   *
   * @param {Object} node - The node to be registered.
   */
  registerDeclaration(e) {
    const t = this.shaderStage, n = this.declarations[t] || (this.declarations[t] = {}), r = this.getPropertyName(e);
    let s = 1, a = r;
    for (; n[a] !== void 0; )
      a = r + "_" + s++;
    s > 1 && (e.name = a, oe(`TSL: Declaration name '${r}' of '${e.type}' already in use. Renamed to '${a}'.`)), n[a] = e;
  }
  /**
   * Returns an instance of {@link NodeCode} for the given code node.
   *
   * @param {CodeNode} node - The code node.
   * @param {string} type - The node type.
   * @param {('vertex'|'fragment'|'compute'|'any')} [shaderStage=this.shaderStage] - The shader stage.
   * @return {NodeCode} The node code.
   */
  getCodeFromNode(e, t, n = this.shaderStage) {
    const r = this.getDataFromNode(e);
    let s = r.code;
    if (s === void 0) {
      const a = this.codes[n] || (this.codes[n] = []), o = a.length;
      s = new kk("nodeCode" + o, t), a.push(s), r.code = s;
    }
    return s;
  }
  /**
  	 * Adds a code flow based on the code-block hierarchy.
  
  	 * This is used so that code-blocks like If,Else create their variables locally if the Node
  	 * is only used inside one of these conditionals in the current shader stage.
  	 *
  	 * @param {Node} node - The node to add.
  	 * @param {Node} nodeBlock - Node-based code-block. Usually 'ConditionalNode'.
  	 */
  addFlowCodeHierarchy(e, t) {
    const { flowCodes: n, flowCodeBlock: r } = this.getDataFromNode(e);
    let s = !0, a = t;
    for (; a; ) {
      if (r.get(a) === !0) {
        s = !1;
        break;
      }
      a = this.getDataFromNode(a).parentNodeBlock;
    }
    if (s)
      for (const o of n)
        this.addLineFlowCode(o);
  }
  /**
   * Add a inline-code to the current flow code-block.
   *
   * @param {Node} node - The node to add.
   * @param {string} code - The code to add.
   * @param {Node} nodeBlock - Current ConditionalNode
   */
  addLineFlowCodeBlock(e, t, n) {
    const r = this.getDataFromNode(e), s = r.flowCodes || (r.flowCodes = []), a = r.flowCodeBlock || (r.flowCodeBlock = /* @__PURE__ */ new WeakMap());
    s.push(t), a.set(n, !0);
  }
  /**
   * Add a inline-code to the current flow.
   *
   * @param {string} code - The code to add.
   * @param {?Node} [node= null] - Optional Node, can help the system understand if the Node is part of a code-block.
   * @return {NodeBuilder} A reference to this node builder.
   */
  addLineFlowCode(e, t = null) {
    return e === "" ? this : (t !== null && this.context.nodeBlock && this.addLineFlowCodeBlock(t, e, this.context.nodeBlock), e = this.tab + e, /;\s*$/.test(e) || (e = e + `;
`), this.flow.code += e, this);
  }
  /**
   * Adds a code to the current code flow.
   *
   * @param {string} code - Shader code.
   * @return {NodeBuilder} A reference to this node builder.
   */
  addFlowCode(e) {
    return this.flow.code += e, this;
  }
  /**
   * Add tab in the code that will be generated so that other snippets respect the current tabulation.
   * Typically used in codes with If,Else.
   *
   * @return {NodeBuilder} A reference to this node builder.
   */
  addFlowTab() {
    return this.tab += "	", this;
  }
  /**
   * Removes a tab.
   *
   * @return {NodeBuilder} A reference to this node builder.
   */
  removeFlowTab() {
    return this.tab = this.tab.slice(0, -1), this;
  }
  /**
   * Gets the current flow data based on a Node.
   *
   * @param {Node} node - Node that the flow was started.
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {Object} The flow data.
   */
  getFlowData(e) {
    return this.flowsData.get(e);
  }
  /**
   * Executes the node flow based on a root node to generate the final shader code.
   *
   * @param {Node} node - The node to execute.
   * @return {Object} The code flow.
   */
  flowNode(e) {
    const t = e.getNodeType(this), n = this.flowChildNode(e, t);
    return this.flowsData.set(e, n), n;
  }
  /**
   * Includes a node in the current function node.
   *
   * @param {Node} node - The node to include.
   * @returns {void}
   */
  addInclude(e) {
    this.currentFunctionNode !== null && this.currentFunctionNode.includes.push(e);
  }
  /**
   * Returns the native shader operator name for a given generic name.
   * It is a similar type of method like {@link NodeBuilder#getMethod}.
   *
   * @param {ShaderNodeInternal} shaderNode - The shader node to build the function node with.
   * @return {FunctionNode} The build function node.
   */
  buildFunctionNode(e) {
    const t = new XO(), n = this.currentFunctionNode;
    return this.currentFunctionNode = t, t.code = this.buildFunctionCode(e), this.currentFunctionNode = n, t;
  }
  /**
   * Generates a code flow based on a TSL function: Fn().
   *
   * @param {ShaderNodeInternal} shaderNode - A function code will be generated based on the input.
   * @return {Object}
   */
  flowShaderNode(e) {
    const t = e.layout, n = {
      [Symbol.iterator]() {
        let a = 0;
        const o = Object.values(this);
        return {
          next: () => ({
            value: o[a],
            done: a++ >= o.length
          })
        };
      }
    };
    for (const a of t.inputs)
      n[a.name] = new MO(a.type, a.name);
    e.layout = null;
    const r = e.call(n), s = this.flowStagesNode(r, t.type);
    return e.layout = t, s;
  }
  /**
   * Executes the node in a specific build stage.
   *
   * This function can be used to arbitrarily execute the specified build stage
   * outside of the standard build process. For instance, if a node's type depends
   * on properties created by the 'setup' stage, then flowBuildStage(node, 'setup')
   * can be used to execute the setup build stage and access its generated nodes
   * before the standard build process begins.
   *
   * @param {Node} node - The node to execute.
   * @param {string} buildStage - The build stage to execute the node in.
   * @param {?(Node|string)} [output=null] - Expected output type. For example 'vec3'.
   * @return {?(Node|string)} The result of the node build.
   */
  flowBuildStage(e, t, n = null) {
    const r = this.getBuildStage();
    this.setBuildStage(t);
    const s = e.build(this, n);
    return this.setBuildStage(r), s;
  }
  /**
   * Runs the node flow through all the steps of creation, 'setup', 'analyze', 'generate'.
   *
   * @param {Node} node - The node to execute.
   * @param {?string} output - Expected output type. For example 'vec3'.
   * @return {Object}
   */
  flowStagesNode(e, t = null) {
    const n = this.flow, r = this.vars, s = this.declarations, a = this.cache, o = this.buildStage, l = this.stack, c = {
      code: ""
    };
    this.flow = c, this.vars = {}, this.declarations = {}, this.cache = new rp(), this.stack = Qf();
    for (const u of k0)
      this.setBuildStage(u), c.result = e.build(this, t);
    return c.vars = this.getVars(this.shaderStage), this.flow = n, this.vars = r, this.declarations = s, this.cache = a, this.stack = l, this.setBuildStage(o), c;
  }
  /**
   * Returns the native shader operator name for a given generic name.
   * It is a similar type of method like {@link NodeBuilder#getMethod}.
   *
   * @abstract
   * @param {string} op - The operator name to resolve.
   * @return {?string} The resolved operator name.
   */
  getFunctionOperator() {
    return null;
  }
  /**
   * Builds the given shader node.
   *
   * @abstract
   * @param {ShaderNodeInternal} shaderNode - The shader node.
   * @return {string} The function code.
   */
  buildFunctionCode() {
    oe("Abstract function.");
  }
  /**
   * Generates a code flow based on a child Node.
   *
   * @param {Node} node - The node to execute.
   * @param {?string} output - Expected output type. For example 'vec3'.
   * @return {Object} The code flow.
   */
  flowChildNode(e, t = null) {
    const n = this.flow, r = {
      code: ""
    };
    return this.flow = r, r.result = e.build(this, t), this.flow = n, r;
  }
  /**
   * Executes a flow of code in a different stage.
   *
   * Some nodes like `varying()` have the ability to compute code in vertex-stage and
   * return the value in fragment-stage even if it is being executed in an input fragment.
   *
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @param {Node} node - The node to execute.
   * @param {?string} output - Expected output type. For example 'vec3'.
   * @param {?string} propertyName - The property name to assign the result.
   * @return {?(Object|Node)} The code flow or node.build() result.
   */
  flowNodeFromShaderStage(e, t, n = null, r = null) {
    const s = this.tab, a = this.cache, o = this.shaderStage, l = this.context;
    this.setShaderStage(e);
    const c = { ...this.context };
    delete c.nodeBlock, this.cache = this.globalCache, this.tab = "	", this.context = c;
    let u = null;
    if (this.buildStage === "generate") {
      const h = this.flowChildNode(t, n);
      r !== null && (h.code += `${this.tab + r} = ${h.result};
`), this.flowCode[e] = this.flowCode[e] + h.code, u = h;
    } else
      u = t.build(this);
    return this.setShaderStage(o), this.cache = a, this.tab = s, this.context = l, u;
  }
  /**
   * Returns an array holding all node attributes of this node builder.
   *
   * @return {Array<NodeAttribute>} The node attributes of this builder.
   */
  getAttributesArray() {
    return this.attributes.concat(this.bufferAttributes);
  }
  /**
   * Returns the attribute definitions as a shader string for the given shader stage.
   *
   * @abstract
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The attribute code section.
   */
  getAttributes() {
    oe("Abstract function.");
  }
  /**
   * Returns the varying definitions as a shader string for the given shader stage.
   *
   * @abstract
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The varying code section.
   */
  getVaryings() {
    oe("Abstract function.");
  }
  /**
   * Returns a single variable definition as a shader string for the given variable type and name.
   *
   * @param {string} type - The variable's type.
   * @param {string} name - The variable's name.
   * @param {?number} [count=null] - The array length.
   * @return {string} The shader string.
   */
  getVar(e, t, n = null) {
    return `${n !== null ? this.generateArrayDeclaration(e, n) : this.getType(e)} ${t}`;
  }
  /**
   * Returns the variable definitions as a shader string for the given shader stage.
   *
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The variable code section.
   */
  getVars(e) {
    let t = "";
    const n = this.vars[e];
    if (n !== void 0)
      for (const r of n)
        t += `${this.getVar(r.type, r.name)}; `;
    return t;
  }
  /**
   * Returns the uniform definitions as a shader string for the given shader stage.
   *
   * @abstract
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The uniform code section.
   */
  getUniforms() {
    oe("Abstract function.");
  }
  /**
   * Returns the native code definitions as a shader string for the given shader stage.
   *
   * @param {('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage.
   * @return {string} The native code section.
   */
  getCodes(e) {
    const t = this.codes[e];
    let n = "";
    if (t !== void 0)
      for (const r of t)
        n += r.code + `
`;
    return n;
  }
  /**
   * Returns the hash of this node builder.
   *
   * @return {string} The hash.
   */
  getHash() {
    return this.vertexShader + this.fragmentShader + this.computeShader;
  }
  /**
   * Sets the current shader stage.
   *
   * @param {?('vertex'|'fragment'|'compute'|'any')} shaderStage - The shader stage to set.
   */
  setShaderStage(e) {
    this.shaderStage = e;
  }
  /**
   * Returns the current shader stage.
   *
   * @return {?('vertex'|'fragment'|'compute'|'any')} The current shader stage.
   */
  getShaderStage() {
    return this.shaderStage;
  }
  /**
   * Sets the current build stage.
   *
   * @param {?('setup'|'analyze'|'generate')} buildStage - The build stage to set.
   */
  setBuildStage(e) {
    this.buildStage = e;
  }
  /**
   * Returns the current build stage.
   *
   * @return {?('setup'|'analyze'|'generate')} The current build stage.
   */
  getBuildStage() {
    return this.buildStage;
  }
  /**
   * Controls the code build of the shader stages.
   *
   * @abstract
   */
  buildCode() {
    oe("Abstract function.");
  }
  /**
   * Returns the current sub-build layer.
   *
   * @return {SubBuildNode} The current sub-build layers.
   */
  get subBuild() {
    return this.subBuildLayers[this.subBuildLayers.length - 1] || null;
  }
  /**
   * Adds a sub-build layer to the node builder.
   *
   * @param {SubBuildNode} subBuild - The sub-build layer to add.
   */
  addSubBuild(e) {
    this.subBuildLayers.push(e);
  }
  /**
   * Removes the last sub-build layer from the node builder.
   *
   * @return {SubBuildNode} The removed sub-build layer.
   */
  removeSubBuild() {
    return this.subBuildLayers.pop();
  }
  /**
   * Returns the closest sub-build layer for the given data.
   *
   * @param {Node|Set<string>|Array<string>} data - The data to get the closest sub-build layer from.
   * @return {?string} The closest sub-build name or null if none found.
   */
  getClosestSubBuild(e) {
    let t;
    if (e && e.isNode ? e.isShaderCallNodeInternal ? t = e.shaderNode.subBuilds : e.isStackNode ? t = [e.subBuild] : t = this.getDataFromNode(e, "any").subBuilds : e instanceof Set ? t = [...e] : t = e, !t)
      return null;
    const n = this.subBuildLayers;
    for (let r = t.length - 1; r >= 0; r--) {
      const s = t[r];
      if (n.includes(s))
        return s;
    }
    return null;
  }
  /**
   * Returns the output node of a sub-build layer.
   *
   * @param {Node} node - The node to get the output from.
   * @return {string} The output node name.
   */
  getSubBuildOutput(e) {
    return this.getSubBuildProperty("outputNode", e);
  }
  /**
   * Returns the sub-build property name for the given property and node.
   *
   * @param {string} [property=''] - The property name.
   * @param {?Node} [node=null] - The node to get the sub-build from.
   * @return {string} The sub-build property name.
   */
  getSubBuildProperty(e = "", t = null) {
    let n;
    t !== null ? n = this.getClosestSubBuild(t) : n = this.subBuildFn;
    let r;
    return n ? r = e ? n + "_" + e : n : r = e, r;
  }
  /**
   * Central build method which controls the build for the given object.
   *
   * @return {NodeBuilder} A reference to this node builder.
   */
  build() {
    const { object: e, material: t, renderer: n } = this;
    if (t !== null) {
      let r = n.library.fromMaterial(t);
      r === null && (le(`NodeMaterial: Material "${t.type}" is not compatible.`), r = new dn()), r.build(this);
    } else
      this.addFlow("compute", e);
    for (const r of k0) {
      this.setBuildStage(r), this.context.position && this.context.position.isNode && this.flowNodeFromShaderStage("vertex", this.context.position);
      for (const s of G0) {
        this.setShaderStage(s);
        const a = this.flowNodes[s];
        for (const o of a)
          r === "generate" ? this.flowNode(o) : o.build(this);
      }
    }
    return this.setBuildStage(null), this.setShaderStage(null), this.buildCode(), this.buildUpdateNodes(), this;
  }
  /**
   * Returns shared data object for the given node.
   *
   * @param {Node} node - The node to get shared data from.
   * @return {Object} The shared data.
   */
  getSharedDataFromNode(e) {
    let t = sG.get(e);
    return t === void 0 && (t = {}), t;
  }
  /**
   * Returns a uniform representation which is later used for UBO generation and rendering.
   *
   * @param {NodeUniform} uniformNode - The uniform node.
   * @param {string} type - The requested type.
   * @return {Uniform} The uniform.
   */
  getNodeUniform(e, t) {
    const n = this.getSharedDataFromNode(e);
    let r = n.cache;
    if (r === void 0) {
      if (t === "float" || t === "int" || t === "uint")
        r = new Kk(e);
      else if (t === "vec2" || t === "ivec2" || t === "uvec2")
        r = new Zk(e);
      else if (t === "vec3" || t === "ivec3" || t === "uvec3")
        r = new Qk(e);
      else if (t === "vec4" || t === "ivec4" || t === "uvec4")
        r = new Jk(e);
      else if (t === "color")
        r = new eG(e);
      else if (t === "mat2")
        r = new tG(e);
      else if (t === "mat3")
        r = new nG(e);
      else if (t === "mat4")
        r = new iG(e);
      else
        throw new Error(`Uniform "${t}" not implemented.`);
      n.cache = r;
    }
    return r;
  }
  /**
   * Formats the given shader snippet from a given type into another one. E.g.
   * this method might be used to convert a simple float string `"1.0"` into a
   * `vec3` representation: `"vec3<f32>( 1.0 )"`.
   *
   * @param {string} snippet - The shader snippet.
   * @param {string} fromType - The source type.
   * @param {string} toType - The target type.
   * @return {string} The updated shader string.
   */
  format(e, t, n) {
    if (t = this.getVectorType(t), n = this.getVectorType(n), t === n || n === null || this.isReference(n))
      return e;
    const r = this.getTypeLength(t), s = this.getTypeLength(n);
    return r === 16 && s === 9 ? `${this.getType(n)}( ${e}[ 0 ].xyz, ${e}[ 1 ].xyz, ${e}[ 2 ].xyz )` : r === 9 && s === 4 ? `${this.getType(n)}( ${e}[ 0 ].xy, ${e}[ 1 ].xy )` : r > 4 || s > 4 || s === 0 ? e : r === s ? `${this.getType(n)}( ${e} )` : r > s ? (e = n === "bool" ? `all( ${e} )` : `${e}.${"xyz".slice(0, s)}`, this.format(e, this.getTypeFromLength(s, this.getComponentType(t)), n)) : s === 4 && r > 1 ? `${this.getType(n)}( ${this.format(e, t, "vec3")}, 1.0 )` : r === 2 ? `${this.getType(n)}( ${this.format(e, t, "vec2")}, 0.0 )` : (r === 1 && s > 1 && t !== this.getComponentType(n) && (e = `${this.getType(this.getComponentType(n))}( ${e} )`), `${this.getType(n)}( ${e} )`);
  }
  /**
   * Returns a signature with the engine's current revision.
   *
   * @return {string} The signature.
   */
  getSignature() {
    return `// Three.js r${za} - Node System
`;
  }
  /**
   * Returns `true` if data from the previous frame are required. Relevant
   * when computing motion vectors with {@link VelocityNode}.
   *
   * @return {boolean} Whether data from the previous frame are required or not.
   */
  needsPreviousData() {
    const e = this.renderer.getMRT();
    return e && e.has("velocity") || yb(this.object).useVelocity === !0;
  }
}
class jx {
  /**
   * Constructs a new node fame.
   */
  constructor() {
    this.time = 0, this.deltaTime = 0, this.frameId = 0, this.renderId = 0, this.updateMap = /* @__PURE__ */ new WeakMap(), this.updateBeforeMap = /* @__PURE__ */ new WeakMap(), this.updateAfterMap = /* @__PURE__ */ new WeakMap(), this.renderer = null, this.material = null, this.camera = null, this.object = null, this.scene = null;
  }
  /**
   * Returns a dictionary for a given node and update map which
   * is used to correctly call node update methods per frame or render.
   *
   * @private
   * @param {WeakMap<Node, Object>} referenceMap - The reference weak map.
   * @param {Node} nodeRef - The reference to the current node.
   * @return {Object<string,WeakMap<Object, number>>} The dictionary.
   */
  _getMaps(e, t) {
    let n = e.get(t);
    return n === void 0 && (n = {
      renderId: 0,
      frameId: 0
    }, e.set(t, n)), n;
  }
  /**
   * This method executes the {@link Node#updateBefore} for the given node.
   * It makes sure {@link Node#updateBeforeType} is honored meaning the update
   * is only executed once per frame, render or object depending on the update
   * type.
   *
   * @param {Node} node - The node that should be updated.
   */
  updateBeforeNode(e) {
    const t = e.getUpdateBeforeType(), n = e.updateReference(this);
    if (t === it.FRAME) {
      const r = this._getMaps(this.updateBeforeMap, n);
      if (r.frameId !== this.frameId) {
        const s = r.frameId;
        r.frameId = this.frameId, e.updateBefore(this) === !1 && (r.frameId = s);
      }
    } else if (t === it.RENDER) {
      const r = this._getMaps(this.updateBeforeMap, n);
      if (r.renderId !== this.renderId) {
        const s = r.renderId;
        r.renderId = this.renderId, e.updateBefore(this) === !1 && (r.renderId = s);
      }
    } else
      t === it.OBJECT && e.updateBefore(this);
  }
  /**
   * This method executes the {@link Node#updateAfter} for the given node.
   * It makes sure {@link Node#updateAfterType} is honored meaning the update
   * is only executed once per frame, render or object depending on the update
   * type.
   *
   * @param {Node} node - The node that should be updated.
   */
  updateAfterNode(e) {
    const t = e.getUpdateAfterType(), n = e.updateReference(this);
    if (t === it.FRAME) {
      const r = this._getMaps(this.updateAfterMap, n);
      r.frameId !== this.frameId && e.updateAfter(this) !== !1 && (r.frameId = this.frameId);
    } else if (t === it.RENDER) {
      const r = this._getMaps(this.updateAfterMap, n);
      r.renderId !== this.renderId && e.updateAfter(this) !== !1 && (r.renderId = this.renderId);
    } else
      t === it.OBJECT && e.updateAfter(this);
  }
  /**
   * This method executes the {@link Node#update} for the given node.
   * It makes sure {@link Node#updateType} is honored meaning the update
   * is only executed once per frame, render or object depending on the update
   * type.
   *
   * @param {Node} node - The node that should be updated.
   */
  updateNode(e) {
    const t = e.getUpdateType(), n = e.updateReference(this);
    if (t === it.FRAME) {
      const r = this._getMaps(this.updateMap, n);
      r.frameId !== this.frameId && e.update(this) !== !1 && (r.frameId = this.frameId);
    } else if (t === it.RENDER) {
      const r = this._getMaps(this.updateMap, n);
      r.renderId !== this.renderId && e.update(this) !== !1 && (r.renderId = this.renderId);
    } else
      t === it.OBJECT && e.update(this);
  }
  /**
   * Updates the internal state of the node frame. This method is
   * called by the renderer in its internal animation loop.
   */
  update() {
    this.frameId++, this.lastTime === void 0 && (this.lastTime = performance.now()), this.deltaTime = (performance.now() - this.lastTime) / 1e3, this.lastTime = performance.now(), this.time += this.deltaTime;
  }
}
class zg {
  /**
   * Constructs a new node function input.
   *
   * @param {string} type - The input type.
   * @param {string} name - The input name.
   * @param {?number} [count=null] - If the input is an Array, count will be the length.
   * @param {('in'|'out'|'inout')} [qualifier=''] - The parameter qualifier (only relevant for GLSL).
   * @param {boolean} [isConst=false] - Whether the input uses a const qualifier or not (only relevant for GLSL).
   */
  constructor(e, t, n = null, r = "", s = !1) {
    this.type = e, this.name = t, this.count = n, this.qualifier = r, this.isConst = s;
  }
}
zg.isNodeFunctionInput = !0;
class oG extends ja {
  static get type() {
    return "AmbientLightNode";
  }
  /**
   * Constructs a new ambient light node.
   *
   * @param {?AmbientLight} [light=null] - The ambient light source.
   */
  constructor(e = null) {
    super(e);
  }
  setup({ context: e }) {
    e.irradiance.addAssign(this.colorNode);
  }
}
class lG extends ja {
  static get type() {
    return "DirectionalLightNode";
  }
  /**
   * Constructs a new directional light node.
   *
   * @param {?DirectionalLight} [light=null] - The directional light source.
   */
  constructor(e = null) {
    super(e);
  }
  setupDirect() {
    const e = this.colorNode;
    return { lightDirection: tT(this.light), lightColor: e };
  }
}
class cG extends ja {
  static get type() {
    return "HemisphereLightNode";
  }
  /**
   * Constructs a new hemisphere light node.
   *
   * @param {?HemisphereLight} [light=null] - The hemisphere light source.
   */
  constructor(e = null) {
    super(e), this.lightPositionNode = JS(e), this.lightDirectionNode = this.lightPositionNode.normalize(), this.groundColorNode = je(new He()).setGroup(Xe);
  }
  /**
   * Overwritten to updated hemisphere light specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    const { light: t } = this;
    super.update(e), this.lightPositionNode.object3d = t, this.groundColorNode.value.copy(t.groundColor).multiplyScalar(t.intensity);
  }
  setup(e) {
    const { colorNode: t, groundColorNode: n, lightDirectionNode: r } = this, a = Pl.dot(r).mul(0.5).add(0.5), o = Lt(n, t, a);
    e.context.irradiance.addAssign(o);
  }
}
class Hg extends ja {
  static get type() {
    return "SpotLightNode";
  }
  /**
   * Constructs a new spot light node.
   *
   * @param {?SpotLight} [light=null] - The spot light source.
   */
  constructor(e = null) {
    super(e), this.coneCosNode = je(0).setGroup(Xe), this.penumbraCosNode = je(0).setGroup(Xe), this.cutoffDistanceNode = je(0).setGroup(Xe), this.decayExponentNode = je(0).setGroup(Xe), this.colorNode = je(this.color).setGroup(Xe);
  }
  /**
   * Overwritten to updated spot light specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    super.update(e);
    const { light: t } = this;
    this.coneCosNode.value = Math.cos(t.angle), this.penumbraCosNode.value = Math.cos(t.angle * (1 - t.penumbra)), this.cutoffDistanceNode.value = t.distance, this.decayExponentNode.value = t.decay;
  }
  /**
   * Computes the spot attenuation for the given angle.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @param {Node<float>} angleCosine - The angle to compute the spot attenuation for.
   * @return {Node<float>} The spot attenuation.
   */
  getSpotAttenuation(e, t) {
    const { coneCosNode: n, penumbraCosNode: r } = this;
    return hs(n, r, t);
  }
  getLightCoord(e) {
    const t = e.getNodeProperties(this);
    let n = t.projectionUV;
    return n === void 0 && (n = ZO(this.light, e.context.positionWorld), t.projectionUV = n), n;
  }
  setupDirect(e) {
    const { colorNode: t, cutoffDistanceNode: n, decayExponentNode: r, light: s } = this, a = this.getLightVector(e), o = a.normalize(), l = o.dot(tT(s)), c = this.getSpotAttenuation(e, l), u = a.length(), h = sT({
      lightDistance: u,
      cutoffDistance: n,
      decayExponent: r
    });
    let d = t.mul(c).mul(h), f, p;
    return s.colorNode ? (p = this.getLightCoord(e), f = s.colorNode(p)) : s.map && (p = this.getLightCoord(e), f = qt(s.map, p.xy).onRenderUpdate(() => s.map)), f && (d = p.mul(2).sub(1).abs().lessThan(1).all().select(d.mul(f), d)), { lightColor: d, lightDirection: o };
  }
}
class uG extends Hg {
  static get type() {
    return "IESSpotLightNode";
  }
  /**
   * Overwrites the default implementation to compute an IES conform spot attenuation.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @param {Node<float>} angleCosine - The angle to compute the spot attenuation for.
   * @return {Node<float>} The spot attenuation.
   */
  getSpotAttenuation(e, t) {
    const n = this.light.iesMap;
    let r = null;
    if (n && n.isTexture === !0) {
      const s = t.acos().mul(1 / Math.PI);
      r = qt(n, Pe(s, 0), 0).r;
    } else
      r = super.getSpotAttenuation(t);
    return r;
  }
}
class hG extends ja {
  static get type() {
    return "LightProbeNode";
  }
  /**
   * Constructs a new light probe node.
   *
   * @param {?LightProbe} [light=null] - The light probe.
   */
  constructor(e = null) {
    super(e);
    const t = [];
    for (let n = 0; n < 9; n++)
      t.push(new P());
    this.lightProbe = Ii(t);
  }
  /**
   * Overwritten to updated light probe specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    const { light: t } = this;
    super.update(e);
    for (let n = 0; n < 9; n++)
      this.lightProbe.array[n].copy(t.sh.coefficients[n]).multiplyScalar(t.intensity);
  }
  setup(e) {
    const t = Lk(Pl, this.lightProbe);
    e.context.irradiance.addAssign(t);
  }
}
const dG = /* @__PURE__ */ ee(([i, e]) => {
  const t = i.abs().sub(e);
  return cs(kn(t, 0)).add(fl(kn(t.x, t.y), 0));
});
class fG extends Hg {
  static get type() {
    return "ProjectorLightNode";
  }
  update(e) {
    super.update(e);
    const t = this.light;
    if (this.penumbraCosNode.value = Math.min(Math.cos(t.angle * (1 - t.penumbra)), 0.99999), t.aspect === null) {
      let n = 1;
      t.map !== null && (n = t.map.width / t.map.height), t.shadow.aspect = n;
    } else
      t.shadow.aspect = t.aspect;
  }
  /**
   * Overwrites the default implementation to compute projection attenuation.
   *
   * @param {NodeBuilder} builder - The node builder.
   * @return {Node<float>} The spot attenuation.
   */
  getSpotAttenuation(e) {
    const t = K(0), n = this.penumbraCosNode, r = Vg(this.light).mul(e.context.positionWorld || pl);
    return Bt(r.w.greaterThan(0), () => {
      const s = r.xyz.div(r.w), a = dG(s.xy.sub(Pe(0.5)), Pe(0.5)), o = Nr(-1, ui(1, Gb(n)).sub(1));
      t.assign(Ng(a.mul(-2).mul(o)));
    }), t;
  }
}
const sp = /* @__PURE__ */ new pt(), lh = /* @__PURE__ */ new pt();
let nc = null;
class pG extends ja {
  static get type() {
    return "RectAreaLightNode";
  }
  /**
   * Constructs a new rect area light node.
   *
   * @param {?RectAreaLight} [light=null] - The rect area light source.
   */
  constructor(e = null) {
    super(e), this.halfHeight = je(new P()).setGroup(Xe), this.halfWidth = je(new P()).setGroup(Xe), this.updateType = it.RENDER;
  }
  /**
   * Overwritten to updated rect area light specific uniforms.
   *
   * @param {NodeFrame} frame - A reference to the current node frame.
   */
  update(e) {
    super.update(e);
    const { light: t } = this, n = e.camera.matrixWorldInverse;
    lh.identity(), sp.copy(t.matrixWorld), sp.premultiply(n), lh.extractRotation(sp), this.halfWidth.value.set(t.width * 0.5, 0, 0), this.halfHeight.value.set(0, t.height * 0.5, 0), this.halfWidth.value.applyMatrix4(lh), this.halfHeight.value.applyMatrix4(lh);
  }
  setupDirectRectArea(e) {
    let t, n;
    e.isAvailable("float32Filterable") ? (t = qt(nc.LTC_FLOAT_1), n = qt(nc.LTC_FLOAT_2)) : (t = qt(nc.LTC_HALF_1), n = qt(nc.LTC_HALF_2));
    const { colorNode: r, light: s } = this, a = eT(s);
    return {
      lightColor: r,
      lightPosition: a,
      halfWidth: this.halfWidth,
      halfHeight: this.halfHeight,
      ltc_1: t,
      ltc_2: n
    };
  }
  /**
   * Used to configure the internal BRDF approximation texture data.
   *
   * @param {RectAreaLightTexturesLib} ltc - The BRDF approximation texture data.
   */
  static setLTC(e) {
    nc = e;
  }
}
class lT {
  /**
   * The method parses the given native code an returns a node function.
   *
   * @abstract
   * @param {string} source - The native shader code.
   * @return {NodeFunction} A node function.
   */
  parseFunction() {
    oe("Abstract function.");
  }
}
class $g {
  /**
   * Constructs a new node function.
   *
   * @param {string} type - The node type. This type is the return type of the node function.
   * @param {Array<NodeFunctionInput>} inputs - The function's inputs.
   * @param {string} [name=''] - The function's name.
   * @param {string} [precision=''] - The precision qualifier.
   */
  constructor(e, t, n = "", r = "") {
    this.type = e, this.inputs = t, this.name = n, this.precision = r;
  }
  /**
   * This method returns the native code of the node function.
   *
   * @abstract
   * @param {string} name - The function's name.
   * @return {string} A shader code.
   */
  getCode() {
    oe("Abstract function.");
  }
}
$g.isNodeFunction = !0;
const mG = /^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i, gG = /[a-z_0-9]+/ig, Yx = "#pragma main", _G = (i) => {
  i = i.trim();
  const e = i.indexOf(Yx), t = e !== -1 ? i.slice(e + Yx.length) : i, n = t.match(mG);
  if (n !== null && n.length === 5) {
    const r = n[4], s = [];
    let a = null;
    for (; (a = gG.exec(r)) !== null; )
      s.push(a);
    const o = [];
    let l = 0;
    for (; l < s.length; ) {
      const p = s[l][0] === "const";
      p === !0 && l++;
      let _ = s[l][0];
      _ === "in" || _ === "out" || _ === "inout" ? l++ : _ = "";
      const g = s[l++][0];
      let m = Number.parseInt(s[l][0]);
      Number.isNaN(m) === !1 ? l++ : m = null;
      const x = s[l++][0];
      o.push(new zg(g, x, m, _, p));
    }
    const c = t.substring(n[0].length), u = n[3] !== void 0 ? n[3] : "", h = n[2], d = n[1] !== void 0 ? n[1] : "", f = e !== -1 ? i.slice(0, e) : "";
    return {
      type: h,
      inputs: o,
      name: u,
      precision: d,
      inputsCode: r,
      blockCode: c,
      headerCode: f
    };
  } else
    throw new Error("FunctionNode: Function is not a GLSL code.");
};
class xG extends $g {
  /**
   * Constructs a new GLSL node function.
   *
   * @param {string} source - The GLSL source.
   */
  constructor(e) {
    const { type: t, inputs: n, name: r, precision: s, inputsCode: a, blockCode: o, headerCode: l } = _G(e);
    super(t, n, r, s), this.inputsCode = a, this.blockCode = o, this.headerCode = l;
  }
  /**
   * This method returns the GLSL code of the node function.
   *
   * @param {string} [name=this.name] - The function's name.
   * @return {string} The shader code.
   */
  getCode(e = this.name) {
    let t;
    const n = this.blockCode;
    if (n !== "") {
      const { type: r, inputsCode: s, headerCode: a, precision: o } = this;
      let l = `${r} ${e} ( ${s.trim()} )`;
      o !== "" && (l = `${o} ${l}`), t = a + l + n;
    } else
      t = "";
    return t;
  }
}
class vG extends lT {
  /**
   * The method parses the given GLSL code an returns a node function.
   *
   * @param {string} source - The GLSL code.
   * @return {GLSLNodeFunction} A node function.
   */
  parseFunction(e) {
    return new xG(e);
  }
}
const Kx = /* @__PURE__ */ new WeakMap(), Di = [], Ms = [];
class yG extends Ks {
  /**
   * Constructs a new nodes management component.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {Backend} backend - The renderer's backend.
   */
  constructor(e, t) {
    super(), this.renderer = e, this.backend = t, this.nodeFrame = new jx(), this.nodeBuilderCache = /* @__PURE__ */ new Map(), this.callHashCache = new qs(), this.groupsData = new qs(), this.cacheLib = {};
  }
  /**
   * Returns `true` if the given node uniforms group must be updated or not.
   *
   * @param {NodeUniformsGroup} nodeUniformsGroup - The node uniforms group.
   * @return {boolean} Whether the node uniforms group requires an update or not.
   */
  updateGroup(e) {
    const t = e.groupNode, n = t.name;
    if (n === Ub.name)
      return !0;
    if (n === Xe.name) {
      const s = this.get(e), a = this.nodeFrame.renderId;
      return s.renderId !== a ? (s.renderId = a, !0) : !1;
    }
    if (n === O2.name) {
      const s = this.get(e), a = this.nodeFrame.frameId;
      return s.frameId !== a ? (s.frameId = a, !0) : !1;
    }
    Di[0] = t, Di[1] = e;
    let r = this.groupsData.get(Di);
    return r === void 0 && this.groupsData.set(Di, r = {}), Di[0] = null, Di[1] = null, r.version !== t.version ? (r.version = t.version, !0) : !1;
  }
  /**
   * Returns the cache key for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {number} The cache key.
   */
  getForRenderCacheKey(e) {
    return e.initialCacheKey;
  }
  /**
   * Returns a node builder state for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {NodeBuilderState} The node builder state.
   */
  getForRender(e) {
    const t = this.get(e);
    let n = t.nodeBuilderState;
    if (n === void 0) {
      const { nodeBuilderCache: r } = this, s = this.getForRenderCacheKey(e);
      if (n = r.get(s), n === void 0) {
        const a = (l) => {
          const c = this.backend.createNodeBuilder(e.object, this.renderer);
          return c.scene = e.scene, c.material = l, c.camera = e.camera, c.context.material = l, c.lightsNode = e.lightsNode, c.environmentNode = this.getEnvironmentNode(e.scene), c.fogNode = this.getFogNode(e.scene), c.clippingContext = e.clippingContext, this.renderer.getOutputRenderTarget() && this.renderer.getOutputRenderTarget().multiview && c.enableMultiview(), c;
        };
        let o = a(e.material);
        try {
          o.build();
        } catch (l) {
          o = a(new dn()), o.build();
          let c = l.stackTrace;
          !c && l.stack && (c = new Yn(l.stack)), le("TSL: " + l, c);
        }
        n = this._createNodeBuilderState(o), r.set(s, n);
      }
      n.usedTimes++, t.nodeBuilderState = n;
    }
    return n;
  }
  /**
   * Deletes the given object from the internal data map
   *
   * @param {any} object - The object to delete.
   * @return {?Object} The deleted dictionary.
   */
  delete(e) {
    if (e.isRenderObject) {
      const t = this.get(e).nodeBuilderState;
      t.usedTimes--, t.usedTimes === 0 && this.nodeBuilderCache.delete(this.getForRenderCacheKey(e));
    }
    return super.delete(e);
  }
  /**
   * Returns a node builder state for the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   * @return {NodeBuilderState} The node builder state.
   */
  getForCompute(e) {
    const t = this.get(e);
    let n = t.nodeBuilderState;
    if (n === void 0) {
      const r = this.backend.createNodeBuilder(e, this.renderer);
      r.build(), n = this._createNodeBuilderState(r), t.nodeBuilderState = n;
    }
    return n;
  }
  /**
   * Creates a node builder state for the given node builder.
   *
   * @private
   * @param {NodeBuilder} nodeBuilder - The node builder.
   * @return {NodeBuilderState} The node builder state.
   */
  _createNodeBuilderState(e) {
    return new Uk(
      e.vertexShader,
      e.fragmentShader,
      e.computeShader,
      e.getAttributesArray(),
      e.getBindings(),
      e.updateNodes,
      e.updateBeforeNodes,
      e.updateAfterNodes,
      e.observer,
      e.transforms
    );
  }
  /**
   * Returns an environment node for the current configured
   * scene environment.
   *
   * @param {Scene} scene - The scene.
   * @return {Node} A node representing the current scene environment.
   */
  getEnvironmentNode(e) {
    this.updateEnvironment(e);
    let t = null;
    if (e.environmentNode && e.environmentNode.isNode)
      t = e.environmentNode;
    else {
      const n = this.get(e);
      n.environmentNode && (t = n.environmentNode);
    }
    return t;
  }
  /**
   * Returns a background node for the current configured
   * scene background.
   *
   * @param {Scene} scene - The scene.
   * @return {Node} A node representing the current scene background.
   */
  getBackgroundNode(e) {
    this.updateBackground(e);
    let t = null;
    if (e.backgroundNode && e.backgroundNode.isNode)
      t = e.backgroundNode;
    else {
      const n = this.get(e);
      n.backgroundNode && (t = n.backgroundNode);
    }
    return t;
  }
  /**
   * Returns a fog node for the current configured scene fog.
   *
   * @param {Scene} scene - The scene.
   * @return {Node} A node representing the current scene fog.
   */
  getFogNode(e) {
    return this.updateFog(e), e.fogNode || this.get(e).fogNode || null;
  }
  /**
   * Returns a cache key for the given scene and lights node.
   * This key is used by `RenderObject` as a part of the dynamic
   * cache key (a key that must be checked every time the render
   * objects is drawn).
   *
   * @param {Scene} scene - The scene.
   * @param {LightsNode} lightsNode - The lights node.
   * @return {number} The cache key.
   */
  getCacheKey(e, t) {
    Di[0] = e, Di[1] = t;
    const n = this.renderer.info.calls, r = this.callHashCache.get(Di) || {};
    if (r.callId !== n) {
      const s = this.getEnvironmentNode(e), a = this.getFogNode(e);
      t && Ms.push(t.getCacheKey(!0)), s && Ms.push(s.getCacheKey()), a && Ms.push(a.getCacheKey()), Ms.push(this.renderer.getOutputRenderTarget() && this.renderer.getOutputRenderTarget().multiview ? 1 : 0), Ms.push(this.renderer.shadowMap.enabled ? 1 : 0), Ms.push(this.renderer.shadowMap.type), r.callId = n, r.cacheKey = ou(Ms), this.callHashCache.set(Di, r), Ms.length = 0;
    }
    return Di[0] = null, Di[1] = null, r.cacheKey;
  }
  /**
   * A boolean that indicates whether tone mapping should be enabled
   * or not.
   *
   * @type {boolean}
   */
  get isToneMappingState() {
    return !this.renderer.getRenderTarget();
  }
  /**
   * If a scene background is configured, this method makes sure to
   * represent the background with a corresponding node-based implementation.
   *
   * @param {Scene} scene - The scene.
   */
  updateBackground(e) {
    const t = this.get(e), n = e.background;
    if (n) {
      const r = e.backgroundBlurriness === 0 && t.backgroundBlurriness > 0 || e.backgroundBlurriness > 0 && t.backgroundBlurriness === 0;
      if (t.background !== n || r) {
        const s = this.getCacheNode("background", n, () => {
          if (n.isCubeTexture === !0 || n.mapping === Co || n.mapping === No || n.mapping === Ra) {
            if (e.backgroundBlurriness > 0 || n.mapping === Ra)
              return HS(n);
            {
              let a;
              return n.isCubeTexture === !0 ? a = di(n) : a = qt(n), FS(a);
            }
          } else {
            if (n.isTexture === !0)
              return qt(n, Ea.flipY()).setUpdateMatrix(!0);
            n.isColor !== !0 && le("WebGPUNodes: Unsupported background configuration.", n);
          }
        }, r);
        t.backgroundNode = s, t.background = n, t.backgroundBlurriness = e.backgroundBlurriness;
      }
    } else
      t.backgroundNode && (delete t.backgroundNode, delete t.background);
  }
  /**
   * This method is part of the caching of nodes which are used to represents the
   * scene's background, fog or environment.
   *
   * @param {string} type - The type of object to cache.
   * @param {Object} object - The object.
   * @param {Function} callback - A callback that produces a node representation for the given object.
   * @param {boolean} [forceUpdate=false] - Whether an update should be enforced or not.
   * @return {Node} The node representation.
   */
  getCacheNode(e, t, n, r = !1) {
    const s = this.cacheLib[e] || (this.cacheLib[e] = /* @__PURE__ */ new WeakMap());
    let a = s.get(t);
    return (a === void 0 || r) && (a = n(), s.set(t, a)), a;
  }
  /**
   * If a scene fog is configured, this method makes sure to
   * represent the fog with a corresponding node-based implementation.
   *
   * @param {Scene} scene - The scene.
   */
  updateFog(e) {
    const t = this.get(e), n = e.fog;
    if (n) {
      if (t.fog !== n) {
        const r = this.getCacheNode("fog", n, () => {
          if (n.isFogExp2) {
            const s = Qt("color", "color", n).setGroup(Xe), a = Qt("density", "float", n).setGroup(Xe);
            return Hx(s, YO(a));
          } else if (n.isFog) {
            const s = Qt("color", "color", n).setGroup(Xe), a = Qt("near", "float", n).setGroup(Xe), o = Qt("far", "float", n).setGroup(Xe);
            return Hx(s, jO(a, o));
          } else
            le("Renderer: Unsupported fog configuration.", n);
        });
        t.fogNode = r, t.fog = n;
      }
    } else
      delete t.fogNode, delete t.fog;
  }
  /**
   * If a scene environment is configured, this method makes sure to
   * represent the environment with a corresponding node-based implementation.
   *
   * @param {Scene} scene - The scene.
   */
  updateEnvironment(e) {
    const t = this.get(e), n = e.environment;
    if (n) {
      if (t.environment !== n) {
        const r = this.getCacheNode("environment", n, () => {
          if (n.isCubeTexture === !0)
            return di(n);
          if (n.isTexture === !0)
            return qt(n);
          le("Nodes: Unsupported environment configuration.", n);
        });
        t.environmentNode = r, t.environment = n;
      }
    } else
      t.environmentNode && (delete t.environmentNode, delete t.environment);
  }
  getNodeFrame(e = this.renderer, t = null, n = null, r = null, s = null) {
    const a = this.nodeFrame;
    return a.renderer = e, a.scene = t, a.object = n, a.camera = r, a.material = s, a;
  }
  getNodeFrameForRender(e) {
    return this.getNodeFrame(e.renderer, e.scene, e.object, e.camera, e.material);
  }
  /**
   * Returns the current output cache key.
   *
   * @return {string} The output cache key.
   */
  getOutputCacheKey() {
    const e = this.renderer;
    return e.toneMapping + "," + e.currentColorSpace + "," + e.xr.isPresenting;
  }
  /**
   * Checks if the output configuration (tone mapping and color space) for
   * the given target has changed.
   *
   * @param {Texture} outputTarget - The output target.
   * @return {boolean} Whether the output configuration has changed or not.
   */
  hasOutputChange(e) {
    return Kx.get(e) !== this.getOutputCacheKey();
  }
  /**
   * Returns a node that represents the output configuration (tone mapping and
   * color space) for the current target.
   *
   * @param {Texture} outputTarget - The output target.
   * @return {Node} The output node.
   */
  getOutputNode(e) {
    const t = this.renderer, n = this.getOutputCacheKey(), r = e.isArrayTexture ? IO(e, Y(Ea, Cl("gl_ViewID_OVR"))).renderOutput(t.toneMapping, t.currentColorSpace) : qt(e, Ea).renderOutput(t.toneMapping, t.currentColorSpace);
    return Kx.set(e, n), r;
  }
  /**
   * Triggers the call of `updateBefore()` methods
   * for all nodes of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateBefore(e) {
    const t = e.getNodeBuilderState();
    for (const n of t.updateBeforeNodes)
      this.getNodeFrameForRender(e).updateBeforeNode(n);
  }
  /**
   * Triggers the call of `updateAfter()` methods
   * for all nodes of the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateAfter(e) {
    const t = e.getNodeBuilderState();
    for (const n of t.updateAfterNodes)
      this.getNodeFrameForRender(e).updateAfterNode(n);
  }
  /**
   * Triggers the call of `update()` methods
   * for all nodes of the given compute node.
   *
   * @param {Node} computeNode - The compute node.
   */
  updateForCompute(e) {
    const t = this.getNodeFrame(), n = this.getForCompute(e);
    for (const r of n.updateNodes)
      t.updateNode(r);
  }
  /**
   * Triggers the call of `update()` methods
   * for all nodes of the given compute node.
   *
   * @param {RenderObject} renderObject - The render object.
   */
  updateForRender(e) {
    const t = this.getNodeFrameForRender(e), n = e.getNodeBuilderState();
    for (const r of n.updateNodes)
      t.updateNode(r);
  }
  /**
   * Returns `true` if the given render object requires a refresh.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the given render object requires a refresh or not.
   */
  needsRefresh(e) {
    const t = this.getNodeFrameForRender(e);
    return e.getMonitor().needsRefresh(e, t);
  }
  /**
   * Frees the internal resources.
   */
  dispose() {
    super.dispose(), this.nodeFrame = new jx(), this.nodeBuilderCache = /* @__PURE__ */ new Map(), this.cacheLib = {};
  }
}
const ap = /* @__PURE__ */ new Zi();
class Kh {
  /**
   * Constructs a new clipping context.
   *
   * @param {?ClippingContext} [parentContext=null] - A reference to the parent clipping context.
   */
  constructor(e = null) {
    this.version = 0, this.clipIntersection = null, this.cacheKey = "", this.shadowPass = !1, this.viewNormalMatrix = new nt(), this.clippingGroupContexts = /* @__PURE__ */ new WeakMap(), this.intersectionPlanes = [], this.unionPlanes = [], this.parentVersion = null, e !== null && (this.viewNormalMatrix = e.viewNormalMatrix, this.clippingGroupContexts = e.clippingGroupContexts, this.shadowPass = e.shadowPass, this.viewMatrix = e.viewMatrix);
  }
  /**
   * Projects the given source clipping planes and writes the result into the
   * destination array.
   *
   * @param {Array<Plane>} source - The source clipping planes.
   * @param {Array<Vector4>} destination - The destination.
   * @param {number} offset - The offset.
   */
  projectPlanes(e, t, n) {
    const r = e.length;
    for (let s = 0; s < r; s++) {
      ap.copy(e[s]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix);
      const a = t[n + s], o = ap.normal;
      a.x = -o.x, a.y = -o.y, a.z = -o.z, a.w = ap.constant;
    }
  }
  /**
   * Updates the root clipping context of a scene.
   *
   * @param {Scene} scene - The scene.
   * @param {Camera} camera - The camera that is used to render the scene.
   */
  updateGlobal(e, t) {
    this.shadowPass = e.overrideMaterial !== null && e.overrideMaterial.isShadowPassMaterial, this.viewMatrix = t.matrixWorldInverse, this.viewNormalMatrix.getNormalMatrix(this.viewMatrix);
  }
  /**
   * Updates the clipping context.
   *
   * @param {ClippingContext} parentContext - The parent context.
   * @param {ClippingGroup} clippingGroup - The clipping group this context belongs to.
   */
  update(e, t) {
    let n = !1;
    e.version !== this.parentVersion && (this.intersectionPlanes = Array.from(e.intersectionPlanes), this.unionPlanes = Array.from(e.unionPlanes), this.parentVersion = e.version), this.clipIntersection !== t.clipIntersection && (this.clipIntersection = t.clipIntersection, this.clipIntersection ? this.unionPlanes.length = e.unionPlanes.length : this.intersectionPlanes.length = e.intersectionPlanes.length);
    const r = t.clippingPlanes, s = r.length;
    let a, o;
    if (this.clipIntersection ? (a = this.intersectionPlanes, o = e.intersectionPlanes.length) : (a = this.unionPlanes, o = e.unionPlanes.length), a.length !== o + s) {
      a.length = o + s;
      for (let l = 0; l < s; l++)
        a[o + l] = new rt();
      n = !0;
    }
    this.projectPlanes(r, a, o), n && (this.version++, this.cacheKey = `${this.intersectionPlanes.length}:${this.unionPlanes.length}`);
  }
  /**
   * Returns a clipping context for the given clipping group.
   *
   * @param {ClippingGroup} clippingGroup - The clipping group.
   * @return {ClippingContext} The clipping context.
   */
  getGroupContext(e) {
    if (this.shadowPass && !e.clipShadows)
      return this;
    let t = this.clippingGroupContexts.get(e);
    return t === void 0 && (t = new Kh(this), this.clippingGroupContexts.set(e, t)), t.update(this, e), t;
  }
  /**
   * The count of union clipping planes.
   *
   * @type {number}
   * @readonly
   */
  get unionClippingCount() {
    return this.unionPlanes.length;
  }
}
class bG {
  /**
   * Constructs a new bundle group.
   *
   * @param {BundleGroup} bundleGroup - The bundle group.
   * @param {Camera} camera - The camera the bundle group is rendered with.
   */
  constructor(e, t) {
    this.bundleGroup = e, this.camera = t;
  }
}
const vo = [];
class SG {
  /**
   * Constructs a new render bundle management component.
   */
  constructor() {
    this.bundles = new qs();
  }
  /**
   * Returns a render bundle for the given bundle group and camera.
   *
   * @param {BundleGroup} bundleGroup - The bundle group.
   * @param {Camera} camera - The camera the bundle group is rendered with.
   * @return {RenderBundle} The render bundle.
   */
  get(e, t) {
    const n = this.bundles;
    vo[0] = e, vo[1] = t;
    let r = n.get(vo);
    return r === void 0 && (r = new bG(e, t), n.set(vo, r)), vo[0] = null, vo[1] = null, r;
  }
  /**
   * Frees all internal resources.
   */
  dispose() {
    this.bundles = new qs();
  }
}
class cT {
  /**
   * Constructs a new node library.
   */
  constructor() {
    this.lightNodes = /* @__PURE__ */ new WeakMap(), this.materialNodes = /* @__PURE__ */ new Map(), this.toneMappingNodes = /* @__PURE__ */ new Map();
  }
  /**
   * Returns a matching node material instance for the given material object.
   *
   * This method also assigns/copies the properties of the given material object
   * to the node material. This is done to make sure the current material
   * configuration carries over to the node version.
   *
   * @param {Material} material - A material.
   * @return {NodeMaterial} The corresponding node material.
   */
  fromMaterial(e) {
    if (e.isNodeMaterial)
      return e;
    let t = null;
    const n = this.getMaterialNodeClass(e.type);
    if (n !== null) {
      t = new n();
      for (const r in e)
        t[r] = e[r];
    }
    return t;
  }
  /**
   * Adds a tone mapping node function for a tone mapping technique (constant).
   *
   * @param {Function} toneMappingNode - The tone mapping node function.
   * @param {number} toneMapping - The tone mapping.
   */
  addToneMapping(e, t) {
    this.addType(e, t, this.toneMappingNodes);
  }
  /**
   * Returns a tone mapping node function for a tone mapping technique (constant).
   *
   * @param {number} toneMapping - The tone mapping.
   * @return {?Function} The tone mapping node function. Returns `null` if no node function is found.
   */
  getToneMappingFunction(e) {
    return this.toneMappingNodes.get(e) || null;
  }
  /**
   * Returns a node material class definition for a material type.
   *
   * @param {string} materialType - The material type.
   * @return {?NodeMaterial.constructor} The node material class definition. Returns `null` if no node material is found.
   */
  getMaterialNodeClass(e) {
    return this.materialNodes.get(e) || null;
  }
  /**
   * Adds a node material class definition for a given material type.
   *
   * @param {NodeMaterial.constructor} materialNodeClass - The node material class definition.
   * @param {string} materialClassType - The material type.
   */
  addMaterial(e, t) {
    this.addType(e, t, this.materialNodes);
  }
  /**
   * Returns a light node class definition for a light class definition.
   *
   * @param {Light.constructor} light - The light class definition.
   * @return {?AnalyticLightNode.constructor} The light node class definition. Returns `null` if no light node is found.
   */
  getLightNodeClass(e) {
    return this.lightNodes.get(e) || null;
  }
  /**
   * Adds a light node class definition for a given light class definition.
   *
   * @param {AnalyticLightNode.constructor} lightNodeClass - The light node class definition.
   * @param {Light.constructor} lightClass - The light class definition.
   */
  addLight(e, t) {
    this.addClass(e, t, this.lightNodes);
  }
  /**
   * Adds a node class definition for the given type to the provided type library.
   *
   * @param {Node.constructor} nodeClass - The node class definition.
   * @param {number|string} type - The object type.
   * @param {Map<number|string,Node.constructor>} library - The type library.
   */
  addType(e, t, n) {
    if (n.has(t)) {
      oe(`Redefinition of node ${t}`);
      return;
    }
    if (typeof e != "function")
      throw new Error(`Node class ${e.name} is not a class.`);
    if (typeof t == "function" || typeof t == "object")
      throw new Error(`Base class ${t} is not a class.`);
    n.set(t, e);
  }
  /**
   * Adds a node class definition for the given class definition to the provided type library.
   *
   * @param {Node.constructor} nodeClass - The node class definition.
   * @param {Node.constructor} baseClass - The class definition.
   * @param {WeakMap<Node.constructor, Node.constructor>} library - The type library.
   */
  addClass(e, t, n) {
    if (n.has(t)) {
      oe(`Redefinition of node ${t.name}`);
      return;
    }
    if (typeof e != "function")
      throw new Error(`Node class ${e.name} is not a class.`);
    if (typeof t != "function")
      throw new Error(`Base class ${t.name} is not a class.`);
    n.set(t, e);
  }
}
const TG = /* @__PURE__ */ new nT(), Zx = /* @__PURE__ */ new WeakMap();
class MG {
  /**
   * Creates a new lights node for the given array of lights.
   *
   * @param {Array<Light>} lights - The render object.
   * @return {LightsNode} The lights node.
   */
  createNode(e = []) {
    return new nT().setLights(e);
  }
  /**
   * Returns a lights node for the given scene and camera.
   *
   * @param {Scene} scene - The scene.
   * @param {Camera} camera - The camera.
   * @return {LightsNode} The lights node.
   */
  getNode(e) {
    if (e.isQuadMesh)
      return TG;
    let t = Zx.get(e);
    return t === void 0 && (t = this.createNode(), Zx.set(e, t)), t;
  }
}
class hc extends js {
  /**
   * Constructs a new XR render target.
   *
   * @param {number} [width=1] - The width of the render target.
   * @param {number} [height=1] - The height of the render target.
   * @param {Object} [options={}] - The configuration options.
   */
  constructor(e = 1, t = 1, n = {}) {
    super(e, t, n), this.isXRRenderTarget = !0, this._hasExternalTextures = !1, this._autoAllocateDepthBuffer = !0, this._isOpaqueFramebuffer = !1;
  }
  copy(e) {
    return super.copy(e), this._hasExternalTextures = e._hasExternalTextures, this._autoAllocateDepthBuffer = e._autoAllocateDepthBuffer, this._isOpaqueFramebuffer = e._isOpaqueFramebuffer, this;
  }
}
const Qx = /* @__PURE__ */ new P(), Jx = /* @__PURE__ */ new P();
class EG extends Fr {
  /**
   * Constructs a new XR manager.
   *
   * @param {Renderer} renderer - The renderer.
   * @param {boolean} [multiview=false] - Enables multiview if the device supports it.
   */
  constructor(e, t = !1) {
    super(), this.enabled = !1, this.isPresenting = !1, this.cameraAutoUpdate = !0, this._renderer = e, this._cameraL = new An(), this._cameraL.viewport = new rt(), this._cameraR = new An(), this._cameraR.viewport = new rt(), this._cameras = [this._cameraL, this._cameraR], this._cameraXR = new my(), this._currentDepthNear = null, this._currentDepthFar = null, this._controllers = [], this._controllerInputSources = [], this._xrRenderTarget = null, this._layers = [], this._sessionUsesLayers = !1, this._supportsGlBinding = typeof XRWebGLBinding < "u", this._frameBufferTargets = null, this._createXRLayer = PG.bind(this), this._gl = null, this._currentAnimationContext = null, this._currentAnimationLoop = null, this._currentPixelRatio = null, this._currentSize = new de(), this._onSessionEvent = RG.bind(this), this._onSessionEnd = CG.bind(this), this._onInputSourcesChange = NG.bind(this), this._onAnimationFrame = DG.bind(this), this._referenceSpace = null, this._referenceSpaceType = "local-floor", this._customReferenceSpace = null, this._framebufferScaleFactor = 1, this._foveation = 1, this._session = null, this._glBaseLayer = null, this._glBinding = null, this._glProjLayer = null, this._xrFrame = null, this._supportsLayers = this._supportsGlBinding && "createProjectionLayer" in XRWebGLBinding.prototype, this._useMultiviewIfPossible = t, this._useMultiview = !1;
  }
  /**
   * Returns an instance of `THREE.Group` that represents the transformation
   * of a XR controller in target ray space. The requested controller is defined
   * by the given index.
   *
   * @param {number} index - The index of the XR controller.
   * @return {Group} A group that represents the controller's transformation.
   */
  getController(e) {
    return this._getController(e).getTargetRaySpace();
  }
  /**
   * Returns an instance of `THREE.Group` that represents the transformation
   * of a XR controller in grip space. The requested controller is defined
   * by the given index.
   *
   * @param {number} index - The index of the XR controller.
   * @return {Group} A group that represents the controller's transformation.
   */
  getControllerGrip(e) {
    return this._getController(e).getGripSpace();
  }
  /**
   * Returns an instance of `THREE.Group` that represents the transformation
   * of a XR controller in hand space. The requested controller is defined
   * by the given index.
   *
   * @param {number} index - The index of the XR controller.
   * @return {Group} A group that represents the controller's transformation.
   */
  getHand(e) {
    return this._getController(e).getHandSpace();
  }
  /**
   * Returns the foveation value.
   *
   * @return {number|undefined} The foveation value. Returns `undefined` if no base or projection layer is defined.
   */
  getFoveation() {
    if (!(this._glProjLayer === null && this._glBaseLayer === null))
      return this._foveation;
  }
  /**
   * Sets the foveation value.
   *
   * @param {number} foveation - A number in the range `[0,1]` where `0` means no foveation (full resolution)
   * and `1` means maximum foveation (the edges render at lower resolution).
   */
  setFoveation(e) {
    this._foveation = e, this._glProjLayer !== null && (this._glProjLayer.fixedFoveation = e), this._glBaseLayer !== null && this._glBaseLayer.fixedFoveation !== void 0 && (this._glBaseLayer.fixedFoveation = e);
  }
  /**
   * Returns the framebuffer scale factor.
   *
   * @return {number} The framebuffer scale factor.
   */
  getFramebufferScaleFactor() {
    return this._framebufferScaleFactor;
  }
  /**
   * Sets the framebuffer scale factor.
   *
   * This method can not be used during a XR session.
   *
   * @param {number} factor - The framebuffer scale factor.
   */
  setFramebufferScaleFactor(e) {
    this._framebufferScaleFactor = e, this.isPresenting === !0 && oe("XRManager: Cannot change framebuffer scale while presenting.");
  }
  /**
   * Returns the reference space type.
   *
   * @return {XRReferenceSpaceType} The reference space type.
   */
  getReferenceSpaceType() {
    return this._referenceSpaceType;
  }
  /**
   * Sets the reference space type.
   *
   * This method can not be used during a XR session.
   *
   * @param {XRReferenceSpaceType} type - The reference space type.
   */
  setReferenceSpaceType(e) {
    this._referenceSpaceType = e, this.isPresenting === !0 && oe("XRManager: Cannot change reference space type while presenting.");
  }
  /**
   * Returns the XR reference space.
   *
   * @return {XRReferenceSpace} The XR reference space.
   */
  getReferenceSpace() {
    return this._customReferenceSpace || this._referenceSpace;
  }
  /**
   * Sets a custom XR reference space.
   *
   * @param {XRReferenceSpace} space - The XR reference space.
   */
  setReferenceSpace(e) {
    this._customReferenceSpace = e;
  }
  /**
   * Returns the XR camera.
   *
   * @return {ArrayCamera} The XR camera.
   */
  getCamera() {
    return this._cameraXR;
  }
  /**
   * Returns the environment blend mode from the current XR session.
   *
   * @return {'opaque'|'additive'|'alpha-blend'|undefined} The environment blend mode. Returns `undefined` when used outside of a XR session.
   */
  getEnvironmentBlendMode() {
    if (this._session !== null)
      return this._session.environmentBlendMode;
  }
  /**
   * Returns the current XR binding.
   *
   * Creates a new binding if needed and the browser is
   * capable of doing so.
   *
   * @return {?XRWebGLBinding} The XR binding. Returns `null` if one cannot be created.
   */
  getBinding() {
    return this._glBinding === null && this._supportsGlBinding && (this._glBinding = new XRWebGLBinding(this._session, this._gl)), this._glBinding;
  }
  /**
   * Returns the current XR frame.
   *
   * @return {?XRFrame} The XR frame. Returns `null` when used outside a XR session.
   */
  getFrame() {
    return this._xrFrame;
  }
  /**
   * Returns `true` if the engine renders to a multiview target.
   *
   * @return {boolean} Whether the engine renders to a multiview render target or not.
   */
  useMultiview() {
    return this._useMultiview;
  }
  /**
   * This method can be used in XR applications to create a quadratic layer that presents a separate
   * rendered scene.
   *
   * @param {number} width - The width of the layer plane in world units.
   * @param {number} height - The height of the layer plane in world units.
   * @param {Vector3} translation - The position/translation of the layer plane in world units.
   * @param {Quaternion} quaternion - The orientation of the layer plane expressed as a quaternion.
   * @param {number} pixelwidth - The width of the layer's render target in pixels.
   * @param {number} pixelheight - The height of the layer's render target in pixels.
   * @param {Function} rendercall - A callback function that renders the layer. Similar to code in
   * the default animation loop, this method can be used to update/transform 3D object in the layer's scene.
   * @param {Object} [attributes={}] - Allows to configure the layer's render target.
   * @return {Mesh} A mesh representing the quadratic XR layer. This mesh should be added to the XR scene.
   */
  createQuadLayer(e, t, n, r, s, a, o, l = {}) {
    const c = new ru(e, t), u = new hc(
      s,
      a,
      {
        format: cn,
        type: Zt,
        depthTexture: new oi(
          s,
          a,
          l.stencil ? Ci : Dt,
          void 0,
          void 0,
          void 0,
          void 0,
          void 0,
          void 0,
          l.stencil ? ii : Un
        ),
        stencilBuffer: l.stencil,
        resolveDepthBuffer: !1,
        resolveStencilBuffer: !1
      }
    );
    u._autoAllocateDepthBuffer = !0;
    const h = new xr({ color: 16777215, side: ai });
    h.map = u.texture, h.map.offset.y = 1, h.map.repeat.y = -1;
    const d = new _n(c, h);
    d.position.copy(n), d.quaternion.copy(r);
    const f = {
      type: "quad",
      width: e,
      height: t,
      translation: n,
      quaternion: r,
      pixelwidth: s,
      pixelheight: a,
      plane: d,
      material: h,
      rendercall: o,
      renderTarget: u
    };
    if (this._layers.push(f), this._session !== null) {
      f.plane.material = new xr({ color: 16777215, side: ai }), f.plane.material.blending = ya, f.plane.material.blendEquation = Xn, f.plane.material.blendSrc = jr, f.plane.material.blendDst = jr, f.xrlayer = this._createXRLayer(f);
      const p = this._session.renderState.layers;
      p.unshift(f.xrlayer), this._session.updateRenderState({ layers: p });
    } else
      u.isXRRenderTarget = !1;
    return d;
  }
  /**
   * This method can be used in XR applications to create a cylindrical layer that presents a separate
   * rendered scene.
   *
   * @param {number} radius - The radius of the cylinder in world units.
   * @param {number} centralAngle - The central angle of the cylinder in radians.
   * @param {number} aspectratio - The aspect ratio.
   * @param {Vector3} translation - The position/translation of the layer plane in world units.
   * @param {Quaternion} quaternion - The orientation of the layer plane expressed as a quaternion.
   * @param {number} pixelwidth - The width of the layer's render target in pixels.
   * @param {number} pixelheight - The height of the layer's render target in pixels.
   * @param {Function} rendercall - A callback function that renders the layer. Similar to code in
   * the default animation loop, this method can be used to update/transform 3D object in the layer's scene.
   * @param {Object} [attributes={}] - Allows to configure the layer's render target.
   * @return {Mesh} A mesh representing the cylindrical XR layer. This mesh should be added to the XR scene.
   */
  createCylinderLayer(e, t, n, r, s, a, o, l, c = {}) {
    const u = new iu(e, e, e * t / n, 64, 64, !0, Math.PI - t / 2, t), h = new hc(
      a,
      o,
      {
        format: cn,
        type: Zt,
        depthTexture: new oi(
          a,
          o,
          c.stencil ? Ci : Dt,
          void 0,
          void 0,
          void 0,
          void 0,
          void 0,
          void 0,
          c.stencil ? ii : Un
        ),
        stencilBuffer: c.stencil,
        resolveDepthBuffer: !1,
        resolveStencilBuffer: !1
      }
    );
    h._autoAllocateDepthBuffer = !0;
    const d = new xr({ color: 16777215, side: Ft });
    d.map = h.texture, d.map.offset.y = 1, d.map.repeat.y = -1;
    const f = new _n(u, d);
    f.position.copy(r), f.quaternion.copy(s);
    const p = {
      type: "cylinder",
      radius: e,
      centralAngle: t,
      aspectratio: n,
      translation: r,
      quaternion: s,
      pixelwidth: a,
      pixelheight: o,
      plane: f,
      material: d,
      rendercall: l,
      renderTarget: h
    };
    if (this._layers.push(p), this._session !== null) {
      p.plane.material = new xr({ color: 16777215, side: Ft }), p.plane.material.blending = ya, p.plane.material.blendEquation = Xn, p.plane.material.blendSrc = jr, p.plane.material.blendDst = jr, p.xrlayer = this._createXRLayer(p);
      const _ = this._session.renderState.layers;
      _.unshift(p.xrlayer), this._session.updateRenderState({ layers: _ });
    } else
      h.isXRRenderTarget = !1;
    return f;
  }
  /**
   * Renders the XR layers that have been previously added to the scene.
   *
   * This method is usually called in your animation loop before rendering
   * the actual scene via `renderer.render( scene, camera );`.
   */
  renderLayers() {
    const e = new P(), t = new Gi(), n = this._renderer, r = this.isPresenting, s = n.getOutputRenderTarget(), a = n._frameBufferTarget;
    this.isPresenting = !1;
    const o = new de();
    n.getSize(o);
    const l = n._quad;
    for (const c of this._layers)
      if (c.renderTarget.isXRRenderTarget = this._session !== null, c.renderTarget._hasExternalTextures = c.renderTarget.isXRRenderTarget, c.renderTarget.isXRRenderTarget && this._sessionUsesLayers) {
        c.xrlayer.transform = new XRRigidTransform(c.plane.getWorldPosition(e), c.plane.getWorldQuaternion(t));
        const u = this._glBinding.getSubImage(c.xrlayer, this._xrFrame);
        n.backend.setXRRenderTargetTextures(
          c.renderTarget,
          u.colorTexture,
          void 0
        ), n._setXRLayerSize(c.renderTarget.width, c.renderTarget.height), n.setOutputRenderTarget(c.renderTarget), n.setRenderTarget(null), n._frameBufferTarget = null, this._frameBufferTargets || (this._frameBufferTargets = /* @__PURE__ */ new WeakMap());
        const { frameBufferTarget: h, quad: d } = this._frameBufferTargets.get(c.renderTarget) || { frameBufferTarget: null, quad: null };
        h ? (n._frameBufferTarget = h, n._quad = d) : (n._quad = new kg(new dn()), this._frameBufferTargets.set(c.renderTarget, { frameBufferTarget: n._getFrameBufferTarget(), quad: n._quad })), c.rendercall(), n._frameBufferTarget = null;
      } else
        n.setRenderTarget(c.renderTarget), c.rendercall();
    n.setRenderTarget(null), n.setOutputRenderTarget(s), n._frameBufferTarget = a, n._setXRLayerSize(o.x, o.y), n._quad = l, this.isPresenting = r;
  }
  /**
   * Returns the current XR session.
   *
   * @return {?XRSession} The XR session. Returns `null` when used outside a XR session.
   */
  getSession() {
    return this._session;
  }
  /**
   * After a XR session has been requested usually with one of the `*Button` modules, it
   * is injected into the renderer with this method. This method triggers the start of
   * the actual XR rendering.
   *
   * @async
   * @param {XRSession} session - The XR session to set.
   * @return {Promise} A Promise that resolves when the session has been set.
   */
  async setSession(e) {
    const t = this._renderer, n = t.backend;
    this._gl = t.getContext();
    const r = this._gl, s = r.getContextAttributes();
    if (this._session = e, e !== null) {
      if (n.isWebGPUBackend === !0)
        throw new Error('THREE.XRManager: XR is currently not supported with a WebGPU backend. Use WebGL by passing "{ forceWebGL: true }" to the constructor of the renderer.');
      if (e.addEventListener("select", this._onSessionEvent), e.addEventListener("selectstart", this._onSessionEvent), e.addEventListener("selectend", this._onSessionEvent), e.addEventListener("squeeze", this._onSessionEvent), e.addEventListener("squeezestart", this._onSessionEvent), e.addEventListener("squeezeend", this._onSessionEvent), e.addEventListener("end", this._onSessionEnd), e.addEventListener("inputsourceschange", this._onInputSourcesChange), await n.makeXRCompatible(), this._currentPixelRatio = t.getPixelRatio(), t.getSize(this._currentSize), this._currentAnimationContext = t._animation.getContext(), this._currentAnimationLoop = t._animation.getAnimationLoop(), t._animation.stop(), this._supportsLayers === !0) {
        let a = null, o = null, l = null;
        t.depth && (l = t.stencil ? r.DEPTH24_STENCIL8 : r.DEPTH_COMPONENT24, a = t.stencil ? ii : Un, o = t.stencil ? Ci : Dt);
        const c = {
          colorFormat: r.RGBA8,
          depthFormat: l,
          scaleFactor: this._framebufferScaleFactor,
          clearOnAccess: !1
        };
        this._useMultiviewIfPossible && t.hasFeature("OVR_multiview2") && (c.textureType = "texture-array", this._useMultiview = !0), this._glBinding = this.getBinding();
        const u = this._glBinding.createProjectionLayer(c), h = [u];
        this._glProjLayer = u, t.setPixelRatio(1), t._setXRLayerSize(u.textureWidth, u.textureHeight);
        const d = this._useMultiview ? 2 : 1, f = new oi(u.textureWidth, u.textureHeight, o, void 0, void 0, void 0, void 0, void 0, void 0, a, d);
        if (this._xrRenderTarget = new hc(
          u.textureWidth,
          u.textureHeight,
          {
            format: cn,
            type: Zt,
            colorSpace: t.outputColorSpace,
            depthTexture: f,
            stencilBuffer: t.stencil,
            samples: s.antialias ? 4 : 0,
            resolveDepthBuffer: u.ignoreDepthValues === !1,
            resolveStencilBuffer: u.ignoreDepthValues === !1,
            depth: this._useMultiview ? 2 : 1,
            multiview: this._useMultiview
          }
        ), this._xrRenderTarget._hasExternalTextures = !0, this._xrRenderTarget.depth = this._useMultiview ? 2 : 1, this._sessionUsesLayers = e.enabledFeatures.includes("layers"), this._referenceSpace = await e.requestReferenceSpace(this.getReferenceSpaceType()), this._sessionUsesLayers)
          for (const p of this._layers)
            p.plane.material = new xr({ color: 16777215, side: p.type === "cylinder" ? Ft : ai }), p.plane.material.blending = ya, p.plane.material.blendEquation = Xn, p.plane.material.blendSrc = jr, p.plane.material.blendDst = jr, p.xrlayer = this._createXRLayer(p), h.unshift(p.xrlayer);
        e.updateRenderState({ layers: h });
      } else {
        const a = {
          antialias: t.currentSamples > 0,
          alpha: !0,
          depth: t.depth,
          stencil: t.stencil,
          framebufferScaleFactor: this.getFramebufferScaleFactor()
        }, o = new XRWebGLLayer(e, r, a);
        this._glBaseLayer = o, e.updateRenderState({ baseLayer: o }), t.setPixelRatio(1), t._setXRLayerSize(o.framebufferWidth, o.framebufferHeight), this._xrRenderTarget = new hc(
          o.framebufferWidth,
          o.framebufferHeight,
          {
            format: cn,
            type: Zt,
            colorSpace: t.outputColorSpace,
            stencilBuffer: t.stencil,
            resolveDepthBuffer: o.ignoreDepthValues === !1,
            resolveStencilBuffer: o.ignoreDepthValues === !1
          }
        ), this._xrRenderTarget._isOpaqueFramebuffer = !0, this._referenceSpace = await e.requestReferenceSpace(this.getReferenceSpaceType());
      }
      this.setFoveation(this.getFoveation()), t._animation.setAnimationLoop(this._onAnimationFrame), t._animation.setContext(e), t._animation.start(), this.isPresenting = !0, this.dispatchEvent({ type: "sessionstart" });
    }
  }
  /**
   * This method is called by the renderer per frame and updates the XR camera
   * and it sub cameras based on the given camera. The given camera is the "user"
   * camera created on application level and used for non-XR rendering.
   *
   * @param {PerspectiveCamera} camera - The camera.
   */
  updateCamera(e) {
    const t = this._session;
    if (t === null)
      return;
    const n = e.near, r = e.far, s = this._cameraXR, a = this._cameraL, o = this._cameraR;
    s.near = o.near = a.near = n, s.far = o.far = a.far = r, s.isMultiViewCamera = this._useMultiview, (this._currentDepthNear !== s.near || this._currentDepthFar !== s.far) && (t.updateRenderState({
      depthNear: s.near,
      depthFar: s.far
    }), this._currentDepthNear = s.near, this._currentDepthFar = s.far), s.layers.mask = e.layers.mask | 6, a.layers.mask = s.layers.mask & -5, o.layers.mask = s.layers.mask & -3;
    const l = e.parent, c = s.cameras;
    ev(s, l);
    for (let u = 0; u < c.length; u++)
      ev(c[u], l);
    c.length === 2 ? wG(s, a, o) : s.projectionMatrix.copy(a.projectionMatrix), AG(e, s, l);
  }
  /**
   * Returns a WebXR controller for the given controller index.
   *
   * @private
   * @param {number} index - The controller index.
   * @return {WebXRController} The XR controller.
   */
  _getController(e) {
    let t = this._controllers[e];
    return t === void 0 && (t = new bh(), this._controllers[e] = t), t;
  }
}
function wG(i, e, t) {
  Qx.setFromMatrixPosition(e.matrixWorld), Jx.setFromMatrixPosition(t.matrixWorld);
  const n = Qx.distanceTo(Jx), r = e.projectionMatrix.elements, s = t.projectionMatrix.elements, a = r[14] / (r[10] - 1), o = r[14] / (r[10] + 1), l = (r[9] + 1) / r[5], c = (r[9] - 1) / r[5], u = (r[8] - 1) / r[0], h = (s[8] + 1) / s[0], d = a * u, f = a * h, p = n / (-u + h), _ = p * -u;
  if (e.matrixWorld.decompose(i.position, i.quaternion, i.scale), i.translateX(_), i.translateZ(p), i.matrixWorld.compose(i.position, i.quaternion, i.scale), i.matrixWorldInverse.copy(i.matrixWorld).invert(), r[10] === -1)
    i.projectionMatrix.copy(e.projectionMatrix), i.projectionMatrixInverse.copy(e.projectionMatrixInverse);
  else {
    const g = a + p, m = o + p, x = d - _, y = f + (n - _), b = l * o / m * g, T = c * o / m * g;
    i.projectionMatrix.makePerspective(x, y, b, T, g, m), i.projectionMatrixInverse.copy(i.projectionMatrix).invert();
  }
}
function ev(i, e) {
  e === null ? i.matrixWorld.copy(i.matrix) : i.matrixWorld.multiplyMatrices(e.matrixWorld, i.matrix), i.matrixWorldInverse.copy(i.matrixWorld).invert();
}
function AG(i, e, t) {
  t === null ? i.matrix.copy(e.matrixWorld) : (i.matrix.copy(t.matrixWorld), i.matrix.invert(), i.matrix.multiply(e.matrixWorld)), i.matrix.decompose(i.position, i.quaternion, i.scale), i.updateMatrixWorld(!0), i.projectionMatrix.copy(e.projectionMatrix), i.projectionMatrixInverse.copy(e.projectionMatrixInverse), i.isPerspectiveCamera && (i.fov = Fa * 2 * Math.atan(1 / i.projectionMatrix.elements[5]), i.zoom = 1);
}
function RG(i) {
  const e = this._controllerInputSources.indexOf(i.inputSource);
  if (e === -1)
    return;
  const t = this._controllers[e];
  if (t !== void 0) {
    const n = this.getReferenceSpace();
    t.update(i.inputSource, i.frame, n), t.dispatchEvent({ type: i.type, data: i.inputSource });
  }
}
function CG() {
  const i = this._session, e = this._renderer;
  i.removeEventListener("select", this._onSessionEvent), i.removeEventListener("selectstart", this._onSessionEvent), i.removeEventListener("selectend", this._onSessionEvent), i.removeEventListener("squeeze", this._onSessionEvent), i.removeEventListener("squeezestart", this._onSessionEvent), i.removeEventListener("squeezeend", this._onSessionEvent), i.removeEventListener("end", this._onSessionEnd), i.removeEventListener("inputsourceschange", this._onInputSourcesChange);
  for (let t = 0; t < this._controllers.length; t++) {
    const n = this._controllerInputSources[t];
    n !== null && (this._controllerInputSources[t] = null, this._controllers[t].disconnect(n));
  }
  if (this._currentDepthNear = null, this._currentDepthFar = null, e._resetXRState(), this._session = null, this._xrRenderTarget = null, this._glBinding = null, this._glBaseLayer = null, this._glProjLayer = null, this._sessionUsesLayers === !0)
    for (const t of this._layers)
      t.renderTarget = new hc(
        t.pixelwidth,
        t.pixelheight,
        {
          format: cn,
          type: Zt,
          depthTexture: new oi(
            t.pixelwidth,
            t.pixelheight,
            t.stencilBuffer ? Ci : Dt,
            void 0,
            void 0,
            void 0,
            void 0,
            void 0,
            void 0,
            t.stencilBuffer ? ii : Un
          ),
          stencilBuffer: t.stencilBuffer,
          resolveDepthBuffer: !1,
          resolveStencilBuffer: !1
        }
      ), t.renderTarget.isXRRenderTarget = !1, t.plane.material = t.material, t.material.map = t.renderTarget.texture, t.material.map.offset.y = 1, t.material.map.repeat.y = -1, delete t.xrlayer;
  this.isPresenting = !1, this._useMultiview = !1, e._animation.stop(), e._animation.setAnimationLoop(this._currentAnimationLoop), e._animation.setContext(this._currentAnimationContext), e._animation.start(), e.setPixelRatio(this._currentPixelRatio), e.setSize(this._currentSize.width, this._currentSize.height, !1), this.dispatchEvent({ type: "sessionend" });
}
function NG(i) {
  const e = this._controllers, t = this._controllerInputSources;
  for (let n = 0; n < i.removed.length; n++) {
    const r = i.removed[n], s = t.indexOf(r);
    s >= 0 && (t[s] = null, e[s].disconnect(r));
  }
  for (let n = 0; n < i.added.length; n++) {
    const r = i.added[n];
    let s = t.indexOf(r);
    if (s === -1) {
      for (let o = 0; o < e.length; o++)
        if (o >= t.length) {
          t.push(r), s = o;
          break;
        } else if (t[o] === null) {
          t[o] = r, s = o;
          break;
        }
      if (s === -1)
        break;
    }
    const a = e[s];
    a && a.connect(r);
  }
}
function PG(i) {
  return i.type === "quad" ? this._glBinding.createQuadLayer({
    transform: new XRRigidTransform(i.translation, i.quaternion),
    width: i.width / 2,
    height: i.height / 2,
    space: this._referenceSpace,
    viewPixelWidth: i.pixelwidth,
    viewPixelHeight: i.pixelheight,
    clearOnAccess: !1
  }) : this._glBinding.createCylinderLayer({
    transform: new XRRigidTransform(i.translation, i.quaternion),
    radius: i.radius,
    centralAngle: i.centralAngle,
    aspectRatio: i.aspectRatio,
    space: this._referenceSpace,
    viewPixelWidth: i.pixelwidth,
    viewPixelHeight: i.pixelheight,
    clearOnAccess: !1
  });
}
function DG(i, e) {
  if (e === void 0)
    return;
  const t = this._cameraXR, n = this._renderer, r = n.backend, s = this._glBaseLayer, a = this.getReferenceSpace(), o = e.getViewerPose(a);
  if (this._xrFrame = e, o !== null) {
    const l = o.views;
    this._glBaseLayer !== null && r.setXRTarget(s.framebuffer);
    let c = !1;
    l.length !== t.cameras.length && (t.cameras.length = 0, c = !0);
    for (let u = 0; u < l.length; u++) {
      const h = l[u];
      let d;
      if (this._supportsLayers === !0) {
        const p = this._glBinding.getViewSubImage(this._glProjLayer, h);
        d = p.viewport, u === 0 && r.setXRRenderTargetTextures(
          this._xrRenderTarget,
          p.colorTexture,
          this._glProjLayer.ignoreDepthValues && !this._useMultiview ? void 0 : p.depthStencilTexture
        );
      } else
        d = s.getViewport(h);
      let f = this._cameras[u];
      f === void 0 && (f = new An(), f.layers.enable(u), f.viewport = new rt(), this._cameras[u] = f), f.matrix.fromArray(h.transform.matrix), f.matrix.decompose(f.position, f.quaternion, f.scale), f.projectionMatrix.fromArray(h.projectionMatrix), f.projectionMatrixInverse.copy(f.projectionMatrix).invert(), f.viewport.set(d.x, d.y, d.width, d.height), u === 0 && (t.matrix.copy(f.matrix), t.matrix.decompose(t.position, t.quaternion, t.scale)), c === !0 && t.cameras.push(f);
    }
    n.setOutputRenderTarget(this._xrRenderTarget);
  }
  for (let l = 0; l < this._controllers.length; l++) {
    const c = this._controllerInputSources[l], u = this._controllers[l];
    c !== null && u !== void 0 && u.update(c, e, a);
  }
  this._currentAnimationLoop && this._currentAnimationLoop(i, e), e.detectedPlanes && this.dispatchEvent({ type: "planesdetected", data: e }), this._xrFrame = null;
}
class LG extends Fr {
  /**
   * Constructs a new CanvasTarget.
   *
   * @param {HTMLCanvasElement|OffscreenCanvas} domElement - The canvas element to render to.
   */
  constructor(e) {
    super(), this.domElement = e, this._pixelRatio = 1, this._width = this.domElement.width, this._height = this.domElement.height, this._viewport = new rt(0, 0, this._width, this._height), this._scissor = new rt(0, 0, this._width, this._height), this._scissorTest = !1, this.colorTexture = new ny(), this.depthTexture = new oi();
  }
  /**
   * Returns the pixel ratio.
   *
   * @return {number} The pixel ratio.
   */
  getPixelRatio() {
    return this._pixelRatio;
  }
  /**
   * Returns the drawing buffer size in physical pixels. This method honors the pixel ratio.
   *
   * @param {Vector2} target - The method writes the result in this target object.
   * @return {Vector2} The drawing buffer size.
   */
  getDrawingBufferSize(e) {
    return e.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor();
  }
  /**
   * Returns the renderer's size in logical pixels. This method does not honor the pixel ratio.
   *
   * @param {Vector2} target - The method writes the result in this target object.
   * @return {Vector2} The renderer's size in logical pixels.
   */
  getSize(e) {
    return e.set(this._width, this._height);
  }
  /**
   * Sets the given pixel ratio and resizes the canvas if necessary.
   *
   * @param {number} [value=1] - The pixel ratio.
   */
  setPixelRatio(e = 1) {
    this._pixelRatio !== e && (this._pixelRatio = e, this.setSize(this._width, this._height, !1));
  }
  /**
   * This method allows to define the drawing buffer size by specifying
   * width, height and pixel ratio all at once. The size of the drawing
   * buffer is computed with this formula:
   * ```js
   * size.x = width * pixelRatio;
   * size.y = height * pixelRatio;
   * ```
   *
   * @param {number} width - The width in logical pixels.
   * @param {number} height - The height in logical pixels.
   * @param {number} pixelRatio - The pixel ratio.
   */
  setDrawingBufferSize(e, t, n) {
    this.xr && this.xr.isPresenting || (this._width = e, this._height = t, this._pixelRatio = n, this.domElement.width = Math.floor(e * n), this.domElement.height = Math.floor(t * n), this.setViewport(0, 0, e, t), this._dispatchResize());
  }
  /**
   * Sets the size of the renderer.
   *
   * @param {number} width - The width in logical pixels.
   * @param {number} height - The height in logical pixels.
   * @param {boolean} [updateStyle=true] - Whether to update the `style` attribute of the canvas or not.
   */
  setSize(e, t, n = !0) {
    this.xr && this.xr.isPresenting || (this._width = e, this._height = t, this.domElement.width = Math.floor(e * this._pixelRatio), this.domElement.height = Math.floor(t * this._pixelRatio), n === !0 && (this.domElement.style.width = e + "px", this.domElement.style.height = t + "px"), this.setViewport(0, 0, e, t), this._dispatchResize());
  }
  /**
   * Returns the scissor rectangle.
   *
   * @param {Vector4} target - The method writes the result in this target object.
   * @return {Vector4} The scissor rectangle.
   */
  getScissor(e) {
    const t = this._scissor;
    return e.x = t.x, e.y = t.y, e.width = t.width, e.height = t.height, e;
  }
  /**
   * Defines the scissor rectangle.
   *
   * @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the box in logical pixel unit.
   * Instead of passing four arguments, the method also works with a single four-dimensional vector.
   * @param {number} y - The vertical coordinate for the lower left corner of the box in logical pixel unit.
   * @param {number} width - The width of the scissor box in logical pixel unit.
   * @param {number} height - The height of the scissor box in logical pixel unit.
   */
  setScissor(e, t, n, r) {
    const s = this._scissor;
    e.isVector4 ? s.copy(e) : s.set(e, t, n, r);
  }
  /**
   * Returns the scissor test value.
   *
   * @return {boolean} Whether the scissor test should be enabled or not.
   */
  getScissorTest() {
    return this._scissorTest;
  }
  /**
   * Defines the scissor test.
   *
   * @param {boolean} boolean - Whether the scissor test should be enabled or not.
   */
  setScissorTest(e) {
    this._scissorTest = e;
  }
  /**
   * Returns the viewport definition.
   *
   * @param {Vector4} target - The method writes the result in this target object.
   * @return {Vector4} The viewport definition.
   */
  getViewport(e) {
    return e.copy(this._viewport);
  }
  /**
   * Defines the viewport.
   *
   * @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the viewport origin in logical pixel unit.
   * @param {number} y - The vertical coordinate for the lower left corner of the viewport origin  in logical pixel unit.
   * @param {number} width - The width of the viewport in logical pixel unit.
   * @param {number} height - The height of the viewport in logical pixel unit.
   * @param {number} minDepth - The minimum depth value of the viewport. WebGPU only.
   * @param {number} maxDepth - The maximum depth value of the viewport. WebGPU only.
   */
  setViewport(e, t, n, r, s = 0, a = 1) {
    const o = this._viewport;
    e.isVector4 ? o.copy(e) : o.set(e, t, n, r), o.minDepth = s, o.maxDepth = a;
  }
  /**
   * Dispatches the resize event.
   *
   * @private
   */
  _dispatchResize() {
    this.dispatchEvent({ type: "resize" });
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever this instance is no longer used in your app.
   *
   * @fires RenderTarget#dispose
   */
  dispose() {
    this.dispatchEvent({ type: "dispose" });
  }
}
const tv = /* @__PURE__ */ new Xm(), yo = /* @__PURE__ */ new de(), op = /* @__PURE__ */ new rt(), lp = /* @__PURE__ */ new nu(), cp = /* @__PURE__ */ new Qm(), ch = /* @__PURE__ */ new pt(), Wr = /* @__PURE__ */ new rt(), FG = { [ai]: Ft, [Ft]: ai, [Rn]: Rn };
class IG {
  /**
   * Renderer options.
   *
   * @typedef {Object} Renderer~Options
   * @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not.
   * @property {boolean} [reversedDepthBuffer=false] - Whether reversed depth buffer is enabled or not.
   * @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque.
   * @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not.
   * @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
   * @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
   * @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. This parameter can set to any other integer value than 0
   * to overwrite the default.
   * @property {?Function} [getFallback=null] - This callback function can be used to provide a fallback backend, if the primary backend can't be targeted.
   * @property {number} [outputBufferType=HalfFloatType] - Defines the type of output buffers. The default `HalfFloatType` is recommend for best
   * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though.
   * @property {boolean} [multiview=false] - If set to `true`, the renderer will use multiview during WebXR rendering if supported.
   */
  /**
  	 * Constructs a new renderer.
  	 *
  	 * @param {Backend} backend - The backend the renderer is targeting (e.g. WebGPU or WebGL 2).
  	 * @param {Renderer~Options} [parameters] - The configuration parameter.
  
  	 */
  constructor(e, t = {}) {
    this.isRenderer = !0;
    const {
      logarithmicDepthBuffer: n = !1,
      reversedDepthBuffer: r = !1,
      alpha: s = !0,
      depth: a = !0,
      stencil: o = !1,
      antialias: l = !1,
      samples: c = 0,
      getFallback: u = null,
      outputBufferType: h = nn,
      multiview: d = !1
    } = t;
    this.backend = e, this.autoClear = !0, this.autoClearColor = !0, this.autoClearDepth = !0, this.autoClearStencil = !0, this.alpha = s, this.logarithmicDepthBuffer = n, this.reversedDepthBuffer = r, this.outputColorSpace = Jn, this.toneMapping = In, this.toneMappingExposure = 1, this.sortObjects = !0, this.depth = a, this.stencil = o, this.info = new uO(), this.contextNode = qa(), this.library = new cT(), this.lighting = new MG(), this._samples = c || l === !0 ? 4 : 0, this._onCanvasTargetResize = this._onCanvasTargetResize.bind(this), this._canvasTarget = new LG(e.getDomElement()), this._canvasTarget.addEventListener("resize", this._onCanvasTargetResize), this._canvasTarget.isDefaultCanvasTarget = !0, this._inspector = new iS(), this._inspector.setRenderer(this), this._getFallback = u, this._attributes = null, this._geometries = null, this._nodes = null, this._animation = null, this._bindings = null, this._objects = null, this._pipelines = null, this._bundles = null, this._renderLists = null, this._renderContexts = null, this._textures = null, this._background = null, this._quad = new kg(new dn()), this._quad.name = "Output Color Transform", this._quad.material.name = "outputColorTransform", this._currentRenderContext = null, this._opaqueSort = null, this._transparentSort = null, this._frameBufferTarget = null;
    const f = this.alpha === !0 ? 0 : 1;
    this._clearColor = new Og(0, 0, 0, f), this._clearDepth = 1, this._clearStencil = 0, this._renderTarget = null, this._activeCubeFace = 0, this._activeMipmapLevel = 0, this._outputRenderTarget = null, this._mrt = null, this._renderObjectFunction = null, this._currentRenderObjectFunction = null, this._currentRenderBundle = null, this._handleObjectFunction = this._renderObjectDirect, this._isDeviceLost = !1, this.onDeviceLost = this._onDeviceLost, this._outputBufferType = h, this._cacheShadowNodes = /* @__PURE__ */ new WeakMap(), this._initialized = !1, this._callDepth = -1, this._initPromise = null, this._compilationPromises = null, this.transparent = !0, this.opaque = !0, this.shadowMap = {
      enabled: !1,
      transmitted: !1,
      type: Ro
    }, this.xr = new EG(this, d), this.debug = {
      checkShaderErrors: !0,
      onShaderError: null,
      getShaderAsync: async (p, _, g) => {
        await this.compileAsync(p, _);
        const m = this._renderLists.get(p, _), x = this._renderContexts.get(this._renderTarget, this._mrt), y = p.overrideMaterial || g.material, b = this._objects.get(g, y, p, _, m.lightsNode, x, x.clippingContext), { fragmentShader: T, vertexShader: S } = b.getNodeBuilderState();
        return { fragmentShader: T, vertexShader: S };
      }
    };
  }
  /**
   * Initializes the renderer so it is ready for usage.
   *
   * @async
   * @return {Promise<this>} A Promise that resolves when the renderer has been initialized.
   */
  async init() {
    return this._initPromise !== null ? this._initPromise : (this._initPromise = new Promise(async (e, t) => {
      let n = this.backend;
      try {
        await n.init(this);
      } catch (r) {
        if (this._getFallback !== null)
          try {
            this.backend = n = this._getFallback(r), await n.init(this);
          } catch (s) {
            t(s);
            return;
          }
        else {
          t(r);
          return;
        }
      }
      this._nodes = new yG(this, n), this._animation = new tO(this, this._nodes, this.info), this._attributes = new lO(n), this._background = new Fk(this, this._nodes), this._geometries = new cO(this._attributes, this.info), this._textures = new TO(this, n, this.info), this._pipelines = new pO(n, this._nodes), this._bindings = new mO(n, this._nodes, this._textures, this._attributes, this._pipelines, this.info), this._objects = new sO(this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info), this._renderLists = new xO(this.lighting), this._bundles = new SG(), this._renderContexts = new bO(this), this._animation.start(), this._initialized = !0, this._inspector.init(), e(this);
    }), this._initPromise);
  }
  /**
   * A reference to the canvas element the renderer is drawing to.
   * This value of this property will automatically be created by
   * the renderer.
   *
   * @type {HTMLCanvasElement|OffscreenCanvas}
   */
  get domElement() {
    return this._canvasTarget.domElement;
  }
  /**
   * The coordinate system of the renderer. The value of this property
   * depends on the selected backend. Either `THREE.WebGLCoordinateSystem` or
   * `THREE.WebGPUCoordinateSystem`.
   *
   * @readonly
   * @type {number}
   */
  get coordinateSystem() {
    return this.backend.coordinateSystem;
  }
  /**
   * Compiles all materials in the given scene. This can be useful to avoid a
   * phenomenon which is called "shader compilation stutter", which occurs when
   * rendering an object with a new shader for the first time.
   *
   * If you want to add a 3D object to an existing scene, use the third optional
   * parameter for applying the target scene. Note that the (target) scene's lighting
   * and environment must be configured before calling this method.
   *
   * @async
   * @param {Object3D} scene - The scene or 3D object to precompile.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {?Scene} targetScene - If the first argument is a 3D object, this parameter must represent the scene the 3D object is going to be added.
   * @return {Promise} A Promise that resolves when the compile has been finished.
   */
  async compileAsync(e, t, n = null) {
    if (this._isDeviceLost === !0)
      return;
    this._initialized === !1 && await this.init();
    const r = this._nodes.nodeFrame, s = r.renderId, a = this._currentRenderContext, o = this._currentRenderObjectFunction, l = this._handleObjectFunction, c = this._compilationPromises, u = e.isScene === !0 ? e : tv;
    n === null && (n = e);
    const h = this._renderTarget, d = this._renderContexts.get(h, this._mrt), f = this._activeMipmapLevel, p = [];
    this._currentRenderContext = d, this._currentRenderObjectFunction = this.renderObject, this._handleObjectFunction = this._createObjectPipeline, this._compilationPromises = p, r.renderId++, r.update(), d.depth = this.depth, d.stencil = this.stencil, d.clippingContext || (d.clippingContext = new Kh()), d.clippingContext.updateGlobal(u, t), u.onBeforeRender(this, e, t, h);
    const _ = this._renderLists.get(e, t);
    if (_.begin(), this._projectObject(e, t, 0, _, d.clippingContext), n !== e && n.traverseVisible(function(b) {
      b.isLight && b.layers.test(t.layers) && _.pushLight(b);
    }), _.finish(), h !== null) {
      this._textures.updateRenderTarget(h, f);
      const b = this._textures.get(h);
      d.textures = b.textures, d.depthTexture = b.depthTexture;
    } else
      d.textures = null, d.depthTexture = null;
    n !== e ? this._background.update(n, _, d) : this._background.update(u, _, d);
    const g = _.opaque, m = _.transparent, x = _.transparentDoublePass, y = _.lightsNode;
    this.opaque === !0 && g.length > 0 && this._renderObjects(g, t, u, y), this.transparent === !0 && m.length > 0 && this._renderTransparents(m, x, t, u, y), r.renderId = s, this._currentRenderContext = a, this._currentRenderObjectFunction = o, this._handleObjectFunction = l, this._compilationPromises = c, await Promise.all(p);
  }
  /**
   * Renders the scene in an async fashion.
   *
   * @async
   * @deprecated
   * @param {Object3D} scene - The scene or 3D object to render.
   * @param {Camera} camera - The camera.
   * @return {Promise} A Promise that resolves when the render has been finished.
   */
  async renderAsync(e, t) {
    Pt('Renderer: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'), await this.init(), this.render(e, t);
  }
  /**
   * Can be used to synchronize CPU operations with GPU tasks. So when this method is called,
   * the CPU waits for the GPU to complete its operation (e.g. a compute task).
   *
   * @async
   * @deprecated
   * @return {Promise} A Promise that resolves when synchronization has been finished.
   */
  async waitForGPU() {
    le("Renderer: waitForGPU() has been removed. Read https://github.com/mrdoob/three.js/issues/32012 for more information.");
  }
  //
  set inspector(e) {
    this._inspector !== null && this._inspector.setRenderer(null), this._inspector = e, this._inspector.setRenderer(this);
  }
  /**
   * The inspector instance. The inspector can be any class that extends from `InspectorBase`.
   *
   * @type {InspectorBase}
   */
  get inspector() {
    return this._inspector;
  }
  /**
   * Enables or disables high precision for model-view and normal-view matrices.
   * When enabled, will use CPU 64-bit precision for higher precision instead of GPU 32-bit for higher performance.
   *
   * NOTE: 64-bit precision is not compatible with `InstancedMesh` and `SkinnedMesh`.
   *
   * @param {boolean} value - Whether to enable or disable high precision.
   * @type {boolean}
   */
  set highPrecision(e) {
    const t = this.contextNode.value;
    e === !0 ? (t.modelViewMatrix = ex, t.modelNormalViewMatrix = tx) : this.highPrecision && (delete t.modelViewMatrix, delete t.modelNormalViewMatrix);
  }
  /**
   * Returns whether high precision is enabled or not.
   *
   * @return {boolean} Whether high precision is enabled or not.
   * @type {boolean}
   */
  get highPrecision() {
    const e = this.contextNode.value;
    return e.modelViewMatrix === ex && e.modelNormalViewMatrix === tx;
  }
  /**
   * Sets the given MRT configuration.
   *
   * @param {MRTNode} mrt - The MRT node to set.
   * @return {Renderer} A reference to this renderer.
   */
  setMRT(e) {
    return this._mrt = e, this;
  }
  /**
   * Returns the MRT configuration.
   *
   * @return {MRTNode} The MRT configuration.
   */
  getMRT() {
    return this._mrt;
  }
  /**
   * Returns the output buffer type.
   *
   * @return {number} The output buffer type.
   */
  getOutputBufferType() {
    return this._outputBufferType;
  }
  /**
   * Returns the output buffer type.
   *
   * @deprecated since r182. Use `.getOutputBufferType()` instead.
   * @return {number} The output buffer type.
   */
  getColorBufferType() {
    return Pt('Renderer: ".getColorBufferType()" has been renamed to ".getOutputBufferType()".'), this.getOutputBufferType();
  }
  /**
   * Default implementation of the device lost callback.
   *
   * @private
   * @param {Object} info - Information about the context lost.
   */
  _onDeviceLost(e) {
    let t = `THREE.WebGPURenderer: ${e.api} Device Lost:

Message: ${e.message}`;
    e.reason && (t += `
Reason: ${e.reason}`), le(t), this._isDeviceLost = !0;
  }
  /**
   * Renders the given render bundle.
   *
   * @private
   * @param {Object} bundle - Render bundle data.
   * @param {Scene} sceneRef - The scene the render bundle belongs to.
   * @param {LightsNode} lightsNode - The lights node.
   */
  _renderBundle(e, t, n) {
    const { bundleGroup: r, camera: s, renderList: a } = e, o = this._currentRenderContext, l = this._bundles.get(r, s), c = this.backend.get(l);
    c.renderContexts === void 0 && (c.renderContexts = /* @__PURE__ */ new Set());
    const u = r.version !== c.version, h = c.renderContexts.has(o) === !1 || u;
    if (c.renderContexts.add(o), h) {
      this.backend.beginBundle(o), (c.renderObjects === void 0 || u) && (c.renderObjects = []), this._currentRenderBundle = l;
      const {
        transparentDoublePass: d,
        transparent: f,
        opaque: p
      } = a;
      this.opaque === !0 && p.length > 0 && this._renderObjects(p, s, t, n), this.transparent === !0 && f.length > 0 && this._renderTransparents(f, d, s, t, n), this._currentRenderBundle = null, this.backend.finishBundle(o, l), c.version = r.version;
    } else {
      const { renderObjects: d } = c;
      for (let f = 0, p = d.length; f < p; f++) {
        const _ = d[f];
        this._nodes.needsRefresh(_) && (this._nodes.updateBefore(_), this._nodes.updateForRender(_), this._bindings.updateForRender(_), this._nodes.updateAfter(_));
      }
    }
    this.backend.addBundle(o, l);
  }
  /**
   * Renders the scene or 3D object with the given camera. This method can only be called
   * if the renderer has been initialized. When using `render()` inside an animation loop,
   * it's guaranteed the renderer will be initialized. The animation loop must be defined
   * with {@link Renderer#setAnimationLoop} though.
   *
   * For all other use cases (like when using on-demand rendering), you must call
   * {@link Renderer#init} before rendering.
   *
   * The target of the method is the default framebuffer (meaning the canvas)
   * or alternatively a render target when specified via `setRenderTarget()`.
   *
   * @param {Object3D} scene - The scene or 3D object to render.
   * @param {Camera} camera - The camera to render the scene with.
   */
  render(e, t) {
    if (this._initialized === !1)
      throw new Error('Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.');
    this._renderScene(e, t);
  }
  /**
   * Returns whether the renderer has been initialized or not.
   *
   * @readonly
   * @return {boolean} Whether the renderer has been initialized or not.
   */
  get initialized() {
    return this._initialized;
  }
  /**
   * Returns an internal render target which is used when computing the output tone mapping
   * and color space conversion. Unlike in `WebGLRenderer`, this is done in a separate render
   * pass and not inline to achieve more correct results.
   *
   * @private
   * @return {?RenderTarget} The render target. The method returns `null` if no output conversion should be applied.
   */
  _getFrameBufferTarget() {
    const { currentToneMapping: e, currentColorSpace: t } = this, n = e !== In, r = t !== Ke.workingColorSpace;
    if (n === !1 && r === !1)
      return null;
    const { width: s, height: a } = this.getDrawingBufferSize(yo), { depth: o, stencil: l } = this;
    let c = this._frameBufferTarget;
    c === null && (c = new js(s, a, {
      depthBuffer: o,
      stencilBuffer: l,
      type: this._outputBufferType,
      format: cn,
      colorSpace: Ke.workingColorSpace,
      generateMipmaps: !1,
      minFilter: Ot,
      magFilter: Ot,
      samples: this.samples
    }), c.isPostProcessingRenderTarget = !0, this._frameBufferTarget = c);
    const u = this.getOutputRenderTarget();
    c.depthBuffer = o, c.stencilBuffer = l, u !== null ? c.setSize(u.width, u.height, u.depth) : c.setSize(s, a, 1);
    const h = this._canvasTarget;
    return c.viewport.copy(h._viewport), c.scissor.copy(h._scissor), c.viewport.multiplyScalar(h._pixelRatio), c.scissor.multiplyScalar(h._pixelRatio), c.scissorTest = h._scissorTest, c.multiview = u !== null ? u.multiview : !1, c.resolveDepthBuffer = u !== null ? u.resolveDepthBuffer : !0, c._autoAllocateDepthBuffer = u !== null ? u._autoAllocateDepthBuffer : !1, c;
  }
  /**
   * Renders the scene or 3D object with the given camera.
   *
   * @private
   * @param {Object3D} scene - The scene or 3D object to render.
   * @param {Camera} camera - The camera to render the scene with.
   * @param {boolean} [useFrameBufferTarget=true] - Whether to use a framebuffer target or not.
   * @return {RenderContext} The current render context.
   */
  _renderScene(e, t, n = !0) {
    if (this._isDeviceLost === !0)
      return;
    const r = n ? this._getFrameBufferTarget() : null, s = this._nodes.nodeFrame, a = s.renderId, o = this._currentRenderContext, l = this._currentRenderObjectFunction, c = this._handleObjectFunction;
    this._callDepth++;
    const u = e.isScene === !0 ? e : tv, h = this._renderTarget || this._outputRenderTarget, d = this._activeCubeFace, f = this._activeMipmapLevel;
    let p;
    r !== null ? (p = r, this.setRenderTarget(p)) : p = h;
    const _ = this._renderContexts.get(p, this._mrt, this._callDepth);
    this._currentRenderContext = _, this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject, this._handleObjectFunction = this._renderObjectDirect, this.info.calls++, this.info.render.calls++, this.info.render.frameCalls++, s.renderId = this.info.calls, this.backend.updateTimeStampUID(_), this.inspector.beginRender(this.backend.getTimestampUID(_), e, t, p);
    const g = this.xr;
    if (g.isPresenting === !1) {
      let N = !1;
      if (this.reversedDepthBuffer === !0 && t.reversedDepth !== !0) {
        if (t._reversedDepth = !0, t.isArrayCamera)
          for (const L of t.cameras)
            L._reversedDepth = !0;
        N = !0;
      }
      const C = this.coordinateSystem;
      if (t.coordinateSystem !== C) {
        if (t.coordinateSystem = C, t.isArrayCamera)
          for (const L of t.cameras)
            L.coordinateSystem = C;
        N = !0;
      }
      if (N === !0 && (t.updateProjectionMatrix(), t.isArrayCamera))
        for (const L of t.cameras)
          L.updateProjectionMatrix();
    }
    e.matrixWorldAutoUpdate === !0 && e.updateMatrixWorld(), t.parent === null && t.matrixWorldAutoUpdate === !0 && t.updateMatrixWorld(), g.enabled === !0 && g.isPresenting === !0 && (g.cameraAutoUpdate === !0 && g.updateCamera(t), t = g.getCamera());
    const m = this._canvasTarget;
    let x = m._viewport, y = m._scissor, b = m._pixelRatio;
    p !== null && (x = p.viewport, y = p.scissor, b = 1), this.getDrawingBufferSize(yo), op.set(0, 0, yo.width, yo.height);
    const T = x.minDepth === void 0 ? 0 : x.minDepth, S = x.maxDepth === void 0 ? 1 : x.maxDepth;
    _.viewportValue.copy(x).multiplyScalar(b).floor(), _.viewportValue.width >>= f, _.viewportValue.height >>= f, _.viewportValue.minDepth = T, _.viewportValue.maxDepth = S, _.viewport = _.viewportValue.equals(op) === !1, _.scissorValue.copy(y).multiplyScalar(b).floor(), _.scissor = m._scissorTest && _.scissorValue.equals(op) === !1, _.scissorValue.width >>= f, _.scissorValue.height >>= f, _.clippingContext || (_.clippingContext = new Kh()), _.clippingContext.updateGlobal(u, t), u.onBeforeRender(this, e, t, p);
    const E = t.isArrayCamera ? cp : lp;
    t.isArrayCamera || (ch.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), E.setFromProjectionMatrix(ch, t.coordinateSystem, t.reversedDepth));
    const v = this._renderLists.get(e, t);
    if (v.begin(), this._projectObject(e, t, 0, v, _.clippingContext), v.finish(), this.sortObjects === !0 && v.sort(this._opaqueSort, this._transparentSort), p !== null) {
      this._textures.updateRenderTarget(p, f);
      const N = this._textures.get(p);
      _.textures = N.textures, _.depthTexture = N.depthTexture, _.width = N.width, _.height = N.height, _.renderTarget = p, _.depth = p.depthBuffer, _.stencil = p.stencilBuffer;
    } else
      _.textures = null, _.depthTexture = null, _.width = yo.width, _.height = yo.height, _.depth = this.depth, _.stencil = this.stencil;
    _.width >>= f, _.height >>= f, _.activeCubeFace = d, _.activeMipmapLevel = f, _.occlusionQueryCount = v.occlusionQueryCount, _.scissorValue.max(Wr.set(0, 0, 0, 0)), _.scissorValue.x + _.scissorValue.width > _.width && (_.scissorValue.width = Math.max(_.width - _.scissorValue.x, 0)), _.scissorValue.y + _.scissorValue.height > _.height && (_.scissorValue.height = Math.max(_.height - _.scissorValue.y, 0)), this._background.update(u, v, _), _.camera = t, this.backend.beginRender(_);
    const {
      bundles: M,
      lightsNode: F,
      transparentDoublePass: R,
      transparent: I,
      opaque: B
    } = v;
    return M.length > 0 && this._renderBundles(M, u, F), this.opaque === !0 && B.length > 0 && this._renderObjects(B, t, u, F), this.transparent === !0 && I.length > 0 && this._renderTransparents(I, R, t, u, F), this.backend.finishRender(_), s.renderId = a, this._currentRenderContext = o, this._currentRenderObjectFunction = l, this._handleObjectFunction = c, this._callDepth--, r !== null && (this.setRenderTarget(h, d, f), this._renderOutput(p)), u.onAfterRender(this, e, t, p), this.inspector.finishRender(this.backend.getTimestampUID(_)), _;
  }
  _setXRLayerSize(e, t) {
    this._canvasTarget._width = e, this._canvasTarget._height = t, this.setViewport(0, 0, e, t);
  }
  /**
   * The output pass performs tone mapping and color space conversion.
   *
   * @private
   * @param {RenderTarget} renderTarget - The current render target.
   */
  _renderOutput(e) {
    const t = this._quad;
    this._nodes.hasOutputChange(e.texture) && (t.material.fragmentNode = this._nodes.getOutputNode(e.texture), t.material.needsUpdate = !0);
    const n = this.autoClear, r = this.xr.enabled;
    this.autoClear = !1, this.xr.enabled = !1, this._renderScene(t, t.camera, !1), this.autoClear = n, this.xr.enabled = r;
  }
  /**
   * Returns the maximum available anisotropy for texture filtering.
   *
   * @return {number} The maximum available anisotropy.
   */
  getMaxAnisotropy() {
    return this.backend.getMaxAnisotropy();
  }
  /**
   * Returns the active cube face.
   *
   * @return {number} The active cube face.
   */
  getActiveCubeFace() {
    return this._activeCubeFace;
  }
  /**
   * Returns the active mipmap level.
   *
   * @return {number} The active mipmap level.
   */
  getActiveMipmapLevel() {
    return this._activeMipmapLevel;
  }
  /**
   * Applications are advised to always define the animation loop
   * with this method and not manually with `requestAnimationFrame()`
   * for best compatibility.
   *
   * @async
   * @param {?onAnimationCallback} callback - The application's animation loop.
   * @return {Promise} A Promise that resolves when the set has been executed.
   */
  async setAnimationLoop(e) {
    this._initialized === !1 && await this.init(), this._animation.setAnimationLoop(e);
  }
  /**
   * Returns the current animation loop callback.
   *
   * @return {?Function} The current animation loop callback.
   */
  getAnimationLoop() {
    return this._animation.getAnimationLoop();
  }
  /**
   * Can be used to transfer buffer data from a storage buffer attribute
   * from the GPU to the CPU in context of compute shaders.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync(e) {
    return await this.backend.getArrayBufferAsync(e);
  }
  /**
   * Returns the rendering context.
   *
   * @return {GPUCanvasContext|WebGL2RenderingContext} The rendering context.
   */
  getContext() {
    return this.backend.getContext();
  }
  /**
   * Returns the pixel ratio.
   *
   * @return {number} The pixel ratio.
   */
  getPixelRatio() {
    return this._canvasTarget.getPixelRatio();
  }
  /**
   * Returns the drawing buffer size in physical pixels. This method honors the pixel ratio.
   *
   * @param {Vector2} target - The method writes the result in this target object.
   * @return {Vector2} The drawing buffer size.
   */
  getDrawingBufferSize(e) {
    return this._canvasTarget.getDrawingBufferSize(e);
  }
  /**
   * Returns the renderer's size in logical pixels. This method does not honor the pixel ratio.
   *
   * @param {Vector2} target - The method writes the result in this target object.
   * @return {Vector2} The renderer's size in logical pixels.
   */
  getSize(e) {
    return this._canvasTarget.getSize(e);
  }
  /**
   * Sets the given pixel ratio and resizes the canvas if necessary.
   *
   * @param {number} [value=1] - The pixel ratio.
   */
  setPixelRatio(e = 1) {
    this._canvasTarget.setPixelRatio(e);
  }
  /**
   * This method allows to define the drawing buffer size by specifying
   * width, height and pixel ratio all at once. The size of the drawing
   * buffer is computed with this formula:
   * ```js
   * size.x = width * pixelRatio;
   * size.y = height * pixelRatio;
   * ```
   *
   * @param {number} width - The width in logical pixels.
   * @param {number} height - The height in logical pixels.
   * @param {number} pixelRatio - The pixel ratio.
   */
  setDrawingBufferSize(e, t, n) {
    this.xr && this.xr.isPresenting || this._canvasTarget.setDrawingBufferSize(e, t, n);
  }
  /**
   * Sets the size of the renderer.
   *
   * @param {number} width - The width in logical pixels.
   * @param {number} height - The height in logical pixels.
   * @param {boolean} [updateStyle=true] - Whether to update the `style` attribute of the canvas or not.
   */
  setSize(e, t, n = !0) {
    this.xr && this.xr.isPresenting || this._canvasTarget.setSize(e, t, n);
  }
  /**
   * Defines a manual sort function for the opaque render list.
   * Pass `null` to use the default sort.
   *
   * @param {Function} method - The sort function.
   */
  setOpaqueSort(e) {
    this._opaqueSort = e;
  }
  /**
   * Defines a manual sort function for the transparent render list.
   * Pass `null` to use the default sort.
   *
   * @param {Function} method - The sort function.
   */
  setTransparentSort(e) {
    this._transparentSort = e;
  }
  /**
   * Returns the scissor rectangle.
   *
   * @param {Vector4} target - The method writes the result in this target object.
   * @return {Vector4} The scissor rectangle.
   */
  getScissor(e) {
    return this._canvasTarget.getScissor(e);
  }
  /**
   * Defines the scissor rectangle.
   *
   * @param {number | Vector4} x - The horizontal coordinate for the upper left corner of the box in logical pixel unit.
   * Instead of passing four arguments, the method also works with a single four-dimensional vector.
   * @param {number} y - The vertical coordinate for the upper left corner of the box in logical pixel unit.
   * @param {number} width - The width of the scissor box in logical pixel unit.
   * @param {number} height - The height of the scissor box in logical pixel unit.
   */
  setScissor(e, t, n, r) {
    this._canvasTarget.setScissor(e, t, n, r);
  }
  /**
   * Returns the scissor test value.
   *
   * @return {boolean} Whether the scissor test should be enabled or not.
   */
  getScissorTest() {
    return this._canvasTarget.getScissorTest();
  }
  /**
   * Defines the scissor test.
   *
   * @param {boolean} boolean - Whether the scissor test should be enabled or not.
   */
  setScissorTest(e) {
    this._canvasTarget.setScissorTest(e), this.backend.setScissorTest(e);
  }
  /**
   * Returns the viewport definition.
   *
   * @param {Vector4} target - The method writes the result in this target object.
   * @return {Vector4} The viewport definition.
   */
  getViewport(e) {
    return this._canvasTarget.getViewport(e);
  }
  /**
   * Defines the viewport.
   *
   * @param {number | Vector4} x - The horizontal coordinate for the upper left corner of the viewport origin in logical pixel unit.
   * @param {number} y - The vertical coordinate for the upper left corner of the viewport origin  in logical pixel unit.
   * @param {number} width - The width of the viewport in logical pixel unit.
   * @param {number} height - The height of the viewport in logical pixel unit.
   * @param {number} minDepth - The minimum depth value of the viewport. WebGPU only.
   * @param {number} maxDepth - The maximum depth value of the viewport. WebGPU only.
   */
  setViewport(e, t, n, r, s = 0, a = 1) {
    this._canvasTarget.setViewport(e, t, n, r, s, a);
  }
  /**
   * Returns the clear color.
   *
   * @param {Color} target - The method writes the result in this target object.
   * @return {Color} The clear color.
   */
  getClearColor(e) {
    return e.copy(this._clearColor);
  }
  /**
   * Defines the clear color and optionally the clear alpha.
   *
   * @param {Color} color - The clear color.
   * @param {number} [alpha=1] - The clear alpha.
   */
  setClearColor(e, t = 1) {
    this._clearColor.set(e), this._clearColor.a = t;
  }
  /**
   * Returns the clear alpha.
   *
   * @return {number} The clear alpha.
   */
  getClearAlpha() {
    return this._clearColor.a;
  }
  /**
   * Defines the clear alpha.
   *
   * @param {number} alpha - The clear alpha.
   */
  setClearAlpha(e) {
    this._clearColor.a = e;
  }
  /**
   * Returns the clear depth.
   *
   * @return {number} The clear depth.
   */
  getClearDepth() {
    return this.reversedDepthBuffer === !0 ? 1 - this._clearDepth : this._clearDepth;
  }
  /**
   * Defines the clear depth.
   *
   * @param {number} depth - The clear depth.
   */
  setClearDepth(e) {
    this._clearDepth = e;
  }
  /**
   * Returns the clear stencil.
   *
   * @return {number} The clear stencil.
   */
  getClearStencil() {
    return this._clearStencil;
  }
  /**
   * Defines the clear stencil.
   *
   * @param {number} stencil - The clear stencil.
   */
  setClearStencil(e) {
    this._clearStencil = e;
  }
  /**
   * This method performs an occlusion query for the given 3D object.
   * It returns `true` if the given 3D object is fully occluded by other
   * 3D objects in the scene.
   *
   * @param {Object3D} object - The 3D object to test.
   * @return {boolean} Whether the 3D object is fully occluded or not.
   */
  isOccluded(e) {
    const t = this._currentRenderContext;
    return t && this.backend.isOccluded(t, e);
  }
  /**
   * Performs a manual clear operation. This method ignores `autoClear` properties.
   *
   * @param {boolean} [color=true] - Whether the color buffer should be cleared or not.
   * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not.
   * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not.
   */
  clear(e = !0, t = !0, n = !0) {
    if (this._initialized === !1)
      throw new Error('Renderer: .clear() called before the backend is initialized. Use "await renderer.init();" before before using this method.');
    const r = this._renderTarget || this._getFrameBufferTarget();
    let s = null;
    if (r !== null) {
      this._textures.updateRenderTarget(r);
      const a = this._textures.get(r);
      s = this._renderContexts.get(r), s.textures = a.textures, s.depthTexture = a.depthTexture, s.width = a.width, s.height = a.height, s.renderTarget = r, s.depth = r.depthBuffer, s.stencil = r.stencilBuffer;
      const o = this.backend.getClearColor();
      s.clearColorValue.r = o.r, s.clearColorValue.g = o.g, s.clearColorValue.b = o.b, s.clearColorValue.a = o.a, s.clearDepthValue = this.getClearDepth(), s.clearStencilValue = this.getClearStencil(), s.activeCubeFace = this.getActiveCubeFace(), s.activeMipmapLevel = this.getActiveMipmapLevel();
    }
    this.backend.clear(e, t, n, s), r !== null && this._renderTarget === null && this._renderOutput(r);
  }
  /**
   * Performs a manual clear operation of the color buffer. This method ignores `autoClear` properties.
   */
  clearColor() {
    this.clear(!0, !1, !1);
  }
  /**
   * Performs a manual clear operation of the depth buffer. This method ignores `autoClear` properties.
   */
  clearDepth() {
    this.clear(!1, !0, !1);
  }
  /**
   * Performs a manual clear operation of the stencil buffer. This method ignores `autoClear` properties.
   */
  clearStencil() {
    this.clear(!1, !1, !0);
  }
  /**
   * Async version of {@link Renderer#clear}.
   *
   * @async
   * @deprecated
   * @param {boolean} [color=true] - Whether the color buffer should be cleared or not.
   * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not.
   * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not.
   * @return {Promise} A Promise that resolves when the clear operation has been executed.
   */
  async clearAsync(e = !0, t = !0, n = !0) {
    Pt('Renderer: "clearAsync()" has been deprecated. Use "clear()" and "await renderer.init();" when creating the renderer.'), await this.init(), this.clear(e, t, n);
  }
  /**
   * Async version of {@link Renderer#clearColor}.
   *
   * @async
   * @deprecated
   * @return {Promise} A Promise that resolves when the clear operation has been executed.
   */
  async clearColorAsync() {
    Pt('Renderer: "clearColorAsync()" has been deprecated. Use "clearColor()" and "await renderer.init();" when creating the renderer.'), this.clear(!0, !1, !1);
  }
  /**
   * Async version of {@link Renderer#clearDepth}.
   *
   * @async
   * @deprecated
   * @return {Promise} A Promise that resolves when the clear operation has been executed.
   */
  async clearDepthAsync() {
    Pt('Renderer: "clearDepthAsync()" has been deprecated. Use "clearDepth()" and "await renderer.init();" when creating the renderer.'), this.clear(!1, !0, !1);
  }
  /**
   * Async version of {@link Renderer#clearStencil}.
   *
   * @async
   * @deprecated
   * @return {Promise} A Promise that resolves when the clear operation has been executed.
   */
  async clearStencilAsync() {
    Pt('Renderer: "clearStencilAsync()" has been deprecated. Use "clearStencil()" and "await renderer.init();" when creating the renderer.'), this.clear(!1, !1, !0);
  }
  /**
   * Returns `true` if a framebuffer target is needed to perform tone mapping or color space conversion.
   * If this is the case, the renderer allocates an internal render target for that purpose.
   *
   */
  get needsFrameBufferTarget() {
    const e = this.currentToneMapping !== In, t = this.currentColorSpace !== Ke.workingColorSpace;
    return e || t;
  }
  /**
   * The number of samples used for multi-sample anti-aliasing (MSAA).
   *
   * @type {number}
   * @default 0
   */
  get samples() {
    return this._samples;
  }
  /**
   * The current number of samples used for multi-sample anti-aliasing (MSAA).
   *
   * When rendering to a custom render target, the number of samples of that render target is used.
   * If the renderer needs an internal framebuffer target for tone mapping or color space conversion,
   * the number of samples is set to 0.
   *
   * @type {number}
   */
  get currentSamples() {
    let e = this._samples;
    return this._renderTarget !== null ? e = this._renderTarget.samples : this.needsFrameBufferTarget && (e = 0), e;
  }
  /**
   * The current tone mapping of the renderer. When not producing screen output,
   * the tone mapping is always `NoToneMapping`.
   *
   * @type {number}
   */
  get currentToneMapping() {
    return this.isOutputTarget ? this.toneMapping : In;
  }
  /**
   * The current color space of the renderer. When not producing screen output,
   * the color space is always the working color space.
   *
   * @type {string}
   */
  get currentColorSpace() {
    return this.isOutputTarget ? this.outputColorSpace : Ke.workingColorSpace;
  }
  /**
   * Returns `true` if the rendering settings are set to screen output.
   *
   * @returns {boolean} True if the current render target is the same of output render target or `null`, otherwise false.
   */
  get isOutputTarget() {
    return this._renderTarget === this._outputRenderTarget || this._renderTarget === null;
  }
  /**
   * Frees all internal resources of the renderer. Call this method if the renderer
   * is no longer in use by your app.
   */
  dispose() {
    this._initialized === !0 && (this.info.dispose(), this.backend.dispose(), this._animation.dispose(), this._objects.dispose(), this._geometries.dispose(), this._pipelines.dispose(), this._nodes.dispose(), this._bindings.dispose(), this._renderLists.dispose(), this._renderContexts.dispose(), this._textures.dispose(), this._frameBufferTarget !== null && this._frameBufferTarget.dispose(), Object.values(this.backend.timestampQueryPool).forEach((e) => {
      e !== null && e.dispose();
    })), this.setRenderTarget(null), this.setAnimationLoop(null);
  }
  /**
   * Sets the given render target. Calling this method means the renderer does not
   * target the default framebuffer (meaning the canvas) anymore but a custom framebuffer.
   * Use `null` as the first argument to reset the state.
   *
   * @param {?RenderTarget} renderTarget - The render target to set.
   * @param {number} [activeCubeFace=0] - The active cube face.
   * @param {number} [activeMipmapLevel=0] - The active mipmap level.
   */
  setRenderTarget(e, t = 0, n = 0) {
    this._renderTarget = e, this._activeCubeFace = t, this._activeMipmapLevel = n;
  }
  /**
   * Returns the current render target.
   *
   * @return {?RenderTarget} The render target. Returns `null` if no render target is set.
   */
  getRenderTarget() {
    return this._renderTarget;
  }
  /**
   * Sets the output render target for the renderer.
   *
   * @param {Object} renderTarget - The render target to set as the output target.
   */
  setOutputRenderTarget(e) {
    this._outputRenderTarget = e;
  }
  /**
   * Returns the current output target.
   *
   * @return {?RenderTarget} The current output render target. Returns `null` if no output target is set.
   */
  getOutputRenderTarget() {
    return this._outputRenderTarget;
  }
  /**
   * Sets the canvas target. The canvas target manages the HTML canvas
   * or the offscreen canvas the renderer draws into.
   *
   * @param {CanvasTarget} canvasTarget - The canvas target.
   */
  setCanvasTarget(e) {
    this._canvasTarget.removeEventListener("resize", this._onCanvasTargetResize), this._canvasTarget = e, this._canvasTarget.addEventListener("resize", this._onCanvasTargetResize);
  }
  /**
   * Returns the current canvas target.
   *
   * @return {CanvasTarget} The current canvas target.
   */
  getCanvasTarget() {
    return this._canvasTarget;
  }
  /**
   * Resets the renderer to the initial state before WebXR started.
   *
   * @private
   */
  _resetXRState() {
    this.backend.setXRTarget(null), this.setOutputRenderTarget(null), this.setRenderTarget(null), this._frameBufferTarget.dispose(), this._frameBufferTarget = null;
  }
  /**
   * Callback for {@link Renderer#setRenderObjectFunction}.
   *
   * @callback renderObjectFunction
   * @param {Object3D} object - The 3D object.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {BufferGeometry} geometry - The object's geometry.
   * @param {Material} material - The object's material.
   * @param {?Object} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {LightsNode} lightsNode - The current lights node.
   * @param {ClippingContext} clippingContext - The clipping context.
   * @param {?string} [passId=null] - An optional ID for identifying the pass.
   */
  /**
   * Sets the given render object function. Calling this method overwrites the default implementation
   * which is {@link Renderer#renderObject}. Defining a custom function can be useful
   * if you want to modify the way objects are rendered. For example you can define things like "every
   * object that has material of a certain type should perform a pre-pass with a special overwrite material".
   * The custom function must always call `renderObject()` in its implementation.
   *
   * Use `null` as the first argument to reset the state.
   *
   * @param {?renderObjectFunction} renderObjectFunction - The render object function.
   */
  setRenderObjectFunction(e) {
    this._renderObjectFunction = e;
  }
  /**
   * Returns the current render object function.
   *
   * @return {?Function} The current render object function. Returns `null` if no function is set.
   */
  getRenderObjectFunction() {
    return this._renderObjectFunction;
  }
  /**
   * Execute a single or an array of compute nodes. This method can only be called
   * if the renderer has been initialized.
   *
   * @param {Node|Array<Node>} computeNodes - The compute node(s).
   * @param {number|Array<number>|IndirectStorageBufferAttribute} [dispatchSize=null]
   * - A single number representing count, or
   * - An array [x, y, z] representing dispatch size, or
   * - A IndirectStorageBufferAttribute for indirect dispatch size.
   * @return {Promise|undefined} A Promise that resolve when the compute has finished. Only returned when the renderer has not been initialized.
   */
  compute(e, t = null) {
    if (this._isDeviceLost === !0)
      return;
    if (this._initialized === !1)
      return oe("Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."), this.computeAsync(e, t);
    const n = this._nodes.nodeFrame, r = n.renderId;
    this.info.calls++, this.info.compute.calls++, this.info.compute.frameCalls++, n.renderId = this.info.calls, this.backend.updateTimeStampUID(e), this.inspector.beginCompute(this.backend.getTimestampUID(e), e);
    const s = this.backend, a = this._pipelines, o = this._bindings, l = this._nodes, c = Array.isArray(e) ? e : [e];
    if (c[0] === void 0 || c[0].isComputeNode !== !0)
      throw new Error("THREE.Renderer: .compute() expects a ComputeNode.");
    s.beginCompute(e);
    for (const u of c) {
      if (a.has(u) === !1) {
        const f = () => {
          u.removeEventListener("dispose", f), a.delete(u), o.deleteForCompute(u), l.delete(u);
        };
        u.addEventListener("dispose", f);
        const p = u.onInitFunction;
        p !== null && p.call(u, { renderer: this });
      }
      l.updateForCompute(u), o.updateForCompute(u);
      const h = o.getForCompute(u), d = a.getForCompute(u, h);
      s.compute(e, u, h, d, t);
    }
    s.finishCompute(e), n.renderId = r, this.inspector.finishCompute(this.backend.getTimestampUID(e));
  }
  /**
   * Execute a single or an array of compute nodes.
   *
   * @async
   * @param {Node|Array<Node>} computeNodes - The compute node(s).
   * @param {number|Array<number>|IndirectStorageBufferAttribute} [dispatchSize=null]
   * - A single number representing count, or
   * - An array [x, y, z] representing dispatch size, or
   * - A IndirectStorageBufferAttribute for indirect dispatch size.
   * @return {Promise} A Promise that resolve when the compute has finished.
   */
  async computeAsync(e, t = null) {
    this._initialized === !1 && await this.init(), this.compute(e, t);
  }
  /**
   * Checks if the given feature is supported by the selected backend.
   *
   * @async
   * @deprecated
   * @param {string} name - The feature's name.
   * @return {Promise<boolean>} A Promise that resolves with a bool that indicates whether the feature is supported or not.
   */
  async hasFeatureAsync(e) {
    return Pt('Renderer: "hasFeatureAsync()" has been deprecated. Use "hasFeature()" and "await renderer.init();" when creating the renderer.'), await this.init(), this.hasFeature(e);
  }
  async resolveTimestampsAsync(e = "render") {
    return this._initialized === !1 && await this.init(), this.backend.resolveTimestampsAsync(e);
  }
  /**
   * Checks if the given feature is supported by the selected backend. If the
   * renderer has not been initialized, this method always returns `false`.
   *
   * @param {string} name - The feature's name.
   * @return {boolean} Whether the feature is supported or not.
   */
  hasFeature(e) {
    if (this._initialized === !1)
      throw new Error('Renderer: .hasFeature() called before the backend is initialized. Use "await renderer.init();" before before using this method.');
    return this.backend.hasFeature(e);
  }
  /**
   * Returns `true` when the renderer has been initialized.
   *
   * @return {boolean} Whether the renderer has been initialized or not.
   */
  hasInitialized() {
    return this._initialized;
  }
  /**
   * Initializes the given textures. Useful for preloading a texture rather than waiting until first render
   * (which can cause noticeable lags due to decode and GPU upload overhead).
   *
   * @async
   * @deprecated
   * @param {Texture} texture - The texture.
   * @return {Promise} A Promise that resolves when the texture has been initialized.
   */
  async initTextureAsync(e) {
    Pt('Renderer: "initTextureAsync()" has been deprecated. Use "initTexture()" and "await renderer.init();" when creating the renderer.'), await this.init(), this.initTexture(e);
  }
  /**
   * Initializes the given texture. Useful for preloading a texture rather than waiting until first render
   * (which can cause noticeable lags due to decode and GPU upload overhead).
   *
   * This method can only be used if the renderer has been initialized.
   *
   * @param {Texture} texture - The texture.
   */
  initTexture(e) {
    if (this._initialized === !1)
      throw new Error('Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before before using this method.');
    this._textures.updateTexture(e);
  }
  /**
   * Initializes the given render target.
   *
   * @param {RenderTarget} renderTarget - The render target to intialize.
   */
  initRenderTarget(e) {
    if (this._initialized === !1)
      throw new Error('Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before before using this method.');
    this._textures.updateRenderTarget(e);
    const t = this._textures.get(e), n = this._renderContexts.get(e);
    n.textures = t.textures, n.depthTexture = t.depthTexture, n.width = t.width, n.height = t.height, n.renderTarget = e, n.depth = e.depthBuffer, n.stencil = e.stencilBuffer, this.backend.initRenderTarget(n);
  }
  /**
   * Copies the current bound framebuffer into the given texture.
   *
   * @param {FramebufferTexture} framebufferTexture - The texture.
   * @param {?(Vector2|Vector4)} [rectangle=null] - A two or four dimensional vector that defines the rectangular portion of the framebuffer that should be copied.
   */
  copyFramebufferToTexture(e, t = null) {
    if (t !== null)
      if (t.isVector2)
        t = Wr.set(t.x, t.y, e.image.width, e.image.height).floor();
      else if (t.isVector4)
        t = Wr.copy(t).floor();
      else {
        le("Renderer.copyFramebufferToTexture: Invalid rectangle.");
        return;
      }
    else
      t = Wr.set(0, 0, e.image.width, e.image.height);
    let n = this._currentRenderContext, r;
    n !== null ? r = n.renderTarget : (r = this._renderTarget || this._getFrameBufferTarget(), r !== null && (this._textures.updateRenderTarget(r), n = this._textures.get(r))), this._textures.updateTexture(e, { renderTarget: r }), this.backend.copyFramebufferToTexture(e, n, t), this._inspector.copyFramebufferToTexture(e);
  }
  /**
   * Copies data of the given source texture into a destination texture.
   *
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   * @param {Box2|Box3} [srcRegion=null] - A bounding box which describes the source region. Can be two or three-dimensional.
   * @param {Vector2|Vector3} [dstPosition=null] - A vector that represents the origin of the destination region. Can be two or three-dimensional.
   * @param {number} [srcLevel=0] - The source mip level to copy from.
   * @param {number} [dstLevel=0] - The destination mip level to copy to.
   */
  copyTextureToTexture(e, t, n = null, r = null, s = 0, a = 0) {
    this._textures.updateTexture(e), this._textures.updateTexture(t), this.backend.copyTextureToTexture(e, t, n, r, s, a), this._inspector.copyTextureToTexture(e, t);
  }
  /**
   * Reads pixel data from the given render target.
   *
   * @async
   * @param {RenderTarget} renderTarget - The render target to read from.
   * @param {number} x - The `x` coordinate of the copy region's origin.
   * @param {number} y - The `y` coordinate of the copy region's origin.
   * @param {number} width - The width of the copy region.
   * @param {number} height - The height of the copy region.
   * @param {number} [textureIndex=0] - The texture index of a MRT render target.
   * @param {number} [faceIndex=0] - The active cube face index.
   * @return {Promise<TypedArray>} A Promise that resolves when the read has been finished. The resolve provides the read data as a typed array.
   */
  async readRenderTargetPixelsAsync(e, t, n, r, s, a = 0, o = 0) {
    return this.backend.copyTextureToBuffer(e.textures[a], t, n, r, s, o);
  }
  /**
   * Analyzes the given 3D object's hierarchy and builds render lists from the
   * processed hierarchy.
   *
   * @private
   * @param {Object3D} object - The 3D object to process (usually a scene).
   * @param {Camera} camera - The camera the object is rendered with.
   * @param {number} groupOrder - The group order is derived from the `renderOrder` of groups and is used to group 3D objects within groups.
   * @param {RenderList} renderList - The current render list.
   * @param {ClippingContext} clippingContext - The current clipping context.
   */
  _projectObject(e, t, n, r, s) {
    if (e.visible === !1)
      return;
    if (e.layers.test(t.layers)) {
      if (e.isGroup)
        n = e.renderOrder, e.isClippingGroup && e.enabled && (s = s.getGroupContext(e));
      else if (e.isLOD)
        e.autoUpdate === !0 && e.update(t);
      else if (e.isLight)
        r.pushLight(e);
      else if (e.isSprite) {
        const l = t.isArrayCamera ? cp : lp;
        if (!e.frustumCulled || l.intersectsSprite(e, t)) {
          this.sortObjects === !0 && Wr.setFromMatrixPosition(e.matrixWorld).applyMatrix4(ch);
          const { geometry: c, material: u } = e;
          u.visible && r.push(e, c, u, n, Wr.z, null, s);
        }
      } else if (e.isLineLoop)
        le("Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.");
      else if (e.isMesh || e.isLine || e.isPoints) {
        const l = t.isArrayCamera ? cp : lp;
        if (!e.frustumCulled || l.intersectsObject(e, t)) {
          const { geometry: c, material: u } = e;
          if (this.sortObjects === !0 && (c.boundingSphere === null && c.computeBoundingSphere(), Wr.copy(c.boundingSphere.center).applyMatrix4(e.matrixWorld).applyMatrix4(ch)), Array.isArray(u)) {
            const h = c.groups;
            for (let d = 0, f = h.length; d < f; d++) {
              const p = h[d], _ = u[p.materialIndex];
              _ && _.visible && r.push(e, c, _, n, Wr.z, p, s);
            }
          } else
            u.visible && r.push(e, c, u, n, Wr.z, null, s);
        }
      }
    }
    if (e.isBundleGroup === !0 && this.backend.beginBundle !== void 0) {
      const l = r;
      r = this._renderLists.get(e, t), r.begin(), l.pushBundle({
        bundleGroup: e,
        camera: t,
        renderList: r
      }), r.finish();
    }
    const o = e.children;
    for (let l = 0, c = o.length; l < c; l++)
      this._projectObject(o[l], t, n, r, s);
  }
  /**
   * Renders the given render bundles.
   *
   * @private
   * @param {Array<Object>} bundles - Array with render bundle data.
   * @param {Scene} sceneRef - The scene the render bundles belong to.
   * @param {LightsNode} lightsNode - The current lights node.
   */
  _renderBundles(e, t, n) {
    for (const r of e)
      this._renderBundle(r, t, n);
  }
  /**
   * Renders the transparent objects from the given render lists.
   *
   * @private
   * @param {Array<Object>} renderList - The transparent render list.
   * @param {Array<Object>} doublePassList - The list of transparent objects which require a double pass (e.g. because of transmission).
   * @param {Camera} camera - The camera the render list should be rendered with.
   * @param {Scene} scene - The scene the render list belongs to.
   * @param {LightsNode} lightsNode - The current lights node.
   */
  _renderTransparents(e, t, n, r, s) {
    if (t.length > 0) {
      for (const { material: a } of t)
        a.side = Ft;
      this._renderObjects(t, n, r, s, "backSide");
      for (const { material: a } of t)
        a.side = ai;
      this._renderObjects(e, n, r, s);
      for (const { material: a } of t)
        a.side = Rn;
    } else
      this._renderObjects(e, n, r, s);
  }
  /**
   * Renders the objects from the given render list.
   *
   * @private
   * @param {Array<Object>} renderList - The render list.
   * @param {Camera} camera - The camera the render list should be rendered with.
   * @param {Scene} scene - The scene the render list belongs to.
   * @param {LightsNode} lightsNode - The current lights node.
   * @param {?string} [passId=null] - An optional ID for identifying the pass.
   */
  _renderObjects(e, t, n, r, s = null) {
    for (let a = 0, o = e.length; a < o; a++) {
      const { object: l, geometry: c, material: u, group: h, clippingContext: d } = e[a];
      this._currentRenderObjectFunction(l, n, t, c, u, h, r, d, s);
    }
  }
  /**
   * Retrieves shadow nodes for the given material. This is used to setup shadow passes.
   * The result is cached per material and updated when the material's version changes.
   *
   * @private
   * @param {Material} material
   * @returns {Object} - The shadow nodes for the material.
   */
  _getShadowNodes(e) {
    const t = e.version;
    let n = this._cacheShadowNodes.get(e);
    if (n === void 0 || n.version !== t) {
      const r = e.map !== null, s = e.colorNode && e.colorNode.isNode, a = e.castShadowNode && e.castShadowNode.isNode, o = e.maskShadowNode && e.maskShadowNode.isNode || e.maskNode && e.maskNode.isNode;
      let l = null, c = null, u = null;
      if (r || s || a || o) {
        let h, d;
        if (a ? (h = e.castShadowNode.rgb, d = e.castShadowNode.a, this.shadowMap.transmitted !== !0 && Pt("Renderer: `shadowMap.transmitted` needs to be set to `true` when using `material.castShadowNode`.")) : (h = Y(0), d = K(1)), r && (d = d.mul(Qt("map", "texture", e).a)), s && (d = d.mul(e.colorNode.a)), c = et(h, d), o) {
          const f = e.maskShadowNode || e.maskNode;
          c = ee(([p]) => (f.not().discard(), p))(c);
        }
      }
      e.depthNode && e.depthNode.isNode && (u = e.depthNode), e.castShadowPositionNode && e.castShadowPositionNode.isNode ? l = e.castShadowPositionNode : e.positionNode && e.positionNode.isNode && (l = e.positionNode), n = {
        version: t,
        colorNode: c,
        depthNode: u,
        positionNode: l
      }, this._cacheShadowNodes.set(e, n);
    }
    return n;
  }
  /**
   * This method represents the default render object function that manages the render lifecycle
   * of the object.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {BufferGeometry} geometry - The object's geometry.
   * @param {Material} material - The object's material.
   * @param {?Object} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {LightsNode} lightsNode - The current lights node.
   * @param {?ClippingContext} clippingContext - The clipping context.
   * @param {?string} [passId=null] - An optional ID for identifying the pass.
   */
  renderObject(e, t, n, r, s, a, o, l = null, c = null) {
    let u = !1, h, d, f, p;
    if (e.onBeforeRender(this, t, n, r, s, a), s.allowOverride === !0 && t.overrideMaterial !== null) {
      const _ = t.overrideMaterial;
      if (u = !0, h = _.isNodeMaterial ? _.colorNode : null, d = _.isNodeMaterial ? _.depthNode : null, f = _.isNodeMaterial ? _.positionNode : null, p = t.overrideMaterial.side, s.positionNode && s.positionNode.isNode && (_.positionNode = s.positionNode), _.alphaTest = s.alphaTest, _.alphaMap = s.alphaMap, _.transparent = s.transparent || s.transmission > 0 || s.transmissionNode && s.transmissionNode.isNode || s.backdropNode && s.backdropNode.isNode, _.isShadowPassMaterial) {
        const { colorNode: g, depthNode: m, positionNode: x } = this._getShadowNodes(s);
        this.shadowMap.type === br ? _.side = s.shadowSide !== null ? s.shadowSide : s.side : _.side = s.shadowSide !== null ? s.shadowSide : FG[s.side], g !== null && (_.colorNode = g), m !== null && (_.depthNode = m), x !== null && (_.positionNode = x);
      }
      s = _;
    }
    s.transparent === !0 && s.side === Rn && s.forceSinglePass === !1 ? (s.side = Ft, this._handleObjectFunction(e, s, t, n, o, a, l, "backSide"), s.side = ai, this._handleObjectFunction(e, s, t, n, o, a, l, c), s.side = Rn) : this._handleObjectFunction(e, s, t, n, o, a, l, c), u && (t.overrideMaterial.colorNode = h, t.overrideMaterial.depthNode = d, t.overrideMaterial.positionNode = f, t.overrideMaterial.side = p), e.onAfterRender(this, t, n, r, s, a);
  }
  /**
   * Checks if the given compatibility is supported by the selected backend. If the
   * renderer has not been initialized, this method always returns `false`.
   *
   * @param {string} name - The compatibility's name.
   * @return {boolean} Whether the compatibility is supported or not.
   */
  hasCompatibility(e) {
    return this.backend.hasCompatibility(e);
  }
  /**
   * This method represents the default `_handleObjectFunction` implementation which creates
   * a render object from the given data and performs the draw command with the selected backend.
   *
   * @private
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The object's material.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {LightsNode} lightsNode - The current lights node.
   * @param {?{start: number, count: number}} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {ClippingContext} clippingContext - The clipping context.
   * @param {string} [passId] - An optional ID for identifying the pass.
   */
  _renderObjectDirect(e, t, n, r, s, a, o, l) {
    const c = this._objects.get(e, t, n, r, s, this._currentRenderContext, o, l);
    c.drawRange = e.geometry.drawRange, c.group = a, this._currentRenderBundle !== null && (this.backend.get(this._currentRenderBundle).renderObjects.push(c), c.bundle = this._currentRenderBundle.bundleGroup);
    const u = this._nodes.needsRefresh(c);
    u && (this._nodes.updateBefore(c), this._geometries.updateForRender(c), this._nodes.updateForRender(c), this._bindings.updateForRender(c)), this._pipelines.updateForRender(c), this.backend.draw(c, this.info), u && this._nodes.updateAfter(c);
  }
  /**
   * A different implementation for `_handleObjectFunction` which only makes sure the object is ready for rendering.
   * Used in `compileAsync()`.
   *
   * @private
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The object's material.
   * @param {Scene} scene - The scene the 3D object belongs to.
   * @param {Camera} camera - The camera the object should be rendered with.
   * @param {LightsNode} lightsNode - The current lights node.
   * @param {?{start: number, count: number}} group - Only relevant for objects using multiple materials. This represents a group entry from the respective `BufferGeometry`.
   * @param {ClippingContext} clippingContext - The clipping context.
   * @param {string} [passId] - An optional ID for identifying the pass.
   */
  _createObjectPipeline(e, t, n, r, s, a, o, l) {
    const c = this._objects.get(e, t, n, r, s, this._currentRenderContext, o, l);
    c.drawRange = e.geometry.drawRange, c.group = a, this._nodes.updateBefore(c), this._geometries.updateForRender(c), this._nodes.updateForRender(c), this._bindings.updateForRender(c), this._pipelines.getForRender(c, this._compilationPromises), this._nodes.updateAfter(c);
  }
  /**
   * Callback when the canvas has been resized.
   *
   * @private
   */
  _onCanvasTargetResize() {
    this._initialized && this.backend.updateSize();
  }
  /**
   * Alias for `compileAsync()`.
   *
   * @method
   * @param {Object3D} scene - The scene or 3D object to precompile.
   * @param {Camera} camera - The camera that is used to render the scene.
   * @param {Scene} targetScene - If the first argument is a 3D object, this parameter must represent the scene the 3D object is going to be added.
   * @return {function(Object3D, Camera, ?Scene): Promise|undefined} A Promise that resolves when the compile has been finished.
   */
  get compile() {
    return this.compileAsync;
  }
}
class uT {
  /**
   * Constructs a new binding.
   *
   * @param {string} [name=''] - The binding's name.
   */
  constructor(e = "") {
    this.name = e, this.visibility = 0;
  }
  /**
   * Makes sure binding's resource is visible for the given shader stage.
   *
   * @param {number} visibility - The shader stage.
   */
  setVisibility(e) {
    this.visibility |= e;
  }
  /**
   * The shader stages in which the binding's resource is visible.
   *
   * @return {number} The visibility bitmask.
   */
  getVisibility() {
    return this.visibility;
  }
  /**
   * Clones the binding.
   *
   * @return {Binding} The cloned binding.
   */
  clone() {
    return Object.assign(new this.constructor(), this);
  }
}
function UG(i) {
  return i + (Cs - i % Cs) % Cs;
}
class hT extends uT {
  /**
   * Constructs a new buffer.
   *
   * @param {string} name - The buffer's name.
   * @param {TypedArray} [buffer=null] - The buffer.
   */
  constructor(e, t = null) {
    super(e), this.isBuffer = !0, this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT, this._buffer = t, this._updateRanges = [];
  }
  /**
   * The array of update ranges.
   *
   * @type {Array<{start: number, count: number}>}
   */
  get updateRanges() {
    return this._updateRanges;
  }
  /**
   * Adds an update range.
   *
   * @param {number} start - The start index.
   * @param {number} count - The number of elements.
   */
  addUpdateRange(e, t) {
    this.updateRanges.push({ start: e, count: t });
  }
  /**
   * Clears all update ranges.
   */
  clearUpdateRanges() {
    this.updateRanges.length = 0;
  }
  /**
   * The buffer's byte length.
   *
   * @type {number}
   * @readonly
   */
  get byteLength() {
    return UG(this._buffer.byteLength);
  }
  /**
   * A reference to the internal buffer.
   *
   * @type {Float32Array}
   * @readonly
   */
  get buffer() {
    return this._buffer;
  }
  /**
   * Updates the binding.
   *
   * @return {boolean} Whether the buffer has been updated and must be
   * uploaded to the GPU.
   */
  update() {
    return !0;
  }
}
class dT extends hT {
  /**
   * Constructs a new uniform buffer.
   *
   * @param {string} name - The buffer's name.
   * @param {TypedArray} [buffer=null] - The buffer.
   */
  constructor(e, t = null) {
    super(e, t), this.isUniformBuffer = !0;
  }
}
let BG = 0;
class fT extends dT {
  /**
   * Constructs a new node-based uniform buffer.
   *
   * @param {BufferNode} nodeUniform - The uniform buffer node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   */
  constructor(e, t) {
    super("UniformBuffer_" + BG++, e ? e.value : null), this.nodeUniform = e, this.groupNode = t, this.isNodeUniformBuffer = !0;
  }
  /**
   * The array of update ranges.
   *
   * @param {Array<{start: number, count: number}>} value - The update ranges.
   */
  set updateRanges(e) {
    this.nodeUniform.updateRanges = e;
  }
  /**
   * The array of update ranges.
   *
   * @type {Array<{start: number, count: number}>}
   */
  get updateRanges() {
    return this.nodeUniform.updateRanges;
  }
  /**
   * Adds a range of data in the data array to be updated on the GPU.
   *
   * @param {number} start - Position at which to start update.
   * @param {number} count - The number of components to update.
   */
  addUpdateRange(e, t) {
    this.nodeUniform.addUpdateRange(e, t);
  }
  /**
   * Clears all update ranges.
   */
  clearUpdateRanges() {
    this.nodeUniform.clearUpdateRanges();
  }
  /**
   * The uniform buffer.
   *
   * @type {Float32Array}
   */
  get buffer() {
    return this.nodeUniform.value;
  }
}
class OG extends dT {
  /**
   * Constructs a new uniforms group.
   *
   * @param {string} name - The group's name.
   */
  constructor(e) {
    super(e), this.isUniformsGroup = !0, this._values = null, this.uniforms = [], this._updateRangeCache = /* @__PURE__ */ new Map();
  }
  /**
   * Adds a uniform's update range to this buffer.
   *
   * @param {Uniform} uniform - The uniform.
   */
  addUniformUpdateRange(e) {
    const t = e.index;
    if (this._updateRangeCache.has(t) !== !0) {
      const n = this.updateRanges, r = e.offset, s = e.itemSize, a = { start: r, count: s };
      n.push(a), this._updateRangeCache.set(t, a);
    }
  }
  /**
   * Clears all update ranges of this buffer.
   */
  clearUpdateRanges() {
    this._updateRangeCache.clear(), super.clearUpdateRanges();
  }
  /**
   * Adds a uniform to this group.
   *
   * @param {Uniform} uniform - The uniform to add.
   * @return {UniformsGroup} A reference to this group.
   */
  addUniform(e) {
    return this.uniforms.push(e), this;
  }
  /**
   * Removes a uniform from this group.
   *
   * @param {Uniform} uniform - The uniform to remove.
   * @return {UniformsGroup} A reference to this group.
   */
  removeUniform(e) {
    const t = this.uniforms.indexOf(e);
    return t !== -1 && this.uniforms.splice(t, 1), this;
  }
  /**
   * An array with the raw uniform values.
   *
   * @type {Array<number>}
   */
  get values() {
    return this._values === null && (this._values = Array.from(this.buffer)), this._values;
  }
  /**
   * A Float32 array buffer with the uniform values.
   *
   * @type {Float32Array}
   */
  get buffer() {
    let e = this._buffer;
    if (e === null) {
      const t = this.byteLength;
      e = new Float32Array(new ArrayBuffer(t)), this._buffer = e;
    }
    return e;
  }
  /**
   * The byte length of the buffer with correct buffer alignment.
   *
   * @type {number}
   */
  get byteLength() {
    const e = this.bytesPerElement;
    let t = 0;
    for (let n = 0, r = this.uniforms.length; n < r; n++) {
      const s = this.uniforms[n], a = s.boundary, o = s.itemSize * e, l = t % Cs, c = l % a, u = l + c;
      t += c, u !== 0 && Cs - u < o && (t += Cs - u), s.offset = t / e, s.index = n, t += o;
    }
    return Math.ceil(t / Cs) * Cs;
  }
  /**
   * Updates this group by updating each uniform object of
   * the internal uniform list. The uniform objects check if their
   * values has actually changed so this method only returns
   * `true` if there is a real value change.
   *
   * @return {boolean} Whether the uniforms have been updated and
   * must be uploaded to the GPU.
   */
  update() {
    let e = !1;
    for (const t of this.uniforms)
      this.updateByType(t) === !0 && (e = !0);
    return e;
  }
  /**
   * Updates a given uniform by calling an update method matching
   * the uniforms type.
   *
   * @param {Uniform} uniform - The uniform to update.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateByType(e) {
    if (e.isNumberUniform)
      return this.updateNumber(e);
    if (e.isVector2Uniform)
      return this.updateVector2(e);
    if (e.isVector3Uniform)
      return this.updateVector3(e);
    if (e.isVector4Uniform)
      return this.updateVector4(e);
    if (e.isColorUniform)
      return this.updateColor(e);
    if (e.isMatrix3Uniform)
      return this.updateMatrix3(e);
    if (e.isMatrix4Uniform)
      return this.updateMatrix4(e);
    le("WebGPUUniformsGroup: Unsupported uniform type.", e);
  }
  /**
   * Updates a given Number uniform.
   *
   * @param {NumberUniform} uniform - The Number uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateNumber(e) {
    let t = !1;
    const n = this.values, r = e.getValue(), s = e.offset, a = e.getType();
    if (n[s] !== r) {
      const o = this._getBufferForType(a);
      o[s] = n[s] = r, t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Vector2 uniform.
   *
   * @param {Vector2Uniform} uniform - The Vector2 uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateVector2(e) {
    let t = !1;
    const n = this.values, r = e.getValue(), s = e.offset, a = e.getType();
    if (n[s + 0] !== r.x || n[s + 1] !== r.y) {
      const o = this._getBufferForType(a);
      o[s + 0] = n[s + 0] = r.x, o[s + 1] = n[s + 1] = r.y, t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Vector3 uniform.
   *
   * @param {Vector3Uniform} uniform - The Vector3 uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateVector3(e) {
    let t = !1;
    const n = this.values, r = e.getValue(), s = e.offset, a = e.getType();
    if (n[s + 0] !== r.x || n[s + 1] !== r.y || n[s + 2] !== r.z) {
      const o = this._getBufferForType(a);
      o[s + 0] = n[s + 0] = r.x, o[s + 1] = n[s + 1] = r.y, o[s + 2] = n[s + 2] = r.z, t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Vector4 uniform.
   *
   * @param {Vector4Uniform} uniform - The Vector4 uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateVector4(e) {
    let t = !1;
    const n = this.values, r = e.getValue(), s = e.offset, a = e.getType();
    if (n[s + 0] !== r.x || n[s + 1] !== r.y || n[s + 2] !== r.z || n[s + 4] !== r.w) {
      const o = this._getBufferForType(a);
      o[s + 0] = n[s + 0] = r.x, o[s + 1] = n[s + 1] = r.y, o[s + 2] = n[s + 2] = r.z, o[s + 3] = n[s + 3] = r.w, t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Color uniform.
   *
   * @param {ColorUniform} uniform - The Color uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateColor(e) {
    let t = !1;
    const n = this.values, r = e.getValue(), s = e.offset;
    if (n[s + 0] !== r.r || n[s + 1] !== r.g || n[s + 2] !== r.b) {
      const a = this.buffer;
      a[s + 0] = n[s + 0] = r.r, a[s + 1] = n[s + 1] = r.g, a[s + 2] = n[s + 2] = r.b, t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Matrix3 uniform.
   *
   * @param {Matrix3Uniform} uniform - The Matrix3 uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateMatrix3(e) {
    let t = !1;
    const n = this.values, r = e.getValue().elements, s = e.offset;
    if (n[s + 0] !== r[0] || n[s + 1] !== r[1] || n[s + 2] !== r[2] || n[s + 4] !== r[3] || n[s + 5] !== r[4] || n[s + 6] !== r[5] || n[s + 8] !== r[6] || n[s + 9] !== r[7] || n[s + 10] !== r[8]) {
      const a = this.buffer;
      a[s + 0] = n[s + 0] = r[0], a[s + 1] = n[s + 1] = r[1], a[s + 2] = n[s + 2] = r[2], a[s + 4] = n[s + 4] = r[3], a[s + 5] = n[s + 5] = r[4], a[s + 6] = n[s + 6] = r[5], a[s + 8] = n[s + 8] = r[6], a[s + 9] = n[s + 9] = r[7], a[s + 10] = n[s + 10] = r[8], t = !0, this.addUniformUpdateRange(e);
    }
    return t;
  }
  /**
   * Updates a given Matrix4 uniform.
   *
   * @param {Matrix4Uniform} uniform - The Matrix4 uniform.
   * @return {boolean} Whether the uniform has been updated or not.
   */
  updateMatrix4(e) {
    let t = !1;
    const n = this.values, r = e.getValue().elements, s = e.offset;
    return GG(n, r, s) === !1 && (this.buffer.set(r, s), kG(n, r, s), t = !0, this.addUniformUpdateRange(e)), t;
  }
  /**
   * Returns a typed array that matches the given data type.
   *
   * @private
   * @param {string} type - The data type.
   * @return {TypedArray} The typed array.
   */
  _getBufferForType(e) {
    return e === "int" || e === "ivec2" || e === "ivec3" || e === "ivec4" ? new Int32Array(this.buffer.buffer) : e === "uint" || e === "uvec2" || e === "uvec3" || e === "uvec4" ? new Uint32Array(this.buffer.buffer) : this.buffer;
  }
}
function kG(i, e, t) {
  for (let n = 0, r = e.length; n < r; n++)
    i[t + n] = e[n];
}
function GG(i, e, t) {
  for (let n = 0, r = e.length; n < r; n++)
    if (i[t + n] !== e[n])
      return !1;
  return !0;
}
let VG = 0;
class pT extends OG {
  /**
   * Constructs a new node-based uniforms group.
   *
   * @param {string} name - The group's name.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   */
  constructor(e, t) {
    super(e), this.id = VG++, this.groupNode = t, this.isNodeUniformsGroup = !0;
  }
}
class mT extends uT {
  /**
   * Constructs a new sampler.
   *
   * @param {string} name - The samplers's name.
   * @param {?Texture} texture - The texture this binding is referring to.
   */
  constructor(e, t) {
    super(e), this._texture = null, this._onTextureDispose = () => {
      this.generation = null, this.version = -1;
    }, this.texture = t, this.version = t ? t.version : -1, this.generation = null, this.samplerKey = "", this.isSampler = !0;
  }
  /**
   * Sets the texture of this sampler.
   *
   * @param {Texture} value - The texture to set.
   */
  set texture(e) {
    this._texture !== e && (this._texture && this._texture.removeEventListener("dispose", this._onTextureDispose), this._texture = e, this.generation = null, this.version = -1, this._texture && this._texture.addEventListener("dispose", this._onTextureDispose));
  }
  /**
   * Gets the texture of this sampler.
   * @return {?Texture} The texture.
   */
  get texture() {
    return this._texture;
  }
  /**
   * Updates the binding.
   *
   * @return {boolean} Whether the texture has been updated and must be
   * uploaded to the GPU.
   */
  update() {
    const { texture: e, version: t } = this;
    return t !== e.version ? (this.version = e.version, !0) : !1;
  }
  clone() {
    const e = super.clone();
    return e._texture = null, e._onTextureDispose = () => {
      e.generation = null, e.version = -1;
    }, e.texture = this.texture, e;
  }
}
let zG = 0;
class HG extends mT {
  /**
   * Constructs a new sampled texture.
   *
   * @param {string} name - The sampled texture's name.
   * @param {?Texture} texture - The texture this binding is referring to.
   */
  constructor(e, t) {
    super(e, t), this.id = zG++, this.store = !1, this.mipLevel = 0, this.isSampledTexture = !0;
  }
}
class Nd extends HG {
  /**
   * Constructs a new node-based sampled texture.
   *
   * @param {string} name - The textures's name.
   * @param {TextureNode} textureNode - The texture node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   * @param {?string} [access=null] - The access type.
   */
  constructor(e, t, n, r = null) {
    super(e, t ? t.value : null), this.textureNode = t, this.groupNode = n, this.access = r;
  }
  /**
   * Updates the binding.
   *
   * @return {boolean} Whether the texture has been updated and must be
   * uploaded to the GPU.
   */
  update() {
    const { textureNode: e } = this;
    return this.texture !== e.value ? (this.texture = e.value, !0) : super.update();
  }
}
class gT extends Nd {
  /**
   * Constructs a new node-based sampled cube texture.
   *
   * @param {string} name - The textures's name.
   * @param {TextureNode} textureNode - The texture node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   * @param {?string} [access=null] - The access type.
   */
  constructor(e, t, n, r = null) {
    super(e, t, n, r), this.isSampledCubeTexture = !0;
  }
}
class rm extends Nd {
  /**
   * Constructs a new node-based sampled 3D texture.
   *
   * @param {string} name - The textures's name.
   * @param {TextureNode} textureNode - The texture node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   * @param {?string} [access=null] - The access type.
   */
  constructor(e, t, n, r = null) {
    super(e, t, n, r), this.isSampledTexture3D = !0;
  }
}
const nv = {
  bitcast_int_uint: new En(
    /* glsl */
    "uint tsl_bitcast_int_to_uint ( int x ) { return floatBitsToUint( intBitsToFloat ( x ) ); }"
  ),
  bitcast_uint_int: new En(
    /* glsl */
    "uint tsl_bitcast_uint_to_int ( uint x ) { return floatBitsToInt( uintBitsToFloat ( x ) ); }"
  )
}, $G = {
  textureDimensions: "textureSize",
  equals: "equal",
  bitcast_float_int: "floatBitsToInt",
  bitcast_int_float: "intBitsToFloat",
  bitcast_uint_float: "uintBitsToFloat",
  bitcast_float_uint: "floatBitsToUint",
  bitcast_uint_int: "tsl_bitcast_uint_to_int",
  bitcast_int_uint: "tsl_bitcast_int_to_uint",
  floatpack_snorm_2x16: "packSnorm2x16",
  floatpack_unorm_2x16: "packUnorm2x16",
  floatpack_float16_2x16: "packHalf2x16",
  floatunpack_snorm_2x16: "unpackSnorm2x16",
  floatunpack_unorm_2x16: "unpackUnorm2x16",
  floatunpack_float16_2x16: "unpackHalf2x16"
}, iv = {
  low: "lowp",
  medium: "mediump",
  high: "highp"
}, rv = {
  swizzleAssign: !0,
  storageBuffer: !1
}, sv = {
  perspective: "smooth",
  linear: "noperspective"
}, av = {
  centroid: "centroid"
}, ov = `
precision highp float;
precision highp int;
precision highp sampler2D;
precision highp sampler3D;
precision highp samplerCube;
precision highp sampler2DArray;

precision highp usampler2D;
precision highp usampler3D;
precision highp usamplerCube;
precision highp usampler2DArray;

precision highp isampler2D;
precision highp isampler3D;
precision highp isamplerCube;
precision highp isampler2DArray;

precision highp sampler2DShadow;
precision highp sampler2DArrayShadow;
precision highp samplerCubeShadow;
`;
class WG extends oT {
  /**
   * Constructs a new GLSL node builder renderer.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Renderer} renderer - The renderer.
   */
  constructor(e, t) {
    super(e, t, new vG()), this.uniformGroups = {}, this.transforms = [], this.extensions = {}, this.builtins = { vertex: [], fragment: [], compute: [] };
  }
  /**
   * Checks if the given texture requires a manual conversion to the working color space.
   *
   * @param {Texture} texture - The texture to check.
   * @return {boolean} Whether the given texture requires a conversion to working color space or not.
   */
  needsToWorkingColorSpace(e) {
    return e.isVideoTexture === !0 && e.colorSpace !== hi;
  }
  /**
   * Includes the given method name into the current
   * function node.
   *
   * @private
   * @param {string} name - The method name to include.
   * @return {CodeNode} The respective code node.
   */
  _include(e) {
    const t = nv[e];
    return t.build(this), this.addInclude(t), t;
  }
  /**
   * Returns the native shader method name for a given generic name.
   *
   * @param {string} method - The method name to resolve.
   * @return {string} The resolved GLSL method name.
   */
  getMethod(e) {
    return nv[e] !== void 0 && this._include(e), $G[e] || e;
  }
  /**
   * Returns the bitcast method name for a given input and outputType.
   *
   * @param {string} type - The output type to bitcast to.
   * @param {string} inputType - The input type of the.
   * @return {string} The resolved WGSL bitcast invocation.
   */
  getBitcastMethod(e, t) {
    return this.getMethod(`bitcast_${t}_${e}`);
  }
  /**
   * Returns the float packing method name for a given numeric encoding.
   *
   * @param {string} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
   * @returns {string} The resolved GLSL float packing method name.
   */
  getFloatPackingMethod(e) {
    return this.getMethod(`floatpack_${e}_2x16`);
  }
  /**
   * Returns the float unpacking method name for a given numeric encoding.
   *
   * @param {string} encoding - The numeric encoding that describes how the integer values are mapped to the float range.
   * @returns {string} The resolved GLSL float unpacking method name.
   */
  getFloatUnpackingMethod(e) {
    return this.getMethod(`floatunpack_${e}_2x16`);
  }
  /**
   * Returns the native snippet for a ternary operation.
   *
   * @param {string} condSnippet - The condition determining which expression gets resolved.
   * @param {string} ifSnippet - The expression to resolve to if the condition is true.
   * @param {string} elseSnippet - The expression to resolve to if the condition is false.
   * @return {string} The resolved method name.
   */
  getTernary(e, t, n) {
    return `${e} ? ${t} : ${n}`;
  }
  /**
   * Returns the output struct name. Not relevant for GLSL.
   *
   * @return {string}
   */
  getOutputStructName() {
    return "";
  }
  /**
   * Builds the given shader node.
   *
   * @param {ShaderNodeInternal} shaderNode - The shader node.
   * @return {string} The GLSL function code.
   */
  buildFunctionCode(e) {
    const t = e.layout, n = this.flowShaderNode(e), r = [];
    for (const a of t.inputs)
      r.push(this.getType(a.type) + " " + a.name);
    return `${this.getType(t.type)} ${t.name}( ${r.join(", ")} ) {

	${n.vars}

${n.code}
	return ${n.result};

}`;
  }
  /**
   * Setups the Pixel Buffer Object (PBO) for the given storage
   * buffer node.
   *
   * @param {StorageBufferNode} storageBufferNode - The storage buffer node.
   */
  setupPBO(e) {
    const t = e.value;
    if (t.pbo === void 0) {
      const n = t.array, r = t.count * t.itemSize, { itemSize: s } = t, a = t.array.constructor.name.toLowerCase().includes("int");
      let o = a ? _l : eu;
      s === 2 ? o = a ? xl : ri : s === 3 ? o = a ? hM : Jc : s === 4 && (o = a ? vl : cn);
      const l = {
        Float32Array: ln,
        Uint8Array: Zt,
        Uint16Array: Ji,
        Uint32Array: Dt,
        Int8Array: ba,
        Int16Array: Sa,
        Int32Array: wn,
        Uint8ClampedArray: Zt
      }, c = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(r / s))));
      let u = Math.ceil(r / s / c);
      c * u * s < r && u++;
      const h = c * u * s, d = new n.constructor(h);
      d.set(n, 0), t.array = d;
      const f = new Zm(t.array, c, u, o, l[t.array.constructor.name] || ln);
      f.needsUpdate = !0, f.isPBOTexture = !0;
      const p = new Rl(f, null, null);
      p.setPrecision("high"), t.pboNode = p, t.pbo = p.value, this.getUniformFromNode(t.pboNode, "texture", this.shaderStage, this.context.nodeName);
    }
  }
  /**
   * Returns a GLSL snippet that represents the property name of the given node.
   *
   * @param {Node} node - The node.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The property name.
   */
  getPropertyName(e, t = this.shaderStage) {
    return e.isNodeUniform && e.node.isTextureNode !== !0 && e.node.isBufferNode !== !0 ? e.name : super.getPropertyName(e, t);
  }
  /**
   * Setups the Pixel Buffer Object (PBO) for the given storage
   * buffer node.
   *
   * @param {StorageArrayElementNode} storageArrayElementNode - The storage array element node.
   * @return {string} The property name.
   */
  generatePBO(e) {
    const { node: t, indexNode: n } = e, r = t.value;
    if (this.renderer.backend.has(r)) {
      const u = this.renderer.backend.get(r);
      u.pbo = r.pbo;
    }
    const s = this.getUniformFromNode(r.pboNode, "texture", this.shaderStage, this.context.nodeName), a = this.getPropertyName(s);
    this.increaseUsage(n);
    const o = n.build(this, "uint"), l = this.getDataFromNode(e);
    let c = l.propertyName;
    if (c === void 0) {
      const u = this.getVarFromNode(e);
      c = this.getPropertyName(u);
      const h = this.getDataFromNode(t);
      let d = h.propertySizeName;
      d === void 0 && (d = c + "Size", this.getVarFromNode(t, d, "uint"), this.addLineFlowCode(`${d} = uint( textureSize( ${a}, 0 ).x )`, e), h.propertySizeName = d);
      const { itemSize: f } = r, p = "." + El.join("").slice(0, f), _ = `ivec2(${o} % ${d}, ${o} / ${d})`, g = this.generateTextureLoad(null, a, _, "0", null, null);
      let m = "vec4";
      r.pbo.type === Dt ? m = "uvec4" : r.pbo.type === wn && (m = "ivec4"), this.addLineFlowCode(`${c} = ${m}(${g})${p}`, e), l.propertyName = c;
    }
    return c;
  }
  /**
   * Generates the GLSL snippet that reads a single texel from a texture without sampling or filtering.
   *
   * @param {?Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvIndexSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {?string} levelSnippet - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A GLSL snippet that represents the 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The GLSL snippet.
   */
  generateTextureLoad(e, t, n, r, s, a) {
    r === null && (r = "0");
    let o;
    return s ? a ? o = `texelFetchOffset( ${t}, ivec3( ${n}, ${s} ), ${r}, ${a} )` : o = `texelFetch( ${t}, ivec3( ${n}, ${s} ), ${r} )` : a ? o = `texelFetchOffset( ${t}, ${n}, ${r}, ${a} )` : o = `texelFetch( ${t}, ${n}, ${r} )`, e !== null && e.isDepthTexture && (o += ".x"), o;
  }
  /**
   * Generates the GLSL snippet for sampling/loading the given texture.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {?string} depthSnippet -  A GLSL snippet that represents the 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The GLSL snippet.
   */
  generateTexture(e, t, n, r, s) {
    return r && (n = `vec3( ${n}, ${r} )`), e.isDepthTexture ? s ? `textureOffset( ${t}, ${n}, ${s} ).x` : `texture( ${t}, ${n} ).x` : s ? `textureOffset( ${t}, ${n}, ${s} )` : `texture( ${t}, ${n} )`;
  }
  /**
   * Generates the GLSL snippet when sampling textures with explicit mip level.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {string} levelSnippet - A GLSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The GLSL snippet.
   */
  generateTextureLevel(e, t, n, r, s, a) {
    return s && (n = `vec3( ${n}, ${s} )`), a ? `textureLodOffset( ${t}, ${n}, ${r}, ${a} )` : `textureLod( ${t}, ${n}, ${r} )`;
  }
  /**
   * Generates the GLSL snippet when sampling textures with a bias to the mip level.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {string} biasSnippet - A GLSL snippet that represents the bias to apply to the mip level before sampling.
   * @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The GLSL snippet.
   */
  generateTextureBias(e, t, n, r, s, a) {
    return s && (n = `vec3( ${n}, ${s} )`), a ? `textureOffset( ${t}, ${n}, ${a}, ${r} )` : `texture( ${t}, ${n}, ${r} )`;
  }
  /**
   * Generates the GLSL snippet for sampling/loading the given texture using explicit gradients.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {Array<string>} gradSnippet - An array holding both gradient GLSL snippets.
   * @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The GLSL snippet.
   */
  generateTextureGrad(e, t, n, r, s, a) {
    return s && (n = `vec3( ${n}, ${s} )`), a ? `textureGradOffset( ${t}, ${n}, ${r[0]}, ${r[1]}, ${a} )` : `textureGrad( ${t}, ${n}, ${r[0]}, ${r[1]} )`;
  }
  /**
   * Generates the GLSL snippet for sampling a depth texture and comparing the sampled depth values
   * against a reference value.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A GLSL snippet that represents texture coordinates used for sampling.
   * @param {string} compareSnippet -  A GLSL snippet that represents the reference value.
   * @param {?string} depthSnippet - A GLSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A GLSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The GLSL snippet.
   */
  generateTextureCompare(e, t, n, r, s, a, o = this.shaderStage) {
    if (o === "fragment")
      return e.isCubeTexture ? `texture( ${t}, vec4( ${n}, ${r} ) )` : s ? a ? `textureOffset( ${t}, vec4( ${n}, ${s}, ${r} ), ${a} )` : `texture( ${t}, vec4( ${n}, ${s}, ${r} ) )` : a ? `textureOffset( ${t}, vec3( ${n}, ${r} ), ${a} )` : `texture( ${t}, vec3( ${n}, ${r} ) )`;
    le(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${o} shader.`);
  }
  /**
   * Returns the variables of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the variables.
   */
  getVars(e) {
    const t = [], n = this.vars[e];
    if (n !== void 0)
      for (const r of n)
        t.push(`${this.getVar(r.type, r.name, r.count)};`);
    return t.join(`
	`);
  }
  /**
   * Returns the uniforms of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the uniforms.
   */
  getUniforms(e) {
    const t = this.uniforms[e], n = [], r = {};
    for (const a of t) {
      let o = null, l = !1;
      if (a.type === "texture" || a.type === "texture3D") {
        const c = a.node.value;
        let u = "";
        (c.isDataTexture === !0 || c.isData3DTexture === !0) && (c.type === Dt ? u = "u" : c.type === wn && (u = "i")), a.type === "texture3D" && c.isArrayTexture === !1 ? o = `${u}sampler3D ${a.name};` : c.compareFunction ? c.isArrayTexture === !0 ? o = `sampler2DArrayShadow ${a.name};` : o = `sampler2DShadow ${a.name};` : c.isArrayTexture === !0 || c.isDataArrayTexture === !0 || c.isCompressedArrayTexture === !0 ? o = `${u}sampler2DArray ${a.name};` : o = `${u}sampler2D ${a.name};`;
      } else if (a.type === "cubeTexture")
        o = `samplerCube ${a.name};`;
      else if (a.type === "cubeDepthTexture")
        a.node.value.compareFunction ? o = `samplerCubeShadow ${a.name};` : o = `samplerCube ${a.name};`;
      else if (a.type === "buffer") {
        const c = a.node, u = this.getType(c.bufferType), h = c.bufferCount, d = h > 0 ? h : "";
        o = `${c.name} {
	${u} ${a.name}[${d}];
};
`;
      } else {
        const c = a.groupNode.name;
        if (r[c] === void 0) {
          const u = this.uniformGroups[c];
          if (u !== void 0) {
            const h = [];
            for (const d of u.uniforms) {
              const f = d.getType(), p = this.getVectorType(f), _ = d.nodeUniform.node.precision;
              let g = `${p} ${d.name};`;
              _ !== null && (g = iv[_] + " " + g), h.push("	" + g);
            }
            r[c] = h;
          }
        }
        l = !0;
      }
      if (!l) {
        const c = a.node.precision;
        c !== null && (o = iv[c] + " " + o), o = "uniform " + o, n.push(o);
      }
    }
    let s = "";
    for (const a in r) {
      const o = r[a];
      s += this._getGLSLUniformStruct(a, o.join(`
`)) + `
`;
    }
    return s += n.join(`
`), s;
  }
  /**
   * Returns the type for a given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   * @return {string} The type.
   */
  getTypeFromAttribute(e) {
    let t = super.getTypeFromAttribute(e);
    if (/^[iu]/.test(t) && e.gpuType !== wn) {
      let n = e;
      e.isInterleavedBufferAttribute && (n = e.data);
      const r = n.array;
      r instanceof Uint32Array || r instanceof Int32Array || (t = t.slice(1));
    }
    return t;
  }
  /**
   * Returns the shader attributes of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the shader attributes.
   */
  getAttributes(e) {
    let t = "";
    if (e === "vertex" || e === "compute") {
      const n = this.getAttributesArray();
      let r = 0;
      for (const s of n)
        t += `layout( location = ${r++} ) in ${s.type} ${s.name};
`;
    }
    return t;
  }
  /**
   * Returns the members of the given struct type node as a GLSL string.
   *
   * @param {StructTypeNode} struct - The struct type node.
   * @return {string} The GLSL snippet that defines the struct members.
   */
  getStructMembers(e) {
    const t = [];
    for (const n of e.members)
      t.push(`	${n.type} ${n.name};`);
    return t.join(`
`);
  }
  /**
   * Returns the structs of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the structs.
   */
  getStructs(e) {
    const t = [], n = this.structs[e], r = [];
    for (const s of n)
      if (s.output)
        for (const a of s.members)
          r.push(`layout( location = ${a.index} ) out ${a.type} ${a.name};`);
      else {
        let a = "struct " + s.name + ` {
`;
        a += this.getStructMembers(s), a += `
};
`, t.push(a);
      }
    return r.length === 0 && r.push("layout( location = 0 ) out vec4 fragColor;"), `
` + r.join(`
`) + `

` + t.join(`
`);
  }
  /**
   * Returns the varyings of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the varyings.
   */
  getVaryings(e) {
    let t = "";
    const n = this.varyings;
    if (e === "vertex" || e === "compute")
      for (const r of n) {
        e === "compute" && (r.needsInterpolation = !0);
        const s = this.getType(r.type);
        if (r.needsInterpolation)
          if (r.interpolationType) {
            const a = sv[r.interpolationType] || r.interpolationType, o = av[r.interpolationSampling] || "";
            t += `${a} ${o} out ${s} ${r.name};
`;
          } else {
            const a = s.includes("int") || s.includes("uv") || s.includes("iv") ? "flat " : "";
            t += `${a}out ${s} ${r.name};
`;
          }
        else
          t += `${s} ${r.name};
`;
      }
    else if (e === "fragment") {
      for (const r of n)
        if (r.needsInterpolation) {
          const s = this.getType(r.type);
          if (r.interpolationType) {
            const a = sv[r.interpolationType] || r.interpolationType, o = av[r.interpolationSampling] || "";
            t += `${a} ${o} in ${s} ${r.name};
`;
          } else {
            const a = s.includes("int") || s.includes("uv") || s.includes("iv") ? "flat " : "";
            t += `${a}in ${s} ${r.name};
`;
          }
        }
    }
    for (const r of this.builtins[e])
      t += `${r};
`;
    return t;
  }
  /**
   * Returns the vertex index builtin.
   *
   * @return {string} The vertex index.
   */
  getVertexIndex() {
    return "uint( gl_VertexID )";
  }
  /**
   * Contextually returns either the vertex stage instance index builtin
   * or the linearized index of an compute invocation within a grid of workgroups.
   *
   * @return {string} The instance index.
   */
  getInstanceIndex() {
    return "uint( gl_InstanceID )";
  }
  /**
   * Returns a builtin representing the index of an invocation within its workgroup.
   *
   * @return {string} The invocation local index.
   */
  getInvocationLocalIndex() {
    return `uint( gl_InstanceID ) % ${this.object.workgroupSize.reduce((n, r) => n * r, 1)}u`;
  }
  /**
   * Returns a builtin representing the size of a subgroup within the current shader.
   */
  getSubgroupSize() {
    le("GLSLNodeBuilder: WebGLBackend does not support the subgroupSize node");
  }
  /**
   * Returns a builtin representing the index of an invocation within its subgroup.
   */
  getInvocationSubgroupIndex() {
    le("GLSLNodeBuilder: WebGLBackend does not support the invocationSubgroupIndex node");
  }
  /**
   * Returns a builtin representing the index of the current invocation's subgroup within its workgroup.
   */
  getSubgroupIndex() {
    le("GLSLNodeBuilder: WebGLBackend does not support the subgroupIndex node");
  }
  /**
   * Returns the draw index builtin.
   *
   * @return {?string} The drawIndex shader string. Returns `null` if `WEBGL_multi_draw` isn't supported by the device.
   */
  getDrawIndex() {
    return this.renderer.backend.extensions.has("WEBGL_multi_draw") ? "uint( gl_DrawID )" : null;
  }
  /**
   * Returns the front facing builtin.
   *
   * @return {string} The front facing builtin.
   */
  getFrontFacing() {
    return "gl_FrontFacing";
  }
  /**
   * Returns the frag coord builtin.
   *
   * @return {string} The frag coord builtin.
   */
  getFragCoord() {
    return "gl_FragCoord.xy";
  }
  /**
   * Returns the frag depth builtin.
   *
   * @return {string} The frag depth builtin.
   */
  getFragDepth() {
    return "gl_FragDepth";
  }
  /**
   * Enables the given extension.
   *
   * @param {string} name - The extension name.
   * @param {string} behavior - The extension behavior.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage.
   */
  enableExtension(e, t, n = this.shaderStage) {
    const r = this.extensions[n] || (this.extensions[n] = /* @__PURE__ */ new Map());
    r.has(e) === !1 && r.set(e, {
      name: e,
      behavior: t
    });
  }
  /**
   * Returns the enabled extensions of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the enabled extensions.
   */
  getExtensions(e) {
    const t = [];
    if (e === "vertex") {
      const r = this.renderer.backend.extensions;
      this.object.isBatchedMesh && r.has("WEBGL_multi_draw") && this.enableExtension("GL_ANGLE_multi_draw", "require", e);
    }
    const n = this.extensions[e];
    if (n !== void 0)
      for (const { name: r, behavior: s } of n.values())
        t.push(`#extension ${r} : ${s}`);
    return t.join(`
`);
  }
  /**
   * Returns the clip distances builtin.
   *
   * @return {string} The clip distances builtin.
   */
  getClipDistance() {
    return "gl_ClipDistance";
  }
  /**
   * Whether the requested feature is available or not.
   *
   * @param {string} name - The requested feature.
   * @return {boolean} Whether the requested feature is supported or not.
   */
  isAvailable(e) {
    let t = rv[e];
    if (t === void 0) {
      let n;
      switch (t = !1, e) {
        case "float32Filterable":
          n = "OES_texture_float_linear";
          break;
        case "clipDistance":
          n = "WEBGL_clip_cull_distance";
          break;
      }
      if (n !== void 0) {
        const r = this.renderer.backend.extensions;
        r.has(n) && (r.get(n), t = !0);
      }
      rv[e] = t;
    }
    return t;
  }
  /**
   * Whether to flip texture data along its vertical axis or not.
   *
   * @return {boolean} Returns always `true` in context of GLSL.
   */
  isFlipY() {
    return !0;
  }
  /**
   * Returns the maximum number of bytes available for uniform buffers.
   *
   * @return {number} The maximum number of bytes available for uniform buffers.
   */
  getUniformBufferLimit() {
    const e = this.renderer.backend.gl;
    return e.getParameter(e.MAX_UNIFORM_BLOCK_SIZE);
  }
  /**
   * Enables hardware clipping.
   *
   * @param {string} planeCount - The clipping plane count.
   */
  enableHardwareClipping(e) {
    this.enableExtension("GL_ANGLE_clip_cull_distance", "require"), this.builtins.vertex.push(`out float gl_ClipDistance[ ${e} ]`);
  }
  /**
   * Enables multiview.
   */
  enableMultiview() {
    this.enableExtension("GL_OVR_multiview2", "require", "fragment"), this.enableExtension("GL_OVR_multiview2", "require", "vertex"), this.builtins.vertex.push("layout(num_views = 2) in");
  }
  /**
   * Registers a transform in context of Transform Feedback.
   *
   * @param {string} varyingName - The varying name.
   * @param {AttributeNode} attributeNode - The attribute node.
   */
  registerTransform(e, t) {
    this.transforms.push({ varyingName: e, attributeNode: t });
  }
  /**
   * Returns the transforms of the given shader stage as a GLSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The GLSL snippet that defines the transforms.
   */
  getTransforms() {
    const e = this.transforms;
    let t = "";
    for (let n = 0; n < e.length; n++) {
      const r = e[n], s = this.getPropertyName(r.attributeNode);
      s && (t += `${r.varyingName} = ${s};
	`);
    }
    return t;
  }
  /**
   * Returns a GLSL struct based on the given name and variables.
   *
   * @private
   * @param {string} name - The struct name.
   * @param {string} vars - The struct variables.
   * @return {string} The GLSL snippet representing a struct.
   */
  _getGLSLUniformStruct(e, t) {
    return `
layout( std140 ) uniform ${e} {
${t}
};`;
  }
  /**
   * Returns a GLSL vertex shader based on the given shader data.
   *
   * @private
   * @param {Object} shaderData - The shader data.
   * @return {string} The vertex shader.
   */
  _getGLSLVertexCode(e) {
    return `#version 300 es

${this.getSignature()}

// extensions
${e.extensions}

// precision
${ov}

// uniforms
${e.uniforms}

// varyings
${e.varyings}

// attributes
${e.attributes}

// codes
${e.codes}

void main() {

	// vars
	${e.vars}

	// transforms
	${e.transforms}

	// flow
	${e.flow}

	gl_PointSize = 1.0;

}
`;
  }
  /**
   * Returns a GLSL fragment shader based on the given shader data.
   *
   * @private
   * @param {Object} shaderData - The shader data.
   * @return {string} The vertex shader.
   */
  _getGLSLFragmentCode(e) {
    return `#version 300 es

${this.getSignature()}

// extensions
${e.extensions}

// precision
${ov}

// structs
${e.structs}

// uniforms
${e.uniforms}

// varyings
${e.varyings}

// codes
${e.codes}

void main() {

	// vars
	${e.vars}

	// flow
	${e.flow}

}
`;
  }
  /**
   * Controls the code build of the shader stages.
   */
  buildCode() {
    const e = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
    this.sortBindingGroups();
    for (const t in e) {
      let n = `// code

`;
      n += this.flowCode[t];
      const r = this.flowNodes[t], s = r[r.length - 1];
      for (const o of r) {
        const l = this.getFlowData(
          o
          /*, shaderStage*/
        ), c = o.name;
        c && (n.length > 0 && (n += `
`), n += `	// flow -> ${c}
	`), n += `${l.code}
	`, o === s && t !== "compute" && (n += `// result
	`, t === "vertex" ? (n += "gl_Position = ", n += `${l.result};`) : t === "fragment" && (o.outputNode.isOutputStructNode || (n += "fragColor = ", n += `${l.result};`)));
      }
      const a = e[t];
      a.extensions = this.getExtensions(t), a.uniforms = this.getUniforms(t), a.attributes = this.getAttributes(t), a.varyings = this.getVaryings(t), a.vars = this.getVars(t), a.structs = this.getStructs(t), a.codes = this.getCodes(t), a.transforms = this.getTransforms(t), a.flow = n;
    }
    this.material !== null ? (this.vertexShader = this._getGLSLVertexCode(e.vertex), this.fragmentShader = this._getGLSLFragmentCode(e.fragment)) : this.computeShader = this._getGLSLVertexCode(e.compute);
  }
  /**
   * This method is one of the more important ones since it's responsible
   * for generating a matching binding instance for the given uniform node.
   *
   * These bindings are later used in the renderer to create bind groups
   * and layouts.
   *
   * @param {UniformNode} node - The uniform node.
   * @param {string} type - The node data type.
   * @param {string} shaderStage - The shader stage.
   * @param {?string} [name=null] - An optional uniform name.
   * @return {NodeUniform} The node uniform object.
   */
  getUniformFromNode(e, t, n, r = null) {
    const s = super.getUniformFromNode(e, t, n, r), a = this.getDataFromNode(e, n, this.globalCache);
    let o = a.uniformGPU;
    if (o === void 0) {
      const l = e.groupNode, c = l.name, u = this.getBindGroupArray(c, n);
      if (t === "texture")
        o = new Nd(s.name, s.node, l), u.push(o);
      else if (t === "cubeTexture" || t === "cubeDepthTexture")
        o = new gT(s.name, s.node, l), u.push(o);
      else if (t === "texture3D")
        o = new rm(s.name, s.node, l), u.push(o);
      else if (t === "buffer") {
        s.name = `buffer${e.id}`;
        const h = this.getSharedDataFromNode(e);
        let d = h.buffer;
        d === void 0 && (e.name = `NodeBuffer_${e.id}`, d = new fT(e, l), d.name = e.name, h.buffer = d), u.push(d), o = d;
      } else {
        let h = this.uniformGroups[c];
        h === void 0 ? (h = new pT(c, l), this.uniformGroups[c] = h, u.push(h)) : u.indexOf(h) === -1 && u.push(h), o = this.getNodeUniform(s, t);
        const d = o.name;
        h.uniforms.some((p) => p.name === d) || h.addUniform(o);
      }
      a.uniformGPU = o;
    }
    return s;
  }
}
let up = null, bo = null;
class _T {
  /**
   * Constructs a new backend.
   *
   * @param {Object} parameters - An object holding parameters for the backend.
   */
  constructor(e = {}) {
    this.parameters = Object.assign({}, e), this.data = /* @__PURE__ */ new WeakMap(), this.renderer = null, this.domElement = null, this.timestampQueryPool = {
      [Sr.RENDER]: null,
      [Sr.COMPUTE]: null
    }, this.trackTimestamp = e.trackTimestamp === !0;
  }
  /**
   * Initializes the backend so it is ready for usage. Concrete backends
   * are supposed to implement their rendering context creation and related
   * operations in this method.
   *
   * @async
   * @param {Renderer} renderer - The renderer.
   * @return {Promise} A Promise that resolves when the backend has been initialized.
   */
  async init(e) {
    this.renderer = e;
  }
  /**
   * The coordinate system of the backend.
   *
   * @abstract
   * @type {number}
   * @readonly
   */
  get coordinateSystem() {
  }
  // render context
  /**
   * This method is executed at the beginning of a render call and
   * can be used by the backend to prepare the state for upcoming
   * draw calls.
   *
   * @abstract
   * @param {RenderContext} renderContext - The render context.
   */
  beginRender() {
  }
  /**
   * This method is executed at the end of a render call and
   * can be used by the backend to finalize work after draw
   * calls.
   *
   * @abstract
   * @param {RenderContext} renderContext - The render context.
   */
  finishRender() {
  }
  /**
   * This method is executed at the beginning of a compute call and
   * can be used by the backend to prepare the state for upcoming
   * compute tasks.
   *
   * @abstract
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  beginCompute() {
  }
  /**
   * This method is executed at the end of a compute call and
   * can be used by the backend to finalize work after compute
   * tasks.
   *
   * @abstract
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  finishCompute() {
  }
  // render object
  /**
   * Executes a draw command for the given render object.
   *
   * @abstract
   * @param {RenderObject} renderObject - The render object to draw.
   * @param {Info} info - Holds a series of statistical information about the GPU memory and the rendering process.
   */
  draw() {
  }
  // compute node
  /**
   * Executes a compute command for the given compute node.
   *
   * @abstract
   * @param {Node|Array<Node>} computeGroup - The group of compute nodes of a compute call. Can be a single compute node.
   * @param {Node} computeNode - The compute node.
   * @param {Array<BindGroup>} bindings - The bindings.
   * @param {ComputePipeline} computePipeline - The compute pipeline.
   */
  compute() {
  }
  // program
  /**
   * Creates a shader program from the given programmable stage.
   *
   * @abstract
   * @param {ProgrammableStage} program - The programmable stage.
   */
  createProgram() {
  }
  /**
   * Destroys the shader program of the given programmable stage.
   *
   * @abstract
   * @param {ProgrammableStage} program - The programmable stage.
   */
  destroyProgram() {
  }
  // bindings
  /**
   * Creates bindings from the given bind group definition.
   *
   * @abstract
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  createBindings() {
  }
  /**
   * Updates the given bind group definition.
   *
   * @abstract
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  updateBindings() {
  }
  /**
   * Updates a buffer binding.
   *
   * @abstract
   * @param {Buffer} binding - The buffer binding to update.
   */
  updateBinding() {
  }
  // pipeline
  /**
   * Creates a render pipeline for the given render object.
   *
   * @abstract
   * @param {RenderObject} renderObject - The render object.
   * @param {Array<Promise>} promises - An array of compilation promises which are used in `compileAsync()`.
   */
  createRenderPipeline() {
  }
  /**
   * Creates a compute pipeline for the given compute node.
   *
   * @abstract
   * @param {ComputePipeline} computePipeline - The compute pipeline.
   * @param {Array<BindGroup>} bindings - The bindings.
   */
  createComputePipeline() {
  }
  // cache key
  /**
   * Returns `true` if the render pipeline requires an update.
   *
   * @abstract
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the render pipeline requires an update or not.
   */
  needsRenderUpdate() {
  }
  /**
   * Returns a cache key that is used to identify render pipelines.
   *
   * @abstract
   * @param {RenderObject} renderObject - The render object.
   * @return {string} The cache key.
   */
  getRenderCacheKey() {
  }
  // node builder
  /**
   * Returns a node builder for the given render object.
   *
   * @abstract
   * @param {RenderObject} renderObject - The render object.
   * @param {Renderer} renderer - The renderer.
   * @return {NodeBuilder} The node builder.
   */
  createNodeBuilder() {
  }
  // textures
  /**
   * Updates a GPU sampler for the given texture.
   *
   * @abstract
   * @param {Texture} texture - The texture to update the sampler for.
   * @return {string} The current sampler key.
   */
  updateSampler() {
  }
  /**
   * Creates a default texture for the given texture that can be used
   * as a placeholder until the actual texture is ready for usage.
   *
   * @abstract
   * @param {Texture} texture - The texture to create a default texture for.
   */
  createDefaultTexture() {
  }
  /**
   * Defines a texture on the GPU for the given texture object.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  createTexture() {
  }
  /**
   * Uploads the updated texture data to the GPU.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  updateTexture() {
  }
  /**
   * Generates mipmaps for the given texture.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   */
  generateMipmaps() {
  }
  /**
   * Destroys the GPU data for the given texture object.
   *
   * @abstract
   * @param {Texture} texture - The texture.
   * @param {boolean} [isDefaultTexture=false] - Whether the texture uses a default GPU texture or not.
   */
  destroyTexture() {
  }
  /**
   * Returns texture data as a typed array.
   *
   * @abstract
   * @async
   * @param {Texture} texture - The texture to copy.
   * @param {number} x - The x coordinate of the copy origin.
   * @param {number} y - The y coordinate of the copy origin.
   * @param {number} width - The width of the copy.
   * @param {number} height - The height of the copy.
   * @param {number} faceIndex - The face index.
   * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
   */
  async copyTextureToBuffer() {
  }
  /**
   * Copies data of the given source texture to the given destination texture.
   *
   * @abstract
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy.
   * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
   * @param {number} [srcLevel=0] - The source mip level to copy from.
   * @param {number} [dstLevel=0] - The destination mip level to copy to.
   */
  copyTextureToTexture() {
  }
  /**
  * Copies the current bound framebuffer to the given texture.
  *
  * @abstract
  * @param {Texture} texture - The destination texture.
  * @param {RenderContext} renderContext - The render context.
  * @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy.
  */
  copyFramebufferToTexture() {
  }
  // attributes
  /**
   * Creates the GPU buffer of a shader attribute.
   *
   * @abstract
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createAttribute() {
  }
  /**
   * Creates the GPU buffer of an indexed shader attribute.
   *
   * @abstract
   * @param {BufferAttribute} attribute - The indexed buffer attribute.
   */
  createIndexAttribute() {
  }
  /**
   * Creates the GPU buffer of a storage attribute.
   *
   * @abstract
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createStorageAttribute() {
  }
  /**
   * Updates the GPU buffer of a shader attribute.
   *
   * @abstract
   * @param {BufferAttribute} attribute - The buffer attribute to update.
   */
  updateAttribute() {
  }
  /**
   * Destroys the GPU buffer of a shader attribute.
   *
   * @abstract
   * @param {BufferAttribute} attribute - The buffer attribute to destroy.
   */
  destroyAttribute() {
  }
  // canvas
  /**
   * Returns the backend's rendering context.
   *
   * @abstract
   * @return {Object} The rendering context.
   */
  getContext() {
  }
  /**
   * Backends can use this method if they have to run
   * logic when the renderer gets resized.
   *
   * @abstract
   */
  updateSize() {
  }
  /**
   * Updates the viewport with the values from the given render context.
   *
   * @abstract
   * @param {RenderContext} renderContext - The render context.
   */
  updateViewport() {
  }
  // utils
  /**
   * Updates a unique identifier for the given render context that can be used
   * to allocate resources like occlusion queries or timestamp queries.
   *
   * @param {RenderContext|ComputeNode} abstractRenderContext - The render context.
   */
  updateTimeStampUID(e) {
    const t = this.get(e), n = this.renderer.info.frame;
    let r;
    e.isComputeNode === !0 ? r = "c:" + this.renderer.info.compute.frameCalls : r = "r:" + this.renderer.info.render.frameCalls, t.timestampUID = r + ":" + e.id + ":f" + n;
  }
  /**
   * Returns a unique identifier for the given render context that can be used
   * to allocate resources like occlusion queries or timestamp queries.
   *
   * @param {RenderContext|ComputeNode} abstractRenderContext - The render context.
   * @return {string} The unique identifier.
   */
  getTimestampUID(e) {
    return this.get(e).timestampUID;
  }
  /**
   * Returns all timestamp frames for the given type.
   *
   * @param {string} type - The type of the time stamp.
   * @return {Array<number>} The timestamp frames.
   */
  getTimestampFrames(e) {
    const t = this.timestampQueryPool[e];
    return t ? t.getTimestampFrames() : [];
  }
  /**
   * Returns the query pool for the given uid.
   *
   * @param {string} uid - The unique identifier.
   * @return {TimestampQueryPool} The query pool.
   */
  _getQueryPool(e) {
    const t = e.startsWith("c:") ? Sr.COMPUTE : Sr.RENDER;
    return this.timestampQueryPool[t];
  }
  /**
   * Returns the timestamp for the given uid.
   *
   * @param {string} uid - The unique identifier.
   * @return {number} The timestamp.
   */
  getTimestamp(e) {
    return this._getQueryPool(e).getTimestamp(e);
  }
  /**
   * Returns `true` if a timestamp for the given uid is available.
   *
   * @param {string} uid - The unique identifier.
   * @return {boolean} Whether the timestamp is available or not.
   */
  hasTimestamp(e) {
    return this._getQueryPool(e).hasTimestamp(e);
  }
  /**
   * Returns `true` if the given 3D object is fully occluded by other
   * 3D objects in the scene. Backends must implement this method by using
   * a Occlusion Query API.
   *
   * @abstract
   * @param {RenderContext} renderContext - The render context.
   * @param {Object3D} object - The 3D object to test.
   * @return {boolean} Whether the 3D object is fully occluded or not.
   */
  isOccluded() {
  }
  /**
   * Resolves the time stamp for the given render context and type.
   *
   * @async
   * @abstract
   * @param {string} [type='render'] - The type of the time stamp.
   * @return {Promise<number>} A Promise that resolves with the time stamp.
   */
  async resolveTimestampsAsync(e = "render") {
    if (!this.trackTimestamp) {
      Pt("WebGPURenderer: Timestamp tracking is disabled.");
      return;
    }
    const t = this.timestampQueryPool[e];
    if (!t)
      return;
    const n = await t.resolveQueriesAsync();
    return this.renderer.info[e].timestamp = n, n;
  }
  /**
   * This method performs a readback operation by moving buffer data from
   * a storage buffer attribute from the GPU to the CPU.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync() {
  }
  /**
   * Checks if the given feature is supported by the backend.
   *
   * @async
   * @abstract
   * @param {string} name - The feature's name.
   * @return {Promise<boolean>} A Promise that resolves with a bool that indicates whether the feature is supported or not.
   */
  async hasFeatureAsync() {
  }
  /**
   * Checks if the given feature is supported  by the backend.
   *
   * @abstract
   * @param {string} name - The feature's name.
   * @return {boolean} Whether the feature is supported or not.
   */
  hasFeature() {
  }
  /**
   * Returns the maximum anisotropy texture filtering value.
   *
   * @abstract
   * @return {number} The maximum anisotropy texture filtering value.
   */
  getMaxAnisotropy() {
  }
  /**
   * Returns the drawing buffer size.
   *
   * @return {Vector2} The drawing buffer size.
   */
  getDrawingBufferSize() {
    return up = up || new de(), this.renderer.getDrawingBufferSize(up);
  }
  /**
   * Defines the scissor test.
   *
   * @abstract
   * @param {boolean} boolean - Whether the scissor test should be enabled or not.
   */
  setScissorTest() {
  }
  /**
   * Returns the clear color and alpha into a single
   * color object.
   *
   * @return {Color4} The clear color.
   */
  getClearColor() {
    const e = this.renderer;
    return bo = bo || new Og(), e.getClearColor(bo), bo.getRGB(bo), bo;
  }
  /**
   * Returns the DOM element. If no DOM element exists, the backend
   * creates a new one.
   *
   * @return {HTMLCanvasElement} The DOM element.
   */
  getDomElement() {
    let e = this.domElement;
    return e === null && (e = this.parameters.canvas !== void 0 ? this.parameters.canvas : Zv(), "setAttribute" in e && e.setAttribute("data-engine", `three.js r${za} webgpu`), this.domElement = e), e;
  }
  /**
   * Checks if the backend has the given compatibility.
   *
   * @abstract
   * @param {string} name - The compatibility.
   * @return {boolean} Whether the backend has the given compatibility or not.
   */
  hasCompatibility() {
    return !1;
  }
  /**
   * Initializes the render target defined in the given render context.
   *
   * @abstract
   * @param {RenderContext} renderContext - The render context.
   */
  initRenderTarget() {
  }
  /**
   * Sets a dictionary for the given object into the
   * internal data structure.
   *
   * @param {Object} object - The object.
   * @param {Object} value - The dictionary to set.
   */
  set(e, t) {
    this.data.set(e, t);
  }
  /**
   * Returns the dictionary for the given object.
   *
   * @param {Object} object - The object.
   * @return {Object} The object's dictionary.
   */
  get(e) {
    let t = this.data.get(e);
    return t === void 0 && (t = {}, this.data.set(e, t)), t;
  }
  /**
   * Checks if the given object has a dictionary
   * with data defined.
   *
   * @param {Object} object - The object.
   * @return {boolean} Whether a dictionary for the given object as been defined or not.
   */
  has(e) {
    return this.data.has(e);
  }
  /**
   * Deletes an object from the internal data structure.
   *
   * @param {Object} object - The object to delete.
   */
  delete(e) {
    this.data.delete(e);
  }
  /**
   * Delete GPU data associated with a bind group.
   *
   * @abstract
   * @param {BindGroup} bindGroup - The bind group.
   */
  deleteBindGroupData() {
  }
  /**
   * Frees internal resources.
   *
   * @abstract
   */
  dispose() {
  }
}
let qG = 0;
class XG {
  constructor(e, t) {
    this.buffers = [e.bufferGPU, t], this.type = e.type, this.bufferType = e.bufferType, this.pbo = e.pbo, this.byteLength = e.byteLength, this.bytesPerElement = e.BYTES_PER_ELEMENT, this.version = e.version, this.isInteger = e.isInteger, this.activeBufferIndex = 0, this.baseId = e.id;
  }
  get id() {
    return `${this.baseId}|${this.activeBufferIndex}`;
  }
  get bufferGPU() {
    return this.buffers[this.activeBufferIndex];
  }
  get transformBuffer() {
    return this.buffers[this.activeBufferIndex ^ 1];
  }
  switchBuffers() {
    this.activeBufferIndex ^= 1;
  }
}
class jG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e;
  }
  /**
   * Creates the GPU buffer for the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   * @param {GLenum } bufferType - A flag that indicates the buffer type and thus binding point target.
   */
  createAttribute(e, t) {
    const n = this.backend, { gl: r } = n, s = e.array, a = e.usage || r.STATIC_DRAW, o = e.isInterleavedBufferAttribute ? e.data : e, l = n.get(o);
    let c = l.bufferGPU;
    c === void 0 && (c = this._createBuffer(r, t, s, a), l.bufferGPU = c, l.bufferType = t, l.version = o.version);
    let u;
    if (s instanceof Float32Array)
      u = r.FLOAT;
    else if (typeof Float16Array < "u" && s instanceof Float16Array)
      u = r.HALF_FLOAT;
    else if (s instanceof Uint16Array)
      e.isFloat16BufferAttribute ? u = r.HALF_FLOAT : u = r.UNSIGNED_SHORT;
    else if (s instanceof Int16Array)
      u = r.SHORT;
    else if (s instanceof Uint32Array)
      u = r.UNSIGNED_INT;
    else if (s instanceof Int32Array)
      u = r.INT;
    else if (s instanceof Int8Array)
      u = r.BYTE;
    else if (s instanceof Uint8Array)
      u = r.UNSIGNED_BYTE;
    else if (s instanceof Uint8ClampedArray)
      u = r.UNSIGNED_BYTE;
    else
      throw new Error("THREE.WebGLBackend: Unsupported buffer data format: " + s);
    let h = {
      bufferGPU: c,
      bufferType: t,
      type: u,
      byteLength: s.byteLength,
      bytesPerElement: s.BYTES_PER_ELEMENT,
      version: e.version,
      pbo: e.pbo,
      isInteger: u === r.INT || u === r.UNSIGNED_INT || e.gpuType === wn,
      id: qG++
    };
    if (e.isStorageBufferAttribute || e.isStorageInstancedBufferAttribute) {
      const d = this._createBuffer(r, t, s, a);
      h = new XG(h, d);
    }
    n.set(e, h);
  }
  /**
   * Updates the GPU buffer of the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  updateAttribute(e) {
    const t = this.backend, { gl: n } = t, r = e.array, s = e.isInterleavedBufferAttribute ? e.data : e, a = t.get(s), o = a.bufferType, l = e.isInterleavedBufferAttribute ? e.data.updateRanges : e.updateRanges;
    if (n.bindBuffer(o, a.bufferGPU), l.length === 0)
      n.bufferSubData(o, 0, r);
    else {
      for (let c = 0, u = l.length; c < u; c++) {
        const h = l[c];
        n.bufferSubData(
          o,
          h.start * r.BYTES_PER_ELEMENT,
          r,
          h.start,
          h.count
        );
      }
      s.clearUpdateRanges();
    }
    n.bindBuffer(o, null), a.version = s.version;
  }
  /**
   * Destroys the GPU buffer of the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  destroyAttribute(e) {
    const t = this.backend, { gl: n } = t;
    e.isInterleavedBufferAttribute && t.delete(e.data);
    const r = t.get(e);
    n.deleteBuffer(r.bufferGPU), t.delete(e);
  }
  /**
   * This method performs a readback operation by moving buffer data from
   * a storage buffer attribute from the GPU to the CPU.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync(e) {
    const t = this.backend, { gl: n } = t, r = e.isInterleavedBufferAttribute ? e.data : e, { bufferGPU: s } = t.get(r), a = e.array, o = a.byteLength;
    n.bindBuffer(n.COPY_READ_BUFFER, s);
    const l = n.createBuffer();
    n.bindBuffer(n.COPY_WRITE_BUFFER, l), n.bufferData(n.COPY_WRITE_BUFFER, o, n.STREAM_READ), n.copyBufferSubData(n.COPY_READ_BUFFER, n.COPY_WRITE_BUFFER, 0, 0, o), await t.utils._clientWaitAsync();
    const c = new e.array.constructor(a.length);
    return n.bindBuffer(n.COPY_WRITE_BUFFER, l), n.getBufferSubData(n.COPY_WRITE_BUFFER, 0, c), n.deleteBuffer(l), n.bindBuffer(n.COPY_READ_BUFFER, null), n.bindBuffer(n.COPY_WRITE_BUFFER, null), c.buffer;
  }
  /**
   * Creates a WebGL buffer with the given data.
   *
   * @private
   * @param {WebGL2RenderingContext} gl - The rendering context.
   * @param {GLenum } bufferType - A flag that indicates the buffer type and thus binding point target.
   * @param {TypedArray} array - The array of the buffer attribute.
   * @param {GLenum} usage - The usage.
   * @return {WebGLBuffer} The WebGL buffer.
   */
  _createBuffer(e, t, n, r) {
    const s = e.createBuffer();
    return e.bindBuffer(t, s), e.bufferData(t, n, r), e.bindBuffer(t, null), s;
  }
}
let ic, qr;
class YG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e, this.gl = this.backend.gl, this.enabled = {}, this.currentFlipSided = null, this.currentCullFace = null, this.currentProgram = null, this.currentBlendingEnabled = !1, this.currentBlending = null, this.currentBlendSrc = null, this.currentBlendDst = null, this.currentBlendSrcAlpha = null, this.currentBlendDstAlpha = null, this.currentPremultipledAlpha = null, this.currentPolygonOffsetFactor = null, this.currentPolygonOffsetUnits = null, this.currentColorMask = null, this.currentDepthReversed = !1, this.currentDepthFunc = null, this.currentDepthMask = null, this.currentStencilFunc = null, this.currentStencilRef = null, this.currentStencilFuncMask = null, this.currentStencilFail = null, this.currentStencilZFail = null, this.currentStencilZPass = null, this.currentStencilMask = null, this.currentLineWidth = null, this.currentClippingPlanes = 0, this.currentVAO = null, this.currentIndex = null, this.currentBoundFramebuffers = {}, this.currentDrawbuffers = /* @__PURE__ */ new WeakMap(), this.maxTextures = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS), this.currentTextureSlot = null, this.currentBoundTextures = {}, this.currentBoundBufferBases = {}, this._init();
  }
  /**
   * Inits the state of the utility.
   *
   * @private
   */
  _init() {
    const e = this.gl;
    ic = {
      [Xn]: e.FUNC_ADD,
      [vm]: e.FUNC_SUBTRACT,
      [ym]: e.FUNC_REVERSE_SUBTRACT
    }, qr = {
      [jr]: e.ZERO,
      [bm]: e.ONE,
      [Sm]: e.SRC_COLOR,
      [Rc]: e.SRC_ALPHA,
      [Rm]: e.SRC_ALPHA_SATURATE,
      [wm]: e.DST_COLOR,
      [Mm]: e.DST_ALPHA,
      [Tm]: e.ONE_MINUS_SRC_COLOR,
      [Cc]: e.ONE_MINUS_SRC_ALPHA,
      [Am]: e.ONE_MINUS_DST_COLOR,
      [Em]: e.ONE_MINUS_DST_ALPHA
    };
    const t = e.getParameter(e.SCISSOR_BOX), n = e.getParameter(e.VIEWPORT);
    this.currentScissor = new rt().fromArray(t), this.currentViewport = new rt().fromArray(n), this._tempVec4 = new rt();
  }
  /**
   * Enables the given WebGL capability.
   *
   * This method caches the capability state so
   * `gl.enable()` is only called when necessary.
   *
   * @param {GLenum} id - The capability to enable.
   */
  enable(e) {
    const { enabled: t } = this;
    t[e] !== !0 && (this.gl.enable(e), t[e] = !0);
  }
  /**
   * Disables the given WebGL capability.
   *
   * This method caches the capability state so
   * `gl.disable()` is only called when necessary.
   *
   * @param {GLenum} id - The capability to enable.
   */
  disable(e) {
    const { enabled: t } = this;
    t[e] !== !1 && (this.gl.disable(e), t[e] = !1);
  }
  /**
   * Specifies whether polygons are front- or back-facing
   * by setting the winding orientation.
   *
   * This method caches the state so `gl.frontFace()` is only
   * called when necessary.
   *
   * @param {boolean} flipSided - Whether triangles flipped their sides or not.
   */
  setFlipSided(e) {
    if (this.currentFlipSided !== e) {
      const { gl: t } = this;
      e ? t.frontFace(t.CW) : t.frontFace(t.CCW), this.currentFlipSided = e;
    }
  }
  /**
   * Specifies whether or not front- and/or back-facing
   * polygons can be culled.
   *
   * This method caches the state so `gl.cullFace()` is only
   * called when necessary.
   *
   * @param {number} cullFace - Defines which polygons are candidates for culling.
   */
  setCullFace(e) {
    const { gl: t } = this;
    e !== Gv ? (this.enable(t.CULL_FACE), e !== this.currentCullFace && (e === Mp ? t.cullFace(t.BACK) : e === Vv ? t.cullFace(t.FRONT) : t.cullFace(t.FRONT_AND_BACK))) : this.disable(t.CULL_FACE), this.currentCullFace = e;
  }
  /**
   * Specifies the width of line primitives.
   *
   * This method caches the state so `gl.lineWidth()` is only
   * called when necessary.
   *
   * @param {number} width - The line width.
   */
  setLineWidth(e) {
    const { currentLineWidth: t, gl: n } = this;
    e !== t && (n.lineWidth(e), this.currentLineWidth = e);
  }
  setMRTBlending(e, t, n) {
    const r = this.gl, s = this.backend.drawBuffersIndexedExt;
    if (!s) {
      Pt("WebGPURenderer: Multiple Render Targets (MRT) blending configuration is not fully supported in compatibility mode. The material blending will be used for all render targets.");
      return;
    }
    for (let a = 0; a < e.length; a++) {
      const o = e[a];
      let l = null;
      if (t !== null) {
        const c = t.getBlendMode(o.name);
        c.blending === Hv ? l = n : c.blending !== Nn && (l = c);
      } else
        l = n;
      l !== null ? this._setMRTBlendingIndex(a, l) : s.blendFuncSeparateiOES(a, r.ONE, r.ZERO, r.ONE, r.ZERO);
    }
  }
  /**
   * Applies blending configuration for a specific draw buffer index.
   *
   * @private
   * @param {number} index - The draw buffer index.
   * @param {Object} blending - The blending configuration (material or BlendMode).
   */
  _setMRTBlendingIndex(e, t) {
    const { gl: n } = this, r = this.backend.drawBuffersIndexedExt, s = t.blending, a = t.blendSrc, o = t.blendDst, l = t.blendEquation, c = t.premultipliedAlpha;
    if (s === ya) {
      const u = t.blendSrcAlpha !== null ? t.blendSrcAlpha : a, h = t.blendDstAlpha !== null ? t.blendDstAlpha : o, d = t.blendEquationAlpha !== null ? t.blendEquationAlpha : l;
      r.blendEquationSeparateiOES(e, ic[l], ic[d]), r.blendFuncSeparateiOES(e, qr[a], qr[o], qr[u], qr[h]);
    } else if (r.blendEquationSeparateiOES(e, n.FUNC_ADD, n.FUNC_ADD), c)
      switch (s) {
        case ei:
          r.blendFuncSeparateiOES(e, n.ONE, n.ONE_MINUS_SRC_ALPHA, n.ONE, n.ONE_MINUS_SRC_ALPHA);
          break;
        case Ns:
          r.blendFuncSeparateiOES(e, n.ONE, n.ONE, n.ONE, n.ONE);
          break;
        case Ps:
          r.blendFuncSeparateiOES(e, n.ZERO, n.ONE_MINUS_SRC_COLOR, n.ZERO, n.ONE);
          break;
        case Ds:
          r.blendFuncSeparateiOES(e, n.DST_COLOR, n.ONE_MINUS_SRC_ALPHA, n.ZERO, n.ONE);
          break;
        default:
          r.blendFuncSeparateiOES(e, n.ONE, n.ONE_MINUS_SRC_ALPHA, n.ONE, n.ONE_MINUS_SRC_ALPHA);
          break;
      }
    else
      switch (s) {
        case ei:
          r.blendFuncSeparateiOES(e, n.SRC_ALPHA, n.ONE_MINUS_SRC_ALPHA, n.ONE, n.ONE_MINUS_SRC_ALPHA);
          break;
        case Ns:
          r.blendFuncSeparateiOES(e, n.SRC_ALPHA, n.ONE, n.ONE, n.ONE);
          break;
        case Ps:
          r.blendFuncSeparateiOES(e, n.ZERO, n.ONE_MINUS_SRC_COLOR, n.ZERO, n.ONE);
          break;
        case Ds:
          r.blendFuncSeparateiOES(e, n.DST_COLOR, n.ONE_MINUS_SRC_ALPHA, n.ZERO, n.ONE);
          break;
        default:
          r.blendFuncSeparateiOES(e, n.SRC_ALPHA, n.ONE_MINUS_SRC_ALPHA, n.ONE, n.ONE_MINUS_SRC_ALPHA);
          break;
      }
  }
  /**
   * Defines the blending.
   *
   * This method caches the state so `gl.blendEquation()`, `gl.blendEquationSeparate()`,
   * `gl.blendFunc()` and  `gl.blendFuncSeparate()` are only called when necessary.
   *
   * @param {number} blending - The blending type.
   * @param {number} blendEquation - The blending equation.
   * @param {number} blendSrc - Only relevant for custom blending. The RGB source blending factor.
   * @param {number} blendDst - Only relevant for custom blending. The RGB destination blending factor.
   * @param {number} blendEquationAlpha - Only relevant for custom blending. The blending equation for alpha.
   * @param {number} blendSrcAlpha - Only relevant for custom blending. The alpha source blending factor.
   * @param {number} blendDstAlpha - Only relevant for custom blending. The alpha destination blending factor.
   * @param {boolean} premultipliedAlpha - Whether premultiplied alpha is enabled or not.
   */
  setBlending(e, t, n, r, s, a, o, l) {
    const { gl: c } = this;
    if (e === Nn) {
      this.currentBlendingEnabled === !0 && (this.disable(c.BLEND), this.currentBlendingEnabled = !1);
      return;
    }
    if (this.currentBlendingEnabled === !1 && (this.enable(c.BLEND), this.currentBlendingEnabled = !0), e !== ya) {
      if (e !== this.currentBlending || l !== this.currentPremultipledAlpha) {
        if ((this.currentBlendEquation !== Xn || this.currentBlendEquationAlpha !== Xn) && (c.blendEquation(c.FUNC_ADD), this.currentBlendEquation = Xn, this.currentBlendEquationAlpha = Xn), l)
          switch (e) {
            case ei:
              c.blendFuncSeparate(c.ONE, c.ONE_MINUS_SRC_ALPHA, c.ONE, c.ONE_MINUS_SRC_ALPHA);
              break;
            case Ns:
              c.blendFunc(c.ONE, c.ONE);
              break;
            case Ps:
              c.blendFuncSeparate(c.ZERO, c.ONE_MINUS_SRC_COLOR, c.ZERO, c.ONE);
              break;
            case Ds:
              c.blendFuncSeparate(c.DST_COLOR, c.ONE_MINUS_SRC_ALPHA, c.ZERO, c.ONE);
              break;
            default:
              le("WebGLState: Invalid blending: ", e);
              break;
          }
        else
          switch (e) {
            case ei:
              c.blendFuncSeparate(c.SRC_ALPHA, c.ONE_MINUS_SRC_ALPHA, c.ONE, c.ONE_MINUS_SRC_ALPHA);
              break;
            case Ns:
              c.blendFuncSeparate(c.SRC_ALPHA, c.ONE, c.ONE, c.ONE);
              break;
            case Ps:
              le("WebGLState: SubtractiveBlending requires material.premultipliedAlpha = true");
              break;
            case Ds:
              le("WebGLState: MultiplyBlending requires material.premultipliedAlpha = true");
              break;
            default:
              le("WebGLState: Invalid blending: ", e);
              break;
          }
        this.currentBlendSrc = null, this.currentBlendDst = null, this.currentBlendSrcAlpha = null, this.currentBlendDstAlpha = null, this.currentBlending = e, this.currentPremultipledAlpha = l;
      }
      return;
    }
    s = s || t, a = a || n, o = o || r, (t !== this.currentBlendEquation || s !== this.currentBlendEquationAlpha) && (c.blendEquationSeparate(ic[t], ic[s]), this.currentBlendEquation = t, this.currentBlendEquationAlpha = s), (n !== this.currentBlendSrc || r !== this.currentBlendDst || a !== this.currentBlendSrcAlpha || o !== this.currentBlendDstAlpha) && (c.blendFuncSeparate(qr[n], qr[r], qr[a], qr[o]), this.currentBlendSrc = n, this.currentBlendDst = r, this.currentBlendSrcAlpha = a, this.currentBlendDstAlpha = o), this.currentBlending = e, this.currentPremultipledAlpha = !1;
  }
  /**
   * Specifies whether colors can be written when rendering
   * into a framebuffer or not.
   *
   * This method caches the state so `gl.colorMask()` is only
   * called when necessary.
   *
   * @param {boolean} colorMask - The color mask.
   */
  setColorMask(e) {
    this.currentColorMask !== e && (this.gl.colorMask(e, e, e, e), this.currentColorMask = e);
  }
  /**
   * Specifies whether the depth test is enabled or not.
   *
   * @param {boolean} depthTest - Whether the depth test is enabled or not.
   */
  setDepthTest(e) {
    const { gl: t } = this;
    e ? this.enable(t.DEPTH_TEST) : this.disable(t.DEPTH_TEST);
  }
  /**
   * Configures the WebGL state to use a reversed depth buffer.
   *
   * @param {boolean} reversed - Whether the depth buffer is reversed or not.
   */
  setReversedDepth(e) {
    if (this.currentDepthReversed !== e) {
      const t = this.backend.extensions.get("EXT_clip_control");
      e ? t.clipControlEXT(t.LOWER_LEFT_EXT, t.ZERO_TO_ONE_EXT) : t.clipControlEXT(t.LOWER_LEFT_EXT, t.NEGATIVE_ONE_TO_ONE_EXT), this.currentDepthReversed = e;
    }
  }
  /**
   * Specifies whether depth values can be written when rendering
   * into a framebuffer or not.
   *
   * This method caches the state so `gl.depthMask()` is only
   * called when necessary.
   *
   * @param {boolean} depthMask - The depth mask.
   */
  setDepthMask(e) {
    this.currentDepthMask !== e && (this.gl.depthMask(e), this.currentDepthMask = e);
  }
  /**
   * Specifies the depth compare function.
   *
   * This method caches the state so `gl.depthFunc()` is only
   * called when necessary.
   *
   * @param {number} depthFunc - The depth compare function.
   */
  setDepthFunc(e) {
    if (this.currentDepthReversed && (e = zm[e]), this.currentDepthFunc !== e) {
      const { gl: t } = this;
      switch (e) {
        case Nc:
          t.depthFunc(t.NEVER);
          break;
        case Pc:
          t.depthFunc(t.ALWAYS);
          break;
        case Dc:
          t.depthFunc(t.LESS);
          break;
        case Hs:
          t.depthFunc(t.LEQUAL);
          break;
        case Lc:
          t.depthFunc(t.EQUAL);
          break;
        case Fc:
          t.depthFunc(t.GEQUAL);
          break;
        case Ic:
          t.depthFunc(t.GREATER);
          break;
        case Uc:
          t.depthFunc(t.NOTEQUAL);
          break;
        default:
          t.depthFunc(t.LEQUAL);
      }
      this.currentDepthFunc = e;
    }
  }
  /**
   * Specifies the scissor box.
   *
   * @param {number} x - The x-coordinate of the lower left corner of the viewport.
   * @param {number} y - The y-coordinate of the lower left corner of the viewport.
   * @param {number} width - The width of the viewport.
   * @param {number} height - The height of the viewport.
   *
   */
  scissor(e, t, n, r) {
    const s = this._tempVec4.set(e, t, n, r);
    if (this.currentScissor.equals(s) === !1) {
      const { gl: a } = this;
      a.scissor(s.x, s.y, s.z, s.w), this.currentScissor.copy(s);
    }
  }
  /**
   * Specifies the viewport.
   *
   * @param {number} x - The x-coordinate of the lower left corner of the viewport.
   * @param {number} y - The y-coordinate of the lower left corner of the viewport.
   * @param {number} width - The width of the viewport.
   * @param {number} height - The height of the viewport.
   *
   */
  viewport(e, t, n, r) {
    const s = this._tempVec4.set(e, t, n, r);
    if (this.currentViewport.equals(s) === !1) {
      const { gl: a } = this;
      a.viewport(s.x, s.y, s.z, s.w), this.currentViewport.copy(s);
    }
  }
  /**
   * Defines the scissor test.
   *
   * @param {boolean} boolean - Whether the scissor test should be enabled or not.
   */
  setScissorTest(e) {
    const t = this.gl;
    e ? this.enable(t.SCISSOR_TEST) : this.disable(t.SCISSOR_TEST);
  }
  /**
   * Specifies whether the stencil test is enabled or not.
   *
   * @param {boolean} stencilTest - Whether the stencil test is enabled or not.
   */
  setStencilTest(e) {
    const { gl: t } = this;
    e ? this.enable(t.STENCIL_TEST) : this.disable(t.STENCIL_TEST);
  }
  /**
   * Specifies whether stencil values can be written when rendering
   * into a framebuffer or not.
   *
   * This method caches the state so `gl.stencilMask()` is only
   * called when necessary.
   *
   * @param {boolean} stencilMask - The stencil mask.
   */
  setStencilMask(e) {
    this.currentStencilMask !== e && (this.gl.stencilMask(e), this.currentStencilMask = e);
  }
  /**
   * Specifies whether the stencil test functions.
   *
   * This method caches the state so `gl.stencilFunc()` is only
   * called when necessary.
   *
   * @param {number} stencilFunc - The stencil compare function.
   * @param {number} stencilRef - The reference value for the stencil test.
   * @param {number} stencilMask - A bit-wise mask that is used to AND the reference value and the stored stencil value when the test is done.
   */
  setStencilFunc(e, t, n) {
    (this.currentStencilFunc !== e || this.currentStencilRef !== t || this.currentStencilFuncMask !== n) && (this.gl.stencilFunc(e, t, n), this.currentStencilFunc = e, this.currentStencilRef = t, this.currentStencilFuncMask = n);
  }
  /**
   * Specifies whether the stencil test operation.
   *
   * This method caches the state so `gl.stencilOp()` is only
   * called when necessary.
   *
   * @param {number} stencilFail - The function to use when the stencil test fails.
   * @param {number} stencilZFail - The function to use when the stencil test passes, but the depth test fail.
   * @param {number} stencilZPass - The function to use when both the stencil test and the depth test pass,
   * or when the stencil test passes and there is no depth buffer or depth testing is disabled.
   */
  setStencilOp(e, t, n) {
    (this.currentStencilFail !== e || this.currentStencilZFail !== t || this.currentStencilZPass !== n) && (this.gl.stencilOp(e, t, n), this.currentStencilFail = e, this.currentStencilZFail = t, this.currentStencilZPass = n);
  }
  /**
   * Configures the WebGL state for the given material.
   *
   * @param {Material} material - The material to configure the state for.
   * @param {number} frontFaceCW - Whether the front faces are counter-clockwise or not.
   * @param {number} hardwareClippingPlanes - The number of hardware clipping planes.
   */
  setMaterial(e, t, n) {
    const { gl: r } = this;
    e.side === Rn ? this.disable(r.CULL_FACE) : this.enable(r.CULL_FACE);
    let s = e.side === Ft;
    t && (s = !s), this.setFlipSided(s), e.blending === ei && e.transparent === !1 ? this.setBlending(Nn) : this.setBlending(e.blending, e.blendEquation, e.blendSrc, e.blendDst, e.blendEquationAlpha, e.blendSrcAlpha, e.blendDstAlpha, e.premultipliedAlpha), this.setDepthFunc(e.depthFunc), this.setDepthTest(e.depthTest), this.setDepthMask(e.depthWrite), this.setColorMask(e.colorWrite);
    const a = e.stencilWrite;
    if (this.setStencilTest(a), a && (this.setStencilMask(e.stencilWriteMask), this.setStencilFunc(e.stencilFunc, e.stencilRef, e.stencilFuncMask), this.setStencilOp(e.stencilFail, e.stencilZFail, e.stencilZPass)), this.setPolygonOffset(e.polygonOffset, e.polygonOffsetFactor, e.polygonOffsetUnits), e.alphaToCoverage === !0 && this.backend.renderer.currentSamples > 0 ? this.enable(r.SAMPLE_ALPHA_TO_COVERAGE) : this.disable(r.SAMPLE_ALPHA_TO_COVERAGE), n > 0 && this.currentClippingPlanes !== n)
      for (let l = 0; l < 8; l++)
        l < n ? this.enable(12288 + l) : this.disable(12288 + l);
  }
  /**
   * Specifies the polygon offset.
   *
   * This method caches the state so `gl.polygonOffset()` is only
   * called when necessary.
   *
   * @param {boolean} polygonOffset - Whether polygon offset is enabled or not.
   * @param {number} factor - The scale factor for the variable depth offset for each polygon.
   * @param {number} units - The multiplier by which an implementation-specific value is multiplied with to create a constant depth offset.
   */
  setPolygonOffset(e, t, n) {
    const { gl: r } = this;
    e ? (this.enable(r.POLYGON_OFFSET_FILL), (this.currentPolygonOffsetFactor !== t || this.currentPolygonOffsetUnits !== n) && (r.polygonOffset(t, n), this.currentPolygonOffsetFactor = t, this.currentPolygonOffsetUnits = n)) : this.disable(r.POLYGON_OFFSET_FILL);
  }
  /**
   * Defines the usage of the given WebGL program.
   *
   * This method caches the state so `gl.useProgram()` is only
   * called when necessary.
   *
   * @param {WebGLProgram} program - The WebGL program to use.
   * @return {boolean} Whether a program change has been executed or not.
   */
  useProgram(e) {
    return this.currentProgram !== e ? (this.gl.useProgram(e), this.currentProgram = e, !0) : !1;
  }
  /**
   * Sets the vertex state by binding the given VAO and element buffer.
   *
   * @param {WebGLVertexArrayObject} vao - The VAO.
   * @param {?WebGLBuffer} indexBuffer - The index buffer.
   * @return {boolean} Whether a vertex state has been changed or not.
   */
  setVertexState(e, t = null) {
    const n = this.gl;
    return this.currentVAO !== e || this.currentIndex !== t ? (n.bindVertexArray(e), t !== null && n.bindBuffer(n.ELEMENT_ARRAY_BUFFER, t), this.currentVAO = e, this.currentIndex = t, !0) : !1;
  }
  /**
   * Resets the vertex array state by resetting the VAO and element buffer.
   */
  resetVertexState() {
    const e = this.gl;
    e.bindVertexArray(null), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, null), this.currentVAO = null, this.currentIndex = null;
  }
  // framebuffer
  /**
   * Binds the given framebuffer.
   *
   * This method caches the state so `gl.bindFramebuffer()` is only
   * called when necessary.
   *
   * @param {number} target - The binding point (target).
   * @param {WebGLFramebuffer} framebuffer - The WebGL framebuffer to bind.
   * @return {boolean} Whether a bind has been executed or not.
   */
  bindFramebuffer(e, t) {
    const { gl: n, currentBoundFramebuffers: r } = this;
    return r[e] !== t ? (n.bindFramebuffer(e, t), r[e] = t, e === n.DRAW_FRAMEBUFFER && (r[n.FRAMEBUFFER] = t), e === n.FRAMEBUFFER && (r[n.DRAW_FRAMEBUFFER] = t), !0) : !1;
  }
  /**
   * Defines draw buffers to which fragment colors are written into.
   * Configures the MRT setup of custom framebuffers.
   *
   * This method caches the state so `gl.drawBuffers()` is only
   * called when necessary.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {WebGLFramebuffer} framebuffer - The WebGL framebuffer.
   */
  drawBuffers(e, t) {
    const { gl: n } = this;
    let r = [], s = !1;
    if (e.textures !== null) {
      r = this.currentDrawbuffers.get(t), r === void 0 && (r = [], this.currentDrawbuffers.set(t, r));
      const a = e.textures;
      if (r.length !== a.length || r[0] !== n.COLOR_ATTACHMENT0) {
        for (let o = 0, l = a.length; o < l; o++)
          r[o] = n.COLOR_ATTACHMENT0 + o;
        r.length = a.length, s = !0;
      }
    } else
      r[0] !== n.BACK && (r[0] = n.BACK, s = !0);
    s && n.drawBuffers(r);
  }
  // texture
  /**
   * Makes the given texture unit active.
   *
   * This method caches the state so `gl.activeTexture()` is only
   * called when necessary.
   *
   * @param {number} webglSlot - The texture unit to make active.
   */
  activeTexture(e) {
    const { gl: t, currentTextureSlot: n, maxTextures: r } = this;
    e === void 0 && (e = t.TEXTURE0 + r - 1), n !== e && (t.activeTexture(e), this.currentTextureSlot = e);
  }
  /**
   * Binds the given WebGL texture to a target.
   *
   * This method caches the state so `gl.bindTexture()` is only
   * called when necessary.
   *
   * @param {number} webglType - The binding point (target).
   * @param {WebGLTexture} webglTexture - The WebGL texture to bind.
   * @param {number} webglSlot - The texture.
   */
  bindTexture(e, t, n) {
    const { gl: r, currentTextureSlot: s, currentBoundTextures: a, maxTextures: o } = this;
    n === void 0 && (s === null ? n = r.TEXTURE0 + o - 1 : n = s);
    let l = a[n];
    l === void 0 && (l = { type: void 0, texture: void 0 }, a[n] = l), (l.type !== e || l.texture !== t) && (s !== n && (r.activeTexture(n), this.currentTextureSlot = n), r.bindTexture(e, t), l.type = e, l.texture = t);
  }
  /**
   * Binds a given WebGL buffer to a given binding point (target) at a given index.
   *
   * This method caches the state so `gl.bindBufferBase()` is only
   * called when necessary.
   *
   * @param {number} target - The target for the bind operation.
   * @param {number} index - The index of the target.
   * @param {WebGLBuffer} buffer - The WebGL buffer.
   * @return {boolean} Whether a bind has been executed or not.
   */
  bindBufferBase(e, t, n) {
    const { gl: r } = this, s = `${e}-${t}`;
    return this.currentBoundBufferBases[s] !== n ? (r.bindBufferBase(e, t, n), this.currentBoundBufferBases[s] = n, !0) : !1;
  }
  /**
   * Unbinds the current bound texture.
   *
   * This method caches the state so `gl.bindTexture()` is only
   * called when necessary.
   */
  unbindTexture() {
    const { gl: e, currentTextureSlot: t, currentBoundTextures: n } = this, r = n[t];
    r !== void 0 && r.type !== void 0 && (e.bindTexture(r.type, null), r.type = void 0, r.texture = void 0);
  }
}
class KG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e, this.gl = this.backend.gl, this.extensions = e.extensions;
  }
  /**
   * Converts the given three.js constant into a WebGL constant.
   * The method currently supports the conversion of texture formats
   * and types.
   *
   * @param {number} p - The three.js constant.
   * @param {string} [colorSpace=NoColorSpace] - The color space.
   * @return {?number} The corresponding WebGL constant.
   */
  convert(e, t = hi) {
    const { gl: n, extensions: r } = this;
    let s;
    const a = Ke.getTransfer(t);
    if (e === Zt)
      return n.UNSIGNED_BYTE;
    if (e === rd)
      return n.UNSIGNED_SHORT_4_4_4_4;
    if (e === sd)
      return n.UNSIGNED_SHORT_5_5_5_1;
    if (e === ad)
      return n.UNSIGNED_INT_5_9_9_9_REV;
    if (e === od)
      return n.UNSIGNED_INT_10F_11F_11F_REV;
    if (e === ba)
      return n.BYTE;
    if (e === Sa)
      return n.SHORT;
    if (e === Ji)
      return n.UNSIGNED_SHORT;
    if (e === wn)
      return n.INT;
    if (e === Dt)
      return n.UNSIGNED_INT;
    if (e === ln)
      return n.FLOAT;
    if (e === nn)
      return n.HALF_FLOAT;
    if (e === Bm)
      return n.ALPHA;
    if (e === Jc)
      return n.RGB;
    if (e === cn)
      return n.RGBA;
    if (e === Un)
      return n.DEPTH_COMPONENT;
    if (e === ii)
      return n.DEPTH_STENCIL;
    if (e === eu)
      return n.RED;
    if (e === _l)
      return n.RED_INTEGER;
    if (e === ri)
      return n.RG;
    if (e === xl)
      return n.RG_INTEGER;
    if (e === vl)
      return n.RGBA_INTEGER;
    if (e === Us || e === Bs || e === Os || e === ks)
      if (a === Te)
        if (s = r.get("WEBGL_compressed_texture_s3tc_srgb"), s !== null) {
          if (e === Us)
            return s.COMPRESSED_SRGB_S3TC_DXT1_EXT;
          if (e === Bs)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
          if (e === Os)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
          if (e === ks)
            return s.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
        } else
          return null;
      else if (s = r.get("WEBGL_compressed_texture_s3tc"), s !== null) {
        if (e === Us)
          return s.COMPRESSED_RGB_S3TC_DXT1_EXT;
        if (e === Bs)
          return s.COMPRESSED_RGBA_S3TC_DXT1_EXT;
        if (e === Os)
          return s.COMPRESSED_RGBA_S3TC_DXT3_EXT;
        if (e === ks)
          return s.COMPRESSED_RGBA_S3TC_DXT5_EXT;
      } else
        return null;
    if (e === Bc || e === Oc || e === kc || e === Gc)
      if (s = r.get("WEBGL_compressed_texture_pvrtc"), s !== null) {
        if (e === Bc)
          return s.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
        if (e === Oc)
          return s.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
        if (e === kc)
          return s.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
        if (e === Gc)
          return s.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
      } else
        return null;
    if (e === Oo || e === ko || e === Go || e === Vo || e === zo || e === Pa || e === Ho)
      if (s = r.get("WEBGL_compressed_texture_etc"), s !== null) {
        if (e === Oo || e === ko)
          return a === Te ? s.COMPRESSED_SRGB8_ETC2 : s.COMPRESSED_RGB8_ETC2;
        if (e === Go)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : s.COMPRESSED_RGBA8_ETC2_EAC;
        if (e === Vo)
          return s.COMPRESSED_R11_EAC;
        if (e === zo)
          return s.COMPRESSED_SIGNED_R11_EAC;
        if (e === Pa)
          return s.COMPRESSED_RG11_EAC;
        if (e === Ho)
          return s.COMPRESSED_SIGNED_RG11_EAC;
      } else
        return null;
    if (e === $o || e === Wo || e === qo || e === Xo || e === jo || e === Yo || e === Ko || e === Zo || e === Qo || e === Jo || e === el || e === tl || e === nl || e === il)
      if (s = r.get("WEBGL_compressed_texture_astc"), s !== null) {
        if (e === $o)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : s.COMPRESSED_RGBA_ASTC_4x4_KHR;
        if (e === Wo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : s.COMPRESSED_RGBA_ASTC_5x4_KHR;
        if (e === qo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : s.COMPRESSED_RGBA_ASTC_5x5_KHR;
        if (e === Xo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : s.COMPRESSED_RGBA_ASTC_6x5_KHR;
        if (e === jo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : s.COMPRESSED_RGBA_ASTC_6x6_KHR;
        if (e === Yo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : s.COMPRESSED_RGBA_ASTC_8x5_KHR;
        if (e === Ko)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : s.COMPRESSED_RGBA_ASTC_8x6_KHR;
        if (e === Zo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : s.COMPRESSED_RGBA_ASTC_8x8_KHR;
        if (e === Qo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : s.COMPRESSED_RGBA_ASTC_10x5_KHR;
        if (e === Jo)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : s.COMPRESSED_RGBA_ASTC_10x6_KHR;
        if (e === el)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : s.COMPRESSED_RGBA_ASTC_10x8_KHR;
        if (e === tl)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : s.COMPRESSED_RGBA_ASTC_10x10_KHR;
        if (e === nl)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : s.COMPRESSED_RGBA_ASTC_12x10_KHR;
        if (e === il)
          return a === Te ? s.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : s.COMPRESSED_RGBA_ASTC_12x12_KHR;
      } else
        return null;
    if (e === rl)
      if (s = r.get("EXT_texture_compression_bptc"), s !== null) {
        if (e === rl)
          return a === Te ? s.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : s.COMPRESSED_RGBA_BPTC_UNORM_EXT;
      } else
        return null;
    if (e === sl || e === al || e === Da || e === ol)
      if (s = r.get("EXT_texture_compression_rgtc"), s !== null) {
        if (e === sl)
          return s.COMPRESSED_RED_RGTC1_EXT;
        if (e === al)
          return s.COMPRESSED_SIGNED_RED_RGTC1_EXT;
        if (e === Da)
          return s.COMPRESSED_RED_GREEN_RGTC2_EXT;
        if (e === ol)
          return s.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
      } else
        return null;
    return e === Ci ? n.UNSIGNED_INT_24_8 : n[e] !== void 0 ? n[e] : null;
  }
  /**
   * This method can be used to synchronize the CPU with the GPU by waiting until
   * ongoing GPU commands have been completed.
   *
   * @private
   * @return {Promise} A promise that resolves when all ongoing GPU commands have been completed.
   */
  _clientWaitAsync() {
    const { gl: e } = this, t = e.fenceSync(e.SYNC_GPU_COMMANDS_COMPLETE, 0);
    return e.flush(), new Promise((n, r) => {
      function s() {
        const a = e.clientWaitSync(t, e.SYNC_FLUSH_COMMANDS_BIT, 0);
        if (a === e.WAIT_FAILED) {
          e.deleteSync(t), r();
          return;
        }
        if (a === e.TIMEOUT_EXPIRED) {
          requestAnimationFrame(s);
          return;
        }
        e.deleteSync(t), n();
      }
      s();
    });
  }
}
let lv = !1, uh, hp, cv;
class ZG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e, this.gl = e.gl, this.extensions = e.extensions, this.defaultTextures = {}, this._srcFramebuffer = null, this._dstFramebuffer = null, lv === !1 && (this._init(), lv = !0);
  }
  /**
   * Inits the state of the utility.
   *
   * @private
   */
  _init() {
    const e = this.gl;
    uh = {
      [Ca]: e.REPEAT,
      [fi]: e.CLAMP_TO_EDGE,
      [Na]: e.MIRRORED_REPEAT
    }, hp = {
      [Tt]: e.NEAREST,
      [Um]: e.NEAREST_MIPMAP_NEAREST,
      [ts]: e.NEAREST_MIPMAP_LINEAR,
      [Ot]: e.LINEAR,
      [Po]: e.LINEAR_MIPMAP_NEAREST,
      [pi]: e.LINEAR_MIPMAP_LINEAR
    }, cv = {
      [Om]: e.NEVER,
      [Vm]: e.ALWAYS,
      [ld]: e.LESS,
      [Xs]: e.LEQUAL,
      [km]: e.EQUAL,
      [us]: e.GEQUAL,
      [Vc]: e.GREATER,
      [Gm]: e.NOTEQUAL
    };
  }
  /**
   * Returns the native texture type for the given texture.
   *
   * @param {Texture} texture - The texture.
   * @return {GLenum} The native texture type.
   */
  getGLTextureType(e) {
    const { gl: t } = this;
    let n;
    return e.isCubeTexture === !0 ? n = t.TEXTURE_CUBE_MAP : e.isArrayTexture === !0 || e.isDataArrayTexture === !0 || e.isCompressedArrayTexture === !0 ? n = t.TEXTURE_2D_ARRAY : e.isData3DTexture === !0 ? n = t.TEXTURE_3D : n = t.TEXTURE_2D, n;
  }
  /**
   * Returns the native texture type for the given texture.
   *
   * @param {?string} internalFormatName - The internal format name. When `null`, the internal format is derived from the subsequent parameters.
   * @param {GLenum} glFormat - The WebGL format.
   * @param {GLenum} glType - The WebGL type.
   * @param {string} colorSpace - The texture's color space.
   * @param {boolean} [forceLinearTransfer=false] - Whether to force a linear transfer or not.
   * @return {GLenum} The internal format.
   */
  getInternalFormat(e, t, n, r, s = !1) {
    const { gl: a, extensions: o } = this;
    if (e !== null) {
      if (a[e] !== void 0)
        return a[e];
      oe("WebGLBackend: Attempt to use non-existing WebGL internal format '" + e + "'");
    }
    let l = t;
    if (t === a.RED && (n === a.FLOAT && (l = a.R32F), n === a.HALF_FLOAT && (l = a.R16F), n === a.UNSIGNED_BYTE && (l = a.R8), n === a.UNSIGNED_SHORT && (l = a.R16), n === a.UNSIGNED_INT && (l = a.R32UI), n === a.BYTE && (l = a.R8I), n === a.SHORT && (l = a.R16I), n === a.INT && (l = a.R32I)), t === a.RED_INTEGER && (n === a.UNSIGNED_BYTE && (l = a.R8UI), n === a.UNSIGNED_SHORT && (l = a.R16UI), n === a.UNSIGNED_INT && (l = a.R32UI), n === a.BYTE && (l = a.R8I), n === a.SHORT && (l = a.R16I), n === a.INT && (l = a.R32I)), t === a.RG && (n === a.FLOAT && (l = a.RG32F), n === a.HALF_FLOAT && (l = a.RG16F), n === a.UNSIGNED_BYTE && (l = a.RG8), n === a.UNSIGNED_SHORT && (l = a.RG16), n === a.UNSIGNED_INT && (l = a.RG32UI), n === a.BYTE && (l = a.RG8I), n === a.SHORT && (l = a.RG16I), n === a.INT && (l = a.RG32I)), t === a.RG_INTEGER && (n === a.UNSIGNED_BYTE && (l = a.RG8UI), n === a.UNSIGNED_SHORT && (l = a.RG16UI), n === a.UNSIGNED_INT && (l = a.RG32UI), n === a.BYTE && (l = a.RG8I), n === a.SHORT && (l = a.RG16I), n === a.INT && (l = a.RG32I)), t === a.RGB) {
      const c = s ? ll : Ke.getTransfer(r);
      n === a.FLOAT && (l = a.RGB32F), n === a.HALF_FLOAT && (l = a.RGB16F), n === a.UNSIGNED_BYTE && (l = a.RGB8), n === a.UNSIGNED_SHORT && (l = a.RGB16), n === a.UNSIGNED_INT && (l = a.RGB32UI), n === a.BYTE && (l = a.RGB8I), n === a.SHORT && (l = a.RGB16I), n === a.INT && (l = a.RGB32I), n === a.UNSIGNED_BYTE && (l = c === Te ? a.SRGB8 : a.RGB8), n === a.UNSIGNED_SHORT_5_6_5 && (l = a.RGB565), n === a.UNSIGNED_SHORT_5_5_5_1 && (l = a.RGB5_A1), n === a.UNSIGNED_SHORT_4_4_4_4 && (l = a.RGB4), n === a.UNSIGNED_INT_5_9_9_9_REV && (l = a.RGB9_E5), n === a.UNSIGNED_INT_10F_11F_11F_REV && (l = a.R11F_G11F_B10F);
    }
    if (t === a.RGB_INTEGER && (n === a.UNSIGNED_BYTE && (l = a.RGB8UI), n === a.UNSIGNED_SHORT && (l = a.RGB16UI), n === a.UNSIGNED_INT && (l = a.RGB32UI), n === a.BYTE && (l = a.RGB8I), n === a.SHORT && (l = a.RGB16I), n === a.INT && (l = a.RGB32I)), t === a.RGBA) {
      const c = s ? ll : Ke.getTransfer(r);
      n === a.FLOAT && (l = a.RGBA32F), n === a.HALF_FLOAT && (l = a.RGBA16F), n === a.UNSIGNED_BYTE && (l = a.RGBA8), n === a.UNSIGNED_SHORT && (l = a.RGBA16), n === a.UNSIGNED_INT && (l = a.RGBA32UI), n === a.BYTE && (l = a.RGBA8I), n === a.SHORT && (l = a.RGBA16I), n === a.INT && (l = a.RGBA32I), n === a.UNSIGNED_BYTE && (l = c === Te ? a.SRGB8_ALPHA8 : a.RGBA8), n === a.UNSIGNED_SHORT_4_4_4_4 && (l = a.RGBA4), n === a.UNSIGNED_SHORT_5_5_5_1 && (l = a.RGB5_A1);
    }
    return t === a.RGBA_INTEGER && (n === a.UNSIGNED_BYTE && (l = a.RGBA8UI), n === a.UNSIGNED_SHORT && (l = a.RGBA16UI), n === a.UNSIGNED_INT && (l = a.RGBA32UI), n === a.BYTE && (l = a.RGBA8I), n === a.SHORT && (l = a.RGBA16I), n === a.INT && (l = a.RGBA32I)), t === a.DEPTH_COMPONENT && (n === a.UNSIGNED_SHORT && (l = a.DEPTH_COMPONENT16), n === a.UNSIGNED_INT && (l = a.DEPTH_COMPONENT24), n === a.FLOAT && (l = a.DEPTH_COMPONENT32F)), t === a.DEPTH_STENCIL && n === a.UNSIGNED_INT_24_8 && (l = a.DEPTH24_STENCIL8), (l === a.R16F || l === a.R32F || l === a.RG16F || l === a.RG32F || l === a.RGBA16F || l === a.RGBA32F) && o.get("EXT_color_buffer_float"), l;
  }
  /**
   * Sets the texture parameters for the given texture.
   *
   * @param {GLenum} textureType - The texture type.
   * @param {Texture} texture - The texture.
   */
  setTextureParameters(e, t) {
    const { gl: n, extensions: r, backend: s } = this, a = Ke.getPrimaries(Ke.workingColorSpace), o = t.colorSpace === hi ? null : Ke.getPrimaries(t.colorSpace), l = t.colorSpace === hi || a === o ? n.NONE : n.BROWSER_DEFAULT_WEBGL;
    n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL, t.flipY), n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL, t.premultiplyAlpha), n.pixelStorei(n.UNPACK_ALIGNMENT, t.unpackAlignment), n.pixelStorei(n.UNPACK_COLORSPACE_CONVERSION_WEBGL, l), n.texParameteri(e, n.TEXTURE_WRAP_S, uh[t.wrapS]), n.texParameteri(e, n.TEXTURE_WRAP_T, uh[t.wrapT]), (e === n.TEXTURE_3D || e === n.TEXTURE_2D_ARRAY) && (t.isArrayTexture || n.texParameteri(e, n.TEXTURE_WRAP_R, uh[t.wrapR])), n.texParameteri(e, n.TEXTURE_MAG_FILTER, hp[t.magFilter]);
    const c = t.mipmaps !== void 0 && t.mipmaps.length > 0, u = t.minFilter === Ot && c ? pi : t.minFilter;
    if (n.texParameteri(e, n.TEXTURE_MIN_FILTER, hp[u]), t.compareFunction && (n.texParameteri(e, n.TEXTURE_COMPARE_MODE, n.COMPARE_REF_TO_TEXTURE), n.texParameteri(e, n.TEXTURE_COMPARE_FUNC, cv[t.compareFunction])), r.has("EXT_texture_filter_anisotropic") === !0) {
      if (t.magFilter === Tt || t.minFilter !== ts && t.minFilter !== pi || t.type === ln && r.has("OES_texture_float_linear") === !1)
        return;
      if (t.anisotropy > 1) {
        const h = r.get("EXT_texture_filter_anisotropic");
        n.texParameterf(e, h.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(t.anisotropy, s.getMaxAnisotropy()));
      }
    }
  }
  /**
   * Creates a default texture for the given texture that can be used
   * as a placeholder until the actual texture is ready for usage.
   *
   * @param {Texture} texture - The texture to create a default texture for.
   */
  createDefaultTexture(e) {
    const { gl: t, backend: n, defaultTextures: r } = this, s = this.getGLTextureType(e);
    let a = r[s];
    a === void 0 && (a = t.createTexture(), n.state.bindTexture(s, a), t.texParameteri(s, t.TEXTURE_MIN_FILTER, t.NEAREST), t.texParameteri(s, t.TEXTURE_MAG_FILTER, t.NEAREST), r[s] = a), n.set(e, {
      textureGPU: a,
      glTextureType: s
    });
  }
  /**
   * Defines a texture on the GPU for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   * @return {undefined}
   */
  createTexture(e, t) {
    const { gl: n, backend: r } = this, { levels: s, width: a, height: o, depth: l } = t, c = r.utils.convert(e.format, e.colorSpace), u = r.utils.convert(e.type), h = this.getInternalFormat(e.internalFormat, c, u, e.colorSpace, e.isVideoTexture), d = n.createTexture(), f = this.getGLTextureType(e);
    r.state.bindTexture(f, d), this.setTextureParameters(f, e), e.isArrayTexture || e.isDataArrayTexture || e.isCompressedArrayTexture ? n.texStorage3D(n.TEXTURE_2D_ARRAY, s, h, a, o, l) : e.isData3DTexture ? n.texStorage3D(n.TEXTURE_3D, s, h, a, o, l) : e.isVideoTexture || n.texStorage2D(f, s, h, a, o), r.set(e, {
      textureGPU: d,
      glTextureType: f,
      glFormat: c,
      glType: u,
      glInternalFormat: h
    });
  }
  /**
   * Uploads texture buffer data to the GPU memory.
   *
   * @param {WebGLBuffer} buffer - The buffer data.
   * @param {Texture} texture - The texture,
   */
  copyBufferToTexture(e, t) {
    const { gl: n, backend: r } = this, { textureGPU: s, glTextureType: a, glFormat: o, glType: l } = r.get(t), { width: c, height: u } = t.source.data;
    n.bindBuffer(n.PIXEL_UNPACK_BUFFER, e), r.state.bindTexture(a, s), n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL, !1), n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), n.texSubImage2D(a, 0, 0, 0, c, u, o, l, 0), n.bindBuffer(n.PIXEL_UNPACK_BUFFER, null), r.state.unbindTexture();
  }
  /**
   * Uploads the updated texture data to the GPU.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  updateTexture(e, t) {
    const { gl: n } = this, { width: r, height: s } = t, { textureGPU: a, glTextureType: o, glFormat: l, glType: c, glInternalFormat: u } = this.backend.get(e);
    if (!(e.isRenderTargetTexture || a === void 0))
      if (this.backend.state.bindTexture(o, a), this.setTextureParameters(o, e), e.isCompressedTexture) {
        const h = e.mipmaps, d = t.image;
        for (let f = 0; f < h.length; f++) {
          const p = h[f];
          e.isCompressedArrayTexture ? e.format !== n.RGBA ? l !== null ? n.compressedTexSubImage3D(n.TEXTURE_2D_ARRAY, f, 0, 0, 0, p.width, p.height, d.depth, l, p.data) : oe("WebGLBackend: Attempt to load unsupported compressed texture format in .uploadTexture()") : n.texSubImage3D(n.TEXTURE_2D_ARRAY, f, 0, 0, 0, p.width, p.height, d.depth, l, c, p.data) : l !== null ? n.compressedTexSubImage2D(n.TEXTURE_2D, f, 0, 0, p.width, p.height, l, p.data) : oe("WebGLBackend: Unsupported compressed texture format");
        }
      } else if (e.isCubeTexture) {
        const h = t.images, d = e.mipmaps;
        for (let f = 0; f < 6; f++) {
          const p = hh(h[f]);
          n.texSubImage2D(n.TEXTURE_CUBE_MAP_POSITIVE_X + f, 0, 0, 0, r, s, l, c, p);
          for (let _ = 0; _ < d.length; _++) {
            const g = d[_], m = hh(g.images[f]);
            n.texSubImage2D(n.TEXTURE_CUBE_MAP_POSITIVE_X + f, _ + 1, 0, 0, m.width, m.height, l, c, m);
          }
        }
      } else if (e.isDataArrayTexture || e.isArrayTexture) {
        const h = t.image;
        if (e.layerUpdates.size > 0) {
          const d = Cp(h.width, h.height, e.format, e.type);
          for (const f of e.layerUpdates) {
            const p = h.data.subarray(
              f * d / h.data.BYTES_PER_ELEMENT,
              (f + 1) * d / h.data.BYTES_PER_ELEMENT
            );
            n.texSubImage3D(n.TEXTURE_2D_ARRAY, 0, 0, 0, f, h.width, h.height, 1, l, c, p);
          }
          e.clearLayerUpdates();
        } else
          n.texSubImage3D(n.TEXTURE_2D_ARRAY, 0, 0, 0, 0, h.width, h.height, h.depth, l, c, h.data);
      } else if (e.isData3DTexture) {
        const h = t.image;
        n.texSubImage3D(n.TEXTURE_3D, 0, 0, 0, 0, h.width, h.height, h.depth, l, c, h.data);
      } else if (e.isVideoTexture)
        e.update(), n.texImage2D(o, 0, u, l, c, t.image);
      else {
        const h = e.mipmaps;
        if (h.length > 0)
          for (let d = 0, f = h.length; d < f; d++) {
            const p = h[d], _ = hh(p);
            n.texSubImage2D(o, d, 0, 0, p.width, p.height, l, c, _);
          }
        else {
          const d = hh(t.image);
          n.texSubImage2D(o, 0, 0, 0, r, s, l, c, d);
        }
      }
  }
  /**
   * Generates mipmaps for the given texture.
   *
   * @param {Texture} texture - The texture.
   */
  generateMipmaps(e) {
    const { gl: t, backend: n } = this, { textureGPU: r, glTextureType: s } = n.get(e);
    n.state.bindTexture(s, r), t.generateMipmap(s);
  }
  /**
   * Deallocates the render buffers of the given render target.
   *
   * @param {RenderTarget} renderTarget - The render target.
   */
  deallocateRenderBuffers(e) {
    const { gl: t, backend: n } = this;
    if (e) {
      const r = n.get(e);
      if (r.renderBufferStorageSetup = void 0, r.framebuffers) {
        for (const s in r.framebuffers)
          t.deleteFramebuffer(r.framebuffers[s]);
        delete r.framebuffers;
      }
      if (r.depthRenderbuffer && (t.deleteRenderbuffer(r.depthRenderbuffer), delete r.depthRenderbuffer), r.stencilRenderbuffer && (t.deleteRenderbuffer(r.stencilRenderbuffer), delete r.stencilRenderbuffer), r.msaaFrameBuffer && (t.deleteFramebuffer(r.msaaFrameBuffer), delete r.msaaFrameBuffer), r.msaaRenderbuffers) {
        for (let s = 0; s < r.msaaRenderbuffers.length; s++)
          t.deleteRenderbuffer(r.msaaRenderbuffers[s]);
        delete r.msaaRenderbuffers;
      }
    }
  }
  /**
   * Destroys the GPU data for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {boolean} [isDefaultTexture=false] - Whether the texture uses a default GPU texture or not.
   */
  destroyTexture(e, t = !1) {
    const { gl: n, backend: r } = this, { textureGPU: s, renderTarget: a } = r.get(e);
    this.deallocateRenderBuffers(a), t === !1 && n.deleteTexture(s), r.delete(e);
  }
  /**
   * Copies data of the given source texture to the given destination texture.
   *
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy.
   * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
   * @param {number} [srcLevel=0] - The source mip level to copy from.
   * @param {number} [dstLevel=0] - The destination mip level to copy to.
   */
  copyTextureToTexture(e, t, n = null, r = null, s = 0, a = 0) {
    const { gl: o, backend: l } = this, { state: c } = this.backend, { textureGPU: u, glTextureType: h, glType: d, glFormat: f } = l.get(t);
    c.bindTexture(h, u);
    let p, _, g, m, x, y, b, T, S;
    const E = e.isCompressedTexture ? e.mipmaps[a] : e.image;
    if (n !== null)
      p = n.max.x - n.min.x, _ = n.max.y - n.min.y, g = n.isBox3 ? n.max.z - n.min.z : 1, m = n.min.x, x = n.min.y, y = n.isBox3 ? n.min.z : 0;
    else {
      const C = Math.pow(2, -s);
      p = Math.floor(E.width * C), _ = Math.floor(E.height * C), e.isDataArrayTexture || e.isArrayTexture ? g = E.depth : e.isData3DTexture ? g = Math.floor(E.depth * C) : g = 1, m = 0, x = 0, y = 0;
    }
    r !== null ? (b = r.x, T = r.y, S = r.z) : (b = 0, T = 0, S = 0), o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL, t.flipY), o.pixelStorei(o.UNPACK_PREMULTIPLY_ALPHA_WEBGL, t.premultiplyAlpha), o.pixelStorei(o.UNPACK_ALIGNMENT, t.unpackAlignment);
    const v = o.getParameter(o.UNPACK_ROW_LENGTH), M = o.getParameter(o.UNPACK_IMAGE_HEIGHT), F = o.getParameter(o.UNPACK_SKIP_PIXELS), R = o.getParameter(o.UNPACK_SKIP_ROWS), I = o.getParameter(o.UNPACK_SKIP_IMAGES);
    o.pixelStorei(o.UNPACK_ROW_LENGTH, E.width), o.pixelStorei(o.UNPACK_IMAGE_HEIGHT, E.height), o.pixelStorei(o.UNPACK_SKIP_PIXELS, m), o.pixelStorei(o.UNPACK_SKIP_ROWS, x), o.pixelStorei(o.UNPACK_SKIP_IMAGES, y);
    const B = e.isDataArrayTexture || e.isData3DTexture || t.isArrayTexture, N = t.isDataArrayTexture || t.isData3DTexture || t.isArrayTexture;
    if (e.isDepthTexture) {
      const C = l.get(e), L = l.get(t), k = l.get(C.renderTarget), re = l.get(L.renderTarget), se = k.framebuffers[C.cacheKey], ve = re.framebuffers[L.cacheKey];
      c.bindFramebuffer(o.READ_FRAMEBUFFER, se), c.bindFramebuffer(o.DRAW_FRAMEBUFFER, ve);
      for (let X = 0; X < g; X++)
        B && (o.framebufferTextureLayer(o.READ_FRAMEBUFFER, o.COLOR_ATTACHMENT0, C.textureGPU, s, y + X), o.framebufferTextureLayer(o.DRAW_FRAMEBUFFER, o.COLOR_ATTACHMENT0, u, a, S + X)), o.blitFramebuffer(m, x, p, _, b, T, p, _, o.DEPTH_BUFFER_BIT, o.NEAREST);
      c.bindFramebuffer(o.READ_FRAMEBUFFER, null), c.bindFramebuffer(o.DRAW_FRAMEBUFFER, null);
    } else if (s !== 0 || e.isRenderTargetTexture || l.has(e)) {
      const C = l.get(e);
      this._srcFramebuffer === null && (this._srcFramebuffer = o.createFramebuffer()), this._dstFramebuffer === null && (this._dstFramebuffer = o.createFramebuffer()), c.bindFramebuffer(o.READ_FRAMEBUFFER, this._srcFramebuffer), c.bindFramebuffer(o.DRAW_FRAMEBUFFER, this._dstFramebuffer);
      for (let L = 0; L < g; L++)
        B ? o.framebufferTextureLayer(o.READ_FRAMEBUFFER, o.COLOR_ATTACHMENT0, C.textureGPU, s, y + L) : o.framebufferTexture2D(o.READ_FRAMEBUFFER, o.COLOR_ATTACHMENT0, o.TEXTURE_2D, C.textureGPU, s), N ? o.framebufferTextureLayer(o.DRAW_FRAMEBUFFER, o.COLOR_ATTACHMENT0, u, a, S + L) : o.framebufferTexture2D(o.DRAW_FRAMEBUFFER, o.COLOR_ATTACHMENT0, o.TEXTURE_2D, u, a), s !== 0 ? o.blitFramebuffer(m, x, p, _, b, T, p, _, o.COLOR_BUFFER_BIT, o.NEAREST) : N ? o.copyTexSubImage3D(h, a, b, T, S + L, m, x, p, _) : o.copyTexSubImage2D(h, a, b, T, m, x, p, _);
      c.bindFramebuffer(o.READ_FRAMEBUFFER, null), c.bindFramebuffer(o.DRAW_FRAMEBUFFER, null);
    } else
      N ? e.isDataTexture || e.isData3DTexture ? o.texSubImage3D(h, a, b, T, S, p, _, g, f, d, E.data) : t.isCompressedArrayTexture ? o.compressedTexSubImage3D(h, a, b, T, S, p, _, g, f, E.data) : o.texSubImage3D(h, a, b, T, S, p, _, g, f, d, E) : e.isDataTexture ? o.texSubImage2D(o.TEXTURE_2D, a, b, T, p, _, f, d, E.data) : e.isCompressedTexture ? o.compressedTexSubImage2D(o.TEXTURE_2D, a, b, T, E.width, E.height, f, E.data) : o.texSubImage2D(o.TEXTURE_2D, a, b, T, p, _, f, d, E);
    o.pixelStorei(o.UNPACK_ROW_LENGTH, v), o.pixelStorei(o.UNPACK_IMAGE_HEIGHT, M), o.pixelStorei(o.UNPACK_SKIP_PIXELS, F), o.pixelStorei(o.UNPACK_SKIP_ROWS, R), o.pixelStorei(o.UNPACK_SKIP_IMAGES, I), a === 0 && t.generateMipmaps && o.generateMipmap(h), c.unbindTexture();
  }
  /**
   * Copies the current bound framebuffer to the given texture.
   *
   * @param {Texture} texture - The destination texture.
   * @param {RenderContext} renderContext - The render context.
   * @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy.
   */
  copyFramebufferToTexture(e, t, n) {
    const { gl: r } = this, { state: s } = this.backend, { textureGPU: a } = this.backend.get(e), { x: o, y: l, z: c, w: u } = n, h = e.isDepthTexture === !0 || t.renderTarget && t.renderTarget.samples > 0, d = t.renderTarget ? t.renderTarget.height : this.backend.getDrawingBufferSize().y;
    if (h) {
      const f = o !== 0 || l !== 0;
      let p, _;
      if (e.isDepthTexture === !0 ? (p = r.DEPTH_BUFFER_BIT, _ = r.DEPTH_ATTACHMENT, t.stencil && (p |= r.STENCIL_BUFFER_BIT)) : (p = r.COLOR_BUFFER_BIT, _ = r.COLOR_ATTACHMENT0), f) {
        const g = this.backend.get(t.renderTarget), m = g.framebuffers[t.getCacheKey()], x = g.msaaFrameBuffer;
        s.bindFramebuffer(r.DRAW_FRAMEBUFFER, m), s.bindFramebuffer(r.READ_FRAMEBUFFER, x);
        const y = d - l - u;
        r.blitFramebuffer(o, y, o + c, y + u, o, y, o + c, y + u, p, r.NEAREST), s.bindFramebuffer(r.READ_FRAMEBUFFER, m), s.bindTexture(r.TEXTURE_2D, a), r.copyTexSubImage2D(r.TEXTURE_2D, 0, 0, 0, o, y, c, u), s.unbindTexture();
      } else {
        const g = r.createFramebuffer();
        s.bindFramebuffer(r.DRAW_FRAMEBUFFER, g), r.framebufferTexture2D(r.DRAW_FRAMEBUFFER, _, r.TEXTURE_2D, a, 0), r.blitFramebuffer(0, 0, c, u, 0, 0, c, u, p, r.NEAREST), r.deleteFramebuffer(g);
      }
    } else
      s.bindTexture(r.TEXTURE_2D, a), r.copyTexSubImage2D(r.TEXTURE_2D, 0, 0, 0, o, d - u - l, c, u), s.unbindTexture();
    e.generateMipmaps && this.generateMipmaps(e), this.backend._setFramebuffer(t);
  }
  /**
   * SetupS storage for internal depth/stencil buffers and bind to correct framebuffer.
   *
   * @param {WebGLRenderbuffer} renderbuffer - The render buffer.
   * @param {RenderContext} renderContext - The render context.
   * @param {number} samples - The MSAA sample count.
   * @param {boolean} [useMultisampledRTT=false] - Whether to use WEBGL_multisampled_render_to_texture or not.
   */
  setupRenderBufferStorage(e, t, n, r = !1) {
    const { gl: s } = this, a = t.renderTarget, { depthTexture: o, depthBuffer: l, stencilBuffer: c, width: u, height: h } = a;
    if (s.bindRenderbuffer(s.RENDERBUFFER, e), l && !c) {
      let d = s.DEPTH_COMPONENT24;
      r === !0 ? this.extensions.get("WEBGL_multisampled_render_to_texture").renderbufferStorageMultisampleEXT(s.RENDERBUFFER, a.samples, d, u, h) : n > 0 ? (o && o.isDepthTexture && o.type === s.FLOAT && (d = s.DEPTH_COMPONENT32F), s.renderbufferStorageMultisample(s.RENDERBUFFER, n, d, u, h)) : s.renderbufferStorage(s.RENDERBUFFER, d, u, h), s.framebufferRenderbuffer(s.FRAMEBUFFER, s.DEPTH_ATTACHMENT, s.RENDERBUFFER, e);
    } else
      l && c && (n > 0 ? s.renderbufferStorageMultisample(s.RENDERBUFFER, n, s.DEPTH24_STENCIL8, u, h) : s.renderbufferStorage(s.RENDERBUFFER, s.DEPTH_STENCIL, u, h), s.framebufferRenderbuffer(s.FRAMEBUFFER, s.DEPTH_STENCIL_ATTACHMENT, s.RENDERBUFFER, e));
    s.bindRenderbuffer(s.RENDERBUFFER, null);
  }
  /**
   * Returns texture data as a typed array.
   *
   * @async
   * @param {Texture} texture - The texture to copy.
   * @param {number} x - The x coordinate of the copy origin.
   * @param {number} y - The y coordinate of the copy origin.
   * @param {number} width - The width of the copy.
   * @param {number} height - The height of the copy.
   * @param {number} faceIndex - The face index.
   * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
   */
  async copyTextureToBuffer(e, t, n, r, s, a) {
    const { backend: o, gl: l } = this, { textureGPU: c, glFormat: u, glType: h } = this.backend.get(e), d = l.createFramebuffer();
    o.state.bindFramebuffer(l.READ_FRAMEBUFFER, d);
    const f = e.isCubeTexture ? l.TEXTURE_CUBE_MAP_POSITIVE_X + a : l.TEXTURE_2D;
    l.framebufferTexture2D(l.READ_FRAMEBUFFER, l.COLOR_ATTACHMENT0, f, c, 0);
    const p = this._getTypedArrayType(h), _ = this._getBytesPerTexel(h, u), m = r * s * _, x = l.createBuffer();
    l.bindBuffer(l.PIXEL_PACK_BUFFER, x), l.bufferData(l.PIXEL_PACK_BUFFER, m, l.STREAM_READ), l.readPixels(t, n, r, s, u, h, 0), l.bindBuffer(l.PIXEL_PACK_BUFFER, null), await o.utils._clientWaitAsync();
    const y = new p(m / p.BYTES_PER_ELEMENT);
    return l.bindBuffer(l.PIXEL_PACK_BUFFER, x), l.getBufferSubData(l.PIXEL_PACK_BUFFER, 0, y), l.bindBuffer(l.PIXEL_PACK_BUFFER, null), o.state.bindFramebuffer(l.READ_FRAMEBUFFER, null), l.deleteFramebuffer(d), y;
  }
  /**
   * Returns the corresponding typed array type for the given WebGL data type.
   *
   * @private
   * @param {GLenum} glType - The WebGL data type.
   * @return {TypedArray.constructor} The typed array type.
   */
  _getTypedArrayType(e) {
    const { gl: t } = this;
    if (e === t.UNSIGNED_BYTE)
      return Uint8Array;
    if (e === t.UNSIGNED_SHORT_4_4_4_4 || e === t.UNSIGNED_SHORT_5_5_5_1 || e === t.UNSIGNED_SHORT_5_6_5 || e === t.UNSIGNED_SHORT)
      return Uint16Array;
    if (e === t.UNSIGNED_INT)
      return Uint32Array;
    if (e === t.HALF_FLOAT)
      return Uint16Array;
    if (e === t.FLOAT)
      return Float32Array;
    throw new Error(`Unsupported WebGL type: ${e}`);
  }
  /**
   * Returns the bytes-per-texel value for the given WebGL data type and texture format.
   *
   * @private
   * @param {GLenum} glType - The WebGL data type.
   * @param {GLenum} glFormat - The WebGL texture format.
   * @return {number} The bytes-per-texel.
   */
  _getBytesPerTexel(e, t) {
    const { gl: n } = this;
    let r = 0;
    if (e === n.UNSIGNED_BYTE && (r = 1), (e === n.UNSIGNED_SHORT_4_4_4_4 || e === n.UNSIGNED_SHORT_5_5_5_1 || e === n.UNSIGNED_SHORT_5_6_5 || e === n.UNSIGNED_SHORT || e === n.HALF_FLOAT) && (r = 2), (e === n.UNSIGNED_INT || e === n.FLOAT) && (r = 4), t === n.RGBA)
      return r * 4;
    if (t === n.RGB)
      return r * 3;
    if (t === n.ALPHA)
      return r;
  }
  /**
   * Frees the internal resources.
   */
  dispose() {
    const { gl: e } = this;
    this._srcFramebuffer !== null && e.deleteFramebuffer(this._srcFramebuffer), this._dstFramebuffer !== null && e.deleteFramebuffer(this._dstFramebuffer);
  }
}
function hh(i) {
  return i.isDataTexture ? i.image.data : typeof HTMLImageElement < "u" && i instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && i instanceof HTMLCanvasElement || typeof ImageBitmap < "u" && i instanceof ImageBitmap || typeof OffscreenCanvas < "u" && i instanceof OffscreenCanvas ? i : i.data;
}
class QG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e, this.gl = this.backend.gl, this.availableExtensions = this.gl.getSupportedExtensions(), this.extensions = {};
  }
  /**
   * Returns the extension object for the given extension name.
   *
   * @param {string} name - The extension name.
   * @return {Object} The extension object.
   */
  get(e) {
    let t = this.extensions[e];
    return t === void 0 && (t = this.gl.getExtension(e), this.extensions[e] = t), t;
  }
  /**
   * Returns `true` if the requested extension is available.
   *
   * @param {string} name - The extension name.
   * @return {boolean} Whether the given extension is available or not.
   */
  has(e) {
    return this.availableExtensions.includes(e);
  }
}
class JG {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGLBackend} backend - The WebGL 2 backend.
   */
  constructor(e) {
    this.backend = e, this.maxAnisotropy = null;
  }
  /**
   * Returns the maximum anisotropy texture filtering value. This value
   * depends on the device and is reported by the `EXT_texture_filter_anisotropic`
   * WebGL extension.
   *
   * @return {number} The maximum anisotropy texture filtering value.
   */
  getMaxAnisotropy() {
    if (this.maxAnisotropy !== null)
      return this.maxAnisotropy;
    const e = this.backend.gl, t = this.backend.extensions;
    if (t.has("EXT_texture_filter_anisotropic") === !0) {
      const n = t.get("EXT_texture_filter_anisotropic");
      this.maxAnisotropy = e.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
    } else
      this.maxAnisotropy = 0;
    return this.maxAnisotropy;
  }
}
const uv = {
  WEBGL_multi_draw: "WEBGL_multi_draw",
  WEBGL_compressed_texture_astc: "texture-compression-astc",
  WEBGL_compressed_texture_etc: "texture-compression-etc2",
  WEBGL_compressed_texture_etc1: "texture-compression-etc1",
  WEBGL_compressed_texture_pvrtc: "texture-compression-pvrtc",
  WEBGL_compressed_texture_s3tc: "texture-compression-s3tc",
  EXT_texture_compression_bptc: "texture-compression-bc",
  EXT_disjoint_timer_query_webgl2: "timestamp-query",
  OVR_multiview2: "OVR_multiview2"
};
class eV {
  constructor(e) {
    this.gl = e.gl, this.extensions = e.extensions, this.info = e.renderer.info, this.mode = null, this.index = 0, this.type = null, this.object = null;
  }
  render(e, t) {
    const { gl: n, mode: r, object: s, type: a, info: o, index: l } = this;
    l !== 0 ? n.drawElements(r, t, a, e) : n.drawArrays(r, e, t), o.update(s, t, 1);
  }
  renderInstances(e, t, n) {
    const { gl: r, mode: s, type: a, index: o, object: l, info: c } = this;
    n !== 0 && (o !== 0 ? r.drawElementsInstanced(s, t, a, e, n) : r.drawArraysInstanced(s, e, t, n), c.update(l, t, n));
  }
  renderMultiDraw(e, t, n) {
    const { extensions: r, mode: s, object: a, info: o } = this;
    if (n === 0)
      return;
    const l = r.get("WEBGL_multi_draw");
    if (l === null)
      for (let c = 0; c < n; c++)
        this.render(e[c], t[c]);
    else {
      this.index !== 0 ? l.multiDrawElementsWEBGL(s, t, 0, this.type, e, 0, n) : l.multiDrawArraysWEBGL(s, e, 0, t, 0, n);
      let c = 0;
      for (let u = 0; u < n; u++)
        c += t[u];
      o.update(a, c, 1);
    }
  }
  renderMultiDrawInstances(e, t, n, r) {
    const { extensions: s, mode: a, object: o, info: l } = this;
    if (n === 0)
      return;
    const c = s.get("WEBGL_multi_draw");
    if (c === null)
      for (let u = 0; u < n; u++)
        this.renderInstances(e[u], t[u], r[u]);
    else {
      this.index !== 0 ? c.multiDrawElementsInstancedWEBGL(a, t, 0, this.type, e, 0, r, 0, n) : c.multiDrawArraysInstancedWEBGL(a, e, 0, t, 0, r, 0, n);
      let u = 0;
      for (let h = 0; h < n; h++)
        u += t[h] * r[h];
      l.update(o, u, 1);
    }
  }
  //
}
class xT {
  /**
   * Creates a new timestamp query pool.
   *
   * @param {number} [maxQueries=256] - Maximum number of queries this pool can hold.
   */
  constructor(e = 256) {
    this.trackTimestamp = !0, this.maxQueries = e, this.currentQueryIndex = 0, this.queryOffsets = /* @__PURE__ */ new Map(), this.isDisposed = !1, this.lastValue = 0, this.frames = [], this.pendingResolve = !1, this.timestamps = /* @__PURE__ */ new Map();
  }
  /**
   * Returns all timestamp frames.
   *
   * @return {Array<number>} The timestamp frames.
   */
  getTimestampFrames() {
    return this.frames;
  }
  /**
   * Returns the timestamp for a given render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @return {?number} The timestamp, or undefined if not available.
   */
  getTimestamp(e) {
    let t = this.timestamps.get(e);
    return t === void 0 && (oe(`TimestampQueryPool: No timestamp available for uid ${e}.`), t = 0), t;
  }
  /**
   * Returns whether a timestamp is available for a given render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @return {boolean} True if a timestamp is available, false otherwise.
   */
  hasTimestamp(e) {
    return this.timestamps.has(e);
  }
  /**
   * Allocate queries for a specific uid.
   *
   * @abstract
   * @param {string} uid - A unique identifier for the render context.
   * @param {number} frameId - The current frame identifier.
   * @returns {?number}
   */
  allocateQueriesForContext() {
  }
  /**
   * Resolve all timestamps and return data (or process them).
   *
   * @abstract
   * @async
   * @returns {Promise<number>|number} The resolved timestamp value.
   */
  async resolveQueriesAsync() {
  }
  /**
   * Dispose of the query pool.
   *
   * @abstract
   */
  dispose() {
  }
}
class tV extends xT {
  /**
   * Creates a new WebGL timestamp query pool.
   *
   * @param {WebGLRenderingContext|WebGL2RenderingContext} gl - The WebGL context.
   * @param {string} type - The type identifier for this query pool.
   * @param {number} [maxQueries=2048] - Maximum number of queries this pool can hold.
   */
  constructor(e, t, n = 2048) {
    if (super(n), this.gl = e, this.type = t, this.ext = e.getExtension("EXT_disjoint_timer_query_webgl2") || e.getExtension("EXT_disjoint_timer_query"), !this.ext) {
      oe("EXT_disjoint_timer_query not supported; timestamps will be disabled."), this.trackTimestamp = !1;
      return;
    }
    this.queries = [];
    for (let r = 0; r < this.maxQueries; r++)
      this.queries.push(e.createQuery());
    this.activeQuery = null, this.queryStates = /* @__PURE__ */ new Map();
  }
  /**
   * Allocates a pair of queries for a given render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @returns {?number} The base offset for the allocated queries, or null if allocation failed.
   */
  allocateQueriesForContext(e) {
    if (!this.trackTimestamp)
      return null;
    if (this.currentQueryIndex + 2 > this.maxQueries)
      return Pt(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`), null;
    const t = this.currentQueryIndex;
    return this.currentQueryIndex += 2, this.queryStates.set(t, "inactive"), this.queryOffsets.set(e, t), t;
  }
  /**
   * Begins a timestamp query for the specified render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   */
  beginQuery(e) {
    if (!this.trackTimestamp || this.isDisposed)
      return;
    const t = this.queryOffsets.get(e);
    if (t == null || this.activeQuery !== null)
      return;
    const n = this.queries[t];
    if (n)
      try {
        this.queryStates.get(t) === "inactive" && (this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT, n), this.activeQuery = t, this.queryStates.set(t, "started"));
      } catch (r) {
        le("Error in beginQuery:", r), this.activeQuery = null, this.queryStates.set(t, "inactive");
      }
  }
  /**
   * Ends the active timestamp query for the specified render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   */
  endQuery(e) {
    if (!this.trackTimestamp || this.isDisposed)
      return;
    const t = this.queryOffsets.get(e);
    if (t != null && this.activeQuery === t)
      try {
        this.gl.endQuery(this.ext.TIME_ELAPSED_EXT), this.queryStates.set(t, "ended"), this.activeQuery = null;
      } catch (n) {
        le("Error in endQuery:", n), this.queryStates.set(t, "inactive"), this.activeQuery = null;
      }
  }
  /**
   * Asynchronously resolves all completed queries and returns the total duration.
   *
   * @async
   * @returns {Promise<number>} The total duration in milliseconds, or the last valid value if resolution fails.
   */
  async resolveQueriesAsync() {
    if (!this.trackTimestamp || this.pendingResolve)
      return this.lastValue;
    this.pendingResolve = !0;
    try {
      const e = /* @__PURE__ */ new Map();
      for (const [s, a] of this.queryOffsets)
        if (this.queryStates.get(a) === "ended") {
          const l = this.queries[a];
          e.set(s, this.resolveQuery(l));
        }
      if (e.size === 0)
        return this.lastValue;
      const t = {}, n = [];
      for (const [s, a] of e) {
        const o = s.match(/^(.*):f(\d+)$/), l = parseInt(o[2]);
        n.includes(l) === !1 && n.push(l), t[l] === void 0 && (t[l] = 0);
        const c = await a;
        this.timestamps.set(s, c), t[l] += c;
      }
      const r = t[n[n.length - 1]];
      return this.lastValue = r, this.frames = n, this.currentQueryIndex = 0, this.queryOffsets.clear(), this.queryStates.clear(), this.activeQuery = null, r;
    } catch (e) {
      return le("Error resolving queries:", e), this.lastValue;
    } finally {
      this.pendingResolve = !1;
    }
  }
  /**
   * Resolves a single query, checking for completion and disjoint operation.
   *
   * @async
   * @param {WebGLQuery} query - The query object to resolve.
   * @returns {Promise<number>} The elapsed time in milliseconds.
   */
  async resolveQuery(e) {
    return new Promise((t) => {
      if (this.isDisposed) {
        t(this.lastValue);
        return;
      }
      let n, r = !1;
      const s = () => {
        n && (clearTimeout(n), n = null);
      }, a = (l) => {
        r || (r = !0, s(), t(l));
      }, o = () => {
        if (this.isDisposed) {
          a(this.lastValue);
          return;
        }
        try {
          if (this.gl.getParameter(this.ext.GPU_DISJOINT_EXT)) {
            a(this.lastValue);
            return;
          }
          if (!this.gl.getQueryParameter(e, this.gl.QUERY_RESULT_AVAILABLE)) {
            n = setTimeout(o, 1);
            return;
          }
          const u = this.gl.getQueryParameter(e, this.gl.QUERY_RESULT);
          t(Number(u) / 1e6);
        } catch (l) {
          le("Error checking query:", l), t(this.lastValue);
        }
      };
      o();
    });
  }
  /**
   * Releases all resources held by this query pool.
   * This includes deleting all query objects and clearing internal state.
   */
  dispose() {
    if (!this.isDisposed && (this.isDisposed = !0, !!this.trackTimestamp)) {
      for (const e of this.queries)
        this.gl.deleteQuery(e);
      this.queries = [], this.queryStates.clear(), this.queryOffsets.clear(), this.lastValue = 0, this.activeQuery = null;
    }
  }
}
class hv extends _T {
  /**
   * WebGLBackend options.
   *
   * @typedef {Object} WebGLBackend~Options
   * @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not.
   * @property {boolean} [reversedDepthBuffer=false] - Whether reversed depth buffer is enabled or not.
   * @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque.
   * @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not.
   * @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
   * @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
   * @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
   * @property {boolean} [forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not.
   * @property {WebGL2RenderingContext} [context=undefined] - A WebGL 2 rendering context.
   */
  /**
   * Constructs a new WebGPU backend.
   *
   * @param {WebGLBackend~Options} [parameters] - The configuration parameter.
   */
  constructor(e = {}) {
    super(e), this.isWebGLBackend = !0, this.attributeUtils = null, this.extensions = null, this.capabilities = null, this.textureUtils = null, this.bufferRenderer = null, this.gl = null, this.state = null, this.utils = null, this.vaoCache = {}, this.transformFeedbackCache = {}, this.discard = !1, this.disjoint = null, this.parallel = null, this._currentContext = null, this._knownBindings = /* @__PURE__ */ new WeakSet(), this._supportsInvalidateFramebuffer = typeof navigator > "u" ? !1 : /OculusBrowser/g.test(navigator.userAgent), this._xrFramebuffer = null;
  }
  /**
   * Initializes the backend so it is ready for usage.
   *
   * @param {Renderer} renderer - The renderer.
   */
  init(e) {
    super.init(e);
    const t = this.parameters, n = {
      antialias: e.currentSamples > 0,
      alpha: !0,
      // always true for performance reasons
      depth: e.depth,
      stencil: e.stencil
    }, r = t.context !== void 0 ? t.context : e.domElement.getContext("webgl2", n);
    function s(a) {
      a.preventDefault();
      const o = {
        api: "WebGL",
        message: a.statusMessage || "Unknown reason",
        reason: null,
        originalEvent: a
      };
      e.onDeviceLost(o);
    }
    this._onContextLost = s, e.domElement.addEventListener("webglcontextlost", s, !1), this.gl = r, this.extensions = new QG(this), this.capabilities = new JG(this), this.attributeUtils = new jG(this), this.textureUtils = new ZG(this), this.bufferRenderer = new eV(this), this.state = new YG(this), this.utils = new KG(this), this.extensions.get("EXT_color_buffer_float"), this.extensions.get("WEBGL_clip_cull_distance"), this.extensions.get("OES_texture_float_linear"), this.extensions.get("EXT_color_buffer_half_float"), this.extensions.get("WEBGL_multisampled_render_to_texture"), this.extensions.get("WEBGL_render_shared_exponent"), this.extensions.get("WEBGL_multi_draw"), this.extensions.get("OVR_multiview2"), this.extensions.get("EXT_clip_control"), this.disjoint = this.extensions.get("EXT_disjoint_timer_query_webgl2"), this.parallel = this.extensions.get("KHR_parallel_shader_compile"), this.drawBuffersIndexedExt = this.extensions.get("OES_draw_buffers_indexed"), t.reversedDepthBuffer === !0 && this.extensions.has("EXT_clip_control") && this.state.setReversedDepth(!0);
  }
  /**
   * The coordinate system of the backend.
   *
   * @type {number}
   * @readonly
   */
  get coordinateSystem() {
    return si;
  }
  /**
   * This method performs a readback operation by moving buffer data from
   * a storage buffer attribute from the GPU to the CPU.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync(e) {
    return await this.attributeUtils.getArrayBufferAsync(e);
  }
  /**
   * Ensures the backend is XR compatible.
   *
   * @async
   * @return {Promise} A Promise that resolve when the renderer is XR compatible.
   */
  async makeXRCompatible() {
    this.gl.getContextAttributes().xrCompatible !== !0 && await this.gl.makeXRCompatible();
  }
  /**
   * Sets the XR rendering destination.
   *
   * @param {WebGLFramebuffer} xrFramebuffer - The XR framebuffer.
   */
  setXRTarget(e) {
    this._xrFramebuffer = e;
  }
  /**
   * Configures the given XR render target with external textures.
   *
   * This method is only relevant when using the WebXR Layers API.
   *
   * @param {XRRenderTarget} renderTarget - The XR render target.
   * @param {WebGLTexture} colorTexture - A native color texture.
   * @param {?WebGLTexture} [depthTexture=null] - A native depth texture.
   */
  setXRRenderTargetTextures(e, t, n = null) {
    const r = this.gl;
    if (this.set(e.texture, { textureGPU: t, glInternalFormat: r.RGBA8 }), n !== null) {
      const s = e.stencilBuffer ? r.DEPTH24_STENCIL8 : r.DEPTH_COMPONENT24;
      this.set(e.depthTexture, { textureGPU: n, glInternalFormat: s }), this.extensions.has("WEBGL_multisampled_render_to_texture") === !0 && e._autoAllocateDepthBuffer === !0 && e.multiview === !1 && oe("WebGLBackend: Render-to-texture extension was disabled because an external texture was provided"), e._autoAllocateDepthBuffer = !1;
    }
  }
  /**
   * Inits a time stamp query for the given render context.
   *
   * @param {string} type - The type of the timestamp query.
   * @param {string} uid - A unique identifier for the timestamp query.
   */
  initTimestampQuery(e, t) {
    if (!this.disjoint || !this.trackTimestamp)
      return;
    this.timestampQueryPool[e] || (this.timestampQueryPool[e] = new tV(this.gl, e, 2048));
    const n = this.timestampQueryPool[e];
    n.allocateQueriesForContext(t) !== null && n.beginQuery(t);
  }
  // timestamp utils
  /**
   * Prepares the timestamp buffer.
   *
   * @param {string} type - The type of the timestamp query.
   * @param {string} uid - A unique identifier for the timestamp query.
   */
  prepareTimestampBuffer(e, t) {
    if (!this.disjoint || !this.trackTimestamp)
      return;
    this.timestampQueryPool[e].endQuery(t);
  }
  /**
   * Returns the backend's rendering context.
   *
   * @return {WebGL2RenderingContext} The rendering context.
   */
  getContext() {
    return this.gl;
  }
  /**
   * This method is executed at the beginning of a render call and prepares
   * the WebGL state for upcoming render calls
   *
   * @param {RenderContext} renderContext - The render context.
   */
  beginRender(e) {
    const { state: t } = this, n = this.get(e);
    if (e.viewport)
      this.updateViewport(e);
    else {
      const { width: s, height: a } = this.getDrawingBufferSize();
      t.viewport(0, 0, s, a);
    }
    if (e.scissor)
      this.updateScissor(e);
    else {
      const { width: s, height: a } = this.getDrawingBufferSize();
      t.scissor(0, 0, s, a);
    }
    this.initTimestampQuery(Sr.RENDER, this.getTimestampUID(e)), n.previousContext = this._currentContext, this._currentContext = e, this._setFramebuffer(e), this.clear(e.clearColor, e.clearDepth, e.clearStencil, e, !1);
    const r = e.occlusionQueryCount;
    r > 0 && (n.currentOcclusionQueries = n.occlusionQueries, n.currentOcclusionQueryObjects = n.occlusionQueryObjects, n.lastOcclusionObject = null, n.occlusionQueries = new Array(r), n.occlusionQueryObjects = new Array(r), n.occlusionQueryIndex = 0);
  }
  /**
   * This method is executed at the end of a render call and finalizes work
   * after draw calls.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  finishRender(e) {
    const { gl: t, state: n } = this, r = this.get(e), s = r.previousContext;
    n.resetVertexState();
    const a = e.occlusionQueryCount;
    a > 0 && (a > r.occlusionQueryIndex && t.endQuery(t.ANY_SAMPLES_PASSED), this.resolveOccludedAsync(e));
    const o = e.textures;
    if (o !== null)
      for (let l = 0; l < o.length; l++) {
        const c = o[l];
        c.generateMipmaps && this.generateMipmaps(c);
      }
    if (this._currentContext = s, this._resolveRenderTarget(e), s !== null) {
      if (this._setFramebuffer(s), s.viewport)
        this.updateViewport(s);
      else {
        const { width: l, height: c } = this.getDrawingBufferSize();
        n.viewport(0, 0, l, c);
      }
      if (s.scissor)
        this.updateScissor(s);
      else {
        const { width: l, height: c } = this.getDrawingBufferSize();
        n.scissor(0, 0, l, c);
      }
    }
    this.prepareTimestampBuffer(Sr.RENDER, this.getTimestampUID(e));
  }
  /**
   * This method processes the result of occlusion queries and writes it
   * into render context data.
   *
   * @async
   * @param {RenderContext} renderContext - The render context.
   */
  resolveOccludedAsync(e) {
    const t = this.get(e), { currentOcclusionQueries: n, currentOcclusionQueryObjects: r } = t;
    if (n && r) {
      const s = /* @__PURE__ */ new WeakSet(), { gl: a } = this;
      t.currentOcclusionQueryObjects = null, t.currentOcclusionQueries = null;
      const o = () => {
        let l = 0;
        for (let c = 0; c < n.length; c++) {
          const u = n[c];
          u !== null && a.getQueryParameter(u, a.QUERY_RESULT_AVAILABLE) && (a.getQueryParameter(u, a.QUERY_RESULT) === 0 && s.add(r[c]), n[c] = null, a.deleteQuery(u), l++);
        }
        l < n.length ? requestAnimationFrame(o) : t.occluded = s;
      };
      o();
    }
  }
  /**
   * Returns `true` if the given 3D object is fully occluded by other
   * 3D objects in the scene.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {Object3D} object - The 3D object to test.
   * @return {boolean} Whether the 3D object is fully occluded or not.
   */
  isOccluded(e, t) {
    const n = this.get(e);
    return n.occluded && n.occluded.has(t);
  }
  /**
   * Updates the viewport with the values from the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  updateViewport(e) {
    const { state: t } = this, { x: n, y: r, width: s, height: a } = e.viewportValue;
    t.viewport(n, e.height - a - r, s, a);
  }
  /**
   * Updates the scissor with the values from the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  updateScissor(e) {
    const { state: t } = this, { x: n, y: r, width: s, height: a } = e.scissorValue;
    t.scissor(n, e.height - a - r, s, a);
  }
  /**
   * Defines the scissor test.
   *
   * @param {boolean} boolean - Whether the scissor test should be enabled or not.
   */
  setScissorTest(e) {
    this.state.setScissorTest(e);
  }
  /**
   * Returns the clear color and alpha into a single
   * color object.
   *
   * @return {Color4} The clear color.
   */
  getClearColor() {
    const e = super.getClearColor();
    return e.r *= e.a, e.g *= e.a, e.b *= e.a, e;
  }
  /**
   * Performs a clear operation.
   *
   * @param {boolean} color - Whether the color buffer should be cleared or not.
   * @param {boolean} depth - Whether the depth buffer should be cleared or not.
   * @param {boolean} stencil - Whether the stencil buffer should be cleared or not.
   * @param {?Object} [descriptor=null] - The render context of the current set render target.
   * @param {boolean} [setFrameBuffer=true] - Controls whether the intermediate framebuffer should be set or not.
   * @param {boolean} [resolveRenderTarget=true] - Controls whether an active render target should be resolved
   * or not. Only relevant for explicit clears.
   */
  clear(e, t, n, r = null, s = !0, a = !0) {
    const { gl: o, renderer: l } = this;
    r === null && (r = {
      textures: null,
      clearColorValue: this.getClearColor()
    });
    let c = 0;
    if (e && (c |= o.COLOR_BUFFER_BIT), t && (c |= o.DEPTH_BUFFER_BIT), n && (c |= o.STENCIL_BUFFER_BIT), c !== 0) {
      let u;
      r.clearColorValue ? u = r.clearColorValue : u = this.getClearColor();
      const h = l.getClearDepth(), d = l.getClearStencil();
      if (t && this.state.setDepthMask(!0), r.textures === null)
        o.clearColor(u.r, u.g, u.b, u.a), o.clear(c);
      else {
        if (s && this._setFramebuffer(r), e)
          for (let f = 0; f < r.textures.length; f++)
            f === 0 ? o.clearBufferfv(o.COLOR, f, [u.r, u.g, u.b, u.a]) : o.clearBufferfv(o.COLOR, f, [0, 0, 0, 1]);
        t && n ? o.clearBufferfi(o.DEPTH_STENCIL, 0, h, d) : t ? o.clearBufferfv(o.DEPTH, 0, [h]) : n && o.clearBufferiv(o.STENCIL, 0, [d]), s && a && this._resolveRenderTarget(r);
      }
    }
  }
  /**
   * This method is executed at the beginning of a compute call and
   * prepares the state for upcoming compute tasks.
   *
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  beginCompute(e) {
    const { state: t, gl: n } = this;
    t.bindFramebuffer(n.FRAMEBUFFER, null), this.initTimestampQuery(Sr.COMPUTE, this.getTimestampUID(e));
  }
  /**
   * Executes a compute command for the given compute node.
   *
   * @param {Node|Array<Node>} computeGroup - The group of compute nodes of a compute call. Can be a single compute node.
   * @param {Node} computeNode - The compute node.
   * @param {Array<BindGroup>} bindings - The bindings.
   * @param {ComputePipeline} pipeline - The compute pipeline.
   * @param {?number} [count=null] - The count of compute invocations. If `null`, the count is determined by the compute node.
   */
  compute(e, t, n, r, s = null) {
    const { state: a, gl: o } = this;
    this.discard === !1 && (a.enable(o.RASTERIZER_DISCARD), this.discard = !0);
    const { programGPU: l, transformBuffers: c, attributes: u } = this.get(r), h = this._getVaoKey(u), d = this.vaoCache[h];
    d === void 0 ? this.vaoCache[h] = this._createVao(u) : a.setVertexState(d), a.useProgram(l), this._bindUniforms(n);
    const f = this._getTransformFeedback(c);
    o.bindTransformFeedback(o.TRANSFORM_FEEDBACK, f), o.beginTransformFeedback(o.POINTS), s = s !== null ? s : t.count, Array.isArray(s) ? (Pt("WebGLBackend.compute(): The count parameter must be a single number, not an array."), s = s[0]) : s && typeof s == "object" && s.isIndirectStorageBufferAttribute && (Pt("WebGLBackend.compute(): The count parameter must be a single number, not IndirectStorageBufferAttribute"), s = t.count), u[0].isStorageInstancedBufferAttribute ? o.drawArraysInstanced(o.POINTS, 0, 1, s) : o.drawArrays(o.POINTS, 0, s), o.endTransformFeedback(), o.bindTransformFeedback(o.TRANSFORM_FEEDBACK, null);
    for (let p = 0; p < c.length; p++) {
      const _ = c[p];
      _.pbo && this.has(_.pbo) && this.textureUtils.copyBufferToTexture(_.transformBuffer, _.pbo), _.switchBuffers();
    }
  }
  /**
   * This method is executed at the end of a compute call and
   * finalizes work after compute tasks.
   *
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  finishCompute(e) {
    const { state: t, gl: n } = this;
    this.discard = !1, t.disable(n.RASTERIZER_DISCARD), this.prepareTimestampBuffer(Sr.COMPUTE, this.getTimestampUID(e)), this._currentContext && this._setFramebuffer(this._currentContext);
  }
  /**
   * Internal to determine if the current render target is a render target array with depth 2D array texture.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {boolean} Whether the render target is a render target array with depth 2D array texture.
   *
   * @private
   */
  _isRenderCameraDepthArray(e) {
    return e.depthTexture && e.depthTexture.isArrayTexture && e.camera.isArrayCamera;
  }
  /**
   * Executes a draw command for the given render object.
   *
   * @param {RenderObject} renderObject - The render object to draw.
   * @param {Info} info - Holds a series of statistical information about the GPU memory and the rendering process.
   */
  draw(e) {
    const { object: t, pipeline: n, material: r, context: s, hardwareClippingPlanes: a } = e, { programGPU: o } = this.get(n), { gl: l, state: c } = this, u = this.get(s), h = e.getDrawParameters();
    if (h === null)
      return;
    this._bindUniforms(e.getBindings());
    const d = t.isMesh && t.matrixWorld.determinant() < 0;
    c.setMaterial(r, d, a), s.mrt !== null && s.textures !== null && c.setMRTBlending(s.textures, s.mrt, r), c.useProgram(o);
    const f = e.getAttributes(), p = this.get(f);
    let _ = p.vaoGPU;
    if (_ === void 0) {
      const v = this._getVaoKey(f);
      _ = this.vaoCache[v], _ === void 0 && (_ = this._createVao(f), this.vaoCache[v] = _, p.vaoGPU = _);
    }
    const g = e.getIndex(), m = g !== null ? this.get(g).bufferGPU : null;
    c.setVertexState(_, m);
    const x = u.lastOcclusionObject;
    if (x !== t && x !== void 0) {
      if (x !== null && x.occlusionTest === !0 && (l.endQuery(l.ANY_SAMPLES_PASSED), u.occlusionQueryIndex++), t.occlusionTest === !0) {
        const v = l.createQuery();
        l.beginQuery(l.ANY_SAMPLES_PASSED, v), u.occlusionQueries[u.occlusionQueryIndex] = v, u.occlusionQueryObjects[u.occlusionQueryIndex] = t;
      }
      u.lastOcclusionObject = t;
    }
    const y = this.bufferRenderer;
    t.isPoints ? y.mode = l.POINTS : t.isLineSegments ? y.mode = l.LINES : t.isLine ? y.mode = l.LINE_STRIP : t.isLineLoop ? y.mode = l.LINE_LOOP : r.wireframe === !0 ? (c.setLineWidth(r.wireframeLinewidth * this.renderer.getPixelRatio()), y.mode = l.LINES) : y.mode = l.TRIANGLES;
    const { vertexCount: b, instanceCount: T } = h;
    let { firstVertex: S } = h;
    if (y.object = t, g !== null) {
      S *= g.array.BYTES_PER_ELEMENT;
      const v = this.get(g);
      y.index = g.count, y.type = v.type;
    } else
      y.index = 0;
    const E = () => {
      t.isBatchedMesh ? t._multiDrawInstances !== null ? (Pt("WebGLBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."), y.renderMultiDrawInstances(t._multiDrawStarts, t._multiDrawCounts, t._multiDrawCount, t._multiDrawInstances)) : this.hasFeature("WEBGL_multi_draw") ? y.renderMultiDraw(t._multiDrawStarts, t._multiDrawCounts, t._multiDrawCount) : Pt("WebGLBackend: WEBGL_multi_draw not supported.") : T > 1 ? y.renderInstances(S, b, T) : y.render(S, b);
    };
    if (e.camera.isArrayCamera === !0 && e.camera.cameras.length > 0 && e.camera.isMultiViewCamera === !1) {
      const v = this.get(e.camera), M = e.camera.cameras, F = e.getBindingGroup("cameraIndex").bindings[0];
      if (v.indexesGPU === void 0 || v.indexesGPU.length !== M.length) {
        const L = new Uint32Array([0, 0, 0, 0]), k = [];
        for (let re = 0, se = M.length; re < se; re++) {
          const ve = l.createBuffer();
          L[0] = re, l.bindBuffer(l.UNIFORM_BUFFER, ve), l.bufferData(l.UNIFORM_BUFFER, L, l.STATIC_DRAW), k.push(ve);
        }
        v.indexesGPU = k;
      }
      const R = this.get(F), I = this.renderer.getPixelRatio(), B = this._currentContext.renderTarget, N = this._isRenderCameraDepthArray(this._currentContext), C = this._currentContext.activeCubeFace;
      if (N) {
        const L = this.get(B.depthTexture);
        if (L.clearedRenderId !== this.renderer._nodes.nodeFrame.renderId) {
          L.clearedRenderId = this.renderer._nodes.nodeFrame.renderId;
          const { stencilBuffer: k } = B;
          for (let re = 0, se = M.length; re < se; re++)
            this.renderer._activeCubeFace = re, this._currentContext.activeCubeFace = re, this._setFramebuffer(this._currentContext), this.clear(!1, !0, k, this._currentContext, !1, !1);
          this.renderer._activeCubeFace = C, this._currentContext.activeCubeFace = C;
        }
      }
      for (let L = 0, k = M.length; L < k; L++) {
        const re = M[L];
        if (t.layers.test(re.layers)) {
          N && (this.renderer._activeCubeFace = L, this._currentContext.activeCubeFace = L, this._setFramebuffer(this._currentContext));
          const se = re.viewport;
          if (se !== void 0) {
            const ve = se.x * I, X = se.y * I, te = se.width * I, me = se.height * I;
            c.viewport(
              Math.floor(ve),
              Math.floor(e.context.height - me - X),
              Math.floor(te),
              Math.floor(me)
            );
          }
          c.bindBufferBase(l.UNIFORM_BUFFER, R.index, v.indexesGPU[L]), E();
        }
        this._currentContext.activeCubeFace = C, this.renderer._activeCubeFace = C;
      }
    } else
      E();
  }
  /**
   * Explain why always null is returned.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the render pipeline requires an update or not.
   */
  needsRenderUpdate() {
    return !1;
  }
  /**
   * Explain why no cache key is computed.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {string} The cache key.
   */
  getRenderCacheKey() {
    return "";
  }
  // textures
  /**
   * Creates a default texture for the given texture that can be used
   * as a placeholder until the actual texture is ready for usage.
   *
   * @param {Texture} texture - The texture to create a default texture for.
   */
  createDefaultTexture(e) {
    this.textureUtils.createDefaultTexture(e);
  }
  /**
   * Defines a texture on the GPU for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  createTexture(e, t) {
    this.textureUtils.createTexture(e, t);
  }
  /**
   * Uploads the updated texture data to the GPU.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  updateTexture(e, t) {
    this.textureUtils.updateTexture(e, t);
  }
  /**
   * Generates mipmaps for the given texture.
   *
   * @param {Texture} texture - The texture.
   */
  generateMipmaps(e) {
    this.textureUtils.generateMipmaps(e);
  }
  /**
   * Destroys the GPU data for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {boolean} [isDefaultTexture=false] - Whether the texture uses a default GPU texture or not.
   */
  destroyTexture(e, t = !1) {
    this.textureUtils.destroyTexture(e, t);
  }
  /**
   * Returns texture data as a typed array.
   *
   * @async
   * @param {Texture} texture - The texture to copy.
   * @param {number} x - The x coordinate of the copy origin.
   * @param {number} y - The y coordinate of the copy origin.
   * @param {number} width - The width of the copy.
   * @param {number} height - The height of the copy.
   * @param {number} faceIndex - The face index.
   * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
   */
  async copyTextureToBuffer(e, t, n, r, s, a) {
    return this.textureUtils.copyTextureToBuffer(e, t, n, r, s, a);
  }
  /**
   * This method does nothing since WebGL 2 has no concept of samplers.
   *
   * @param {Texture} texture - The texture to update the sampler for.
   * @return {string} The current sampler key.
   */
  updateSampler() {
    return "";
  }
  // node builder
  /**
   * Returns a node builder for the given render object.
   *
   * @param {RenderObject} object - The render object.
   * @param {Renderer} renderer - The renderer.
   * @return {GLSLNodeBuilder} The node builder.
   */
  createNodeBuilder(e, t) {
    return new WG(e, t);
  }
  // program
  /**
   * Creates a shader program from the given programmable stage.
   *
   * @param {ProgrammableStage} program - The programmable stage.
   */
  createProgram(e) {
    const t = this.gl, { stage: n, code: r } = e, s = n === "fragment" ? t.createShader(t.FRAGMENT_SHADER) : t.createShader(t.VERTEX_SHADER);
    t.shaderSource(s, r), t.compileShader(s), this.set(e, {
      shaderGPU: s
    });
  }
  /**
   * Destroys the shader program of the given programmable stage.
   *
   * @param {ProgrammableStage} program - The programmable stage.
   */
  destroyProgram(e) {
    this.delete(e);
  }
  /**
   * Creates a render pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {Array<Promise>} promises - An array of compilation promises which are used in `compileAsync()`.
   */
  createRenderPipeline(e, t) {
    const n = this.gl, r = e.pipeline, { fragmentProgram: s, vertexProgram: a } = r, o = n.createProgram(), l = this.get(s).shaderGPU, c = this.get(a).shaderGPU;
    if (n.attachShader(o, l), n.attachShader(o, c), n.linkProgram(o), this.set(r, {
      programGPU: o,
      fragmentShader: l,
      vertexShader: c
    }), t !== null && this.parallel) {
      const u = new Promise((h) => {
        const d = this.parallel, f = () => {
          n.getProgramParameter(o, d.COMPLETION_STATUS_KHR) ? (this._completeCompile(e, r), h()) : requestAnimationFrame(f);
        };
        f();
      });
      t.push(u);
      return;
    }
    this._completeCompile(e, r);
  }
  /**
   * Formats the source code of error messages.
   *
   * @private
   * @param {string} string - The code.
   * @param {number} errorLine - The error line.
   * @return {string} The formatted code.
   */
  _handleSource(e, t) {
    const n = e.split(`
`), r = [], s = Math.max(t - 6, 0), a = Math.min(t + 6, n.length);
    for (let o = s; o < a; o++) {
      const l = o + 1;
      r.push(`${l === t ? ">" : " "} ${l}: ${n[o]}`);
    }
    return r.join(`
`);
  }
  /**
   * Gets the shader compilation errors from the info log.
   *
   * @private
   * @param {WebGL2RenderingContext} gl - The rendering context.
   * @param {WebGLShader} shader - The WebGL shader object.
   * @param {string} type - The shader type.
   * @return {string} The shader errors.
   */
  _getShaderErrors(e, t, n) {
    const r = e.getShaderParameter(t, e.COMPILE_STATUS), a = (e.getShaderInfoLog(t) || "").trim();
    if (r && a === "")
      return "";
    const o = /ERROR: 0:(\d+)/.exec(a);
    if (o) {
      const l = parseInt(o[1]);
      return n.toUpperCase() + `

` + a + `

` + this._handleSource(e.getShaderSource(t), l);
    } else
      return a;
  }
  /**
   * Logs shader compilation errors.
   *
   * @private
   * @param {WebGLProgram} programGPU - The WebGL program.
   * @param {WebGLShader} glFragmentShader - The fragment shader as a native WebGL shader object.
   * @param {WebGLShader} glVertexShader - The vertex shader as a native WebGL shader object.
   */
  _logProgramError(e, t, n) {
    if (this.renderer.debug.checkShaderErrors) {
      const r = this.gl, a = (r.getProgramInfoLog(e) || "").trim();
      if (r.getProgramParameter(e, r.LINK_STATUS) === !1)
        if (typeof this.renderer.debug.onShaderError == "function")
          this.renderer.debug.onShaderError(r, e, n, t);
        else {
          const o = this._getShaderErrors(r, n, "vertex"), l = this._getShaderErrors(r, t, "fragment");
          le(
            "THREE.WebGLProgram: Shader Error " + r.getError() + " - VALIDATE_STATUS " + r.getProgramParameter(e, r.VALIDATE_STATUS) + `

Program Info Log: ` + a + `
` + o + `
` + l
          );
        }
      else
        a !== "" && oe("WebGLProgram: Program Info Log:", a);
    }
  }
  /**
   * Completes the shader program setup for the given render object.
   *
   * @private
   * @param {RenderObject} renderObject - The render object.
   * @param {RenderPipeline} pipeline - The render pipeline.
   */
  _completeCompile(e, t) {
    const { state: n, gl: r } = this, s = this.get(t), { programGPU: a, fragmentShader: o, vertexShader: l } = s;
    r.getProgramParameter(a, r.LINK_STATUS) === !1 && this._logProgramError(a, o, l), n.useProgram(a);
    const c = e.getBindings();
    this._setupBindings(c, a), this.set(t, {
      programGPU: a
    });
  }
  /**
   * Creates a compute pipeline for the given compute node.
   *
   * @param {ComputePipeline} computePipeline - The compute pipeline.
   * @param {Array<BindGroup>} bindings - The bindings.
   */
  createComputePipeline(e, t) {
    const { state: n, gl: r } = this, s = {
      stage: "fragment",
      code: `#version 300 es
precision highp float;
void main() {}`
    };
    this.createProgram(s);
    const { computeProgram: a } = e, o = r.createProgram(), l = this.get(s).shaderGPU, c = this.get(a).shaderGPU, u = a.transforms, h = [], d = [];
    for (let g = 0; g < u.length; g++) {
      const m = u[g];
      h.push(m.varyingName), d.push(m.attributeNode);
    }
    r.attachShader(o, l), r.attachShader(o, c), r.transformFeedbackVaryings(
      o,
      h,
      r.SEPARATE_ATTRIBS
    ), r.linkProgram(o), r.getProgramParameter(o, r.LINK_STATUS) === !1 && this._logProgramError(o, l, c), n.useProgram(o), this._setupBindings(t, o);
    const f = a.attributes, p = [], _ = [];
    for (let g = 0; g < f.length; g++) {
      const m = f[g].node.attribute;
      p.push(m), this.has(m) || this.attributeUtils.createAttribute(m, r.ARRAY_BUFFER);
    }
    for (let g = 0; g < d.length; g++) {
      const m = d[g].attribute;
      this.has(m) || this.attributeUtils.createAttribute(m, r.ARRAY_BUFFER);
      const x = this.get(m);
      _.push(x);
    }
    this.set(e, {
      programGPU: o,
      transformBuffers: _,
      attributes: p
    });
  }
  /**
   * Creates bindings from the given bind group definition.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  createBindings(e, t) {
    if (this._knownBindings.has(t) === !1) {
      this._knownBindings.add(t);
      let n = 0, r = 0;
      for (const s of t) {
        this.set(s, {
          textures: r,
          uniformBuffers: n
        });
        for (const a of s.bindings)
          a.isUniformBuffer && n++, a.isSampledTexture && r++;
      }
    }
    this.updateBindings(e, t);
  }
  /**
   * Updates the given bind group definition.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  updateBindings(e) {
    const { gl: t } = this, n = this.get(e);
    let r = n.uniformBuffers, s = n.textures;
    for (const a of e.bindings) {
      const o = this.get(a);
      if (a.isUniformsGroup || a.isUniformBuffer) {
        const l = a.buffer;
        let { bufferGPU: c } = this.get(l);
        c === void 0 ? (c = t.createBuffer(), t.bindBuffer(t.UNIFORM_BUFFER, c), t.bufferData(t.UNIFORM_BUFFER, l.byteLength, t.DYNAMIC_DRAW), this.set(l, { bufferGPU: c })) : t.bindBuffer(t.UNIFORM_BUFFER, c);
        const u = a.updateRanges;
        if (t.bindBuffer(t.UNIFORM_BUFFER, c), u.length === 0)
          t.bufferData(t.UNIFORM_BUFFER, l, t.DYNAMIC_DRAW);
        else {
          const h = Lh(l), d = h ? 1 : l.BYTES_PER_ELEMENT;
          for (let f = 0, p = u.length; f < p; f++) {
            const _ = u[f], g = _.start * d, m = _.count * d, x = g * (h ? l.BYTES_PER_ELEMENT : 1);
            t.bufferSubData(t.UNIFORM_BUFFER, x, l, g, m);
          }
        }
        o.index = r++, o.bufferGPU = c, this.set(a, o);
      } else if (a.isSampledTexture) {
        const { textureGPU: l, glTextureType: c } = this.get(a.texture);
        o.index = s++, o.textureGPU = l, o.glTextureType = c, this.set(a, o);
      }
    }
  }
  /**
   * Updates a buffer binding.
   *
   *  @param {Buffer} binding - The buffer binding to update.
   */
  updateBinding(e) {
    const t = this.gl;
    if (e.isUniformsGroup || e.isUniformBuffer) {
      const r = this.get(e).bufferGPU, s = e.buffer, a = e.updateRanges;
      if (t.bindBuffer(t.UNIFORM_BUFFER, r), a.length === 0)
        t.bufferData(t.UNIFORM_BUFFER, s, t.DYNAMIC_DRAW);
      else {
        const o = Lh(s), l = o ? 1 : s.BYTES_PER_ELEMENT;
        for (let c = 0, u = a.length; c < u; c++) {
          const h = a[c], d = h.start * l, f = h.count * l, p = d * (o ? s.BYTES_PER_ELEMENT : 1);
          t.bufferSubData(t.UNIFORM_BUFFER, p, s, d, f);
        }
      }
    }
  }
  // attributes
  /**
   * Creates the GPU buffer of an indexed shader attribute.
   *
   * @param {BufferAttribute} attribute - The indexed buffer attribute.
   */
  createIndexAttribute(e) {
    const t = this.gl;
    this.attributeUtils.createAttribute(e, t.ELEMENT_ARRAY_BUFFER);
  }
  /**
   * Creates the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createAttribute(e) {
    if (this.has(e))
      return;
    const t = this.gl;
    this.attributeUtils.createAttribute(e, t.ARRAY_BUFFER);
  }
  /**
   * Creates the GPU buffer of a storage attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createStorageAttribute(e) {
    if (this.has(e))
      return;
    const t = this.gl;
    this.attributeUtils.createAttribute(e, t.ARRAY_BUFFER);
  }
  /**
   * Updates the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute to update.
   */
  updateAttribute(e) {
    this.attributeUtils.updateAttribute(e);
  }
  /**
   * Destroys the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute to destroy.
   */
  destroyAttribute(e) {
    this.attributeUtils.destroyAttribute(e);
  }
  /**
   * Checks if the given feature is supported  by the backend.
   *
   * @param {string} name - The feature's name.
   * @return {boolean} Whether the feature is supported or not.
   */
  hasFeature(e) {
    const t = Object.keys(uv).filter((r) => uv[r] === e), n = this.extensions;
    for (let r = 0; r < t.length; r++)
      if (n.has(t[r]))
        return !0;
    return !1;
  }
  /**
   * Returns the maximum anisotropy texture filtering value.
   *
   * @return {number} The maximum anisotropy texture filtering value.
   */
  getMaxAnisotropy() {
    return this.capabilities.getMaxAnisotropy();
  }
  /**
   * Copies data of the given source texture to the given destination texture.
   *
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy.
   * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
   * @param {number} [srcLevel=0] - The source mip level to copy from.
   * @param {number} [dstLevel=0] - The destination mip level to copy to.
   */
  copyTextureToTexture(e, t, n = null, r = null, s = 0, a = 0) {
    this.textureUtils.copyTextureToTexture(e, t, n, r, s, a);
  }
  /**
   * Copies the current bound framebuffer to the given texture.
   *
   * @param {Texture} texture - The destination texture.
   * @param {RenderContext} renderContext - The render context.
   * @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy.
   */
  copyFramebufferToTexture(e, t, n) {
    this.textureUtils.copyFramebufferToTexture(e, t, n);
  }
  /**
   * Checks if the given compatibility is supported by the backend.
   *
   * @param {string} name - The compatibility name.
   * @return {boolean} Whether the compatibility is supported or not.
   */
  hasCompatibility(e) {
    return e === rs.TEXTURE_COMPARE ? !0 : super.hasCompatibility(e);
  }
  /**
   * Initializes the render target defined in the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  initRenderTarget(e) {
    const { gl: t, state: n } = this;
    this._setFramebuffer(e), n.bindFramebuffer(t.FRAMEBUFFER, null);
  }
  /**
   * Configures the active framebuffer from the given render context.
   *
   * @private
   * @param {RenderContext} descriptor - The render context.
   */
  _setFramebuffer(e) {
    const { gl: t, state: n } = this;
    let r = null;
    if (e.textures !== null) {
      const s = e.renderTarget, a = this.get(s), { samples: o, depthBuffer: l, stencilBuffer: c } = s, u = s.isCubeRenderTarget === !0, h = s.isRenderTarget3D === !0, d = s.depth > 1, f = s.isXRRenderTarget === !0, p = f === !0 && s._hasExternalTextures === !0;
      let _ = a.msaaFrameBuffer, g = a.depthRenderbuffer;
      const m = this.extensions.get("WEBGL_multisampled_render_to_texture"), x = this.extensions.get("OVR_multiview2"), y = this._useMultisampledExtension(s), b = KS(e);
      let T;
      if (u ? (a.cubeFramebuffers || (a.cubeFramebuffers = {}), T = a.cubeFramebuffers[b]) : f && p === !1 ? T = this._xrFramebuffer : (a.framebuffers || (a.framebuffers = {}), T = a.framebuffers[b]), T === void 0) {
        T = t.createFramebuffer(), n.bindFramebuffer(t.FRAMEBUFFER, T);
        const S = e.textures, E = [];
        if (u) {
          a.cubeFramebuffers[b] = T;
          const { textureGPU: M } = this.get(S[0]), F = this.renderer._activeCubeFace, R = this.renderer._activeMipmapLevel;
          t.framebufferTexture2D(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_CUBE_MAP_POSITIVE_X + F, M, R);
        } else {
          a.framebuffers[b] = T;
          for (let M = 0; M < S.length; M++) {
            const F = S[M], R = this.get(F);
            R.renderTarget = e.renderTarget, R.cacheKey = b;
            const I = t.COLOR_ATTACHMENT0 + M;
            if (s.multiview)
              x.framebufferTextureMultisampleMultiviewOVR(t.FRAMEBUFFER, I, R.textureGPU, 0, o, 0, 2);
            else if (h || d) {
              const B = this.renderer._activeCubeFace, N = this.renderer._activeMipmapLevel;
              t.framebufferTextureLayer(t.FRAMEBUFFER, I, R.textureGPU, N, B);
            } else if (y)
              m.framebufferTexture2DMultisampleEXT(t.FRAMEBUFFER, I, t.TEXTURE_2D, R.textureGPU, 0, o);
            else {
              const B = this.renderer._activeMipmapLevel;
              t.framebufferTexture2D(t.FRAMEBUFFER, I, t.TEXTURE_2D, R.textureGPU, B);
            }
          }
        }
        const v = c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT;
        if (s._autoAllocateDepthBuffer === !0) {
          const M = t.createRenderbuffer();
          this.textureUtils.setupRenderBufferStorage(M, e, 0, y), a.xrDepthRenderbuffer = M, E.push(c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT), t.bindRenderbuffer(t.RENDERBUFFER, M), t.framebufferRenderbuffer(t.FRAMEBUFFER, v, t.RENDERBUFFER, M);
        } else if (e.depthTexture !== null) {
          E.push(c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT);
          const M = this.get(e.depthTexture);
          if (M.renderTarget = e.renderTarget, M.cacheKey = b, s.multiview)
            x.framebufferTextureMultisampleMultiviewOVR(t.FRAMEBUFFER, v, M.textureGPU, 0, o, 0, 2);
          else if (p && y)
            m.framebufferTexture2DMultisampleEXT(t.FRAMEBUFFER, v, t.TEXTURE_2D, M.textureGPU, 0, o);
          else if (e.depthTexture.isArrayTexture) {
            const F = this.renderer._activeCubeFace;
            t.framebufferTextureLayer(t.FRAMEBUFFER, v, M.textureGPU, 0, F);
          } else if (e.depthTexture.isCubeTexture) {
            const F = this.renderer._activeCubeFace;
            t.framebufferTexture2D(t.FRAMEBUFFER, v, t.TEXTURE_CUBE_MAP_POSITIVE_X + F, M.textureGPU, 0);
          } else
            t.framebufferTexture2D(t.FRAMEBUFFER, v, t.TEXTURE_2D, M.textureGPU, 0);
        }
        a.depthInvalidationArray = E;
      } else {
        if (this._isRenderCameraDepthArray(e)) {
          n.bindFramebuffer(t.FRAMEBUFFER, T);
          const E = this.renderer._activeCubeFace, v = this.get(e.depthTexture), M = c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT;
          t.framebufferTextureLayer(
            t.FRAMEBUFFER,
            M,
            v.textureGPU,
            0,
            E
          );
        }
        if ((f || y || s.multiview) && s._isOpaqueFramebuffer !== !0) {
          n.bindFramebuffer(t.FRAMEBUFFER, T);
          const E = this.get(e.textures[0]);
          s.multiview ? x.framebufferTextureMultisampleMultiviewOVR(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, E.textureGPU, 0, o, 0, 2) : y ? m.framebufferTexture2DMultisampleEXT(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_2D, E.textureGPU, 0, o) : t.framebufferTexture2D(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_2D, E.textureGPU, 0);
          const v = c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT;
          if (s._autoAllocateDepthBuffer === !0) {
            const M = a.xrDepthRenderbuffer;
            t.bindRenderbuffer(t.RENDERBUFFER, M), t.framebufferRenderbuffer(t.FRAMEBUFFER, v, t.RENDERBUFFER, M);
          } else {
            const M = this.get(e.depthTexture);
            s.multiview ? x.framebufferTextureMultisampleMultiviewOVR(t.FRAMEBUFFER, v, M.textureGPU, 0, o, 0, 2) : y ? m.framebufferTexture2DMultisampleEXT(t.FRAMEBUFFER, v, t.TEXTURE_2D, M.textureGPU, 0, o) : t.framebufferTexture2D(t.FRAMEBUFFER, v, t.TEXTURE_2D, M.textureGPU, 0);
          }
        }
      }
      if (o > 0 && y === !1 && !s.multiview) {
        if (_ === void 0) {
          const S = [];
          _ = t.createFramebuffer(), n.bindFramebuffer(t.FRAMEBUFFER, _);
          const E = [], v = e.textures;
          for (let M = 0; M < v.length; M++) {
            E[M] = t.createRenderbuffer(), t.bindRenderbuffer(t.RENDERBUFFER, E[M]), S.push(t.COLOR_ATTACHMENT0 + M);
            const F = e.textures[M], R = this.get(F);
            t.renderbufferStorageMultisample(t.RENDERBUFFER, o, R.glInternalFormat, e.width, e.height), t.framebufferRenderbuffer(t.FRAMEBUFFER, t.COLOR_ATTACHMENT0 + M, t.RENDERBUFFER, E[M]);
          }
          if (t.bindRenderbuffer(t.RENDERBUFFER, null), a.msaaFrameBuffer = _, a.msaaRenderbuffers = E, l && g === void 0) {
            g = t.createRenderbuffer(), this.textureUtils.setupRenderBufferStorage(g, e, o), a.depthRenderbuffer = g;
            const M = c ? t.DEPTH_STENCIL_ATTACHMENT : t.DEPTH_ATTACHMENT;
            S.push(M);
          }
          a.invalidationArray = S;
        }
        r = a.msaaFrameBuffer;
      } else
        r = T;
      n.drawBuffers(e, T);
    }
    n.bindFramebuffer(t.FRAMEBUFFER, r);
  }
  /**
   * Computes the VAO key for the given index and attributes.
   *
   * @private
   * @param {Array<BufferAttribute>} attributes - An array of buffer attributes.
   * @return {string} The VAO key.
   */
  _getVaoKey(e) {
    let t = "";
    for (let n = 0; n < e.length; n++) {
      const r = this.get(e[n]);
      t += ":" + r.id;
    }
    return t;
  }
  /**
   * Creates a VAO from the index and attributes.
   *
   * @private
   * @param {Array<BufferAttribute>} attributes - An array of buffer attributes.
   * @return {Object} The VAO data.
   */
  _createVao(e) {
    const { gl: t } = this, n = t.createVertexArray();
    t.bindVertexArray(n);
    for (let r = 0; r < e.length; r++) {
      const s = e[r], a = this.get(s);
      t.bindBuffer(t.ARRAY_BUFFER, a.bufferGPU), t.enableVertexAttribArray(r);
      let o, l;
      s.isInterleavedBufferAttribute === !0 ? (o = s.data.stride * a.bytesPerElement, l = s.offset * a.bytesPerElement) : (o = 0, l = 0), a.isInteger ? t.vertexAttribIPointer(r, s.itemSize, a.type, o, l) : t.vertexAttribPointer(r, s.itemSize, a.type, s.normalized, o, l), s.isInstancedBufferAttribute && !s.isInterleavedBufferAttribute ? t.vertexAttribDivisor(r, s.meshPerAttribute) : s.isInterleavedBufferAttribute && s.data.isInstancedInterleavedBuffer && t.vertexAttribDivisor(r, s.data.meshPerAttribute);
    }
    return t.bindBuffer(t.ARRAY_BUFFER, null), n;
  }
  /**
   * Creates a transform feedback from the given transform buffers.
   *
   * @private
   * @param {Array<DualAttributeData>} transformBuffers - The transform buffers.
   * @return {WebGLTransformFeedback} The transform feedback.
   */
  _getTransformFeedback(e) {
    let t = "";
    for (let s = 0; s < e.length; s++)
      t += ":" + e[s].id;
    let n = this.transformFeedbackCache[t];
    if (n !== void 0)
      return n;
    const { gl: r } = this;
    n = r.createTransformFeedback(), r.bindTransformFeedback(r.TRANSFORM_FEEDBACK, n);
    for (let s = 0; s < e.length; s++) {
      const a = e[s];
      r.bindBufferBase(r.TRANSFORM_FEEDBACK_BUFFER, s, a.transformBuffer);
    }
    return r.bindTransformFeedback(r.TRANSFORM_FEEDBACK, null), this.transformFeedbackCache[t] = n, n;
  }
  /**
   * Setups the given bindings.
   *
   * @private
   * @param {Array<BindGroup>} bindings - The bindings.
   * @param {WebGLProgram} programGPU - The WebGL program.
   */
  _setupBindings(e, t) {
    const n = this.gl;
    for (const r of e)
      for (const s of r.bindings) {
        const o = this.get(s).index;
        if (s.isUniformsGroup || s.isUniformBuffer) {
          const l = n.getUniformBlockIndex(t, s.name);
          n.uniformBlockBinding(t, l, o);
        } else if (s.isSampledTexture) {
          const l = n.getUniformLocation(t, s.name);
          n.uniform1i(l, o);
        }
      }
  }
  /**
   * Binds the given uniforms.
   *
   * @private
   * @param {Array<BindGroup>} bindings - The bindings.
   */
  _bindUniforms(e) {
    const { gl: t, state: n } = this;
    for (const r of e)
      for (const s of r.bindings) {
        const a = this.get(s), o = a.index;
        s.isUniformsGroup || s.isUniformBuffer ? n.bindBufferBase(t.UNIFORM_BUFFER, o, a.bufferGPU) : s.isSampledTexture && n.bindTexture(a.glTextureType, a.textureGPU, t.TEXTURE0 + o);
      }
  }
  /**
   * The method ensures multisampled render targets are resolved.
   *
   * @private
   * @param {RenderContext} renderContext - The render context.
   */
  _resolveRenderTarget(e) {
    const { gl: t, state: n } = this, r = e.renderTarget;
    if (e.textures !== null && r) {
      const s = this.get(r);
      if (r.samples > 0 && this._useMultisampledExtension(r) === !1) {
        const a = s.framebuffers[e.getCacheKey()];
        let o = t.COLOR_BUFFER_BIT;
        r.resolveDepthBuffer && (r.depthBuffer && (o |= t.DEPTH_BUFFER_BIT), r.stencilBuffer && r.resolveStencilBuffer && (o |= t.STENCIL_BUFFER_BIT));
        const l = s.msaaFrameBuffer, c = s.msaaRenderbuffers, u = e.textures, h = u.length > 1;
        if (n.bindFramebuffer(t.READ_FRAMEBUFFER, l), n.bindFramebuffer(t.DRAW_FRAMEBUFFER, a), h)
          for (let d = 0; d < u.length; d++)
            t.framebufferRenderbuffer(t.READ_FRAMEBUFFER, t.COLOR_ATTACHMENT0 + d, t.RENDERBUFFER, null), t.framebufferTexture2D(t.DRAW_FRAMEBUFFER, t.COLOR_ATTACHMENT0 + d, t.TEXTURE_2D, null, 0);
        for (let d = 0; d < u.length; d++) {
          if (h) {
            const { textureGPU: f } = this.get(u[d]);
            t.framebufferRenderbuffer(t.READ_FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.RENDERBUFFER, c[d]), t.framebufferTexture2D(t.DRAW_FRAMEBUFFER, t.COLOR_ATTACHMENT0, t.TEXTURE_2D, f, 0);
          }
          if (e.scissor) {
            const { x: f, y: p, width: _, height: g } = e.scissorValue, m = e.height - g - p;
            t.blitFramebuffer(f, m, f + _, m + g, f, m, f + _, m + g, o, t.NEAREST);
          } else
            t.blitFramebuffer(0, 0, e.width, e.height, 0, 0, e.width, e.height, o, t.NEAREST);
        }
        if (h)
          for (let d = 0; d < u.length; d++) {
            const { textureGPU: f } = this.get(u[d]);
            t.framebufferRenderbuffer(t.READ_FRAMEBUFFER, t.COLOR_ATTACHMENT0 + d, t.RENDERBUFFER, c[d]), t.framebufferTexture2D(t.DRAW_FRAMEBUFFER, t.COLOR_ATTACHMENT0 + d, t.TEXTURE_2D, f, 0);
          }
        this._supportsInvalidateFramebuffer === !0 && t.invalidateFramebuffer(t.READ_FRAMEBUFFER, s.invalidationArray);
      } else if (r.resolveDepthBuffer === !1 && s.framebuffers) {
        const a = s.framebuffers[e.getCacheKey()];
        n.bindFramebuffer(t.DRAW_FRAMEBUFFER, a), t.invalidateFramebuffer(t.DRAW_FRAMEBUFFER, s.depthInvalidationArray);
      }
    }
  }
  /**
   * Returns `true` if the `WEBGL_multisampled_render_to_texture` extension
   * should be used when MSAA is enabled.
   *
   * @private
   * @param {RenderTarget} renderTarget - The render target that should be multisampled.
   * @return {boolean} Whether to use the `WEBGL_multisampled_render_to_texture` extension for MSAA or not.
   */
  _useMultisampledExtension(e) {
    return e.multiview === !0 ? !0 : e.samples > 0 && this.extensions.has("WEBGL_multisampled_render_to_texture") === !0 && e._autoAllocateDepthBuffer !== !1;
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this.textureUtils !== null && this.textureUtils.dispose();
    const e = this.extensions.get("WEBGL_lose_context");
    e && e.loseContext(), this.renderer.domElement.removeEventListener("webglcontextlost", this._onContextLost);
  }
}
const dh = {
  PointList: "point-list",
  LineList: "line-list",
  LineStrip: "line-strip",
  TriangleList: "triangle-list"
}, Tr = typeof self < "u" && self.GPUShaderStage ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 }, Ln = {
  Never: "never",
  Less: "less",
  Equal: "equal",
  LessEqual: "less-equal",
  Greater: "greater",
  NotEqual: "not-equal",
  GreaterEqual: "greater-equal",
  Always: "always"
}, Qn = {
  Store: "store"
}, wt = {
  Load: "load",
  Clear: "clear"
}, dv = {
  CCW: "ccw",
  CW: "cw"
}, fv = {
  None: "none",
  Back: "back"
}, Zh = {
  Uint16: "uint16",
  Uint32: "uint32"
}, U = {
  // 8-bit formats
  R8Unorm: "r8unorm",
  R8Snorm: "r8snorm",
  R8Uint: "r8uint",
  R8Sint: "r8sint",
  // 16-bit formats
  R16Uint: "r16uint",
  R16Sint: "r16sint",
  R16Float: "r16float",
  RG8Unorm: "rg8unorm",
  RG8Snorm: "rg8snorm",
  RG8Uint: "rg8uint",
  RG8Sint: "rg8sint",
  // 32-bit formats
  R32Uint: "r32uint",
  R32Sint: "r32sint",
  R32Float: "r32float",
  RG16Uint: "rg16uint",
  RG16Sint: "rg16sint",
  RG16Float: "rg16float",
  RGBA8Unorm: "rgba8unorm",
  RGBA8UnormSRGB: "rgba8unorm-srgb",
  RGBA8Snorm: "rgba8snorm",
  RGBA8Uint: "rgba8uint",
  RGBA8Sint: "rgba8sint",
  BGRA8Unorm: "bgra8unorm",
  BGRA8UnormSRGB: "bgra8unorm-srgb",
  // Packed 32-bit formats
  RGB9E5UFloat: "rgb9e5ufloat",
  RGB10A2Unorm: "rgb10a2unorm",
  RG11B10UFloat: "rg11b10ufloat",
  // 64-bit formats
  RG32Uint: "rg32uint",
  RG32Sint: "rg32sint",
  RG32Float: "rg32float",
  RGBA16Uint: "rgba16uint",
  RGBA16Sint: "rgba16sint",
  RGBA16Float: "rgba16float",
  // 128-bit formats
  RGBA32Uint: "rgba32uint",
  RGBA32Sint: "rgba32sint",
  RGBA32Float: "rgba32float",
  Depth16Unorm: "depth16unorm",
  Depth24Plus: "depth24plus",
  Depth24PlusStencil8: "depth24plus-stencil8",
  Depth32Float: "depth32float",
  // 'depth32float-stencil8' extension
  Depth32FloatStencil8: "depth32float-stencil8",
  // BC compressed formats usable if 'texture-compression-bc' is both
  // supported by the device/user agent and enabled in requestDevice.
  BC1RGBAUnorm: "bc1-rgba-unorm",
  BC1RGBAUnormSRGB: "bc1-rgba-unorm-srgb",
  BC2RGBAUnorm: "bc2-rgba-unorm",
  BC2RGBAUnormSRGB: "bc2-rgba-unorm-srgb",
  BC3RGBAUnorm: "bc3-rgba-unorm",
  BC3RGBAUnormSRGB: "bc3-rgba-unorm-srgb",
  BC4RUnorm: "bc4-r-unorm",
  BC4RSnorm: "bc4-r-snorm",
  BC5RGUnorm: "bc5-rg-unorm",
  BC5RGSnorm: "bc5-rg-snorm",
  BC6HRGBUFloat: "bc6h-rgb-ufloat",
  BC6HRGBFloat: "bc6h-rgb-float",
  BC7RGBAUnorm: "bc7-rgba-unorm",
  BC7RGBAUnormSRGB: "bc7-rgba-unorm-srgb",
  // ETC2 compressed formats usable if 'texture-compression-etc2' is both
  // supported by the device/user agent and enabled in requestDevice.
  ETC2RGB8Unorm: "etc2-rgb8unorm",
  ETC2RGB8UnormSRGB: "etc2-rgb8unorm-srgb",
  ETC2RGB8A1Unorm: "etc2-rgb8a1unorm",
  ETC2RGB8A1UnormSRGB: "etc2-rgb8a1unorm-srgb",
  ETC2RGBA8Unorm: "etc2-rgba8unorm",
  ETC2RGBA8UnormSRGB: "etc2-rgba8unorm-srgb",
  EACR11Unorm: "eac-r11unorm",
  EACR11Snorm: "eac-r11snorm",
  EACRG11Unorm: "eac-rg11unorm",
  EACRG11Snorm: "eac-rg11snorm",
  // ASTC compressed formats usable if 'texture-compression-astc' is both
  // supported by the device/user agent and enabled in requestDevice.
  ASTC4x4Unorm: "astc-4x4-unorm",
  ASTC4x4UnormSRGB: "astc-4x4-unorm-srgb",
  ASTC5x4Unorm: "astc-5x4-unorm",
  ASTC5x4UnormSRGB: "astc-5x4-unorm-srgb",
  ASTC5x5Unorm: "astc-5x5-unorm",
  ASTC5x5UnormSRGB: "astc-5x5-unorm-srgb",
  ASTC6x5Unorm: "astc-6x5-unorm",
  ASTC6x5UnormSRGB: "astc-6x5-unorm-srgb",
  ASTC6x6Unorm: "astc-6x6-unorm",
  ASTC6x6UnormSRGB: "astc-6x6-unorm-srgb",
  ASTC8x5Unorm: "astc-8x5-unorm",
  ASTC8x5UnormSRGB: "astc-8x5-unorm-srgb",
  ASTC8x6Unorm: "astc-8x6-unorm",
  ASTC8x6UnormSRGB: "astc-8x6-unorm-srgb",
  ASTC8x8Unorm: "astc-8x8-unorm",
  ASTC8x8UnormSRGB: "astc-8x8-unorm-srgb",
  ASTC10x5Unorm: "astc-10x5-unorm",
  ASTC10x5UnormSRGB: "astc-10x5-unorm-srgb",
  ASTC10x6Unorm: "astc-10x6-unorm",
  ASTC10x6UnormSRGB: "astc-10x6-unorm-srgb",
  ASTC10x8Unorm: "astc-10x8-unorm",
  ASTC10x8UnormSRGB: "astc-10x8-unorm-srgb",
  ASTC10x10Unorm: "astc-10x10-unorm",
  ASTC10x10UnormSRGB: "astc-10x10-unorm-srgb",
  ASTC12x10Unorm: "astc-12x10-unorm",
  ASTC12x10UnormSRGB: "astc-12x10-unorm-srgb",
  ASTC12x12Unorm: "astc-12x12-unorm",
  ASTC12x12UnormSRGB: "astc-12x12-unorm-srgb"
}, dp = {
  ClampToEdge: "clamp-to-edge",
  Repeat: "repeat",
  MirrorRepeat: "mirror-repeat"
}, pr = {
  Linear: "linear",
  Nearest: "nearest"
}, _t = {
  Zero: "zero",
  One: "one",
  Src: "src",
  OneMinusSrc: "one-minus-src",
  SrcAlpha: "src-alpha",
  OneMinusSrcAlpha: "one-minus-src-alpha",
  Dst: "dst",
  OneMinusDst: "one-minus-dst",
  DstAlpha: "dst-alpha",
  OneMinusDstAlpha: "one-minus-dst-alpha",
  SrcAlphaSaturated: "src-alpha-saturated",
  Constant: "constant",
  OneMinusConstant: "one-minus-constant"
}, la = {
  Add: "add",
  Subtract: "subtract",
  ReverseSubtract: "reverse-subtract",
  Min: "min",
  Max: "max"
}, pv = {
  None: 0,
  All: 15
}, Es = {
  Keep: "keep",
  Zero: "zero",
  Replace: "replace",
  Invert: "invert",
  IncrementClamp: "increment-clamp",
  DecrementClamp: "decrement-clamp",
  IncrementWrap: "increment-wrap",
  DecrementWrap: "decrement-wrap"
}, fp = {
  Storage: "storage",
  ReadOnlyStorage: "read-only-storage"
}, pp = {
  WriteOnly: "write-only",
  ReadOnly: "read-only",
  ReadWrite: "read-write"
}, mv = {
  NonFiltering: "non-filtering",
  Comparison: "comparison"
}, ca = {
  Float: "float",
  UnfilterableFloat: "unfilterable-float",
  Depth: "depth",
  SInt: "sint",
  UInt: "uint"
}, gv = {
  TwoD: "2d",
  ThreeD: "3d"
}, Wn = {
  TwoD: "2d",
  TwoDArray: "2d-array",
  Cube: "cube",
  ThreeD: "3d"
}, nV = {
  All: "all"
}, fh = {
  Vertex: "vertex",
  Instance: "instance"
}, sm = {
  CoreFeaturesAndLimits: "core-features-and-limits",
  DepthClipControl: "depth-clip-control",
  Depth32FloatStencil8: "depth32float-stencil8",
  TextureCompressionBC: "texture-compression-bc",
  TextureCompressionBCSliced3D: "texture-compression-bc-sliced-3d",
  TextureCompressionETC2: "texture-compression-etc2",
  TextureCompressionASTC: "texture-compression-astc",
  TextureCompressionASTCSliced3D: "texture-compression-astc-sliced-3d",
  TimestampQuery: "timestamp-query",
  IndirectFirstInstance: "indirect-first-instance",
  ShaderF16: "shader-f16",
  RG11B10UFloat: "rg11b10ufloat-renderable",
  BGRA8UNormStorage: "bgra8unorm-storage",
  Float32Filterable: "float32-filterable",
  Float32Blendable: "float32-blendable",
  ClipDistances: "clip-distances",
  DualSourceBlending: "dual-source-blending",
  Subgroups: "subgroups",
  TextureFormatsTier1: "texture-formats-tier1",
  TextureFormatsTier2: "texture-formats-tier2"
}, _v = {
  "texture-compression-s3tc": "texture-compression-bc",
  "texture-compression-etc1": "texture-compression-etc2"
};
class iV extends mT {
  /**
   * Constructs a new node-based sampler.
   *
   * @param {string} name - The samplers's name.
   * @param {TextureNode} textureNode - The texture node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   */
  constructor(e, t, n) {
    super(e, t ? t.value : null), this.textureNode = t, this.groupNode = n;
  }
  /**
   * Updates the texture value of this sampler.
   *
   * @return {boolean} Whether the sampler needs an update or not.
   */
  update() {
    const { textureNode: e } = this;
    return this.texture !== e.value ? (this.texture = e.value, !0) : super.update();
  }
}
class rV extends hT {
  /**
   * Constructs a new uniform buffer.
   *
   * @param {string} name - The buffer's name.
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  constructor(e, t) {
    super(e, t ? t.array : null), this._attribute = t, this.isStorageBuffer = !0;
  }
  /**
   * The storage buffer attribute.
   *
   * @type {BufferAttribute}
   */
  get attribute() {
    return this._attribute;
  }
}
let sV = 0;
class aV extends rV {
  /**
   * Constructs a new node-based storage buffer.
   *
   * @param {StorageBufferNode} nodeUniform - The storage buffer node.
   * @param {UniformGroupNode} groupNode - The uniform group node.
   */
  constructor(e, t) {
    super("StorageBuffer_" + sV++, e ? e.value : null), this.nodeUniform = e, this.access = e ? e.access : Bi.READ_WRITE, this.groupNode = t;
  }
  /**
   * The storage buffer attribute node.
   *
   * @type {StorageBufferAttribute}
   */
  get attribute() {
    return this.nodeUniform.value;
  }
  /**
   * The storage buffer.
   *
   * @type {Float32Array}
   */
  get buffer() {
    return this.nodeUniform.value.array;
  }
}
class oV extends Ks {
  /**
   * Constructs a new utility object.
   *
   * @param {GPUDevice} device - The WebGPU device.
   */
  constructor(e) {
    super(), this.device = e;
    const t = `
struct VarysStruct {
	@builtin( position ) Position: vec4f,
	@location( 0 ) vTex : vec2f,
	@location( 1 ) @interpolate(flat, either) vBaseArrayLayer: u32,
};

@group( 0 ) @binding ( 2 )
var<uniform> flipY: u32;

@vertex
fn mainVS(
		@builtin( vertex_index ) vertexIndex : u32,
		@builtin( instance_index ) instanceIndex : u32 ) -> VarysStruct {

	var Varys : VarysStruct;

	var pos = array(
		vec2f( -1, -1 ),
		vec2f( -1,  3 ),
		vec2f(  3, -1 ),
	);

	let p = pos[ vertexIndex ];
	let mult = select( vec2f( 0.5, -0.5 ), vec2f( 0.5, 0.5 ), flipY != 0 );
	Varys.vTex = p * mult + vec2f( 0.5 );
	Varys.Position = vec4f( p, 0, 1 );
	Varys.vBaseArrayLayer = instanceIndex;

	return Varys;

}

@group( 0 ) @binding( 0 )
var imgSampler : sampler;

@group( 0 ) @binding( 1 )
var img2d : texture_2d<f32>;

@fragment
fn main_2d( Varys: VarysStruct ) -> @location( 0 ) vec4<f32> {

	return textureSample( img2d, imgSampler, Varys.vTex );

}

@group( 0 ) @binding( 1 )
var img2dArray : texture_2d_array<f32>;

@fragment
fn main_2d_array( Varys: VarysStruct ) -> @location( 0 ) vec4<f32> {

	return textureSample( img2dArray, imgSampler, Varys.vTex, Varys.vBaseArrayLayer );

}

const faceMat = array(
  mat3x3f(  0,  0,  -2,  0, -2,   0,  1,  1,   1 ),   // pos-x
  mat3x3f(  0,  0,   2,  0, -2,   0, -1,  1,  -1 ),   // neg-x
  mat3x3f(  2,  0,   0,  0,  0,   2, -1,  1,  -1 ),   // pos-y
  mat3x3f(  2,  0,   0,  0,  0,  -2, -1, -1,   1 ),   // neg-y
  mat3x3f(  2,  0,   0,  0, -2,   0, -1,  1,   1 ),   // pos-z
  mat3x3f( -2,  0,   0,  0, -2,   0,  1,  1,  -1 ),   // neg-z
);

@group( 0 ) @binding( 1 )
var imgCube : texture_cube<f32>;

@fragment
fn main_cube( Varys: VarysStruct ) -> @location( 0 ) vec4<f32> {

	return textureSample( imgCube, imgSampler, faceMat[ Varys.vBaseArrayLayer ] * vec3f( fract( Varys.vTex ), 1 ) );

}
`;
    this.mipmapSampler = e.createSampler({ minFilter: pr.Linear }), this.flipYSampler = e.createSampler({ minFilter: pr.Nearest }), this.flipUniformBuffer = e.createBuffer({
      size: 4,
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
    }), e.queue.writeBuffer(this.flipUniformBuffer, 0, new Uint32Array([1])), this.noFlipUniformBuffer = e.createBuffer({
      size: 4,
      usage: GPUBufferUsage.UNIFORM
    }), this.transferPipelines = {}, this.mipmapShaderModule = e.createShaderModule({
      label: "mipmap",
      code: t
    });
  }
  /**
   * Returns a render pipeline for the internal copy render pass. The pass
   * requires a unique render pipeline for each texture format.
   *
   * @param {string} format - The GPU texture format
   * @param {string?} textureBindingViewDimension - The GPU texture binding view dimension
   * @return {GPURenderPipeline} The GPU render pipeline.
   */
  getTransferPipeline(e, t) {
    t = t || "2d-array";
    const n = `${e}-${t}`;
    let r = this.transferPipelines[n];
    return r === void 0 && (r = this.device.createRenderPipeline({
      label: `mipmap-${e}-${t}`,
      vertex: {
        module: this.mipmapShaderModule
      },
      fragment: {
        module: this.mipmapShaderModule,
        entryPoint: `main_${t.replace("-", "_")}`,
        targets: [{ format: e }]
      },
      layout: "auto"
    }), this.transferPipelines[n] = r), r;
  }
  /**
   * Flip the contents of the given GPU texture along its vertical axis.
   *
   * @param {GPUTexture} textureGPU - The GPU texture object.
   * @param {Object} textureGPUDescriptor - The texture descriptor.
   * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view.
   */
  flipY(e, t, n = 0) {
    const r = t.format, { width: s, height: a } = t.size, o = this.device.createTexture({
      size: { width: s, height: a },
      format: r,
      usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
    }), l = this.getTransferPipeline(r, e.textureBindingViewDimension), c = this.getTransferPipeline(r, o.textureBindingViewDimension), u = this.device.createCommandEncoder({}), h = (d, f, p, _, g, m) => {
      const x = d.getBindGroupLayout(0), y = this.device.createBindGroup({
        layout: x,
        entries: [{
          binding: 0,
          resource: this.flipYSampler
        }, {
          binding: 1,
          resource: f.createView({
            dimension: f.textureBindingViewDimension || "2d-array",
            baseMipLevel: 0,
            mipLevelCount: 1
          })
        }, {
          binding: 2,
          resource: { buffer: m ? this.flipUniformBuffer : this.noFlipUniformBuffer }
        }]
      }), b = u.beginRenderPass({
        colorAttachments: [{
          view: _.createView({
            dimension: "2d",
            baseMipLevel: 0,
            mipLevelCount: 1,
            baseArrayLayer: g,
            arrayLayerCount: 1
          }),
          loadOp: wt.Clear,
          storeOp: Qn.Store
        }]
      });
      b.setPipeline(d), b.setBindGroup(0, y), b.draw(3, 1, 0, p), b.end();
    };
    h(l, e, n, o, 0, !1), h(c, o, 0, e, n, !0), this.device.queue.submit([u.finish()]), o.destroy();
  }
  /**
   * Generates mipmaps for the given GPU texture.
   *
   * @param {GPUTexture} textureGPU - The GPU texture object.
   * @param {?GPUCommandEncoder} [encoder=null] - An optional command encoder used to generate mipmaps.
   */
  generateMipmaps(e, t = null) {
    const n = this.get(e), r = n.layers || this._mipmapCreateBundles(e), s = t || this.device.createCommandEncoder({ label: "mipmapEncoder" });
    this._mipmapRunBundles(s, r), t === null && this.device.queue.submit([s.finish()]), n.layers = r;
  }
  /**
   * Since multiple copy render passes are required to generate mipmaps, the passes
   * are managed as render bundles to improve performance.
   *
   * @param {GPUTexture} textureGPU - The GPU texture object.
   * @return {Array<Object>} An array of render bundles.
   */
  _mipmapCreateBundles(e) {
    const t = e.textureBindingViewDimension || "2d-array", n = this.getTransferPipeline(e.format, t), r = n.getBindGroupLayout(0), s = [];
    for (let a = 1; a < e.mipLevelCount; a++)
      for (let o = 0; o < e.depthOrArrayLayers; o++) {
        const l = this.device.createBindGroup({
          layout: r,
          entries: [{
            binding: 0,
            resource: this.mipmapSampler
          }, {
            binding: 1,
            resource: e.createView({
              dimension: t,
              baseMipLevel: a - 1,
              mipLevelCount: 1
            })
          }, {
            binding: 2,
            resource: { buffer: this.noFlipUniformBuffer }
          }]
        }), c = {
          colorAttachments: [{
            view: e.createView({
              dimension: "2d",
              baseMipLevel: a,
              mipLevelCount: 1,
              baseArrayLayer: o,
              arrayLayerCount: 1
            }),
            loadOp: wt.Clear,
            storeOp: Qn.Store
          }]
        }, u = this.device.createRenderBundleEncoder({
          colorFormats: [e.format]
        });
        u.setPipeline(n), u.setBindGroup(0, l), u.draw(3, 1, 0, o), s.push({
          renderBundles: [u.finish()],
          passDescriptor: c
        });
      }
    return s;
  }
  /**
   * Executes the render bundles.
   *
   * @param {GPUCommandEncoder} commandEncoder - The GPU command encoder.
   * @param {Array<Object>} passes - An array of render bundles.
   */
  _mipmapRunBundles(e, t) {
    const n = t.length;
    for (let r = 0; r < n; r++) {
      const s = t[r], a = e.beginRenderPass(s.passDescriptor);
      a.executeBundles(s.renderBundles), a.end();
    }
  }
}
const lV = {
  [Om]: "never",
  [ld]: "less",
  [km]: "equal",
  [Xs]: "less-equal",
  [Vc]: "greater",
  [us]: "greater-equal",
  [Vm]: "always",
  [Gm]: "not-equal"
}, cV = [0, 1, 3, 2, 4, 5];
class uV {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGPUBackend} backend - The WebGPU backend.
   */
  constructor(e) {
    this.backend = e, this._passUtils = null, this.defaultTexture = {}, this.defaultCubeTexture = {}, this.defaultVideoFrame = null, this._samplerCache = /* @__PURE__ */ new Map();
  }
  /**
   * Creates a GPU sampler for the given texture.
   *
   * @param {Texture} texture - The texture to create the sampler for.
   * @return {string} The current sampler key.
   */
  updateSampler(e) {
    const t = this.backend, n = e.minFilter + "-" + e.magFilter + "-" + e.wrapS + "-" + e.wrapT + "-" + (e.wrapR || "0") + "-" + e.anisotropy + "-" + (e.compareFunction || 0);
    let r = this._samplerCache.get(n);
    if (r === void 0) {
      const a = {
        addressModeU: this._convertAddressMode(e.wrapS),
        addressModeV: this._convertAddressMode(e.wrapT),
        addressModeW: this._convertAddressMode(e.wrapR),
        magFilter: this._convertFilterMode(e.magFilter),
        minFilter: this._convertFilterMode(e.minFilter),
        mipmapFilter: this._convertFilterMode(e.minFilter),
        maxAnisotropy: 1
      };
      e.isDepthTexture && e.compareFunction === null && (a.magFilter = pr.Nearest, a.minFilter = pr.Nearest, a.mipmapFilter = pr.Nearest), a.magFilter === pr.Linear && a.minFilter === pr.Linear && a.mipmapFilter === pr.Linear && (a.maxAnisotropy = e.anisotropy), e.isDepthTexture && e.compareFunction !== null && t.hasCompatibility(rs.TEXTURE_COMPARE) && (a.compare = lV[e.compareFunction]), r = { sampler: t.device.createSampler(a), usedTimes: 0 }, this._samplerCache.set(n, r);
    }
    const s = t.get(e);
    if (s.sampler !== r.sampler) {
      if (s.sampler !== void 0) {
        const a = this._samplerCache.get(s.samplerKey);
        a.usedTimes--, a.usedTimes === 0 && this._samplerCache.delete(s.samplerKey);
      }
      s.samplerKey = n, s.sampler = r.sampler, r.usedTimes++;
    }
    return n;
  }
  /**
   * Creates a default texture for the given texture that can be used
   * as a placeholder until the actual texture is ready for usage.
   *
   * @param {Texture} texture - The texture to create a default texture for.
   */
  createDefaultTexture(e) {
    let t;
    const n = am(e);
    e.isCubeTexture ? t = this._getDefaultCubeTextureGPU(n) : t = this._getDefaultTextureGPU(n), this.backend.get(e).texture = t;
  }
  /**
   * Defines a texture on the GPU for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  createTexture(e, t = {}) {
    const n = this.backend, r = n.get(e);
    if (r.initialized)
      throw new Error("WebGPUTextureUtils: Texture already initialized.");
    if (e.isExternalTexture) {
      r.texture = e.sourceTexture, r.initialized = !0;
      return;
    }
    t.needsMipmaps === void 0 && (t.needsMipmaps = !1), t.levels === void 0 && (t.levels = 1), t.depth === void 0 && (t.depth = 1);
    const { width: s, height: a, depth: o, levels: l } = t;
    e.isFramebufferTexture && (t.renderTarget ? t.format = this.backend.utils.getCurrentColorFormat(t.renderTarget) : t.format = this.backend.utils.getPreferredCanvasFormat());
    const c = this._getDimension(e), u = e.internalFormat || t.format || am(e, n.device);
    r.format = u;
    const { samples: h, primarySamples: d, isMSAA: f } = n.utils.getTextureSampleData(e);
    let p = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
    e.isStorageTexture === !0 && (p |= GPUTextureUsage.STORAGE_BINDING), e.isCompressedTexture !== !0 && e.isCompressedArrayTexture !== !0 && u !== U.RGB9E5UFloat && (p |= GPUTextureUsage.RENDER_ATTACHMENT);
    const _ = {
      label: e.name,
      size: {
        width: s,
        height: a,
        depthOrArrayLayers: o
      },
      mipLevelCount: l,
      sampleCount: d,
      dimension: c,
      format: u,
      usage: p
    };
    if (u === void 0) {
      oe("WebGPURenderer: Texture format not supported."), this.createDefaultTexture(e);
      return;
    }
    e.isCubeTexture && (_.textureBindingViewDimension = Wn.Cube);
    try {
      r.texture = n.device.createTexture(_);
    } catch {
      oe("WebGPURenderer: Failed to create texture with descriptor:", _), this.createDefaultTexture(e);
      return;
    }
    if (f) {
      const g = Object.assign({}, _);
      g.label = g.label + "-msaa", g.sampleCount = h, g.mipLevelCount = 1, r.msaaTexture = n.device.createTexture(g);
    }
    r.initialized = !0, r.textureDescriptorGPU = _;
  }
  /**
   * Destroys the GPU data for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {boolean} [isDefaultTexture=false] - Whether the texture uses a default GPU texture or not.
   */
  destroyTexture(e, t = !1) {
    const n = this.backend, r = n.get(e);
    r.texture !== void 0 && t === !1 && r.texture.destroy(), r.msaaTexture !== void 0 && r.msaaTexture.destroy(), n.delete(e);
  }
  /**
   * Generates mipmaps for the given texture.
   *
   * @param {Texture} texture - The texture.
   * @param {?GPUCommandEncoder} [encoder=null] - An optional command encoder used to generate mipmaps.
   */
  generateMipmaps(e, t = null) {
    const n = this.backend.get(e);
    this._generateMipmaps(n.texture, t);
  }
  /**
   * Returns the color buffer representing the color
   * attachment of the default framebuffer.
   *
   * @return {GPUTexture} The color buffer.
   */
  getColorBuffer() {
    const e = this.backend, t = e.renderer.getCanvasTarget(), { width: n, height: r } = e.getDrawingBufferSize(), s = e.renderer.currentSamples, a = t.colorTexture, o = e.get(a);
    if (a.width === n && a.height === r && a.samples === s)
      return o.texture;
    let l = o.texture;
    return l && l.destroy(), l = e.device.createTexture({
      label: "colorBuffer",
      size: {
        width: n,
        height: r,
        depthOrArrayLayers: 1
      },
      sampleCount: e.utils.getSampleCount(e.renderer.currentSamples),
      format: e.utils.getPreferredCanvasFormat(),
      usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
    }), a.source.width = n, a.source.height = r, a.samples = s, o.texture = l, l;
  }
  /**
   * Returns the depth buffer representing the depth
   * attachment of the default framebuffer.
   *
   * @param {boolean} [depth=true] - Whether depth is enabled or not.
   * @param {boolean} [stencil=false] -  Whether stencil is enabled or not.
   * @return {GPUTexture} The depth buffer.
   */
  getDepthBuffer(e = !0, t = !1) {
    const n = this.backend, r = n.renderer.getCanvasTarget(), { width: s, height: a } = n.getDrawingBufferSize(), o = n.renderer.currentSamples, l = r.depthTexture;
    if (l.width === s && l.height === a && l.samples === o && l.depth === e && l.stencil === t)
      return n.get(l).texture;
    const c = n.get(l).texture;
    let u, h;
    if (t ? (u = ii, h = Ci) : e && (u = Un, h = Dt), c !== void 0) {
      if (l.image.width === s && l.image.height === a && l.format === u && l.type === h && l.samples === o)
        return c;
      this.destroyTexture(l);
    }
    return l.name = "depthBuffer", l.format = u, l.type = h, l.image.width = s, l.image.height = a, l.samples = o, this.createTexture(l, { width: s, height: a }), n.get(l).texture;
  }
  /**
   * Uploads the updated texture data to the GPU.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  updateTexture(e, t) {
    const n = this.backend.get(e), r = e.mipmaps, { textureDescriptorGPU: s } = n;
    if (!(e.isRenderTargetTexture || s === void 0)) {
      if (e.isDataTexture)
        if (r.length > 0)
          for (let a = 0, o = r.length; a < o; a++) {
            const l = r[a];
            this._copyBufferToTexture(l, n.texture, s, 0, e.flipY, 0, a);
          }
        else
          this._copyBufferToTexture(t.image, n.texture, s, 0, e.flipY);
      else if (e.isArrayTexture || e.isDataArrayTexture || e.isData3DTexture)
        for (let a = 0; a < t.image.depth; a++)
          this._copyBufferToTexture(t.image, n.texture, s, a, e.flipY, a);
      else if (e.isCompressedTexture || e.isCompressedArrayTexture)
        this._copyCompressedBufferToTexture(e.mipmaps, n.texture, s);
      else if (e.isCubeTexture)
        this._copyCubeMapToTexture(e, n.texture, s);
      else if (r.length > 0)
        for (let a = 0, o = r.length; a < o; a++) {
          const l = r[a];
          this._copyImageToTexture(l, n.texture, s, 0, e.flipY, e.premultiplyAlpha, a);
        }
      else
        this._copyImageToTexture(t.image, n.texture, s, 0, e.flipY, e.premultiplyAlpha);
      n.version = e.version;
    }
  }
  /**
   * Returns texture data as a typed array.
   *
   * @async
   * @param {Texture} texture - The texture to copy.
   * @param {number} x - The x coordinate of the copy origin.
   * @param {number} y - The y coordinate of the copy origin.
   * @param {number} width - The width of the copy.
   * @param {number} height - The height of the copy.
   * @param {number} faceIndex - The face index.
   * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
   */
  async copyTextureToBuffer(e, t, n, r, s, a) {
    const o = this.backend.device, l = this.backend.get(e), c = l.texture, u = l.textureDescriptorGPU.format, h = this._getBytesPerTexel(u);
    let d = r * h;
    d = Math.ceil(d / 256) * 256;
    const f = o.createBuffer(
      {
        size: (s - 1) * d + r * h,
        // see https://github.com/mrdoob/three.js/issues/31658#issuecomment-3229442010
        usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
      }
    ), p = o.createCommandEncoder();
    p.copyTextureToBuffer(
      {
        texture: c,
        origin: { x: t, y: n, z: a }
      },
      {
        buffer: f,
        bytesPerRow: d
      },
      {
        width: r,
        height: s
      }
    );
    const _ = this._getTypedArrayType(u);
    o.queue.submit([p.finish()]), await f.mapAsync(GPUMapMode.READ);
    const g = f.getMappedRange();
    return new _(g);
  }
  /**
   * Frees all internal resources.
   */
  dispose() {
    this._samplerCache.clear();
  }
  /**
   * Returns the default GPU texture for the given format.
   *
   * @private
   * @param {string} format - The GPU format.
   * @return {GPUTexture} The GPU texture.
   */
  _getDefaultTextureGPU(e) {
    let t = this.defaultTexture[e];
    if (t === void 0) {
      const n = new mn();
      n.minFilter = Tt, n.magFilter = Tt, this.createTexture(n, { width: 1, height: 1, format: e }), this.defaultTexture[e] = t = n;
    }
    return this.backend.get(t).texture;
  }
  /**
   * Returns the default GPU cube texture for the given format.
   *
   * @private
   * @param {string} format - The GPU format.
   * @return {GPUTexture} The GPU texture.
   */
  _getDefaultCubeTextureGPU(e) {
    let t = this.defaultCubeTexture[e];
    if (t === void 0) {
      const n = new yl();
      n.minFilter = Tt, n.magFilter = Tt, this.createTexture(n, { width: 1, height: 1, depth: 6 }), this.defaultCubeTexture[e] = t = n;
    }
    return this.backend.get(t).texture;
  }
  /**
   * Uploads cube texture image data to the GPU memory.
   *
   * @private
   * @param {CubeTexture} texture - The cube texture.
   * @param {GPUTexture} textureGPU - The GPU texture.
   * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
   */
  _copyCubeMapToTexture(e, t, n) {
    const r = e.images, s = e.mipmaps;
    for (let a = 0; a < 6; a++) {
      const o = r[a], l = e.flipY === !0 ? cV[a] : a;
      o.isDataTexture ? this._copyBufferToTexture(o.image, t, n, l, e.flipY) : this._copyImageToTexture(o, t, n, l, e.flipY, e.premultiplyAlpha);
      for (let c = 0; c < s.length; c++) {
        const h = s[c].images[a];
        h.isDataTexture ? this._copyBufferToTexture(h.image, t, n, l, e.flipY, 0, c + 1) : this._copyImageToTexture(h, t, n, l, e.flipY, e.premultiplyAlpha, c + 1);
      }
    }
  }
  /**
   * Uploads texture image data to the GPU memory.
   *
   * @private
   * @param {HTMLImageElement|ImageBitmap|HTMLCanvasElement} image - The image data.
   * @param {GPUTexture} textureGPU - The GPU texture.
   * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
   * @param {number} originDepth - The origin depth.
   * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not.
   * @param {boolean} premultiplyAlpha - Whether the texture should have its RGB channels premultiplied by the alpha channel or not.
   * @param {number} [mipLevel=0] - The mip level where the data should be copied to.
   */
  _copyImageToTexture(e, t, n, r, s, a, o = 0) {
    const l = this.backend.device, c = o > 0 ? e.width : n.size.width, u = o > 0 ? e.height : n.size.height;
    try {
      l.queue.copyExternalImageToTexture(
        {
          source: e,
          flipY: s
        },
        {
          texture: t,
          mipLevel: o,
          origin: { x: 0, y: 0, z: r },
          premultipliedAlpha: a
        },
        {
          width: c,
          height: u,
          depthOrArrayLayers: 1
        }
      );
    } catch {
    }
  }
  /**
   * Returns the pass utils singleton.
   *
   * @private
   * @return {WebGPUTexturePassUtils} The utils instance.
   */
  _getPassUtils() {
    let e = this._passUtils;
    return e === null && (this._passUtils = e = new oV(this.backend.device)), e;
  }
  /**
   * Generates mipmaps for the given GPU texture.
   *
   * @private
   * @param {GPUTexture} textureGPU - The GPU texture object.
   * @param {?GPUCommandEncoder} [encoder=null] - An optional command encoder used to generate mipmaps.
   */
  _generateMipmaps(e, t = null) {
    this._getPassUtils().generateMipmaps(e, t);
  }
  /**
   * Flip the contents of the given GPU texture along its vertical axis.
   *
   * @private
   * @param {GPUTexture} textureGPU - The GPU texture object.
   * @param {Object} textureDescriptorGPU - The texture descriptor.
   * @param {number} [originDepth=0] - The origin depth.
   */
  _flipY(e, t, n = 0) {
    this._getPassUtils().flipY(e, t, n);
  }
  /**
   * Uploads texture buffer data to the GPU memory.
   *
   * @private
   * @param {Object} image - An object defining the image buffer data.
   * @param {GPUTexture} textureGPU - The GPU texture.
   * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
   * @param {number} originDepth - The origin depth.
   * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not.
   * @param {number} [depth=0] - The depth offset when copying array or 3D texture data.
   * @param {number} [mipLevel=0] - The mip level where the data should be copied to.
   */
  _copyBufferToTexture(e, t, n, r, s, a = 0, o = 0) {
    const l = this.backend.device, c = e.data, u = this._getBytesPerTexel(n.format), h = e.width * u;
    l.queue.writeTexture(
      {
        texture: t,
        mipLevel: o,
        origin: { x: 0, y: 0, z: r }
      },
      c,
      {
        offset: e.width * e.height * u * a,
        bytesPerRow: h
      },
      {
        width: e.width,
        height: e.height,
        depthOrArrayLayers: 1
      }
    ), s === !0 && this._flipY(t, n, r);
  }
  /**
   * Uploads compressed texture data to the GPU memory.
   *
   * @private
   * @param {Array<Object>} mipmaps - An array with mipmap data.
   * @param {GPUTexture} textureGPU - The GPU texture.
   * @param {Object} textureDescriptorGPU - The GPU texture descriptor.
   */
  _copyCompressedBufferToTexture(e, t, n) {
    const r = this.backend.device, s = this._getBlockData(n.format), a = n.size.depthOrArrayLayers > 1;
    for (let o = 0; o < e.length; o++) {
      const l = e[o], c = l.width, u = l.height, h = a ? n.size.depthOrArrayLayers : 1, d = Math.ceil(c / s.width) * s.byteLength, f = d * Math.ceil(u / s.height);
      for (let p = 0; p < h; p++)
        r.queue.writeTexture(
          {
            texture: t,
            mipLevel: o,
            origin: { x: 0, y: 0, z: p }
          },
          l.data,
          {
            offset: p * f,
            bytesPerRow: d,
            rowsPerImage: Math.ceil(u / s.height)
          },
          {
            width: Math.ceil(c / s.width) * s.width,
            height: Math.ceil(u / s.height) * s.height,
            depthOrArrayLayers: 1
          }
        );
    }
  }
  /**
   * This method is only relevant for compressed texture formats. It returns a block
   * data descriptor for the given GPU compressed texture format.
   *
   * @private
   * @param {string} format - The GPU compressed texture format.
   * @return {Object} The block data descriptor.
   */
  _getBlockData(e) {
    if (e === U.BC1RGBAUnorm || e === U.BC1RGBAUnormSRGB)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.BC2RGBAUnorm || e === U.BC2RGBAUnormSRGB)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.BC3RGBAUnorm || e === U.BC3RGBAUnormSRGB)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.BC4RUnorm || e === U.BC4RSnorm)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.BC5RGUnorm || e === U.BC5RGSnorm)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.BC6HRGBUFloat || e === U.BC6HRGBFloat)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.BC7RGBAUnorm || e === U.BC7RGBAUnormSRGB)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.ETC2RGB8Unorm || e === U.ETC2RGB8UnormSRGB)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.ETC2RGB8A1Unorm || e === U.ETC2RGB8A1UnormSRGB)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.ETC2RGBA8Unorm || e === U.ETC2RGBA8UnormSRGB)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.EACR11Unorm)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.EACR11Snorm)
      return { byteLength: 8, width: 4, height: 4 };
    if (e === U.EACRG11Unorm)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.EACRG11Snorm)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.ASTC4x4Unorm || e === U.ASTC4x4UnormSRGB)
      return { byteLength: 16, width: 4, height: 4 };
    if (e === U.ASTC5x4Unorm || e === U.ASTC5x4UnormSRGB)
      return { byteLength: 16, width: 5, height: 4 };
    if (e === U.ASTC5x5Unorm || e === U.ASTC5x5UnormSRGB)
      return { byteLength: 16, width: 5, height: 5 };
    if (e === U.ASTC6x5Unorm || e === U.ASTC6x5UnormSRGB)
      return { byteLength: 16, width: 6, height: 5 };
    if (e === U.ASTC6x6Unorm || e === U.ASTC6x6UnormSRGB)
      return { byteLength: 16, width: 6, height: 6 };
    if (e === U.ASTC8x5Unorm || e === U.ASTC8x5UnormSRGB)
      return { byteLength: 16, width: 8, height: 5 };
    if (e === U.ASTC8x6Unorm || e === U.ASTC8x6UnormSRGB)
      return { byteLength: 16, width: 8, height: 6 };
    if (e === U.ASTC8x8Unorm || e === U.ASTC8x8UnormSRGB)
      return { byteLength: 16, width: 8, height: 8 };
    if (e === U.ASTC10x5Unorm || e === U.ASTC10x5UnormSRGB)
      return { byteLength: 16, width: 10, height: 5 };
    if (e === U.ASTC10x6Unorm || e === U.ASTC10x6UnormSRGB)
      return { byteLength: 16, width: 10, height: 6 };
    if (e === U.ASTC10x8Unorm || e === U.ASTC10x8UnormSRGB)
      return { byteLength: 16, width: 10, height: 8 };
    if (e === U.ASTC10x10Unorm || e === U.ASTC10x10UnormSRGB)
      return { byteLength: 16, width: 10, height: 10 };
    if (e === U.ASTC12x10Unorm || e === U.ASTC12x10UnormSRGB)
      return { byteLength: 16, width: 12, height: 10 };
    if (e === U.ASTC12x12Unorm || e === U.ASTC12x12UnormSRGB)
      return { byteLength: 16, width: 12, height: 12 };
  }
  /**
   * Converts the three.js uv wrapping constants to GPU address mode constants.
   *
   * @private
   * @param {number} value - The three.js constant defining a uv wrapping mode.
   * @return {string} The GPU address mode.
   */
  _convertAddressMode(e) {
    let t = dp.ClampToEdge;
    return e === Ca ? t = dp.Repeat : e === Na && (t = dp.MirrorRepeat), t;
  }
  /**
   * Converts the three.js filter constants to GPU filter constants.
   *
   * @private
   * @param {number} value - The three.js constant defining a filter mode.
   * @return {string} The GPU filter mode.
   */
  _convertFilterMode(e) {
    let t = pr.Linear;
    return (e === Tt || e === Um || e === ts) && (t = pr.Nearest), t;
  }
  /**
   * Returns the bytes-per-texel value for the given GPU texture format.
   *
   * @private
   * @param {string} format - The GPU texture format.
   * @return {number} The bytes-per-texel.
   */
  _getBytesPerTexel(e) {
    if (e === U.R8Unorm || e === U.R8Snorm || e === U.R8Uint || e === U.R8Sint)
      return 1;
    if (e === U.R16Uint || e === U.R16Sint || e === U.R16Float || e === U.RG8Unorm || e === U.RG8Snorm || e === U.RG8Uint || e === U.RG8Sint)
      return 2;
    if (e === U.R32Uint || e === U.R32Sint || e === U.R32Float || e === U.RG16Uint || e === U.RG16Sint || e === U.RG16Float || e === U.RGBA8Unorm || e === U.RGBA8UnormSRGB || e === U.RGBA8Snorm || e === U.RGBA8Uint || e === U.RGBA8Sint || e === U.BGRA8Unorm || e === U.BGRA8UnormSRGB || // Packed 32-bit formats
    e === U.RGB9E5UFloat || e === U.RGB10A2Unorm || e === U.RG11B10UFloat || e === U.Depth32Float || e === U.Depth24Plus || e === U.Depth24PlusStencil8 || e === U.Depth32FloatStencil8)
      return 4;
    if (e === U.RG32Uint || e === U.RG32Sint || e === U.RG32Float || e === U.RGBA16Uint || e === U.RGBA16Sint || e === U.RGBA16Float)
      return 8;
    if (e === U.RGBA32Uint || e === U.RGBA32Sint || e === U.RGBA32Float)
      return 16;
  }
  /**
   * Returns the corresponding typed array type for the given GPU texture format.
   *
   * @private
   * @param {string} format - The GPU texture format.
   * @return {TypedArray.constructor} The typed array type.
   */
  _getTypedArrayType(e) {
    if (e === U.R8Uint)
      return Uint8Array;
    if (e === U.R8Sint)
      return Int8Array;
    if (e === U.R8Unorm)
      return Uint8Array;
    if (e === U.R8Snorm)
      return Int8Array;
    if (e === U.RG8Uint)
      return Uint8Array;
    if (e === U.RG8Sint)
      return Int8Array;
    if (e === U.RG8Unorm)
      return Uint8Array;
    if (e === U.RG8Snorm)
      return Int8Array;
    if (e === U.RGBA8Uint)
      return Uint8Array;
    if (e === U.RGBA8Sint)
      return Int8Array;
    if (e === U.RGBA8Unorm || e === U.RGBA8UnormSRGB)
      return Uint8Array;
    if (e === U.RGBA8Snorm)
      return Int8Array;
    if (e === U.R16Uint)
      return Uint16Array;
    if (e === U.R16Sint)
      return Int16Array;
    if (e === U.RG16Uint)
      return Uint16Array;
    if (e === U.RG16Sint)
      return Int16Array;
    if (e === U.RGBA16Uint)
      return Uint16Array;
    if (e === U.RGBA16Sint)
      return Int16Array;
    if (e === U.R16Float || e === U.RG16Float || e === U.RGBA16Float)
      return Uint16Array;
    if (e === U.R32Uint)
      return Uint32Array;
    if (e === U.R32Sint)
      return Int32Array;
    if (e === U.R32Float)
      return Float32Array;
    if (e === U.RG32Uint)
      return Uint32Array;
    if (e === U.RG32Sint)
      return Int32Array;
    if (e === U.RG32Float)
      return Float32Array;
    if (e === U.RGBA32Uint)
      return Uint32Array;
    if (e === U.RGBA32Sint)
      return Int32Array;
    if (e === U.RGBA32Float)
      return Float32Array;
    if (e === U.BGRA8Unorm || e === U.BGRA8UnormSRGB)
      return Uint8Array;
    if (e === U.RGB10A2Unorm || e === U.RGB9E5UFloat || e === U.RG11B10UFloat)
      return Uint32Array;
    if (e === U.Depth32Float)
      return Float32Array;
    if (e === U.Depth24Plus || e === U.Depth24PlusStencil8)
      return Uint32Array;
    if (e === U.Depth32FloatStencil8)
      return Float32Array;
  }
  /**
   * Returns the GPU dimensions for the given texture.
   *
   * @private
   * @param {Texture} texture - The texture.
   * @return {string} The GPU dimension.
   */
  _getDimension(e) {
    let t;
    return e.is3DTexture || e.isData3DTexture ? t = gv.ThreeD : t = gv.TwoD, t;
  }
}
function am(i, e = null) {
  const t = i.format, n = i.type, r = i.colorSpace, s = Ke.getTransfer(r);
  let a;
  if (i.isCompressedTexture === !0 || i.isCompressedArrayTexture === !0)
    switch (t) {
      case Us:
      case Bs:
        a = s === Te ? U.BC1RGBAUnormSRGB : U.BC1RGBAUnorm;
        break;
      case Os:
        a = s === Te ? U.BC2RGBAUnormSRGB : U.BC2RGBAUnorm;
        break;
      case ks:
        a = s === Te ? U.BC3RGBAUnormSRGB : U.BC3RGBAUnorm;
        break;
      case sl:
        a = U.BC4RUnorm;
        break;
      case al:
        a = U.BC4RSnorm;
        break;
      case Da:
        a = U.BC5RGUnorm;
        break;
      case ol:
        a = U.BC5RGSnorm;
        break;
      case rl:
        a = s === Te ? U.BC7RGBAUnormSRGB : U.BC7RGBAUnorm;
        break;
      case ko:
      case Oo:
        a = s === Te ? U.ETC2RGB8UnormSRGB : U.ETC2RGB8Unorm;
        break;
      case Go:
        a = s === Te ? U.ETC2RGBA8UnormSRGB : U.ETC2RGBA8Unorm;
        break;
      case Vo:
        a = U.EACR11Unorm;
        break;
      case zo:
        a = U.EACR11Snorm;
        break;
      case Pa:
        a = U.EACRG11Unorm;
        break;
      case Ho:
        a = U.EACRG11Snorm;
        break;
      case $o:
        a = s === Te ? U.ASTC4x4UnormSRGB : U.ASTC4x4Unorm;
        break;
      case Wo:
        a = s === Te ? U.ASTC5x4UnormSRGB : U.ASTC5x4Unorm;
        break;
      case qo:
        a = s === Te ? U.ASTC5x5UnormSRGB : U.ASTC5x5Unorm;
        break;
      case Xo:
        a = s === Te ? U.ASTC6x5UnormSRGB : U.ASTC6x5Unorm;
        break;
      case jo:
        a = s === Te ? U.ASTC6x6UnormSRGB : U.ASTC6x6Unorm;
        break;
      case Yo:
        a = s === Te ? U.ASTC8x5UnormSRGB : U.ASTC8x5Unorm;
        break;
      case Ko:
        a = s === Te ? U.ASTC8x6UnormSRGB : U.ASTC8x6Unorm;
        break;
      case Zo:
        a = s === Te ? U.ASTC8x8UnormSRGB : U.ASTC8x8Unorm;
        break;
      case Qo:
        a = s === Te ? U.ASTC10x5UnormSRGB : U.ASTC10x5Unorm;
        break;
      case Jo:
        a = s === Te ? U.ASTC10x6UnormSRGB : U.ASTC10x6Unorm;
        break;
      case el:
        a = s === Te ? U.ASTC10x8UnormSRGB : U.ASTC10x8Unorm;
        break;
      case tl:
        a = s === Te ? U.ASTC10x10UnormSRGB : U.ASTC10x10Unorm;
        break;
      case nl:
        a = s === Te ? U.ASTC12x10UnormSRGB : U.ASTC12x10Unorm;
        break;
      case il:
        a = s === Te ? U.ASTC12x12UnormSRGB : U.ASTC12x12Unorm;
        break;
      case cn:
        a = s === Te ? U.RGBA8UnormSRGB : U.RGBA8Unorm;
        break;
      default:
        le("WebGPURenderer: Unsupported texture format.", t);
    }
  else
    switch (t) {
      case cn:
        switch (n) {
          case ba:
            a = U.RGBA8Snorm;
            break;
          case Sa:
            a = U.RGBA16Sint;
            break;
          case Ji:
            a = U.RGBA16Uint;
            break;
          case Dt:
            a = U.RGBA32Uint;
            break;
          case wn:
            a = U.RGBA32Sint;
            break;
          case Zt:
            a = s === Te ? U.RGBA8UnormSRGB : U.RGBA8Unorm;
            break;
          case nn:
            a = U.RGBA16Float;
            break;
          case ln:
            a = U.RGBA32Float;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RGBAFormat.", n);
        }
        break;
      case Jc:
        switch (n) {
          case ad:
            a = U.RGB9E5UFloat;
            break;
          case od:
            a = U.RG11B10UFloat;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RGBFormat.", n);
        }
        break;
      case eu:
        switch (n) {
          case ba:
            a = U.R8Snorm;
            break;
          case Sa:
            a = U.R16Sint;
            break;
          case Ji:
            a = U.R16Uint;
            break;
          case Dt:
            a = U.R32Uint;
            break;
          case wn:
            a = U.R32Sint;
            break;
          case Zt:
            a = U.R8Unorm;
            break;
          case nn:
            a = U.R16Float;
            break;
          case ln:
            a = U.R32Float;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RedFormat.", n);
        }
        break;
      case ri:
        switch (n) {
          case ba:
            a = U.RG8Snorm;
            break;
          case Sa:
            a = U.RG16Sint;
            break;
          case Ji:
            a = U.RG16Uint;
            break;
          case Dt:
            a = U.RG32Uint;
            break;
          case wn:
            a = U.RG32Sint;
            break;
          case Zt:
            a = U.RG8Unorm;
            break;
          case nn:
            a = U.RG16Float;
            break;
          case ln:
            a = U.RG32Float;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RGFormat.", n);
        }
        break;
      case Un:
        switch (n) {
          case Ji:
            a = U.Depth16Unorm;
            break;
          case Dt:
            a = U.Depth24Plus;
            break;
          case ln:
            a = U.Depth32Float;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with DepthFormat.", n);
        }
        break;
      case ii:
        switch (n) {
          case Ci:
            a = U.Depth24PlusStencil8;
            break;
          case ln:
            e && e.features.has(sm.Depth32FloatStencil8) === !1 && le('WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.'), a = U.Depth32FloatStencil8;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with DepthStencilFormat.", n);
        }
        break;
      case _l:
        switch (n) {
          case wn:
            a = U.R32Sint;
            break;
          case Dt:
            a = U.R32Uint;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RedIntegerFormat.", n);
        }
        break;
      case xl:
        switch (n) {
          case wn:
            a = U.RG32Sint;
            break;
          case Dt:
            a = U.RG32Uint;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RGIntegerFormat.", n);
        }
        break;
      case vl:
        switch (n) {
          case wn:
            a = U.RGBA32Sint;
            break;
          case Dt:
            a = U.RGBA32Uint;
            break;
          default:
            le("WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.", n);
        }
        break;
      default:
        le("WebGPURenderer: Unsupported texture format.", t);
    }
  return a;
}
const hV = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i, dV = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/ig, xv = {
  f32: "float",
  i32: "int",
  u32: "uint",
  bool: "bool",
  "vec2<f32>": "vec2",
  "vec2<i32>": "ivec2",
  "vec2<u32>": "uvec2",
  "vec2<bool>": "bvec2",
  vec2f: "vec2",
  vec2i: "ivec2",
  vec2u: "uvec2",
  vec2b: "bvec2",
  "vec3<f32>": "vec3",
  "vec3<i32>": "ivec3",
  "vec3<u32>": "uvec3",
  "vec3<bool>": "bvec3",
  vec3f: "vec3",
  vec3i: "ivec3",
  vec3u: "uvec3",
  vec3b: "bvec3",
  "vec4<f32>": "vec4",
  "vec4<i32>": "ivec4",
  "vec4<u32>": "uvec4",
  "vec4<bool>": "bvec4",
  vec4f: "vec4",
  vec4i: "ivec4",
  vec4u: "uvec4",
  vec4b: "bvec4",
  "mat2x2<f32>": "mat2",
  mat2x2f: "mat2",
  "mat3x3<f32>": "mat3",
  mat3x3f: "mat3",
  "mat4x4<f32>": "mat4",
  mat4x4f: "mat4",
  sampler: "sampler",
  texture_1d: "texture",
  texture_2d: "texture",
  texture_2d_array: "texture",
  texture_multisampled_2d: "cubeTexture",
  texture_depth_2d: "depthTexture",
  texture_depth_2d_array: "depthTexture",
  texture_depth_multisampled_2d: "depthTexture",
  texture_depth_cube: "depthTexture",
  texture_depth_cube_array: "depthTexture",
  texture_3d: "texture3D",
  texture_cube: "cubeTexture",
  texture_cube_array: "cubeTexture",
  texture_storage_1d: "storageTexture",
  texture_storage_2d: "storageTexture",
  texture_storage_2d_array: "storageTexture",
  texture_storage_3d: "storageTexture"
}, fV = (i) => {
  i = i.trim();
  const e = i.match(hV);
  if (e !== null && e.length === 4) {
    const t = e[2], n = [];
    let r = null;
    for (; (r = dV.exec(t)) !== null; )
      n.push({ name: r[1], type: r[2] });
    const s = [];
    for (let u = 0; u < n.length; u++) {
      const { name: h, type: d } = n[u];
      let f = d;
      f.startsWith("ptr") ? f = "pointer" : (f.startsWith("texture") && (f = d.split("<")[0]), f = xv[f]), s.push(new zg(f, h));
    }
    const a = i.substring(e[0].length), o = e[3] || "void", l = e[1] !== void 0 ? e[1] : "";
    return {
      type: xv[o] || o,
      inputs: s,
      name: l,
      inputsCode: t,
      blockCode: a,
      outputType: o
    };
  } else
    throw new Error("FunctionNode: Function is not a WGSL code.");
};
class pV extends $g {
  /**
   * Constructs a new WGSL node function.
   *
   * @param {string} source - The WGSL source.
   */
  constructor(e) {
    const { type: t, inputs: n, name: r, inputsCode: s, blockCode: a, outputType: o } = fV(e);
    super(t, n, r), this.inputsCode = s, this.blockCode = a, this.outputType = o;
  }
  /**
   * This method returns the WGSL code of the node function.
   *
   * @param {string} [name=this.name] - The function's name.
   * @return {string} The shader code.
   */
  getCode(e = this.name) {
    const t = this.outputType !== "void" ? "-> " + this.outputType : "";
    return `fn ${e} ( ${this.inputsCode.trim()} ) ${t}` + this.blockCode;
  }
}
class mV extends lT {
  /**
   * The method parses the given WGSL code an returns a node function.
   *
   * @param {string} source - The WGSL code.
   * @return {WGSLNodeFunction} A node function.
   */
  parseFunction(e) {
    return new pV(e);
  }
}
const gV = {
  [Bi.READ_ONLY]: "read",
  [Bi.WRITE_ONLY]: "write",
  [Bi.READ_WRITE]: "read_write"
}, vv = {
  [Ca]: "repeat",
  [fi]: "clamp",
  [Na]: "mirror"
}, mp = {
  vertex: Tr.VERTEX,
  fragment: Tr.FRAGMENT,
  compute: Tr.COMPUTE
}, yv = {
  instance: !0,
  swizzleAssign: !1,
  storageBuffer: !0
}, _V = {
  "^^": "tsl_xor"
}, xV = {
  float: "f32",
  int: "i32",
  uint: "u32",
  bool: "bool",
  color: "vec3<f32>",
  vec2: "vec2<f32>",
  ivec2: "vec2<i32>",
  uvec2: "vec2<u32>",
  bvec2: "vec2<bool>",
  vec3: "vec3<f32>",
  ivec3: "vec3<i32>",
  uvec3: "vec3<u32>",
  bvec3: "vec3<bool>",
  vec4: "vec4<f32>",
  ivec4: "vec4<i32>",
  uvec4: "vec4<u32>",
  bvec4: "vec4<bool>",
  mat2: "mat2x2<f32>",
  mat3: "mat3x3<f32>",
  mat4: "mat4x4<f32>"
}, bv = {}, rc = {
  tsl_xor: new En("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"),
  mod_float: new En("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"),
  mod_vec2: new En("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"),
  mod_vec3: new En("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"),
  mod_vec4: new En("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"),
  equals_bool: new En("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"),
  equals_bvec2: new En("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2<bool> { return vec2<bool>( a.x == b.x, a.y == b.y ); }"),
  equals_bvec3: new En("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3<bool> { return vec3<bool>( a.x == b.x, a.y == b.y, a.z == b.z ); }"),
  equals_bvec4: new En("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4<bool> { return vec4<bool>( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"),
  repeatWrapping_float: new En("fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }"),
  mirrorWrapping_float: new En("fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }"),
  clampWrapping_float: new En("fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }"),
  biquadraticTexture: new En(
    /* wgsl */
    `
fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {

	let res = vec2f( iRes );

	let uvScaled = coord * res;
	let uvWrapping = ( ( uvScaled % res ) + res ) % res;

	// https://www.shadertoy.com/view/WtyXRy

	let uv = uvWrapping - 0.5;
	let iuv = floor( uv );
	let f = fract( uv );

	let rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );
	let rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );
	let rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );
	let rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );

	return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );

}
`
  ),
  biquadraticTextureArray: new En(
    /* wgsl */
    `
fn tsl_biquadraticTexture_array( map : texture_2d_array<f32>, coord : vec2f, iRes : vec2u, layer : u32, level : u32 ) -> vec4f {

	let res = vec2f( iRes );

	let uvScaled = coord * res;
	let uvWrapping = ( ( uvScaled % res ) + res ) % res;

	// https://www.shadertoy.com/view/WtyXRy

	let uv = uvWrapping - 0.5;
	let iuv = floor( uv );
	let f = fract( uv );

	let rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, layer, level );
	let rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, layer, level );
	let rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, layer, level );
	let rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, layer, level );

	return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );

}
`
  )
}, vV = {
  dFdx: "dpdx",
  dFdy: "- dpdy",
  mod_float: "tsl_mod_float",
  mod_vec2: "tsl_mod_vec2",
  mod_vec3: "tsl_mod_vec3",
  mod_vec4: "tsl_mod_vec4",
  equals_bool: "tsl_equals_bool",
  equals_bvec2: "tsl_equals_bvec2",
  equals_bvec3: "tsl_equals_bvec3",
  equals_bvec4: "tsl_equals_bvec4",
  inversesqrt: "inverseSqrt",
  bitcast: "bitcast<f32>",
  floatpack_snorm_2x16: "pack2x16snorm",
  floatpack_unorm_2x16: "pack2x16unorm",
  floatpack_float16_2x16: "pack2x16float",
  floatunpack_snorm_2x16: "unpack2x16snorm",
  floatunpack_unorm_2x16: "unpack2x16unorm",
  floatunpack_float16_2x16: "unpack2x16float"
};
let vT = "";
(typeof navigator < "u" && /Firefox|Deno/g.test(navigator.userAgent)) !== !0 && (vT += `diagnostic( off, derivative_uniformity );
`);
class yV extends oT {
  /**
   * Constructs a new WGSL node builder renderer.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Renderer} renderer - The renderer.
   */
  constructor(e, t) {
    super(e, t, new mV()), this.uniformGroups = {}, this.uniformGroupsBindings = {}, this.builtins = {}, this.directives = {}, this.scopedArrays = /* @__PURE__ */ new Map();
  }
  /**
   * Generates the WGSL snippet for sampled textures.
   *
   * @private
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  _generateTextureSample(e, t, n, r, s, a = this.shaderStage) {
    return a === "fragment" ? r ? s ? `textureSample( ${t}, ${t}_sampler, ${n}, ${r}, ${s} )` : `textureSample( ${t}, ${t}_sampler, ${n}, ${r} )` : s ? `textureSample( ${t}, ${t}_sampler, ${n}, ${s} )` : `textureSample( ${t}, ${t}_sampler, ${n} )` : this.generateTextureSampleLevel(e, t, n, "0", r);
  }
  /**
   * Generates the WGSL snippet when sampling textures with explicit mip level.
   *
   * @private
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The WGSL snippet.
   */
  generateTextureSampleLevel(e, t, n, r, s, a) {
    return this.isUnfilterable(e) === !1 ? s ? a ? `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${s}, ${r}, ${a} )` : `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${s}, ${r} )` : a ? `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${r}, ${a} )` : `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${r} )` : this.isFilteredTexture(e) ? this.generateFilteredTexture(e, t, n, a, r, s) : this.generateTextureLod(e, t, n, s, a, r);
  }
  /**
   * Generates a wrap function used in context of textures.
   *
   * @param {Texture} texture - The texture to generate the function for.
   * @return {string} The name of the generated function.
   */
  generateWrapFunction(e) {
    const t = `tsl_coord_${vv[e.wrapS]}S_${vv[e.wrapT]}_${e.is3DTexture || e.isData3DTexture ? "3d" : "2d"}T`;
    let n = bv[t];
    if (n === void 0) {
      const r = [], s = e.is3DTexture || e.isData3DTexture ? "vec3f" : "vec2f";
      let a = `fn ${t}( coord : ${s} ) -> ${s} {

	return ${s}(
`;
      const o = (l, c) => {
        l === Ca ? (r.push(rc.repeatWrapping_float), a += `		tsl_repeatWrapping_float( coord.${c} )`) : l === fi ? (r.push(rc.clampWrapping_float), a += `		tsl_clampWrapping_float( coord.${c} )`) : l === Na ? (r.push(rc.mirrorWrapping_float), a += `		tsl_mirrorWrapping_float( coord.${c} )`) : (a += `		coord.${c}`, oe(`WebGPURenderer: Unsupported texture wrap type "${l}" for vertex shader.`));
      };
      o(e.wrapS, "x"), a += `,
`, o(e.wrapT, "y"), (e.is3DTexture || e.isData3DTexture) && (a += `,
`, o(e.wrapR, "z")), a += `
	);

}
`, bv[t] = n = new En(a, r);
    }
    return n.build(this), t;
  }
  /**
   * Generates the array declaration string.
   *
   * @param {string} type - The type.
   * @param {?number} [count] - The count.
   * @return {string} The generated value as a shader string.
   */
  generateArrayDeclaration(e, t) {
    return `array< ${this.getType(e)}, ${t} >`;
  }
  /**
   * Generates a WGSL variable that holds the texture dimension of the given texture.
   * It also returns information about the number of layers (elements) of an arrayed
   * texture as well as the cube face count of cube textures.
   *
   * @param {Texture} texture - The texture to generate the function for.
   * @param {string} textureProperty - The name of the video texture uniform in the shader.
   * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @return {string} The name of the dimension variable.
   */
  generateTextureDimension(e, t, n) {
    const r = this.getDataFromNode(e, this.shaderStage, this.globalCache);
    r.dimensionsSnippet === void 0 && (r.dimensionsSnippet = {});
    let s = r.dimensionsSnippet[n];
    if (r.dimensionsSnippet[n] === void 0) {
      let a, o;
      const { primarySamples: l } = this.renderer.backend.utils.getTextureSampleData(e), c = l > 1;
      e.is3DTexture || e.isData3DTexture ? o = "vec3<u32>" : o = "vec2<u32>", c || e.isStorageTexture ? a = t : a = `${t}${n ? `, u32( ${n} )` : ""}`, s = new Ah(new Rh(`textureDimensions( ${a} )`, o)), r.dimensionsSnippet[n] = s, (e.isArrayTexture || e.isDataArrayTexture || e.is3DTexture || e.isData3DTexture) && (r.arrayLayerCount = new Ah(
        new Rh(
          `textureNumLayers(${t})`,
          "u32"
        )
      )), e.isTextureCube && (r.cubeFaceCount = new Ah(
        new Rh("6u", "u32")
      ));
    }
    return s.build(this);
  }
  /**
   * Generates the WGSL snippet for a manual filtered texture.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @return {string} The WGSL snippet.
   */
  generateFilteredTexture(e, t, n, r, s = "0u", a) {
    const o = this.generateWrapFunction(e), l = this.generateTextureDimension(e, t, s);
    return r && (n = `${n} + vec2<f32>(${r}) / ${l}`), a ? (this._include("biquadraticTextureArray"), `tsl_biquadraticTexture_array( ${t}, ${o}( ${n} ), ${l}, u32( ${a} ), u32( ${s} ) )`) : (this._include("biquadraticTexture"), `tsl_biquadraticTexture( ${t}, ${o}( ${n} ), ${l}, u32( ${s} ) )`);
  }
  /**
   * Generates the WGSL snippet for a texture lookup with explicit level-of-detail.
   * Since it's a lookup, no sampling or filtering is applied.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [levelSnippet='0u'] - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @return {string} The WGSL snippet.
   */
  generateTextureLod(e, t, n, r, s, a = "0u") {
    if (e.isCubeTexture === !0) {
      s && (n = `${n} + vec3<f32>(${s})`);
      const f = e.isDepthTexture ? "u32" : "f32";
      return `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${f}( ${a} ) )`;
    }
    const o = this.generateWrapFunction(e), l = this.generateTextureDimension(e, t, a), c = e.is3DTexture || e.isData3DTexture ? "vec3" : "vec2", u = c === "vec3" ? "vec3<u32>( 1, 1, 1 )" : "vec2<u32>( 1, 1 )";
    s && (n = `${n} + ${c}<f32>(${s}) / ${c}<f32>( ${l} )`);
    const h = `${c}<f32>( 0 )`, d = `${c}<f32>( ${l} - ${u} )`;
    return n = `${c}<u32>( clamp( floor( ${o}( ${n} ) * ${c}<f32>( ${l} ) ), ${h}, ${d} ) )`, this.generateTextureLoad(e, t, n, a, r, null);
  }
  /**
   * Generates the WGSL snippet that reads a single texel from a storage texture.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The WGSL snippet.
   */
  generateStorageTextureLoad(e, t, n, r, s, a) {
    a && (n = `${n} + ${a}`);
    let o;
    return s ? o = `textureLoad( ${t}, ${n}, ${s} )` : o = `textureLoad( ${t}, ${n} )`, o;
  }
  /**
   * Generates the WGSL snippet that reads a single texel from a texture without sampling or filtering.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @return {string} The WGSL snippet.
   */
  generateTextureLoad(e, t, n, r, s, a) {
    r === null && (r = "0u"), a && (n = `${n} + ${a}`);
    let o;
    return s ? o = `textureLoad( ${t}, ${n}, ${s}, u32( ${r} ) )` : (o = `textureLoad( ${t}, ${n}, u32( ${r} ) )`, this.renderer.backend.compatibilityMode && e.isDepthTexture && (o += ".x")), o;
  }
  /**
   * Generates the WGSL snippet that writes a single texel to a texture.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvIndexSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {string} valueSnippet - A WGSL snippet that represent the new texel value.
   * @return {string} The WGSL snippet.
   */
  generateTextureStore(e, t, n, r, s) {
    let a;
    return r ? a = `textureStore( ${t}, ${n}, ${r}, ${s} )` : a = `textureStore( ${t}, ${n}, ${s} )`, a;
  }
  /**
   * Returns `true` if the sampled values of the given texture should be compared against a reference value.
   *
   * @param {Texture} texture - The texture.
   * @return {boolean} Whether the sampled values of the given texture should be compared against a reference value or not.
   */
  isSampleCompare(e) {
    return e.isDepthTexture === !0 && e.compareFunction !== null && this.renderer.hasCompatibility(rs.TEXTURE_COMPARE);
  }
  /**
   * Returns `true` if the given texture is unfilterable.
   *
   * @param {Texture} texture - The texture.
   * @return {boolean} Whether the given texture is unfilterable or not.
   */
  isUnfilterable(e) {
    return this.getComponentTypeFromTexture(e) !== "float" || !this.isAvailable("float32Filterable") && e.isDataTexture === !0 && e.type === ln || this.isSampleCompare(e) === !1 && e.minFilter === Tt && e.magFilter === Tt || this.renderer.backend.utils.getTextureSampleData(e).primarySamples > 1;
  }
  /**
   * Generates the WGSL snippet for sampling/loading the given texture.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  generateTexture(e, t, n, r, s, a = this.shaderStage) {
    let o = null;
    return this.isUnfilterable(e) ? o = this.generateTextureLod(e, t, n, r, s, "0", a) : o = this._generateTextureSample(e, t, n, r, s, a), o;
  }
  /**
   * Generates the WGSL snippet for sampling/loading the given texture using explicit gradients.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {Array<string>} gradSnippet - An array holding both gradient WGSL snippets.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  generateTextureGrad(e, t, n, r, s, a, o = this.shaderStage) {
    if (o === "fragment")
      return s ? a ? `textureSampleGrad( ${t}, ${t}_sampler, ${n}, ${s}, ${r[0]}, ${r[1]}, ${a} )` : `textureSampleGrad( ${t}, ${t}_sampler, ${n}, ${s}, ${r[0]}, ${r[1]} )` : a ? `textureSampleGrad( ${t}, ${t}_sampler, ${n}, ${r[0]}, ${r[1]}, ${a} )` : `textureSampleGrad( ${t}, ${t}_sampler, ${n}, ${r[0]}, ${r[1]} )`;
    le(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${o} shader.`);
  }
  /**
   * Generates the WGSL snippet for sampling a depth texture and comparing the sampled depth values
   * against a reference value.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {string} compareSnippet -  A WGSL snippet that represents the reference value.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  generateTextureCompare(e, t, n, r, s, a, o = this.shaderStage) {
    if (o === "fragment")
      return e.isDepthTexture === !0 && e.isArrayTexture === !0 ? a ? `textureSampleCompare( ${t}, ${t}_sampler, ${n}, ${s}, ${r}, ${a} )` : `textureSampleCompare( ${t}, ${t}_sampler, ${n}, ${s}, ${r} )` : a ? `textureSampleCompare( ${t}, ${t}_sampler, ${n}, ${r}, ${a} )` : `textureSampleCompare( ${t}, ${t}_sampler, ${n}, ${r} )`;
    le(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${o} shader.`);
  }
  /**
   * Generates the WGSL snippet when sampling textures with explicit mip level.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {string} levelSnippet - A WGSL snippet that represents the mip level, with level 0 containing a full size version of the texture.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  generateTextureLevel(e, t, n, r, s, a) {
    return this.isUnfilterable(e) === !1 ? s ? a ? `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${s}, ${r}, ${a} )` : `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${s}, ${r} )` : a ? `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${r}, ${a} )` : `textureSampleLevel( ${t}, ${t}_sampler, ${n}, ${r} )` : this.isFilteredTexture(e) ? this.generateFilteredTexture(e, t, n, a, r, s) : this.generateTextureLod(e, t, n, s, a, r);
  }
  /**
   * Generates the WGSL snippet when sampling textures with a bias to the mip level.
   *
   * @param {Texture} texture - The texture.
   * @param {string} textureProperty - The name of the texture uniform in the shader.
   * @param {string} uvSnippet - A WGSL snippet that represents texture coordinates used for sampling.
   * @param {string} biasSnippet - A WGSL snippet that represents the bias to apply to the mip level before sampling.
   * @param {?string} depthSnippet - A WGSL snippet that represents 0-based texture array index to sample.
   * @param {?string} offsetSnippet - A WGSL snippet that represents the offset that will be applied to the unnormalized texture coordinate before sampling the texture.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The WGSL snippet.
   */
  generateTextureBias(e, t, n, r, s, a, o = this.shaderStage) {
    if (o === "fragment")
      return s ? a ? `textureSampleBias( ${t}, ${t}_sampler, ${n}, ${s}, ${r}, ${a} )` : `textureSampleBias( ${t}, ${t}_sampler, ${n}, ${s}, ${r} )` : a ? `textureSampleBias( ${t}, ${t}_sampler, ${n}, ${r}, ${a} )` : `textureSampleBias( ${t}, ${t}_sampler, ${n}, ${r} )`;
    le(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${o} shader.`);
  }
  /**
   * Returns a WGSL snippet that represents the property name of the given node.
   *
   * @param {Node} node - The node.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The property name.
   */
  getPropertyName(e, t = this.shaderStage) {
    if (e.isNodeVarying === !0 && e.needsInterpolation === !0) {
      if (t === "vertex")
        return `varyings.${e.name}`;
    } else if (e.isNodeUniform === !0) {
      const n = e.name, r = e.type;
      return r === "texture" || r === "cubeTexture" || r === "cubeDepthTexture" || r === "storageTexture" || r === "texture3D" ? n : r === "buffer" || r === "storageBuffer" || r === "indirectStorageBuffer" ? this.isCustomStruct(e) ? n : n + ".value" : e.groupNode.name + "." + n;
    }
    return super.getPropertyName(e);
  }
  /**
   * Returns the output struct name.
   *
   * @return {string} The name of the output struct.
   */
  getOutputStructName() {
    return "output";
  }
  /**
   * Returns the native shader operator name for a given generic name.
   *
   * @param {string} op - The operator name to resolve.
   * @return {?string} The resolved operator name.
   */
  getFunctionOperator(e) {
    const t = _V[e];
    return t !== void 0 ? (this._include(t), t) : null;
  }
  /**
   * Returns the node access for the given node and shader stage.
   *
   * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
   * @param {string} shaderStage - The shader stage.
   * @return {string} The node access.
   */
  getNodeAccess(e, t) {
    return t !== "compute" ? e.isAtomic === !0 ? (oe("WebGPURenderer: Atomic operations are only supported in compute shaders."), Bi.READ_WRITE) : Bi.READ_ONLY : e.access;
  }
  /**
   * Returns A WGSL snippet representing the storage access.
   *
   * @param {StorageTextureNode|StorageBufferNode} node - The storage node.
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet representing the storage access.
   */
  getStorageAccess(e, t) {
    return gV[this.getNodeAccess(e, t)];
  }
  /**
   * This method is one of the more important ones since it's responsible
   * for generating a matching binding instance for the given uniform node.
   *
   * These bindings are later used in the renderer to create bind groups
   * and layouts.
   *
   * @param {UniformNode} node - The uniform node.
   * @param {string} type - The node data type.
   * @param {string} shaderStage - The shader stage.
   * @param {?string} [name=null] - An optional uniform name.
   * @return {NodeUniform} The node uniform object.
   */
  getUniformFromNode(e, t, n, r = null) {
    const s = super.getUniformFromNode(e, t, n, r), a = this.getDataFromNode(e, n, this.globalCache);
    if (a.uniformGPU === void 0) {
      let o;
      const l = e.groupNode, c = l.name, u = this.getBindGroupArray(c, n);
      if (t === "texture" || t === "cubeTexture" || t === "cubeDepthTexture" || t === "storageTexture" || t === "texture3D") {
        let h = null;
        const d = this.getNodeAccess(e, n);
        if (t === "texture" || t === "storageTexture" ? e.value.is3DTexture === !0 ? h = new rm(s.name, s.node, l, d) : h = new Nd(s.name, s.node, l, d) : t === "cubeTexture" || t === "cubeDepthTexture" ? h = new gT(s.name, s.node, l, d) : t === "texture3D" && (h = new rm(s.name, s.node, l, d)), h.store = e.isStorageTextureNode === !0, h.mipLevel = h.store ? e.mipLevel : 0, h.setVisibility(mp[n]), e.value.isCubeTexture === !0 || this.isUnfilterable(e.value) === !1 && h.store === !1) {
          const p = new iV(`${s.name}_sampler`, s.node, l);
          p.setVisibility(mp[n]), u.push(p, h), o = [p, h];
        } else
          u.push(h), o = [h];
      } else if (t === "buffer" || t === "storageBuffer" || t === "indirectStorageBuffer") {
        const h = this.getSharedDataFromNode(e);
        let d = h.buffer;
        if (d === void 0) {
          const f = t === "buffer" ? fT : aV;
          d = new f(e, l), h.buffer = d;
        }
        d.setVisibility(d.getVisibility() | mp[n]), u.push(d), o = d, s.name = r || "NodeBuffer_" + s.id;
      } else {
        let h = this.uniformGroups[c];
        h === void 0 && (h = new pT(c, l), h.setVisibility(Tr.VERTEX | Tr.FRAGMENT | Tr.COMPUTE), this.uniformGroups[c] = h), u.indexOf(h) === -1 && u.push(h), o = this.getNodeUniform(s, t);
        const d = o.name;
        h.uniforms.some((p) => p.name === d) || h.addUniform(o);
      }
      a.uniformGPU = o;
    }
    return s;
  }
  /**
   * This method should be used whenever builtins are required in nodes.
   * The internal builtins data structure will make sure builtins are
   * defined in the WGSL source.
   *
   * @param {string} name - The builtin name.
   * @param {string} property - The property name.
   * @param {string} type - The node data type.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {string} The property name.
   */
  getBuiltin(e, t, n, r = this.shaderStage) {
    const s = this.builtins[r] || (this.builtins[r] = /* @__PURE__ */ new Map());
    return s.has(e) === !1 && s.set(e, {
      name: e,
      property: t,
      type: n
    }), t;
  }
  /**
   * Returns `true` if the given builtin is defined in the given shader stage.
   *
   * @param {string} name - The builtin name.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage this code snippet is generated for.
   * @return {boolean} Whether the given builtin is defined in the given shader stage or not.
   */
  hasBuiltin(e, t = this.shaderStage) {
    return this.builtins[t] !== void 0 && this.builtins[t].has(e);
  }
  /**
   * Returns the vertex index builtin.
   *
   * @return {string} The vertex index.
   */
  getVertexIndex() {
    return this.shaderStage === "vertex" ? this.getBuiltin("vertex_index", "vertexIndex", "u32", "attribute") : "vertexIndex";
  }
  /**
   * Builds the given shader node.
   *
   * @param {ShaderNodeInternal} shaderNode - The shader node.
   * @return {string} The WGSL function code.
   */
  buildFunctionCode(e) {
    const t = e.layout, n = this.flowShaderNode(e), r = [];
    for (const a of t.inputs)
      r.push(a.name + " : " + this.getType(a.type));
    let s = `fn ${t.name}( ${r.join(", ")} ) -> ${this.getType(t.type)} {
${n.vars}
${n.code}
`;
    return n.result && (s += `	return ${n.result};
`), s += `
}
`, s;
  }
  /**
   * Contextually returns either the vertex stage instance index builtin
   * or the linearized index of an compute invocation within a grid of workgroups.
   *
   * @return {string} The instance index.
   */
  getInstanceIndex() {
    return this.shaderStage === "vertex" ? this.getBuiltin("instance_index", "instanceIndex", "u32", "attribute") : "instanceIndex";
  }
  /**
   * Returns a builtin representing the index of a compute invocation within the scope of a workgroup load.
   *
   * @return {string} The invocation local index.
   */
  getInvocationLocalIndex() {
    return this.getBuiltin("local_invocation_index", "invocationLocalIndex", "u32", "attribute");
  }
  /**
   * Returns a builtin representing the size of a subgroup within the current shader.
   *
   * @return {string} The subgroup size.
   */
  getSubgroupSize() {
    return this.enableSubGroups(), this.getBuiltin("subgroup_size", "subgroupSize", "u32", "attribute");
  }
  /**
   * Returns a builtin representing the index of a compute invocation within the scope of a subgroup.
   *
   * @return {string} The invocation subgroup index.
   */
  getInvocationSubgroupIndex() {
    return this.enableSubGroups(), this.getBuiltin("subgroup_invocation_id", "invocationSubgroupIndex", "u32", "attribute");
  }
  /**
   * Returns a builtin representing the index of a compute invocation's subgroup within its workgroup.
   *
   * @return {string} The subgroup index.
   */
  getSubgroupIndex() {
    return this.enableSubGroups(), this.getBuiltin("subgroup_id", "subgroupIndex", "u32", "attribute");
  }
  /**
   * Overwritten as a NOP since this method is intended for the WebGL 2 backend.
   *
   * @return {null} Null.
   */
  getDrawIndex() {
    return null;
  }
  /**
   * Returns the front facing builtin.
   *
   * @return {string} The front facing builtin.
   */
  getFrontFacing() {
    return this.getBuiltin("front_facing", "isFront", "bool");
  }
  /**
   * Returns the frag coord builtin.
   *
   * @return {string} The frag coord builtin.
   */
  getFragCoord() {
    return this.getBuiltin("position", "fragCoord", "vec4<f32>") + ".xy";
  }
  /**
   * Returns the frag depth builtin.
   *
   * @return {string} The frag depth builtin.
   */
  getFragDepth() {
    return "output." + this.getBuiltin("frag_depth", "depth", "f32", "output");
  }
  /**
   * Returns the clip distances builtin.
   *
   * @return {string} The clip distances builtin.
   */
  getClipDistance() {
    return "varyings.hw_clip_distances";
  }
  /**
   * Whether to flip texture data along its vertical axis or not.
   *
   * @return {boolean} Returns always `false` in context of WGSL.
   */
  isFlipY() {
    return !1;
  }
  /**
   * Enables the given directive for the given shader stage.
   *
   * @param {string} name - The directive name.
   * @param {string} [shaderStage=this.shaderStage] - The shader stage to enable the directive for.
   */
  enableDirective(e, t = this.shaderStage) {
    (this.directives[t] || (this.directives[t] = /* @__PURE__ */ new Set())).add(e);
  }
  /**
   * Returns the directives of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} A WGSL snippet that enables the directives of the given stage.
   */
  getDirectives(e) {
    const t = [], n = this.directives[e];
    if (n !== void 0)
      for (const r of n)
        t.push(`enable ${r};`);
    return t.join(`
`);
  }
  /**
   * Enables the 'subgroups' directive.
   */
  enableSubGroups() {
    this.enableDirective("subgroups");
  }
  /**
   * Enables the 'subgroups-f16' directive.
   */
  enableSubgroupsF16() {
    this.enableDirective("subgroups-f16");
  }
  /**
   * Enables the 'clip_distances' directive.
   */
  enableClipDistances() {
    this.enableDirective("clip_distances");
  }
  /**
   * Enables the 'f16' directive.
   */
  enableShaderF16() {
    this.enableDirective("f16");
  }
  /**
   * Enables the 'dual_source_blending' directive.
   */
  enableDualSourceBlending() {
    this.enableDirective("dual_source_blending");
  }
  /**
   * Enables hardware clipping.
   *
   * @param {string} planeCount - The clipping plane count.
   */
  enableHardwareClipping(e) {
    this.enableClipDistances(), this.getBuiltin("clip_distances", "hw_clip_distances", `array<f32, ${e} >`, "vertex");
  }
  /**
   * Returns the builtins of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} A WGSL snippet that represents the builtins of the given stage.
   */
  getBuiltins(e) {
    const t = [], n = this.builtins[e];
    if (n !== void 0)
      for (const { name: r, property: s, type: a } of n.values())
        t.push(`@builtin( ${r} ) ${s} : ${a}`);
    return t.join(`,
	`);
  }
  /**
   * This method should be used when a new scoped buffer is used in context of
   * compute shaders. It adds the array to the internal data structure which is
   * later used to generate the respective WGSL.
   *
   * @param {string} name - The array name.
   * @param {string} scope - The scope.
   * @param {string} bufferType - The buffer type.
   * @param {string} bufferCount - The buffer count.
   * @return {string} The array name.
   */
  getScopedArray(e, t, n, r) {
    return this.scopedArrays.has(e) === !1 && this.scopedArrays.set(e, {
      name: e,
      scope: t,
      bufferType: n,
      bufferCount: r
    }), e;
  }
  /**
   * Returns the scoped arrays of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string|undefined} The WGSL snippet that defines the scoped arrays.
   * Returns `undefined` when used in the vertex or fragment stage.
   */
  getScopedArrays(e) {
    if (e !== "compute")
      return;
    const t = [];
    for (const { name: n, scope: r, bufferType: s, bufferCount: a } of this.scopedArrays.values()) {
      const o = this.getType(s);
      t.push(`var<${r}> ${n}: array< ${o}, ${a} >;`);
    }
    return t.join(`
`);
  }
  /**
   * Returns the shader attributes of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet that defines the shader attributes.
   */
  getAttributes(e) {
    const t = [];
    if (e === "compute" && (this.getBuiltin("global_invocation_id", "globalId", "vec3<u32>", "attribute"), this.getBuiltin("workgroup_id", "workgroupId", "vec3<u32>", "attribute"), this.getBuiltin("local_invocation_id", "localId", "vec3<u32>", "attribute"), this.getBuiltin("num_workgroups", "numWorkgroups", "vec3<u32>", "attribute"), this.renderer.hasFeature("subgroups") && (this.enableDirective("subgroups", e), this.getBuiltin("subgroup_size", "subgroupSize", "u32", "attribute"))), e === "vertex" || e === "compute") {
      const n = this.getBuiltins("attribute");
      n && t.push(n);
      const r = this.getAttributesArray();
      for (let s = 0, a = r.length; s < a; s++) {
        const o = r[s], l = o.name, c = this.getType(o.type);
        t.push(`@location( ${s} ) ${l} : ${c}`);
      }
    }
    return t.join(`,
	`);
  }
  /**
   * Returns the members of the given struct type node as a WGSL string.
   *
   * @param {StructTypeNode} struct - The struct type node.
   * @return {string} The WGSL snippet that defines the struct members.
   */
  getStructMembers(e) {
    const t = [];
    for (const n of e.members) {
      const r = e.output ? "@location( " + n.index + " ) " : "";
      let s = this.getType(n.type);
      n.atomic && (s = "atomic< " + s + " >"), t.push(`	${r + n.name} : ${s}`);
    }
    return e.output && t.push(`	${this.getBuiltins("output")}`), t.join(`,
`);
  }
  /**
   * Returns the structs of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet that defines the structs.
   */
  getStructs(e) {
    let t = "";
    const n = this.structs[e];
    if (n.length > 0) {
      const r = [];
      for (const s of n) {
        let a = `struct ${s.name} {
`;
        a += this.getStructMembers(s), a += `
};`, r.push(a);
      }
      t = `
` + r.join(`

`) + `
`;
    }
    return t;
  }
  /**
   * Returns a WGSL string representing a variable.
   *
   * @param {string} type - The variable's type.
   * @param {string} name - The variable's name.
   * @param {?number} [count=null] - The array length.
   * @return {string} The WGSL snippet that defines a variable.
   */
  getVar(e, t, n = null) {
    let r = `var ${t} : `;
    return n !== null ? r += this.generateArrayDeclaration(e, n) : r += this.getType(e), r;
  }
  /**
   * Returns the variables of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet that defines the variables.
   */
  getVars(e) {
    const t = [], n = this.vars[e];
    if (n !== void 0)
      for (const r of n)
        t.push(`	${this.getVar(r.type, r.name, r.count)};`);
    return `
${t.join(`
`)}
`;
  }
  /**
   * Returns the varyings of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet that defines the varyings.
   */
  getVaryings(e) {
    const t = [];
    if (e === "vertex" && this.getBuiltin("position", "builtinClipSpace", "vec4<f32>", "vertex"), e === "vertex" || e === "fragment") {
      const s = this.varyings, a = this.vars[e];
      for (let o = 0; o < s.length; o++) {
        const l = s[o];
        if (l.needsInterpolation) {
          let c = `@location( ${o} )`;
          if (l.interpolationType) {
            const u = l.interpolationSampling !== null ? `, ${l.interpolationSampling} )` : " )";
            c += ` @interpolate( ${l.interpolationType}${u}`;
          } else
            /^(int|uint|ivec|uvec)/.test(l.type) && (c += " @interpolate(flat, either)");
          t.push(`${c} ${l.name} : ${this.getType(l.type)}`);
        } else
          e === "vertex" && a.includes(l) === !1 && a.push(l);
      }
    }
    const n = this.getBuiltins(e);
    n && t.push(n);
    const r = t.join(`,
	`);
    return e === "vertex" ? this._getWGSLStruct("VaryingsStruct", "	" + r) : r;
  }
  isCustomStruct(e) {
    const t = e.value, n = e.node, r = (t.isBufferAttribute || t.isInstancedBufferAttribute) && n.structTypeNode !== null, s = n.value && n.value.array && typeof n.value.itemSize == "number" && n.value.array.length > n.value.itemSize;
    return r && !s;
  }
  /**
   * Returns the uniforms of the given shader stage as a WGSL string.
   *
   * @param {string} shaderStage - The shader stage.
   * @return {string} The WGSL snippet that defines the uniforms.
   */
  getUniforms(e) {
    const t = this.uniforms[e], n = [], r = [], s = [], a = {};
    for (const l of t) {
      const c = l.groupNode.name, u = this.bindingsIndexes[c];
      if (l.type === "texture" || l.type === "cubeTexture" || l.type === "cubeDepthTexture" || l.type === "storageTexture" || l.type === "texture3D") {
        const h = l.node.value;
        (h.isCubeTexture === !0 || this.isUnfilterable(h) === !1 && l.node.isStorageTextureNode !== !0) && (this.isSampleCompare(h) ? n.push(`@binding( ${u.binding++} ) @group( ${u.group} ) var ${l.name}_sampler : sampler_comparison;`) : n.push(`@binding( ${u.binding++} ) @group( ${u.group} ) var ${l.name}_sampler : sampler;`));
        let f, p = "";
        const { primarySamples: _ } = this.renderer.backend.utils.getTextureSampleData(h);
        if (_ > 1 && (p = "_multisampled"), h.isCubeTexture === !0 && h.isDepthTexture === !0)
          f = "texture_depth_cube";
        else if (h.isCubeTexture === !0)
          f = "texture_cube<f32>";
        else if (h.isDepthTexture === !0)
          this.renderer.backend.compatibilityMode && h.compareFunction === null ? f = `texture${p}_2d<f32>` : f = `texture_depth${p}_2d${h.isArrayTexture === !0 ? "_array" : ""}`;
        else if (l.node.isStorageTextureNode === !0) {
          const g = am(h), m = this.getStorageAccess(l.node, e), x = l.node.value.is3DTexture, y = l.node.value.isArrayTexture;
          f = `texture_storage_${x ? "3d" : `2d${y ? "_array" : ""}`}<${g}, ${m}>`;
        } else if (h.isArrayTexture === !0 || h.isDataArrayTexture === !0 || h.isCompressedArrayTexture === !0)
          f = "texture_2d_array<f32>";
        else if (h.is3DTexture === !0 || h.isData3DTexture === !0)
          f = "texture_3d<f32>";
        else {
          const g = this.getComponentTypeFromTexture(h).charAt(0);
          f = `texture${p}_2d<${g}32>`;
        }
        n.push(`@binding( ${u.binding++} ) @group( ${u.group} ) var ${l.name} : ${f};`);
      } else if (l.type === "buffer" || l.type === "storageBuffer" || l.type === "indirectStorageBuffer") {
        const h = l.node, d = this.getType(h.getNodeType(this)), f = h.bufferCount, p = f > 0 && l.type === "buffer" ? ", " + f : "", _ = h.isStorageBufferNode ? `storage, ${this.getStorageAccess(h, e)}` : "uniform";
        if (this.isCustomStruct(l))
          r.push(`@binding( ${u.binding++} ) @group( ${u.group} ) var<${_}> ${l.name} : ${d};`);
        else {
          const m = `	value : array< ${h.isAtomic ? `atomic<${d}>` : `${d}`}${p} >`;
          r.push(this._getWGSLStructBinding(l.name, m, _, u.binding++, u.group));
        }
      } else {
        const h = l.groupNode.name;
        if (a[h] === void 0) {
          const d = this.uniformGroups[h];
          if (d !== void 0) {
            const f = [];
            for (const _ of d.uniforms) {
              const g = _.getType(), m = this.getType(this.getVectorType(g));
              f.push(`	${_.name} : ${m}`);
            }
            let p = this.uniformGroupsBindings[h];
            p === void 0 && (p = {
              index: u.binding++,
              id: u.group
            }, this.uniformGroupsBindings[h] = p), a[h] = {
              index: p.index,
              id: p.id,
              snippets: f
            };
          }
        }
      }
    }
    for (const l in a) {
      const c = a[l];
      s.push(this._getWGSLStructBinding(l, c.snippets.join(`,
`), "uniform", c.index, c.id));
    }
    return [...n, ...r, ...s].join(`
`);
  }
  /**
   * Controls the code build of the shader stages.
   */
  buildCode() {
    const e = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} };
    this.sortBindingGroups();
    for (const t in e) {
      this.shaderStage = t;
      const n = e[t];
      n.uniforms = this.getUniforms(t), n.attributes = this.getAttributes(t), n.varyings = this.getVaryings(t), n.structs = this.getStructs(t), n.vars = this.getVars(t), n.codes = this.getCodes(t), n.directives = this.getDirectives(t), n.scopedArrays = this.getScopedArrays(t);
      let r = `// code

`;
      r += this.flowCode[t];
      const s = this.flowNodes[t], a = s[s.length - 1], o = a.outputNode, l = o !== void 0 && o.isOutputStructNode === !0;
      for (const c of s) {
        const u = this.getFlowData(
          c
          /*, shaderStage*/
        ), h = c.name;
        if (h && (r.length > 0 && (r += `
`), r += `	// flow -> ${h}
`), r += `${u.code}
	`, c === a && t !== "compute") {
          if (r += `// result

	`, t === "vertex")
            r += `varyings.builtinClipSpace = ${u.result};`;
          else if (t === "fragment")
            if (l)
              n.returnType = o.getNodeType(this), n.structs += "var<private> output : " + n.returnType + ";", r += `return ${u.result};`;
            else {
              let d = "	@location(0) color: vec4<f32>";
              const f = this.getBuiltins("output");
              f && (d += `,
	` + f), n.returnType = "OutputStruct", n.structs += this._getWGSLStruct("OutputStruct", d), n.structs += `
var<private> output : OutputStruct;`, r += `output.color = ${u.result};

	return output;`;
            }
        }
      }
      n.flow = r;
    }
    if (this.shaderStage = null, this.material !== null)
      this.vertexShader = this._getWGSLVertexCode(e.vertex), this.fragmentShader = this._getWGSLFragmentCode(e.fragment);
    else {
      const t = this.object.workgroupSize;
      this.computeShader = this._getWGSLComputeCode(e.compute, t);
    }
  }
  /**
   * Returns the native shader method name for a given generic name.
   *
   * @param {string} method - The method name to resolve.
   * @param {?string} [output=null] - An optional output.
   * @return {string} The resolved WGSL method name.
   */
  getMethod(e, t = null) {
    let n;
    return t !== null && (n = this._getWGSLMethod(e + "_" + t)), n === void 0 && (n = this._getWGSLMethod(e)), n || e;
  }
  /**
   * Returns the bitcast method name for a given input and outputType.
   *
   * @param {string} type - The output type to bitcast to.
   * @return {string} The resolved WGSL bitcast invocation.
   */
  getBitcastMethod(e) {
    return `bitcast<${this.getType(e)}>`;
  }
  /**
   * Returns the float packing method name for a given numeric encoding.
   *
   * @param {string} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
   * @returns {string} The resolve WGSL float packing method name.
   */
  getFloatPackingMethod(e) {
    return this.getMethod(`floatpack_${e}_2x16`);
  }
  /**
   * Returns the float unpacking method name for a given numeric encoding.
   *
   * @param {string} encoding - The numeric encoding that describes how the integer values are mapped to the float range.
   * @returns {string} The resolve WGSL float unpacking method name.
   */
  getFloatUnpackingMethod(e) {
    return this.getMethod(`floatunpack_${e}_2x16`);
  }
  /**
   * Returns the native snippet for a ternary operation.
   *
   * @param {string} condSnippet - The condition determining which expression gets resolved.
   * @param {string} ifSnippet - The expression to resolve to if the condition is true.
   * @param {string} elseSnippet - The expression to resolve to if the condition is false.
   * @return {string} The resolved method name.
   */
  getTernary(e, t, n) {
    return `select( ${n}, ${t}, ${e} )`;
  }
  /**
   * Returns the WGSL type of the given node data type.
   *
   * @param {string} type - The node data type.
   * @return {string} The WGSL type.
   */
  getType(e) {
    return xV[e] || e;
  }
  /**
   * Whether the requested feature is available or not.
   *
   * @param {string} name - The requested feature.
   * @return {boolean} Whether the requested feature is supported or not.
   */
  isAvailable(e) {
    let t = yv[e];
    return t === void 0 && (e === "float32Filterable" ? t = this.renderer.hasFeature("float32-filterable") : e === "clipDistance" && (t = this.renderer.hasFeature("clip-distances")), yv[e] = t), t;
  }
  /**
   * Returns the maximum uniform buffer size limit.
   *
   * @return {number} The maximum uniform buffer size in bytes.
   */
  getUniformBufferLimit() {
    return this.renderer.backend.device.limits.maxUniformBufferBindingSize;
  }
  /**
   * Returns the native shader method name for a given generic name.
   *
   * @private
   * @param {string} method - The method name to resolve.
   * @return {string} The resolved WGSL method name.
   */
  _getWGSLMethod(e) {
    return rc[e] !== void 0 && this._include(e), vV[e];
  }
  /**
   * Includes the given method name into the current
   * function node.
   *
   * @private
   * @param {string} name - The method name to include.
   * @return {CodeNode} The respective code node.
   */
  _include(e) {
    const t = rc[e];
    return t.build(this), this.addInclude(t), t;
  }
  /**
   * Returns a WGSL vertex shader based on the given shader data.
   *
   * @private
   * @param {Object} shaderData - The shader data.
   * @return {string} The vertex shader.
   */
  _getWGSLVertexCode(e) {
    return `${this.getSignature()}
// directives
${e.directives}

// structs
${e.structs}

// uniforms
${e.uniforms}

// varyings
${e.varyings}
var<private> varyings : VaryingsStruct;

// codes
${e.codes}

@vertex
fn main( ${e.attributes} ) -> VaryingsStruct {

	// vars
	${e.vars}

	// flow
	${e.flow}

	return varyings;

}
`;
  }
  /**
   * Returns a WGSL fragment shader based on the given shader data.
   *
   * @private
   * @param {Object} shaderData - The shader data.
   * @return {string} The vertex shader.
   */
  _getWGSLFragmentCode(e) {
    return `${this.getSignature()}
// global
${vT}

// structs
${e.structs}

// uniforms
${e.uniforms}

// codes
${e.codes}

@fragment
fn main( ${e.varyings} ) -> ${e.returnType} {

	// vars
	${e.vars}

	// flow
	${e.flow}

}
`;
  }
  /**
   * Returns a WGSL compute shader based on the given shader data.
   *
   * @private
   * @param {Object} shaderData - The shader data.
   * @param {string} workgroupSize - The workgroup size.
   * @return {string} The vertex shader.
   */
  _getWGSLComputeCode(e, t) {
    const [n, r, s] = t;
    return `${this.getSignature()}
// directives
${e.directives}

// system
var<private> instanceIndex : u32;

// locals
${e.scopedArrays}

// structs
${e.structs}

// uniforms
${e.uniforms}

// codes
${e.codes}

@compute @workgroup_size( ${n}, ${r}, ${s} )
fn main( ${e.attributes} ) {

	// system
	instanceIndex = globalId.x
		+ globalId.y * ( ${n} * numWorkgroups.x )
		+ globalId.z * ( ${n} * numWorkgroups.x ) * ( ${r} * numWorkgroups.y );

	// vars
	${e.vars}

	// flow
	${e.flow}

}
`;
  }
  /**
   * Returns a WGSL struct based on the given name and variables.
   *
   * @private
   * @param {string} name - The struct name.
   * @param {string} vars - The struct variables.
   * @return {string} The WGSL snippet representing a struct.
   */
  _getWGSLStruct(e, t) {
    return `
struct ${e} {
${t}
};`;
  }
  /**
   * Returns a WGSL struct binding.
   *
   * @private
   * @param {string} name - The struct name.
   * @param {string} vars - The struct variables.
   * @param {string} access - The access.
   * @param {number} [binding=0] - The binding index.
   * @param {number} [group=0] - The group index.
   * @return {string} The WGSL snippet representing a struct binding.
   */
  _getWGSLStructBinding(e, t, n, r = 0, s = 0) {
    const a = e + "Struct";
    return `${this._getWGSLStruct(a, t)}
@binding( ${r} ) @group( ${s} )
var<${n}> ${e} : ${a};`;
  }
}
class bV {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGPUBackend} backend - The WebGPU backend.
   */
  constructor(e) {
    this.backend = e;
  }
  /**
   * Returns the depth/stencil GPU format for the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {string} The depth/stencil GPU texture format.
   */
  getCurrentDepthStencilFormat(e) {
    let t;
    return e.depth && (e.depthTexture !== null ? t = this.getTextureFormatGPU(e.depthTexture) : e.stencil ? t = U.Depth24PlusStencil8 : t = U.Depth24Plus), t;
  }
  /**
   * Returns the GPU format for the given texture.
   *
   * @param {Texture} texture - The texture.
   * @return {string} The GPU texture format.
   */
  getTextureFormatGPU(e) {
    return this.backend.get(e).format;
  }
  /**
   * Returns an object that defines the multi-sampling state of the given texture.
   *
   * @param {Texture} texture - The texture.
   * @return {Object} The multi-sampling state.
   */
  getTextureSampleData(e) {
    let t;
    if (e.isFramebufferTexture)
      t = 1;
    else if (e.isDepthTexture && !e.renderTarget) {
      const s = this.backend.renderer, a = s.getRenderTarget();
      t = a ? a.samples : s.currentSamples;
    } else
      e.renderTarget && (t = e.renderTarget.samples);
    t = t || 1;
    const n = t > 1 && e.renderTarget !== null && e.isDepthTexture !== !0 && e.isFramebufferTexture !== !0;
    return { samples: t, primarySamples: n ? 1 : t, isMSAA: n };
  }
  /**
   * Returns the default color attachment's GPU format of the current render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {string} The GPU texture format of the default color attachment.
   */
  getCurrentColorFormat(e) {
    let t;
    return e.textures !== null ? t = this.getTextureFormatGPU(e.textures[0]) : t = this.getPreferredCanvasFormat(), t;
  }
  /**
   * Returns the GPU formats of all color attachments of the current render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {Array<string>} The GPU texture formats of all color attachments.
   */
  getCurrentColorFormats(e) {
    return e.textures !== null ? e.textures.map((t) => this.getTextureFormatGPU(t)) : [this.getPreferredCanvasFormat()];
  }
  /**
   * Returns the output color space of the current render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {string} The output color space.
   */
  getCurrentColorSpace(e) {
    return e.textures !== null ? e.textures[0].colorSpace : this.backend.renderer.outputColorSpace;
  }
  /**
   * Returns GPU primitive topology for the given object and material.
   *
   * @param {Object3D} object - The 3D object.
   * @param {Material} material - The material.
   * @return {string} The GPU primitive topology.
   */
  getPrimitiveTopology(e, t) {
    if (e.isPoints)
      return dh.PointList;
    if (e.isLineSegments || e.isMesh && t.wireframe === !0)
      return dh.LineList;
    if (e.isLine)
      return dh.LineStrip;
    if (e.isMesh)
      return dh.TriangleList;
  }
  /**
   * Returns a modified sample count from the given sample count value.
   *
   * That is required since WebGPU only supports either 1 or 4.
   *
   * @param {number} sampleCount - The input sample count.
   * @return {number} The (potentially updated) output sample count.
   */
  getSampleCount(e) {
    return e >= 4 ? 4 : 1;
  }
  /**
   * Returns the sample count of the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {number} The sample count.
   */
  getSampleCountRenderContext(e) {
    return e.textures !== null ? this.getSampleCount(e.sampleCount) : this.getSampleCount(this.backend.renderer.currentSamples);
  }
  /**
   * Returns the preferred canvas format.
   *
   * There is a separate method for this so it's possible to
   * honor edge cases for specific devices.
   *
   * @return {string} The GPU texture format of the canvas.
   */
  getPreferredCanvasFormat() {
    const t = this.backend.parameters.outputType;
    if (t === void 0)
      return navigator.gpu.getPreferredCanvasFormat();
    if (t === Zt)
      return U.BGRA8Unorm;
    if (t === nn)
      return U.RGBA16Float;
    throw new Error("Unsupported output buffer type.");
  }
}
const yT = /* @__PURE__ */ new Map([
  [Int8Array, ["sint8", "snorm8"]],
  [Uint8Array, ["uint8", "unorm8"]],
  [Int16Array, ["sint16", "snorm16"]],
  [Uint16Array, ["uint16", "unorm16"]],
  [Int32Array, ["sint32", "snorm32"]],
  [Uint32Array, ["uint32", "unorm32"]],
  [Float32Array, ["float32"]]
]);
typeof Float16Array < "u" && yT.set(Float16Array, ["float16"]);
const SV = /* @__PURE__ */ new Map([
  [ey, ["float16"]]
]), TV = /* @__PURE__ */ new Map([
  [Int32Array, "sint32"],
  [Int16Array, "sint32"],
  // patch for INT16
  [Uint32Array, "uint32"],
  [Uint16Array, "uint32"],
  // patch for UINT16
  [Float32Array, "float32"]
]);
class MV {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGPUBackend} backend - The WebGPU backend.
   */
  constructor(e) {
    this.backend = e;
  }
  /**
   * Creates the GPU buffer for the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   * @param {GPUBufferUsage} usage - A flag that indicates how the buffer may be used after its creation.
   */
  createAttribute(e, t) {
    const n = this._getBufferAttribute(e), r = this.backend, s = r.get(n);
    let a = s.buffer;
    if (a === void 0) {
      const o = r.device;
      let l = n.array;
      if (e.normalized === !1) {
        if (l.constructor === Int16Array || l.constructor === Int8Array)
          l = new Int32Array(l);
        else if ((l.constructor === Uint16Array || l.constructor === Uint8Array) && (l = new Uint32Array(l), t & GPUBufferUsage.INDEX))
          for (let h = 0; h < l.length; h++)
            l[h] === 65535 && (l[h] = 4294967295);
      }
      if (n.array = l, (n.isStorageBufferAttribute || n.isStorageInstancedBufferAttribute) && n.itemSize === 3) {
        l = new l.constructor(n.count * 4);
        for (let h = 0; h < n.count; h++)
          l.set(n.array.subarray(h * 3, h * 3 + 3), h * 4);
        n.itemSize = 4, n.array = l, s._force3to4BytesAlignment = !0;
      }
      const c = l.byteLength, u = c + (4 - c % 4) % 4;
      a = o.createBuffer({
        label: n.name,
        size: u,
        usage: t,
        mappedAtCreation: !0
      }), new l.constructor(a.getMappedRange()).set(l), a.unmap(), s.buffer = a;
    }
  }
  /**
   * Updates the GPU buffer of the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  updateAttribute(e) {
    const t = this._getBufferAttribute(e), n = this.backend, r = n.device, s = n.get(t), a = n.get(t).buffer;
    let o = t.array;
    if (s._force3to4BytesAlignment === !0) {
      o = new o.constructor(t.count * 4);
      for (let c = 0; c < t.count; c++)
        o.set(t.array.subarray(c * 3, c * 3 + 3), c * 4);
      t.array = o;
    }
    const l = t.updateRanges;
    if (l.length === 0)
      r.queue.writeBuffer(
        a,
        0,
        o,
        0
      );
    else {
      const c = Lh(o), u = c ? 1 : o.BYTES_PER_ELEMENT;
      for (let h = 0, d = l.length; h < d; h++) {
        const f = l[h];
        let p, _;
        if (s._force3to4BytesAlignment === !0) {
          const m = Math.floor(f.start / 3), x = Math.ceil(f.count / 3);
          p = m * 4 * u, _ = x * 4 * u;
        } else
          p = f.start * u, _ = f.count * u;
        const g = p * (c ? o.BYTES_PER_ELEMENT : 1);
        r.queue.writeBuffer(
          a,
          g,
          o,
          p,
          _
        );
      }
      t.clearUpdateRanges();
    }
  }
  /**
   * This method creates the vertex buffer layout data which are
   * require when creating a render pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {Array<Object>} An array holding objects which describe the vertex buffer layout.
   */
  createShaderVertexBuffers(e) {
    const t = e.getAttributes(), n = /* @__PURE__ */ new Map();
    for (let r = 0; r < t.length; r++) {
      const s = t[r], a = s.array.BYTES_PER_ELEMENT, o = this._getBufferAttribute(s);
      let l = n.get(o);
      if (l === void 0) {
        let h, d;
        s.isInterleavedBufferAttribute === !0 ? (h = s.data.stride * a, d = s.data.isInstancedInterleavedBuffer ? fh.Instance : fh.Vertex) : (h = s.itemSize * a, d = s.isInstancedBufferAttribute ? fh.Instance : fh.Vertex), s.normalized === !1 && (s.array.constructor === Int16Array || s.array.constructor === Uint16Array) && (h = 4), l = {
          arrayStride: h,
          attributes: [],
          stepMode: d
        }, n.set(o, l);
      }
      const c = this._getVertexFormat(s), u = s.isInterleavedBufferAttribute === !0 ? s.offset * a : 0;
      l.attributes.push({
        shaderLocation: r,
        offset: u,
        format: c
      });
    }
    return Array.from(n.values());
  }
  /**
   * Destroys the GPU buffer of the given buffer attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  destroyAttribute(e) {
    const t = this.backend;
    t.get(this._getBufferAttribute(e)).buffer.destroy(), t.delete(e);
  }
  /**
   * This method performs a readback operation by moving buffer data from
   * a storage buffer attribute from the GPU to the CPU.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync(e) {
    const t = this.backend, n = t.device, s = t.get(this._getBufferAttribute(e)).buffer, a = s.size, o = n.createBuffer({
      label: `${e.name}_readback`,
      size: a,
      usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
    }), l = n.createCommandEncoder({
      label: `readback_encoder_${e.name}`
    });
    l.copyBufferToBuffer(
      s,
      0,
      o,
      0,
      a
    );
    const c = l.finish();
    n.queue.submit([c]), await o.mapAsync(GPUMapMode.READ);
    const u = o.getMappedRange(), h = new e.array.constructor(u.slice(0));
    return o.unmap(), h.buffer;
  }
  /**
   * Returns the vertex format of the given buffer attribute.
   *
   * @private
   * @param {BufferAttribute} geometryAttribute - The buffer attribute.
   * @return {string|undefined} The vertex format (e.g. 'float32x3').
   */
  _getVertexFormat(e) {
    const { itemSize: t, normalized: n } = e, r = e.array.constructor, s = e.constructor;
    let a;
    if (t === 1)
      a = TV.get(r);
    else {
      const l = (SV.get(s) || yT.get(r))[n ? 1 : 0];
      if (l) {
        const c = r.BYTES_PER_ELEMENT * t, h = Math.floor((c + 3) / 4) * 4 / r.BYTES_PER_ELEMENT;
        if (h % 1)
          throw new Error("THREE.WebGPUAttributeUtils: Bad vertex format item size.");
        a = `${l}x${h}`;
      }
    }
    return a || le("WebGPUAttributeUtils: Vertex format not supported yet."), a;
  }
  /**
   * Utility method for handling interleaved buffer attributes correctly.
   * To process them, their `InterleavedBuffer` is returned.
   *
   * @private
   * @param {BufferAttribute} attribute - The attribute.
   * @return {BufferAttribute|InterleavedBuffer}
   */
  _getBufferAttribute(e) {
    return e.isInterleavedBufferAttribute && (e = e.data), e;
  }
}
class EV {
  /**
   * Constructs a new layout.
   *
   * @param {GPUBindGroupLayout} layoutGPU - A GPU Bind Group Layout.
   */
  constructor(e) {
    this.layoutGPU = e, this.usedTimes = 0;
  }
}
class wV {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGPUBackend} backend - The WebGPU backend.
   */
  constructor(e) {
    this.backend = e, this._bindGroupLayoutCache = /* @__PURE__ */ new Map();
  }
  /**
   * Creates a GPU bind group layout for the given bind group.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @return {GPUBindGroupLayout} The GPU bind group layout.
   */
  createBindingsLayout(e) {
    const t = this.backend, n = t.device, r = t.get(e);
    if (r.layout)
      return r.layout.layoutGPU;
    const s = this._createLayoutEntries(e), a = Ml(JSON.stringify(s));
    let o = this._bindGroupLayoutCache.get(a);
    return o === void 0 && (o = new EV(n.createBindGroupLayout({ entries: s })), this._bindGroupLayoutCache.set(a, o)), o.usedTimes++, r.layout = o, r.layoutKey = a, o.layoutGPU;
  }
  /**
   * Creates bindings from the given bind group definition.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  createBindings(e, t, n, r = 0) {
    const { backend: s } = this, a = s.get(e), o = this.createBindingsLayout(e);
    let l;
    n > 0 && (a.groups === void 0 && (a.groups = [], a.versions = []), a.versions[n] === r && (l = a.groups[n])), l === void 0 && (l = this.createBindGroup(e, o), n > 0 && (a.groups[n] = l, a.versions[n] = r)), a.group = l;
  }
  /**
   * Updates a buffer binding.
   *
   *  @param {Buffer} binding - The buffer binding to update.
   */
  updateBinding(e) {
    const t = this.backend, n = t.device, r = e.buffer, s = t.get(e).buffer, a = e.updateRanges;
    if (a.length === 0)
      n.queue.writeBuffer(
        s,
        0,
        r,
        0
      );
    else {
      const o = Lh(r), l = o ? 1 : r.BYTES_PER_ELEMENT;
      for (let c = 0, u = a.length; c < u; c++) {
        const h = a[c], d = h.start * l, f = h.count * l, p = d * (o ? r.BYTES_PER_ELEMENT : 1);
        n.queue.writeBuffer(
          s,
          p,
          r,
          d,
          f
        );
      }
    }
  }
  /**
   * Creates a GPU bind group for the camera index.
   *
   * @param {Uint32Array} data - The index data.
   * @param {GPUBindGroupLayout} layoutGPU - The GPU bind group layout.
   * @return {GPUBindGroup} The GPU bind group.
   */
  createBindGroupIndex(e, t) {
    const r = this.backend.device, s = GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, a = e[0], o = r.createBuffer({
      label: "bindingCameraIndex_" + a,
      size: 16,
      // uint(4) * 4
      usage: s
    });
    r.queue.writeBuffer(o, 0, e, 0);
    const l = [{ binding: 0, resource: { buffer: o } }];
    return r.createBindGroup({
      label: "bindGroupCameraIndex_" + a,
      layout: t,
      entries: l
    });
  }
  /**
   * Creates a GPU bind group for the given bind group and GPU layout.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {GPUBindGroupLayout} layoutGPU - The GPU bind group layout.
   * @return {GPUBindGroup} The GPU bind group.
   */
  createBindGroup(e, t) {
    const n = this.backend, r = n.device;
    let s = 0;
    const a = [];
    for (const o of e.bindings) {
      if (o.isUniformBuffer) {
        const l = n.get(o);
        if (l.buffer === void 0) {
          const c = o.byteLength, u = GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, h = [];
          o.visibility & Tr.VERTEX && h.push("vertex"), o.visibility & Tr.FRAGMENT && h.push("fragment"), o.visibility & Tr.COMPUTE && h.push("compute");
          const d = `(${h.join(",")})`, f = r.createBuffer({
            label: `bindingBuffer${o.id}_${o.name}_${d}`,
            size: c,
            usage: u
          });
          l.buffer = f;
        }
        a.push({ binding: s, resource: { buffer: l.buffer } });
      } else if (o.isStorageBuffer) {
        const l = n.get(o.attribute).buffer;
        a.push({ binding: s, resource: { buffer: l } });
      } else if (o.isSampledTexture) {
        const l = n.get(o.texture);
        let c;
        if (l.externalTexture !== void 0)
          c = r.importExternalTexture({ source: l.externalTexture });
        else {
          const u = o.store ? 1 : l.texture.mipLevelCount, h = o.store ? o.mipLevel : 0;
          let d = `view-${l.texture.width}-${l.texture.height}`;
          if (l.texture.depthOrArrayLayers > 1 && (d += `-${l.texture.depthOrArrayLayers}`), d += `-${u}-${h}`, c = l[d], c === void 0) {
            const f = nV.All;
            let p;
            o.isSampledCubeTexture ? p = Wn.Cube : o.isSampledTexture3D ? p = Wn.ThreeD : o.texture.isArrayTexture || o.texture.isDataArrayTexture || o.texture.isCompressedArrayTexture ? p = Wn.TwoDArray : p = Wn.TwoD, c = l[d] = l.texture.createView({ aspect: f, dimension: p, mipLevelCount: u, baseMipLevel: h });
          }
        }
        a.push({ binding: s, resource: c });
      } else if (o.isSampler) {
        const l = n.get(o.texture);
        a.push({ binding: s, resource: l.sampler });
      }
      s++;
    }
    return r.createBindGroup({
      label: "bindGroup_" + e.name,
      layout: t,
      entries: a
    });
  }
  /**
   * Creates a GPU bind group layout entries for the given bind group.
   *
   * @private
   * @param {BindGroup} bindGroup - The bind group.
   * @return {Array<GPUBindGroupLayoutEntry>} The GPU bind group layout entries.
   */
  _createLayoutEntries(e) {
    const t = [];
    let n = 0;
    for (const r of e.bindings) {
      const s = this.backend, a = {
        binding: n,
        visibility: r.visibility
      };
      if (r.isUniformBuffer || r.isStorageBuffer) {
        const o = {};
        r.isStorageBuffer && (r.visibility & Tr.COMPUTE && (r.access === Bi.READ_WRITE || r.access === Bi.WRITE_ONLY) ? o.type = fp.Storage : o.type = fp.ReadOnlyStorage), a.buffer = o;
      } else if (r.isSampledTexture && r.store) {
        const o = {};
        o.format = this.backend.get(r.texture).texture.format;
        const l = r.access;
        l === Bi.READ_WRITE ? o.access = pp.ReadWrite : l === Bi.WRITE_ONLY ? o.access = pp.WriteOnly : o.access = pp.ReadOnly, r.texture.isArrayTexture ? o.viewDimension = Wn.TwoDArray : r.texture.is3DTexture && (o.viewDimension = Wn.ThreeD), a.storageTexture = o;
      } else if (r.isSampledTexture) {
        const o = {}, { primarySamples: l } = s.utils.getTextureSampleData(r.texture);
        if (l > 1 && (o.multisampled = !0, r.texture.isDepthTexture || (o.sampleType = ca.UnfilterableFloat)), r.texture.isDepthTexture)
          s.compatibilityMode && r.texture.compareFunction === null ? o.sampleType = ca.UnfilterableFloat : o.sampleType = ca.Depth;
        else if (r.texture.isDataTexture || r.texture.isDataArrayTexture || r.texture.isData3DTexture) {
          const c = r.texture.type;
          c === wn ? o.sampleType = ca.SInt : c === Dt ? o.sampleType = ca.UInt : c === ln && (this.backend.hasFeature("float32-filterable") ? o.sampleType = ca.Float : o.sampleType = ca.UnfilterableFloat);
        }
        r.isSampledCubeTexture ? o.viewDimension = Wn.Cube : r.texture.isArrayTexture || r.texture.isDataArrayTexture || r.texture.isCompressedArrayTexture ? o.viewDimension = Wn.TwoDArray : r.isSampledTexture3D && (o.viewDimension = Wn.ThreeD), a.texture = o;
      } else if (r.isSampler) {
        const o = {};
        r.texture.isDepthTexture && (r.texture.compareFunction !== null && s.hasCompatibility(rs.TEXTURE_COMPARE) ? o.type = mv.Comparison : o.type = mv.NonFiltering), a.sampler = o;
      } else
        le(`WebGPUBindingUtils: Unsupported binding "${r}".`);
      t.push(a), n++;
    }
    return t;
  }
  /**
   * Delete the data associated with a bind group.
   *
   * @param {BindGroup} bindGroup - The bind group.
   */
  deleteBindGroupData(e) {
    const { backend: t } = this, n = t.get(e);
    n.layout && (n.layout.usedTimes--, n.layout.usedTimes === 0 && this._bindGroupLayoutCache.delete(n.layoutKey), n.layout = void 0, n.layoutKey = void 0);
  }
  /**
   * Frees internal resources.
   */
  dispose() {
    this._bindGroupLayoutCache.clear();
  }
}
class AV {
  /**
   * Constructs a new utility object.
   *
   * @param {WebGPUBackend} backend - The WebGPU backend.
   */
  constructor(e) {
    this.backend = e, this._activePipelines = /* @__PURE__ */ new WeakMap();
  }
  /**
   * Sets the given pipeline for the given pass. The method makes sure to only set the
   * pipeline when necessary.
   *
   * @param {(GPURenderPassEncoder|GPUComputePassEncoder)} pass - The pass encoder.
   * @param {(GPURenderPipeline|GPUComputePipeline)} pipeline - The pipeline.
   */
  setPipeline(e, t) {
    this._activePipelines.get(e) !== t && (e.setPipeline(t), this._activePipelines.set(e, t));
  }
  /**
   * Returns the sample count derived from the given render context.
   *
   * @private
   * @param {RenderContext} renderContext - The render context.
   * @return {number} The sample count.
   */
  _getSampleCount(e) {
    return this.backend.utils.getSampleCountRenderContext(e);
  }
  /**
   * Creates a render pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {Array<Promise>} promises - An array of compilation promises which are used in `compileAsync()`.
   */
  createRenderPipeline(e, t) {
    const { object: n, material: r, geometry: s, pipeline: a } = e, { vertexProgram: o, fragmentProgram: l } = a, c = this.backend, u = c.device, h = c.utils, d = c.get(a), f = [];
    for (const B of e.getBindings()) {
      const N = c.get(B), { layoutGPU: C } = N.layout;
      f.push(C);
    }
    const p = c.attributeUtils.createShaderVertexBuffers(e);
    let _;
    r.blending !== Nn && (r.blending !== ei || r.transparent !== !1) && (_ = this._getBlending(r));
    let g = {};
    r.stencilWrite === !0 && (g = {
      compare: this._getStencilCompare(r),
      failOp: this._getStencilOperation(r.stencilFail),
      depthFailOp: this._getStencilOperation(r.stencilZFail),
      passOp: this._getStencilOperation(r.stencilZPass)
    });
    const m = this._getColorWriteMask(r), x = [];
    if (e.context.textures !== null) {
      const B = e.context.textures, N = e.context.mrt;
      for (let C = 0; C < B.length; C++) {
        const L = B[C], k = h.getTextureFormatGPU(L);
        let re;
        if (N !== null)
          if (this.backend.compatibilityMode !== !0) {
            const se = N.getBlendMode(L.name);
            se.blending === Hv ? re = _ : se.blending !== Nn && (re = this._getBlending(se));
          } else
            Pt("WebGPURenderer: Multiple Render Targets (MRT) blending configuration is not fully supported in compatibility mode. The material blending will be used for all render targets."), re = _;
        else
          re = _;
        x.push({
          format: k,
          blend: re,
          writeMask: m
        });
      }
    } else {
      const B = h.getCurrentColorFormat(e.context);
      x.push({
        format: B,
        blend: _,
        writeMask: m
      });
    }
    const y = c.get(o).module, b = c.get(l).module, T = this._getPrimitiveState(n, s, r), S = this._getDepthCompare(r), E = h.getCurrentDepthStencilFormat(e.context), v = this._getSampleCount(e.context), M = {
      label: `renderPipeline_${r.name || r.type}_${r.id}`,
      vertex: Object.assign({}, y, { buffers: p }),
      fragment: Object.assign({}, b, { targets: x }),
      primitive: T,
      multisample: {
        count: v,
        alphaToCoverageEnabled: r.alphaToCoverage && v > 1
      },
      layout: u.createPipelineLayout({
        bindGroupLayouts: f
      })
    }, F = {}, R = e.context.depth, I = e.context.stencil;
    if ((R === !0 || I === !0) && (R === !0 && (F.format = E, F.depthWriteEnabled = r.depthWrite, F.depthCompare = S), I === !0 && (F.stencilFront = g, F.stencilBack = g, F.stencilReadMask = r.stencilFuncMask, F.stencilWriteMask = r.stencilWriteMask), r.polygonOffset === !0 && (F.depthBias = r.polygonOffsetUnits, F.depthBiasSlopeScale = r.polygonOffsetFactor, F.depthBiasClamp = 0), M.depthStencil = F), u.pushErrorScope("validation"), t === null)
      d.pipeline = u.createRenderPipeline(M), u.popErrorScope().then((B) => {
        B !== null && (d.error = !0, le(B.message));
      });
    else {
      const B = new Promise(async (N) => {
        try {
          d.pipeline = await u.createRenderPipelineAsync(M);
        } catch {
        }
        const C = await u.popErrorScope();
        C !== null && (d.error = !0, le(C.message)), N();
      });
      t.push(B);
    }
  }
  /**
   * Creates GPU render bundle encoder for the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {?string} [label='renderBundleEncoder'] - The label.
   * @return {GPURenderBundleEncoder} The GPU render bundle encoder.
   */
  createBundleEncoder(e, t = "renderBundleEncoder") {
    const n = this.backend, { utils: r, device: s } = n, a = r.getCurrentDepthStencilFormat(e), o = r.getCurrentColorFormats(e), l = this._getSampleCount(e), c = {
      label: t,
      colorFormats: o,
      depthStencilFormat: a,
      sampleCount: l
    };
    return s.createRenderBundleEncoder(c);
  }
  /**
   * Creates a compute pipeline for the given compute node.
   *
   * @param {ComputePipeline} pipeline - The compute pipeline.
   * @param {Array<BindGroup>} bindings - The bindings.
   */
  createComputePipeline(e, t) {
    const n = this.backend, r = n.device, s = n.get(e.computeProgram).module, a = n.get(e), o = [];
    for (const l of t) {
      const c = n.get(l), { layoutGPU: u } = c.layout;
      o.push(u);
    }
    a.pipeline = r.createComputePipeline({
      compute: s,
      layout: r.createPipelineLayout({
        bindGroupLayouts: o
      })
    });
  }
  /**
   * Returns the blending state as a descriptor object required
   * for the pipeline creation.
   *
   * @private
   * @param {Material|BlendMode} object - The object containing blending information.
   * @return {Object} The blending state.
   */
  _getBlending(e) {
    let t, n;
    const r = e.blending, s = e.blendSrc, a = e.blendDst, o = e.blendEquation;
    if (r === ya) {
      const l = e.blendSrcAlpha !== null ? e.blendSrcAlpha : s, c = e.blendDstAlpha !== null ? e.blendDstAlpha : a, u = e.blendEquationAlpha !== null ? e.blendEquationAlpha : o;
      t = {
        srcFactor: this._getBlendFactor(s),
        dstFactor: this._getBlendFactor(a),
        operation: this._getBlendOperation(o)
      }, n = {
        srcFactor: this._getBlendFactor(l),
        dstFactor: this._getBlendFactor(c),
        operation: this._getBlendOperation(u)
      };
    } else {
      const l = e.premultipliedAlpha, c = (u, h, d, f) => {
        t = {
          srcFactor: u,
          dstFactor: h,
          operation: la.Add
        }, n = {
          srcFactor: d,
          dstFactor: f,
          operation: la.Add
        };
      };
      if (l)
        switch (r) {
          case ei:
            c(_t.One, _t.OneMinusSrcAlpha, _t.One, _t.OneMinusSrcAlpha);
            break;
          case Ns:
            c(_t.One, _t.One, _t.One, _t.One);
            break;
          case Ps:
            c(_t.Zero, _t.OneMinusSrc, _t.Zero, _t.One);
            break;
          case Ds:
            c(_t.Dst, _t.OneMinusSrcAlpha, _t.Zero, _t.One);
            break;
        }
      else
        switch (r) {
          case ei:
            c(_t.SrcAlpha, _t.OneMinusSrcAlpha, _t.One, _t.OneMinusSrcAlpha);
            break;
          case Ns:
            c(_t.SrcAlpha, _t.One, _t.One, _t.One);
            break;
          case Ps:
            le(`WebGPURenderer: "SubtractiveBlending" requires "${e.isMaterial ? "material" : "blendMode"}.premultipliedAlpha = true".`);
            break;
          case Ds:
            le(`WebGPURenderer: "MultiplyBlending" requires "${e.isMaterial ? "material" : "blendMode"}.premultipliedAlpha = true".`);
            break;
        }
    }
    if (t !== void 0 && n !== void 0)
      return { color: t, alpha: n };
    le("WebGPURenderer: Invalid blending: ", r);
  }
  /**
   * Returns the GPU blend factor which is required for the pipeline creation.
   *
   * @private
   * @param {number} blend - The blend factor as a three.js constant.
   * @return {string} The GPU blend factor.
   */
  _getBlendFactor(e) {
    let t;
    switch (e) {
      case jr:
        t = _t.Zero;
        break;
      case bm:
        t = _t.One;
        break;
      case Sm:
        t = _t.Src;
        break;
      case Tm:
        t = _t.OneMinusSrc;
        break;
      case Rc:
        t = _t.SrcAlpha;
        break;
      case Cc:
        t = _t.OneMinusSrcAlpha;
        break;
      case wm:
        t = _t.Dst;
        break;
      case Am:
        t = _t.OneMinusDst;
        break;
      case Mm:
        t = _t.DstAlpha;
        break;
      case Em:
        t = _t.OneMinusDstAlpha;
        break;
      case Rm:
        t = _t.SrcAlphaSaturated;
        break;
      case aO:
        t = _t.Constant;
        break;
      case oO:
        t = _t.OneMinusConstant;
        break;
      default:
        le("WebGPURenderer: Blend factor not supported.", e);
    }
    return t;
  }
  /**
   * Returns the GPU stencil compare function which is required for the pipeline creation.
   *
   * @private
   * @param {Material} material - The material.
   * @return {string} The GPU stencil compare function.
   */
  _getStencilCompare(e) {
    let t;
    const n = e.stencilFunc;
    switch (n) {
      case bM:
        t = Ln.Never;
        break;
      case Ap:
        t = Ln.Always;
        break;
      case SM:
        t = Ln.Less;
        break;
      case MM:
        t = Ln.LessEqual;
        break;
      case TM:
        t = Ln.Equal;
        break;
      case AM:
        t = Ln.GreaterEqual;
        break;
      case EM:
        t = Ln.Greater;
        break;
      case wM:
        t = Ln.NotEqual;
        break;
      default:
        le("WebGPURenderer: Invalid stencil function.", n);
    }
    return t;
  }
  /**
   * Returns the GPU stencil operation which is required for the pipeline creation.
   *
   * @private
   * @param {number} op - A three.js constant defining the stencil operation.
   * @return {string} The GPU stencil operation.
   */
  _getStencilOperation(e) {
    let t;
    switch (e) {
      case ha:
        t = Es.Keep;
        break;
      case pM:
        t = Es.Zero;
        break;
      case mM:
        t = Es.Replace;
        break;
      case yM:
        t = Es.Invert;
        break;
      case gM:
        t = Es.IncrementClamp;
        break;
      case _M:
        t = Es.DecrementClamp;
        break;
      case xM:
        t = Es.IncrementWrap;
        break;
      case vM:
        t = Es.DecrementWrap;
        break;
      default:
        le("WebGPURenderer: Invalid stencil operation.", t);
    }
    return t;
  }
  /**
   * Returns the GPU blend operation which is required for the pipeline creation.
   *
   * @private
   * @param {number} blendEquation - A three.js constant defining the blend equation.
   * @return {string} The GPU blend operation.
   */
  _getBlendOperation(e) {
    let t;
    switch (e) {
      case Xn:
        t = la.Add;
        break;
      case vm:
        t = la.Subtract;
        break;
      case ym:
        t = la.ReverseSubtract;
        break;
      case $v:
        t = la.Min;
        break;
      case Wv:
        t = la.Max;
        break;
      default:
        le("WebGPUPipelineUtils: Blend equation not supported.", e);
    }
    return t;
  }
  /**
   * Returns the primitive state as a descriptor object required
   * for the pipeline creation.
   *
   * @private
   * @param {Object3D} object - The 3D object.
   * @param {BufferGeometry} geometry - The geometry.
   * @param {Material} material - The material.
   * @return {Object} The primitive state.
   */
  _getPrimitiveState(e, t, n) {
    const r = {}, s = this.backend.utils;
    r.topology = s.getPrimitiveTopology(e, n), t.index !== null && e.isLine === !0 && e.isLineSegments !== !0 && (r.stripIndexFormat = t.index.array instanceof Uint16Array ? Zh.Uint16 : Zh.Uint32);
    let a = n.side === Ft;
    return e.isMesh && e.matrixWorld.determinant() < 0 && (a = !a), r.frontFace = a === !0 ? dv.CW : dv.CCW, r.cullMode = n.side === Rn ? fv.None : fv.Back, r;
  }
  /**
   * Returns the GPU color write mask which is required for the pipeline creation.
   *
   * @private
   * @param {Material} material - The material.
   * @return {number} The GPU color write mask.
   */
  _getColorWriteMask(e) {
    return e.colorWrite === !0 ? pv.All : pv.None;
  }
  /**
   * Returns the GPU depth compare function which is required for the pipeline creation.
   *
   * @private
   * @param {Material} material - The material.
   * @return {string} The GPU depth compare function.
   */
  _getDepthCompare(e) {
    let t;
    if (e.depthTest === !1)
      t = Ln.Always;
    else {
      const n = this.backend.parameters.reversedDepthBuffer ? zm[e.depthFunc] : e.depthFunc;
      switch (n) {
        case Nc:
          t = Ln.Never;
          break;
        case Pc:
          t = Ln.Always;
          break;
        case Dc:
          t = Ln.Less;
          break;
        case Hs:
          t = Ln.LessEqual;
          break;
        case Lc:
          t = Ln.Equal;
          break;
        case Fc:
          t = Ln.GreaterEqual;
          break;
        case Ic:
          t = Ln.Greater;
          break;
        case Uc:
          t = Ln.NotEqual;
          break;
        default:
          le("WebGPUPipelineUtils: Invalid depth function.", n);
      }
    }
    return t;
  }
}
class RV extends xT {
  /**
   * Creates a new WebGPU timestamp query pool.
   *
   * @param {GPUDevice} device - The WebGPU device to create queries on.
   * @param {string} type - The type identifier for this query pool.
   * @param {number} [maxQueries=2048] - Maximum number of queries this pool can hold.
   */
  constructor(e, t, n = 2048) {
    super(n), this.device = e, this.type = t, this.querySet = this.device.createQuerySet({
      type: "timestamp",
      count: this.maxQueries,
      label: `queryset_global_timestamp_${t}`
    });
    const r = this.maxQueries * 8;
    this.resolveBuffer = this.device.createBuffer({
      label: `buffer_timestamp_resolve_${t}`,
      size: r,
      usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
    }), this.resultBuffer = this.device.createBuffer({
      label: `buffer_timestamp_result_${t}`,
      size: r,
      usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
    });
  }
  /**
   * Allocates a pair of queries for a given render context.
   *
   * @param {string} uid - A unique identifier for the render context.
   * @returns {?number} The base offset for the allocated queries, or null if allocation failed.
   */
  allocateQueriesForContext(e) {
    if (!this.trackTimestamp || this.isDisposed)
      return null;
    if (this.currentQueryIndex + 2 > this.maxQueries)
      return Pt(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`), null;
    const t = this.currentQueryIndex;
    return this.currentQueryIndex += 2, this.queryOffsets.set(e, t), t;
  }
  /**
   * Asynchronously resolves all pending queries and returns the total duration.
   * If there's already a pending resolve operation, returns that promise instead.
   *
   * @async
   * @returns {Promise<number>} The total duration in milliseconds, or the last valid value if resolution fails.
   */
  async resolveQueriesAsync() {
    if (!this.trackTimestamp || this.currentQueryIndex === 0 || this.isDisposed)
      return this.lastValue;
    if (this.pendingResolve)
      return this.pendingResolve;
    this.pendingResolve = this._resolveQueries();
    try {
      return await this.pendingResolve;
    } finally {
      this.pendingResolve = null;
    }
  }
  /**
   * Internal method to resolve queries and calculate total duration.
   *
   * @async
   * @private
   * @returns {Promise<number>} The total duration in milliseconds.
   */
  async _resolveQueries() {
    if (this.isDisposed)
      return this.lastValue;
    try {
      if (this.resultBuffer.mapState !== "unmapped")
        return this.lastValue;
      const e = new Map(this.queryOffsets), t = this.currentQueryIndex, n = t * 8;
      this.currentQueryIndex = 0, this.queryOffsets.clear();
      const r = this.device.createCommandEncoder();
      r.resolveQuerySet(
        this.querySet,
        0,
        t,
        this.resolveBuffer,
        0
      ), r.copyBufferToBuffer(
        this.resolveBuffer,
        0,
        this.resultBuffer,
        0,
        n
      );
      const s = r.finish();
      if (this.device.queue.submit([s]), this.resultBuffer.mapState !== "unmapped")
        return this.lastValue;
      if (await this.resultBuffer.mapAsync(GPUMapMode.READ, 0, n), this.isDisposed)
        return this.resultBuffer.mapState === "mapped" && this.resultBuffer.unmap(), this.lastValue;
      const a = new BigUint64Array(this.resultBuffer.getMappedRange(0, n)), o = {}, l = [];
      for (const [u, h] of e) {
        const d = u.match(/^(.*):f(\d+)$/), f = parseInt(d[2]);
        l.includes(f) === !1 && l.push(f), o[f] === void 0 && (o[f] = 0);
        const p = a[h], _ = a[h + 1], g = Number(_ - p) / 1e6;
        this.timestamps.set(u, g), o[f] += g;
      }
      const c = o[l[l.length - 1]];
      return this.resultBuffer.unmap(), this.lastValue = c, this.frames = l, c;
    } catch (e) {
      return le("Error resolving queries:", e), this.resultBuffer.mapState === "mapped" && this.resultBuffer.unmap(), this.lastValue;
    }
  }
  /**
   * Dispose of the query pool.
   *
   * @async
   * @returns {Promise} A Promise that resolves when the dispose has been executed.
   */
  async dispose() {
    if (!this.isDisposed) {
      if (this.isDisposed = !0, this.pendingResolve)
        try {
          await this.pendingResolve;
        } catch (e) {
          le("Error waiting for pending resolve:", e);
        }
      if (this.resultBuffer && this.resultBuffer.mapState === "mapped")
        try {
          this.resultBuffer.unmap();
        } catch (e) {
          le("Error unmapping buffer:", e);
        }
      this.querySet && (this.querySet.destroy(), this.querySet = null), this.resolveBuffer && (this.resolveBuffer.destroy(), this.resolveBuffer = null), this.resultBuffer && (this.resultBuffer.destroy(), this.resultBuffer = null), this.queryOffsets.clear(), this.pendingResolve = null;
    }
  }
}
class CV extends _T {
  /**
   * WebGPUBackend options.
   *
   * @typedef {Object} WebGPUBackend~Options
   * @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not.
   * @property {boolean} [reversedDepthBuffer=false] - Whether reversed depth buffer is enabled or not.
   * @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque.
   * @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not.
   * @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
   * @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
   * @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
   * @property {boolean} [forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not.
   * @property {boolean} [trackTimestamp=false] - Whether to track timestamps with a Timestamp Query API or not.
   * @property {string} [powerPreference=undefined] - The power preference.
   * @property {Object} [requiredLimits=undefined] - Specifies the limits that are required by the device request. The request will fail if the adapter cannot provide these limits.
   * @property {GPUDevice} [device=undefined] - If there is an existing GPU device on app level, it can be passed to the renderer as a parameter.
   * @property {number} [outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead.
   */
  /**
   * Constructs a new WebGPU backend.
   *
   * @param {WebGPUBackend~Options} [parameters] - The configuration parameter.
   */
  constructor(e = {}) {
    super(e), this.isWebGPUBackend = !0, this.parameters.alpha = e.alpha === void 0 ? !0 : e.alpha, this.parameters.requiredLimits = e.requiredLimits === void 0 ? {} : e.requiredLimits, this.compatibilityMode = null, this.device = null, this.defaultRenderPassdescriptor = null, this.utils = new bV(this), this.attributeUtils = new MV(this), this.bindingUtils = new wV(this), this.pipelineUtils = new AV(this), this.textureUtils = new uV(this), this.occludedResolveCache = /* @__PURE__ */ new Map();
    const t = typeof navigator > "u" ? !0 : /Android/.test(navigator.userAgent) === !1;
    this._compatibility = {
      [rs.TEXTURE_COMPARE]: t
    };
  }
  /**
   * Initializes the backend so it is ready for usage.
   *
   * @async
   * @param {Renderer} renderer - The renderer.
   * @return {Promise} A Promise that resolves when the backend has been initialized.
   */
  async init(e) {
    await super.init(e);
    const t = this.parameters;
    let n;
    if (t.device === void 0) {
      const r = {
        powerPreference: t.powerPreference,
        featureLevel: "compatibility"
      }, s = typeof navigator < "u" ? await navigator.gpu.requestAdapter(r) : null;
      if (s === null)
        throw new Error("WebGPUBackend: Unable to create WebGPU adapter.");
      const a = Object.values(sm), o = [];
      for (const c of a)
        s.features.has(c) && o.push(c);
      const l = {
        requiredFeatures: o,
        requiredLimits: t.requiredLimits
      };
      n = await s.requestDevice(l);
    } else
      n = t.device;
    this.compatibilityMode = !n.features.has("core-features-and-limits"), this.compatibilityMode && (e._samples = 0), n.lost.then((r) => {
      if (r.reason === "destroyed")
        return;
      const s = {
        api: "WebGPU",
        message: r.message || "Unknown reason",
        reason: r.reason || null,
        originalEvent: r
      };
      e.onDeviceLost(s);
    }), this.device = n, this.trackTimestamp = this.trackTimestamp && this.hasFeature(sm.TimestampQuery), this.updateSize();
  }
  /**
   * A reference to the context.
   *
   * @type {?GPUCanvasContext}
   * @default null
   */
  get context() {
    const e = this.renderer.getCanvasTarget(), t = this.get(e);
    let n = t.context;
    if (n === void 0) {
      const r = this.parameters;
      e.isDefaultCanvasTarget === !0 && r.context !== void 0 ? n = r.context : n = e.domElement.getContext("webgpu"), "setAttribute" in e.domElement && e.domElement.setAttribute("data-engine", `three.js r${za} webgpu`);
      const s = r.alpha ? "premultiplied" : "opaque", a = r.outputType === nn ? "extended" : "standard";
      n.configure({
        device: this.device,
        format: this.utils.getPreferredCanvasFormat(),
        usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
        alphaMode: s,
        toneMapping: {
          mode: a
        }
      }), t.context = n;
    }
    return n;
  }
  /**
   * The coordinate system of the backend.
   *
   * @type {number}
   * @readonly
   */
  get coordinateSystem() {
    return Cr;
  }
  /**
   * This method performs a readback operation by moving buffer data from
   * a storage buffer attribute from the GPU to the CPU.
   *
   * @async
   * @param {StorageBufferAttribute} attribute - The storage buffer attribute.
   * @return {Promise<ArrayBuffer>} A promise that resolves with the buffer data when the data are ready.
   */
  async getArrayBufferAsync(e) {
    return await this.attributeUtils.getArrayBufferAsync(e);
  }
  /**
   * Returns the backend's rendering context.
   *
   * @return {GPUCanvasContext} The rendering context.
   */
  getContext() {
    return this.context;
  }
  /**
   * Returns the default render pass descriptor.
   *
   * In WebGPU, the default framebuffer must be configured
   * like custom framebuffers so the backend needs a render
   * pass descriptor even when rendering directly to screen.
   *
   * @private
   * @return {Object} The render pass descriptor.
   */
  _getDefaultRenderPassDescriptor() {
    const e = this.renderer, t = e.getCanvasTarget(), n = this.get(t), r = e.currentSamples;
    let s = n.descriptor;
    if (s === void 0 || n.samples !== r) {
      s = {
        colorAttachments: [{
          view: null
        }]
      }, (e.depth === !0 || e.stencil === !0) && (s.depthStencilAttachment = {
        view: this.textureUtils.getDepthBuffer(e.depth, e.stencil).createView()
      });
      const o = s.colorAttachments[0];
      r > 0 ? o.view = this.textureUtils.getColorBuffer().createView() : o.resolveTarget = void 0, n.descriptor = s, n.samples = r;
    }
    const a = s.colorAttachments[0];
    return r > 0 ? a.resolveTarget = this.context.getCurrentTexture().createView() : a.view = this.context.getCurrentTexture().createView(), s;
  }
  /**
   * Internal to determine if the current render target is a render target array with depth 2D array texture.
   *
   * @param {RenderContext} renderContext - The render context.
   * @return {boolean} Whether the render target is a render target array with depth 2D array texture.
   *
   * @private
   */
  _isRenderCameraDepthArray(e) {
    return e.depthTexture && e.depthTexture.image.depth > 1 && e.camera.isArrayCamera;
  }
  /**
   * Returns the render pass descriptor for the given render context.
   *
   * @private
   * @param {RenderContext} renderContext - The render context.
   * @param {Object} colorAttachmentsConfig - Configuration object for the color attachments.
   * @return {Object} The render pass descriptor.
   */
  _getRenderPassDescriptor(e, t = {}) {
    const n = e.renderTarget, r = this.get(n);
    let s = r.descriptors;
    (s === void 0 || r.width !== n.width || r.height !== n.height || r.samples !== n.samples) && (s = {}, r.descriptors = s);
    const a = e.getCacheKey();
    let o = s[a];
    if (o === void 0) {
      const c = e.textures, u = [];
      let h;
      const d = this._isRenderCameraDepthArray(e);
      for (let f = 0; f < c.length; f++) {
        const p = this.get(c[f]), _ = {
          label: `colorAttachment_${f}`,
          baseMipLevel: e.activeMipmapLevel,
          mipLevelCount: 1,
          baseArrayLayer: e.activeCubeFace,
          arrayLayerCount: 1,
          dimension: Wn.TwoD
        };
        if (n.isRenderTarget3D)
          h = e.activeCubeFace, _.baseArrayLayer = 0, _.dimension = Wn.ThreeD, _.depthOrArrayLayers = c[f].image.depth;
        else if (n.isRenderTarget && c[f].image.depth > 1)
          if (d === !0) {
            const g = e.camera.cameras;
            for (let m = 0; m < g.length; m++) {
              const x = {
                ..._,
                baseArrayLayer: m,
                arrayLayerCount: 1,
                dimension: Wn.TwoD
              }, y = p.texture.createView(x);
              u.push({
                view: y,
                resolveTarget: void 0,
                depthSlice: void 0
              });
            }
          } else
            _.dimension = Wn.TwoDArray, _.depthOrArrayLayers = c[f].image.depth;
        if (d !== !0) {
          const g = p.texture.createView(_);
          let m, x;
          p.msaaTexture !== void 0 ? (m = p.msaaTexture.createView(), x = g) : (m = g, x = void 0), u.push({
            view: m,
            resolveTarget: x,
            depthSlice: h
          });
        }
      }
      if (o = { textureViews: u }, e.depth) {
        const f = this.get(e.depthTexture), p = {};
        (e.depthTexture.isArrayTexture || e.depthTexture.isCubeTexture) && (p.dimension = Wn.TwoD, p.arrayLayerCount = 1, p.baseArrayLayer = e.activeCubeFace), o.depthStencilView = f.texture.createView(p);
      }
      s[a] = o, r.width = n.width, r.height = n.height, r.samples = n.samples, r.activeMipmapLevel = e.activeMipmapLevel, r.activeCubeFace = e.activeCubeFace;
    }
    const l = {
      colorAttachments: []
    };
    for (let c = 0; c < o.textureViews.length; c++) {
      const u = o.textureViews[c];
      let h = { r: 0, g: 0, b: 0, a: 1 };
      c === 0 && t.clearValue && (h = t.clearValue), l.colorAttachments.push({
        view: u.view,
        depthSlice: u.depthSlice,
        resolveTarget: u.resolveTarget,
        loadOp: t.loadOp || wt.Load,
        storeOp: t.storeOp || Qn.Store,
        clearValue: h
      });
    }
    return o.depthStencilView && (l.depthStencilAttachment = {
      view: o.depthStencilView
    }), l;
  }
  /**
   * This method is executed at the beginning of a render call and prepares
   * the WebGPU state for upcoming render calls
   *
   * @param {RenderContext} renderContext - The render context.
   */
  beginRender(e) {
    const t = this.get(e), n = this.device, r = e.occlusionQueryCount;
    let s;
    r > 0 && (t.currentOcclusionQuerySet && t.currentOcclusionQuerySet.destroy(), t.currentOcclusionQueryBuffer && t.currentOcclusionQueryBuffer.destroy(), t.currentOcclusionQuerySet = t.occlusionQuerySet, t.currentOcclusionQueryBuffer = t.occlusionQueryBuffer, t.currentOcclusionQueryObjects = t.occlusionQueryObjects, s = n.createQuerySet({ type: "occlusion", count: r, label: `occlusionQuerySet_${e.id}` }), t.occlusionQuerySet = s, t.occlusionQueryIndex = 0, t.occlusionQueryObjects = new Array(r), t.lastOcclusionObject = null);
    let a;
    e.textures === null ? a = this._getDefaultRenderPassDescriptor() : a = this._getRenderPassDescriptor(e, { loadOp: wt.Load }), this.initTimestampQuery(Sr.RENDER, this.getTimestampUID(e), a), a.occlusionQuerySet = s;
    const o = a.depthStencilAttachment;
    if (e.textures !== null) {
      const c = a.colorAttachments;
      for (let u = 0; u < c.length; u++) {
        const h = c[u];
        e.clearColor ? (h.clearValue = u === 0 ? e.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }, h.loadOp = wt.Clear) : h.loadOp = wt.Load, h.storeOp = Qn.Store;
      }
    } else {
      const c = a.colorAttachments[0];
      e.clearColor ? (c.clearValue = e.clearColorValue, c.loadOp = wt.Clear) : c.loadOp = wt.Load, c.storeOp = Qn.Store;
    }
    e.depth && (e.clearDepth ? (o.depthClearValue = e.clearDepthValue, o.depthLoadOp = wt.Clear) : o.depthLoadOp = wt.Load, o.depthStoreOp = Qn.Store), e.stencil && (e.clearStencil ? (o.stencilClearValue = e.clearStencilValue, o.stencilLoadOp = wt.Clear) : o.stencilLoadOp = wt.Load, o.stencilStoreOp = Qn.Store);
    const l = n.createCommandEncoder({ label: "renderContext_" + e.id });
    if (this._isRenderCameraDepthArray(e) === !0) {
      const c = e.camera.cameras;
      !t.layerDescriptors || t.layerDescriptors.length !== c.length ? this._createDepthLayerDescriptors(e, t, a, c) : this._updateDepthLayerDescriptors(e, t, c), t.bundleEncoders = [], t.bundleSets = [];
      for (let u = 0; u < c.length; u++) {
        const h = this.pipelineUtils.createBundleEncoder(
          e,
          "renderBundleArrayCamera_" + u
        ), d = {
          attributes: {},
          bindingGroups: [],
          pipeline: null,
          index: null
        };
        t.bundleEncoders.push(h), t.bundleSets.push(d);
      }
      t.currentPass = null;
    } else {
      const c = l.beginRenderPass(a);
      t.currentPass = c, e.viewport && this.updateViewport(e), e.scissor && this.updateScissor(e);
    }
    t.descriptor = a, t.encoder = l, t.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }, t.renderBundles = [];
  }
  /**
   * This method creates layer descriptors for each camera in an array camera
   * to prepare for rendering to a depth array texture.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {Object} renderContextData - The render context data.
   * @param {Object} descriptor  - The render pass descriptor.
   * @param {ArrayCamera} cameras - The array camera.
   *
   * @private
   */
  _createDepthLayerDescriptors(e, t, n, r) {
    const s = n.depthStencilAttachment;
    t.layerDescriptors = [];
    const a = this.get(e.depthTexture);
    a.viewCache || (a.viewCache = []);
    for (let o = 0; o < r.length; o++) {
      const l = {
        ...n,
        colorAttachments: [{
          ...n.colorAttachments[0],
          view: n.colorAttachments[o].view
        }]
      };
      if (n.depthStencilAttachment) {
        const c = o;
        a.viewCache[c] || (a.viewCache[c] = a.texture.createView({
          dimension: Wn.TwoD,
          baseArrayLayer: o,
          arrayLayerCount: 1
        })), l.depthStencilAttachment = {
          view: a.viewCache[c],
          depthLoadOp: s.depthLoadOp || wt.Clear,
          depthStoreOp: s.depthStoreOp || Qn.Store,
          depthClearValue: s.depthClearValue || 1
        }, e.stencil && (l.depthStencilAttachment.stencilLoadOp = s.stencilLoadOp, l.depthStencilAttachment.stencilStoreOp = s.stencilStoreOp, l.depthStencilAttachment.stencilClearValue = s.stencilClearValue);
      } else
        l.depthStencilAttachment = { ...s };
      t.layerDescriptors.push(l);
    }
  }
  /**
   * This method updates the layer descriptors for each camera in an array camera
   * to prepare for rendering to a depth array texture.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {Object} renderContextData - The render context data.
   * @param {ArrayCamera} cameras - The array camera.
   *
   */
  _updateDepthLayerDescriptors(e, t, n) {
    for (let r = 0; r < n.length; r++) {
      const s = t.layerDescriptors[r];
      if (s.depthStencilAttachment) {
        const a = s.depthStencilAttachment;
        e.depth && (e.clearDepth ? (a.depthClearValue = e.clearDepthValue, a.depthLoadOp = wt.Clear) : a.depthLoadOp = wt.Load), e.stencil && (e.clearStencil ? (a.stencilClearValue = e.clearStencilValue, a.stencilLoadOp = wt.Clear) : a.stencilLoadOp = wt.Load);
      }
    }
  }
  /**
   * This method is executed at the end of a render call and finalizes work
   * after draw calls.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  finishRender(e) {
    const t = this.get(e), n = e.occlusionQueryCount;
    t.renderBundles.length > 0 && t.currentPass.executeBundles(t.renderBundles), n > t.occlusionQueryIndex && t.currentPass.endOcclusionQuery();
    const r = t.encoder;
    if (this._isRenderCameraDepthArray(e) === !0) {
      const s = [];
      for (let a = 0; a < t.bundleEncoders.length; a++) {
        const o = t.bundleEncoders[a];
        s.push(o.finish());
      }
      for (let a = 0; a < t.layerDescriptors.length; a++)
        if (a < s.length) {
          const o = t.layerDescriptors[a], l = r.beginRenderPass(o);
          if (e.viewport) {
            const { x: c, y: u, width: h, height: d, minDepth: f, maxDepth: p } = e.viewportValue;
            l.setViewport(c, u, h, d, f, p);
          }
          if (e.scissor) {
            const { x: c, y: u, width: h, height: d } = e.scissorValue;
            l.setScissorRect(c, u, h, d);
          }
          l.executeBundles([s[a]]), l.end();
        }
    } else
      t.currentPass && t.currentPass.end();
    if (n > 0) {
      const s = n * 8;
      let a = this.occludedResolveCache.get(s);
      a === void 0 && (a = this.device.createBuffer(
        {
          size: s,
          usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
        }
      ), this.occludedResolveCache.set(s, a));
      const o = this.device.createBuffer(
        {
          size: s,
          usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
        }
      );
      t.encoder.resolveQuerySet(t.occlusionQuerySet, 0, n, a, 0), t.encoder.copyBufferToBuffer(a, 0, o, 0, s), t.occlusionQueryBuffer = o, this.resolveOccludedAsync(e);
    }
    if (this.device.queue.submit([t.encoder.finish()]), e.textures !== null) {
      const s = e.textures;
      for (let a = 0; a < s.length; a++) {
        const o = s[a];
        o.generateMipmaps === !0 && this.textureUtils.generateMipmaps(o);
      }
    }
  }
  /**
   * Returns `true` if the given 3D object is fully occluded by other
   * 3D objects in the scene.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {Object3D} object - The 3D object to test.
   * @return {boolean} Whether the 3D object is fully occluded or not.
   */
  isOccluded(e, t) {
    const n = this.get(e);
    return n.occluded && n.occluded.has(t);
  }
  /**
   * This method processes the result of occlusion queries and writes it
   * into render context data.
   *
   * @async
   * @param {RenderContext} renderContext - The render context.
   * @return {Promise} A Promise that resolves when the occlusion query results have been processed.
   */
  async resolveOccludedAsync(e) {
    const t = this.get(e), { currentOcclusionQueryBuffer: n, currentOcclusionQueryObjects: r } = t;
    if (n && r) {
      const s = /* @__PURE__ */ new WeakSet();
      t.currentOcclusionQueryObjects = null, t.currentOcclusionQueryBuffer = null, await n.mapAsync(GPUMapMode.READ);
      const a = n.getMappedRange(), o = new BigUint64Array(a);
      for (let l = 0; l < r.length; l++)
        o[l] === BigInt(0) && s.add(r[l]);
      n.destroy(), t.occluded = s;
    }
  }
  /**
   * Updates the viewport with the values from the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  updateViewport(e) {
    const { currentPass: t } = this.get(e), { x: n, y: r, width: s, height: a, minDepth: o, maxDepth: l } = e.viewportValue;
    t.setViewport(n, r, s, a, o, l);
  }
  /**
   * Updates the scissor with the values from the given render context.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  updateScissor(e) {
    const { currentPass: t } = this.get(e), { x: n, y: r, width: s, height: a } = e.scissorValue;
    t.setScissorRect(n, r, s, a);
  }
  /**
   * Returns the clear color and alpha into a single
   * color object.
   *
   * @return {Color4} The clear color.
   */
  getClearColor() {
    const e = super.getClearColor();
    return this.renderer.alpha === !0 && (e.r *= e.a, e.g *= e.a, e.b *= e.a), e;
  }
  /**
   * Performs a clear operation.
   *
   * @param {boolean} color - Whether the color buffer should be cleared or not.
   * @param {boolean} depth - Whether the depth buffer should be cleared or not.
   * @param {boolean} stencil - Whether the stencil buffer should be cleared or not.
   * @param {?RenderContext} [renderTargetContext=null] - The render context of the current set render target.
   */
  clear(e, t, n, r = null) {
    const s = this.device, a = this.renderer;
    let o = [], l, c, u, h;
    if (e) {
      const p = this.getClearColor();
      c = { r: p.r, g: p.g, b: p.b, a: p.a };
    }
    if (r === null) {
      u = a.depth, h = a.stencil;
      const p = this._getDefaultRenderPassDescriptor();
      if (e) {
        o = p.colorAttachments;
        const _ = o[0];
        _.clearValue = c, _.loadOp = wt.Clear, _.storeOp = Qn.Store;
      }
      (u || h) && (l = p.depthStencilAttachment);
    } else {
      u = r.depth, h = r.stencil;
      const p = {
        loadOp: e ? wt.Clear : wt.Load,
        clearValue: e ? c : void 0
      };
      u && (p.depthLoadOp = t ? wt.Clear : wt.Load, p.depthClearValue = t ? a.getClearDepth() : void 0, p.depthStoreOp = Qn.Store), h && (p.stencilLoadOp = n ? wt.Clear : wt.Load, p.stencilClearValue = n ? a.getClearStencil() : void 0, p.stencilStoreOp = Qn.Store);
      const _ = this._getRenderPassDescriptor(r, p);
      o = _.colorAttachments, l = _.depthStencilAttachment;
    }
    u && l && (t ? (l.depthLoadOp = wt.Clear, l.depthClearValue = a.getClearDepth(), l.depthStoreOp = Qn.Store) : (l.depthLoadOp = wt.Load, l.depthStoreOp = Qn.Store)), h && l && (n ? (l.stencilLoadOp = wt.Clear, l.stencilClearValue = a.getClearStencil(), l.stencilStoreOp = Qn.Store) : (l.stencilLoadOp = wt.Load, l.stencilStoreOp = Qn.Store));
    const d = s.createCommandEncoder({ label: "clear" });
    d.beginRenderPass({
      colorAttachments: o,
      depthStencilAttachment: l
    }).end(), s.queue.submit([d.finish()]);
  }
  // compute
  /**
   * This method is executed at the beginning of a compute call and
   * prepares the state for upcoming compute tasks.
   *
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  beginCompute(e) {
    const t = this.get(e), n = {
      label: "computeGroup_" + e.id
    };
    this.initTimestampQuery(Sr.COMPUTE, this.getTimestampUID(e), n), t.cmdEncoderGPU = this.device.createCommandEncoder({ label: "computeGroup_" + e.id }), t.passEncoderGPU = t.cmdEncoderGPU.beginComputePass(n);
  }
  /**
   * Executes a compute command for the given compute node.
   *
   * @param {Node|Array<Node>} computeGroup - The group of compute nodes of a compute call. Can be a single compute node.
   * @param {Node} computeNode - The compute node.
   * @param {Array<BindGroup>} bindings - The bindings.
   * @param {ComputePipeline} pipeline - The compute pipeline.
   * @param {number|Array<number>|IndirectStorageBufferAttribute} [dispatchSize=null]
   * - A single number representing count, or
   * - An array [x, y, z] representing dispatch size, or
   * - A IndirectStorageBufferAttribute for indirect dispatch size.
   */
  compute(e, t, n, r, s = null) {
    const a = this.get(t), { passEncoderGPU: o } = this.get(e), l = this.get(r).pipeline;
    this.pipelineUtils.setPipeline(o, l);
    for (let c = 0, u = n.length; c < u; c++) {
      const h = n[c], d = this.get(h);
      o.setBindGroup(c, d.group);
    }
    if (s === null && (s = t.count), s && typeof s == "object" && s.isIndirectStorageBufferAttribute) {
      const c = this.get(s).buffer;
      o.dispatchWorkgroupsIndirect(c, 0);
      return;
    }
    if (typeof s == "number") {
      const c = s;
      if (a.dispatchSize === void 0 || a.count !== c) {
        a.dispatchSize = [0, 1, 1], a.count = c;
        const u = t.workgroupSize;
        let h = u[0];
        for (let p = 1; p < u.length; p++)
          h *= u[p];
        const d = Math.ceil(c / h), f = this.device.limits.maxComputeWorkgroupsPerDimension;
        s = [d, 1, 1], d > f && (s[0] = Math.min(d, f), s[1] = Math.ceil(d / f)), a.dispatchSize = s;
      }
      s = a.dispatchSize;
    }
    o.dispatchWorkgroups(
      s[0],
      s[1] || 1,
      s[2] || 1
    );
  }
  /**
   * This method is executed at the end of a compute call and
   * finalizes work after compute tasks.
   *
   * @param {Node|Array<Node>} computeGroup - The compute node(s).
   */
  finishCompute(e) {
    const t = this.get(e);
    t.passEncoderGPU.end(), this.device.queue.submit([t.cmdEncoderGPU.finish()]);
  }
  // render object
  /**
   * Executes a draw command for the given render object.
   *
   * @param {RenderObject} renderObject - The render object to draw.
   * @param {Info} info - Holds a series of statistical information about the GPU memory and the rendering process.
   */
  draw(e, t) {
    const { object: n, material: r, context: s, pipeline: a } = e, o = e.getBindings(), l = this.get(s), c = this.get(a), u = c.pipeline;
    if (c.error === !0)
      return;
    const h = e.getIndex(), d = h !== null, f = e.getDrawParameters();
    if (f === null)
      return;
    const p = (g, m) => {
      this.pipelineUtils.setPipeline(g, u), m.pipeline = u;
      const x = m.bindingGroups;
      for (let b = 0, T = o.length; b < T; b++) {
        const S = o[b], E = this.get(S);
        x[S.index] !== S.id && (g.setBindGroup(S.index, E.group), x[S.index] = S.id);
      }
      if (d === !0 && m.index !== h) {
        const b = this.get(h).buffer, T = h.array instanceof Uint16Array ? Zh.Uint16 : Zh.Uint32;
        g.setIndexBuffer(b, T), m.index = h;
      }
      const y = e.getVertexBuffers();
      for (let b = 0, T = y.length; b < T; b++) {
        const S = y[b];
        if (m.attributes[b] !== S) {
          const E = this.get(S).buffer;
          g.setVertexBuffer(b, E), m.attributes[b] = S;
        }
      }
      s.stencil === !0 && r.stencilWrite === !0 && l.currentStencilRef !== r.stencilRef && (g.setStencilReference(r.stencilRef), l.currentStencilRef = r.stencilRef);
    }, _ = (g, m) => {
      if (p(g, m), n.isBatchedMesh === !0) {
        const x = n._multiDrawStarts, y = n._multiDrawCounts, b = n._multiDrawCount, T = n._multiDrawInstances;
        T !== null && Pt("WebGPUBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.");
        let S = d === !0 ? h.array.BYTES_PER_ELEMENT : 1;
        r.wireframe && (S = n.geometry.attributes.position.count > 65535 ? 4 : 2);
        for (let E = 0; E < b; E++) {
          const v = T ? T[E] : 1, M = v > 1 ? 0 : E;
          d === !0 ? g.drawIndexed(y[E], v, x[E] / S, 0, M) : g.draw(y[E], v, x[E], M), t.update(n, y[E], v);
        }
      } else if (d === !0) {
        const { vertexCount: x, instanceCount: y, firstVertex: b } = f, T = e.getIndirect();
        if (T !== null) {
          const S = this.get(T).buffer, E = e.getIndirectOffset(), v = Array.isArray(E) ? E : [E];
          for (let M = 0; M < v.length; M++)
            g.drawIndexedIndirect(S, v[M]);
        } else
          g.drawIndexed(x, y, b, 0, 0);
        t.update(n, x, y);
      } else {
        const { vertexCount: x, instanceCount: y, firstVertex: b } = f, T = e.getIndirect();
        if (T !== null) {
          const S = this.get(T).buffer, E = e.getIndirectOffset(), v = Array.isArray(E) ? E : [E];
          for (let M = 0; M < v.length; M++)
            g.drawIndirect(S, v[M]);
        } else
          g.draw(x, y, b, 0);
        t.update(n, x, y);
      }
    };
    if (e.camera.isArrayCamera && e.camera.cameras.length > 0) {
      const g = this.get(e.camera), m = e.camera.cameras, x = e.getBindingGroup("cameraIndex");
      if (g.indexesGPU === void 0 || g.indexesGPU.length !== m.length) {
        const b = this.get(x), T = [], S = new Uint32Array([0, 0, 0, 0]);
        for (let E = 0, v = m.length; E < v; E++) {
          S[0] = E;
          const { layoutGPU: M } = b.layout, F = this.bindingUtils.createBindGroupIndex(S, M);
          T.push(F);
        }
        g.indexesGPU = T;
      }
      const y = this.renderer.getPixelRatio();
      for (let b = 0, T = m.length; b < T; b++) {
        const S = m[b];
        if (n.layers.test(S.layers)) {
          const E = S.viewport;
          let v = l.currentPass, M = l.currentSets;
          if (l.bundleEncoders) {
            const F = l.bundleEncoders[b], R = l.bundleSets[b];
            v = F, M = R;
          }
          E && v.setViewport(
            Math.floor(E.x * y),
            Math.floor(E.y * y),
            Math.floor(E.width * y),
            Math.floor(E.height * y),
            s.viewportValue.minDepth,
            s.viewportValue.maxDepth
          ), x && g.indexesGPU && (v.setBindGroup(x.index, g.indexesGPU[b]), M.bindingGroups[x.index] = x.id), _(v, M);
        }
      }
    } else if (l.currentPass) {
      if (l.occlusionQuerySet !== void 0) {
        const g = l.lastOcclusionObject;
        g !== n && (g !== null && g.occlusionTest === !0 && (l.currentPass.endOcclusionQuery(), l.occlusionQueryIndex++), n.occlusionTest === !0 && (l.currentPass.beginOcclusionQuery(l.occlusionQueryIndex), l.occlusionQueryObjects[l.occlusionQueryIndex] = n), l.lastOcclusionObject = n);
      }
      _(l.currentPass, l.currentSets);
    }
  }
  // cache key
  /**
   * Returns `true` if the render pipeline requires an update.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {boolean} Whether the render pipeline requires an update or not.
   */
  needsRenderUpdate(e) {
    const t = this.get(e), { object: n, material: r } = e, s = this.utils, a = s.getSampleCountRenderContext(e.context), o = s.getCurrentColorSpace(e.context), l = s.getCurrentColorFormat(e.context), c = s.getCurrentDepthStencilFormat(e.context), u = s.getPrimitiveTopology(n, r);
    let h = !1;
    return (t.material !== r || t.materialVersion !== r.version || t.transparent !== r.transparent || t.blending !== r.blending || t.premultipliedAlpha !== r.premultipliedAlpha || t.blendSrc !== r.blendSrc || t.blendDst !== r.blendDst || t.blendEquation !== r.blendEquation || t.blendSrcAlpha !== r.blendSrcAlpha || t.blendDstAlpha !== r.blendDstAlpha || t.blendEquationAlpha !== r.blendEquationAlpha || t.colorWrite !== r.colorWrite || t.depthWrite !== r.depthWrite || t.depthTest !== r.depthTest || t.depthFunc !== r.depthFunc || t.stencilWrite !== r.stencilWrite || t.stencilFunc !== r.stencilFunc || t.stencilFail !== r.stencilFail || t.stencilZFail !== r.stencilZFail || t.stencilZPass !== r.stencilZPass || t.stencilFuncMask !== r.stencilFuncMask || t.stencilWriteMask !== r.stencilWriteMask || t.side !== r.side || t.alphaToCoverage !== r.alphaToCoverage || t.sampleCount !== a || t.colorSpace !== o || t.colorFormat !== l || t.depthStencilFormat !== c || t.primitiveTopology !== u || t.clippingContextCacheKey !== e.clippingContextCacheKey) && (t.material = r, t.materialVersion = r.version, t.transparent = r.transparent, t.blending = r.blending, t.premultipliedAlpha = r.premultipliedAlpha, t.blendSrc = r.blendSrc, t.blendDst = r.blendDst, t.blendEquation = r.blendEquation, t.blendSrcAlpha = r.blendSrcAlpha, t.blendDstAlpha = r.blendDstAlpha, t.blendEquationAlpha = r.blendEquationAlpha, t.colorWrite = r.colorWrite, t.depthWrite = r.depthWrite, t.depthTest = r.depthTest, t.depthFunc = r.depthFunc, t.stencilWrite = r.stencilWrite, t.stencilFunc = r.stencilFunc, t.stencilFail = r.stencilFail, t.stencilZFail = r.stencilZFail, t.stencilZPass = r.stencilZPass, t.stencilFuncMask = r.stencilFuncMask, t.stencilWriteMask = r.stencilWriteMask, t.side = r.side, t.alphaToCoverage = r.alphaToCoverage, t.sampleCount = a, t.colorSpace = o, t.colorFormat = l, t.depthStencilFormat = c, t.primitiveTopology = u, t.clippingContextCacheKey = e.clippingContextCacheKey, h = !0), h;
  }
  /**
   * Returns a cache key that is used to identify render pipelines.
   *
   * @param {RenderObject} renderObject - The render object.
   * @return {string} The cache key.
   */
  getRenderCacheKey(e) {
    const { object: t, material: n } = e, r = this.utils, s = e.context, a = t.isMesh && t.matrixWorld.determinant() < 0;
    return [
      n.transparent,
      n.blending,
      n.premultipliedAlpha,
      n.blendSrc,
      n.blendDst,
      n.blendEquation,
      n.blendSrcAlpha,
      n.blendDstAlpha,
      n.blendEquationAlpha,
      n.colorWrite,
      n.depthWrite,
      n.depthTest,
      n.depthFunc,
      n.stencilWrite,
      n.stencilFunc,
      n.stencilFail,
      n.stencilZFail,
      n.stencilZPass,
      n.stencilFuncMask,
      n.stencilWriteMask,
      n.side,
      a,
      r.getSampleCountRenderContext(s),
      r.getCurrentColorSpace(s),
      r.getCurrentColorFormat(s),
      r.getCurrentDepthStencilFormat(s),
      r.getPrimitiveTopology(t, n),
      e.getGeometryCacheKey(),
      e.clippingContextCacheKey
    ].join();
  }
  // textures
  /**
   * Updates a GPU sampler for the given texture.
   *
   * @param {Texture} texture - The texture to update the sampler for.
   * @return {string} The current sampler key.
   */
  updateSampler(e) {
    return this.textureUtils.updateSampler(e);
  }
  /**
   * Creates a default texture for the given texture that can be used
   * as a placeholder until the actual texture is ready for usage.
   *
   * @param {Texture} texture - The texture to create a default texture for.
   * @return {boolean} Whether the sampler has been updated or not.
   */
  createDefaultTexture(e) {
    return this.textureUtils.createDefaultTexture(e);
  }
  /**
   * Defines a texture on the GPU for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  createTexture(e, t) {
    this.textureUtils.createTexture(e, t);
  }
  /**
   * Uploads the updated texture data to the GPU.
   *
   * @param {Texture} texture - The texture.
   * @param {Object} [options={}] - Optional configuration parameter.
   */
  updateTexture(e, t) {
    this.textureUtils.updateTexture(e, t);
  }
  /**
   * Generates mipmaps for the given texture.
   *
   * @param {Texture} texture - The texture.
   */
  generateMipmaps(e) {
    this.textureUtils.generateMipmaps(e);
  }
  /**
   * Destroys the GPU data for the given texture object.
   *
   * @param {Texture} texture - The texture.
   * @param {boolean} [isDefaultTexture=false] - Whether the texture uses a default GPU texture or not.
   */
  destroyTexture(e, t = !1) {
    this.textureUtils.destroyTexture(e, t);
  }
  /**
   * Returns texture data as a typed array.
   *
   * @async
   * @param {Texture} texture - The texture to copy.
   * @param {number} x - The x coordinate of the copy origin.
   * @param {number} y - The y coordinate of the copy origin.
   * @param {number} width - The width of the copy.
   * @param {number} height - The height of the copy.
   * @param {number} faceIndex - The face index.
   * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished.
   */
  async copyTextureToBuffer(e, t, n, r, s, a) {
    return this.textureUtils.copyTextureToBuffer(e, t, n, r, s, a);
  }
  /**
   * Inits a time stamp query for the given render context.
   *
   * @param {string} type - The type of the timestamp query (e.g. 'render', 'compute').
   * @param {number} uid - Unique id for the context (e.g. render context id).
   * @param {Object} descriptor - The query descriptor.
   */
  initTimestampQuery(e, t, n) {
    if (!this.trackTimestamp)
      return;
    this.timestampQueryPool[e] || (this.timestampQueryPool[e] = new RV(this.device, e, 2048));
    const r = this.timestampQueryPool[e], s = r.allocateQueriesForContext(t);
    n.timestampWrites = {
      querySet: r.querySet,
      beginningOfPassWriteIndex: s,
      endOfPassWriteIndex: s + 1
    };
  }
  // node builder
  /**
   * Returns a node builder for the given render object.
   *
   * @param {RenderObject} object - The render object.
   * @param {Renderer} renderer - The renderer.
   * @return {WGSLNodeBuilder} The node builder.
   */
  createNodeBuilder(e, t) {
    return new yV(e, t);
  }
  // program
  /**
   * Creates a shader program from the given programmable stage.
   *
   * @param {ProgrammableStage} program - The programmable stage.
   */
  createProgram(e) {
    const t = this.get(e);
    t.module = {
      module: this.device.createShaderModule({ code: e.code, label: e.stage + (e.name !== "" ? `_${e.name}` : "") }),
      entryPoint: "main"
    };
  }
  /**
   * Destroys the shader program of the given programmable stage.
   *
   * @param {ProgrammableStage} program - The programmable stage.
   */
  destroyProgram(e) {
    this.delete(e);
  }
  // pipelines
  /**
   * Creates a render pipeline for the given render object.
   *
   * @param {RenderObject} renderObject - The render object.
   * @param {Array<Promise>} promises - An array of compilation promises which are used in `compileAsync()`.
   */
  createRenderPipeline(e, t) {
    this.pipelineUtils.createRenderPipeline(e, t);
  }
  /**
   * Creates a compute pipeline for the given compute node.
   *
   * @param {ComputePipeline} computePipeline - The compute pipeline.
   * @param {Array<BindGroup>} bindings - The bindings.
   */
  createComputePipeline(e, t) {
    this.pipelineUtils.createComputePipeline(e, t);
  }
  /**
   * Prepares the state for encoding render bundles.
   *
   * @param {RenderContext} renderContext - The render context.
   */
  beginBundle(e) {
    const t = this.get(e);
    t._currentPass = t.currentPass, t._currentSets = t.currentSets, t.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }, t.currentPass = this.pipelineUtils.createBundleEncoder(e);
  }
  /**
   * After processing render bundles this method finalizes related work.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {RenderBundle} bundle - The render bundle.
   */
  finishBundle(e, t) {
    const n = this.get(e), s = n.currentPass.finish();
    this.get(t).bundleGPU = s, n.currentSets = n._currentSets, n.currentPass = n._currentPass;
  }
  /**
   * Adds a render bundle to the render context data.
   *
   * @param {RenderContext} renderContext - The render context.
   * @param {RenderBundle} bundle - The render bundle to add.
   */
  addBundle(e, t) {
    this.get(e).renderBundles.push(this.get(t).bundleGPU);
  }
  // bindings
  /**
   * Creates bindings from the given bind group definition.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  createBindings(e, t, n, r) {
    this.bindingUtils.createBindings(e, t, n, r);
  }
  /**
   * Updates the given bind group definition.
   *
   * @param {BindGroup} bindGroup - The bind group.
   * @param {Array<BindGroup>} bindings - Array of bind groups.
   * @param {number} cacheIndex - The cache index.
   * @param {number} version - The version.
   */
  updateBindings(e, t, n, r) {
    this.bindingUtils.createBindings(e, t, n, r);
  }
  /**
   * Updates a buffer binding.
   *
   *  @param {Buffer} binding - The buffer binding to update.
   */
  updateBinding(e) {
    this.bindingUtils.updateBinding(e);
  }
  /**
   * Delete data associated with the current bind group.
   *
   * @param {BindGroup} bindGroup - The bind group.
   */
  deleteBindGroupData(e) {
    this.bindingUtils.deleteBindGroupData(e);
  }
  // attributes
  /**
   * Creates the buffer of an indexed shader attribute.
   *
   * @param {BufferAttribute} attribute - The indexed buffer attribute.
   */
  createIndexAttribute(e) {
    let t = GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST;
    (e.isStorageBufferAttribute || e.isStorageInstancedBufferAttribute) && (t |= GPUBufferUsage.STORAGE), this.attributeUtils.createAttribute(e, t);
  }
  /**
   * Creates the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createAttribute(e) {
    this.attributeUtils.createAttribute(e, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST);
  }
  /**
   * Creates the GPU buffer of a storage attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createStorageAttribute(e) {
    this.attributeUtils.createAttribute(e, GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST);
  }
  /**
   * Creates the GPU buffer of an indirect storage attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute.
   */
  createIndirectStorageAttribute(e) {
    this.attributeUtils.createAttribute(e, GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST);
  }
  /**
   * Updates the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute to update.
   */
  updateAttribute(e) {
    this.attributeUtils.updateAttribute(e);
  }
  /**
   * Destroys the GPU buffer of a shader attribute.
   *
   * @param {BufferAttribute} attribute - The buffer attribute to destroy.
   */
  destroyAttribute(e) {
    this.attributeUtils.destroyAttribute(e);
  }
  // canvas
  /**
   * Triggers an update of the default render pass descriptor.
   */
  updateSize() {
    this.delete(this.renderer.getCanvasTarget());
  }
  // utils public
  /**
   * Returns the maximum anisotropy texture filtering value.
   *
   * @return {number} The maximum anisotropy texture filtering value.
   */
  getMaxAnisotropy() {
    return 16;
  }
  /**
   * Checks if the given feature is supported by the backend.
   *
   * @param {string} name - The feature's name.
   * @return {boolean} Whether the feature is supported or not.
   */
  hasFeature(e) {
    return _v[e] !== void 0 && (e = _v[e]), this.device.features.has(e);
  }
  /**
   * Copies data of the given source texture to the given destination texture.
   *
   * @param {Texture} srcTexture - The source texture.
   * @param {Texture} dstTexture - The destination texture.
   * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy.
   * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy.
   * @param {number} [srcLevel=0] - The mipmap level to copy.
   * @param {number} [dstLevel=0] - The destination mip level to copy to.
   */
  copyTextureToTexture(e, t, n = null, r = null, s = 0, a = 0) {
    let o = 0, l = 0, c = 0, u = 0, h = 0, d = 0, f = e.image.width, p = e.image.height, _ = 1;
    n !== null && (n.isBox3 === !0 ? (u = n.min.x, h = n.min.y, d = n.min.z, f = n.max.x - n.min.x, p = n.max.y - n.min.y, _ = n.max.z - n.min.z) : (u = n.min.x, h = n.min.y, f = n.max.x - n.min.x, p = n.max.y - n.min.y, _ = 1)), r !== null && (o = r.x, l = r.y, c = r.z || 0);
    const g = this.device.createCommandEncoder({ label: "copyTextureToTexture_" + e.id + "_" + t.id }), m = this.get(e).texture, x = this.get(t).texture;
    g.copyTextureToTexture(
      {
        texture: m,
        mipLevel: s,
        origin: { x: u, y: h, z: d }
      },
      {
        texture: x,
        mipLevel: a,
        origin: { x: o, y: l, z: c }
      },
      [
        f,
        p,
        _
      ]
    ), this.device.queue.submit([g.finish()]), a === 0 && t.generateMipmaps && this.textureUtils.generateMipmaps(t);
  }
  /**
   * Copies the current bound framebuffer to the given texture.
   *
   * @param {Texture} texture - The destination texture.
   * @param {RenderContext} renderContext - The render context.
   * @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy.
   */
  copyFramebufferToTexture(e, t, n) {
    const r = this.get(t);
    let s = null;
    t.renderTarget ? e.isDepthTexture ? s = this.get(t.depthTexture).texture : s = this.get(t.textures[0]).texture : e.isDepthTexture ? s = this.textureUtils.getDepthBuffer(t.depth, t.stencil) : s = this.context.getCurrentTexture();
    const a = this.get(e).texture;
    if (s.format !== a.format) {
      le("WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.", s.format, a.format);
      return;
    }
    let o;
    if (r.currentPass ? (r.currentPass.end(), o = r.encoder) : o = this.device.createCommandEncoder({ label: "copyFramebufferToTexture_" + e.id }), o.copyTextureToTexture(
      {
        texture: s,
        origin: [n.x, n.y, 0]
      },
      {
        texture: a
      },
      [
        n.z,
        n.w
      ]
    ), e.generateMipmaps && this.textureUtils.generateMipmaps(e, o), r.currentPass) {
      const { descriptor: l } = r;
      for (let c = 0; c < l.colorAttachments.length; c++)
        l.colorAttachments[c].loadOp = wt.Load;
      t.depth && (l.depthStencilAttachment.depthLoadOp = wt.Load), t.stencil && (l.depthStencilAttachment.stencilLoadOp = wt.Load), r.currentPass = o.beginRenderPass(l), r.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }, t.viewport && this.updateViewport(t), t.scissor && this.updateScissor(t);
    } else
      this.device.queue.submit([o.finish()]);
  }
  /**
   * Checks if the given compatibility is supported by the backend.
   *
   * @param {string} name - The compatibility name.
   * @return {boolean} Whether the compatibility is supported or not.
   */
  hasCompatibility(e) {
    return this._compatibility[rs.TEXTURE_COMPARE] !== void 0 ? this._compatibility[rs.TEXTURE_COMPARE] : super.hasCompatibility(e);
  }
  dispose() {
    if (this.bindingUtils.dispose(), this.textureUtils.dispose(), this.occludedResolveCache) {
      for (const e of this.occludedResolveCache.values())
        e.destroy();
      this.occludedResolveCache.clear();
    }
    if (this.timestampQueryPool)
      for (const e of Object.values(this.timestampQueryPool))
        e !== null && e.dispose();
    this.parameters.device === void 0 && this.device !== null && this.device.destroy();
  }
}
class NV extends sg {
  /**
   * Constructs a new IES spot light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
   * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
   * @param {number} [angle=Math.PI/3] - Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`.
   * @param {number} [penumbra=0] - Percent of the spotlight cone that is attenuated due to penumbra. Value range is `[0,1]`.
   * @param {number} [decay=2] - The amount the light dims along the distance of the light.
   */
  constructor(e, t, n, r, s, a) {
    super(e, t, n, r, s, a), this.iesMap = null;
  }
  copy(e, t) {
    return super.copy(e, t), this.iesMap = e.iesMap, this;
  }
}
class PV extends sg {
  /**
   * Constructs a new projector light.
   *
   * @param {(number|Color|string)} [color=0xffffff] - The light's color.
   * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
   * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
   * @param {number} [angle=Math.PI/3] - Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`.
   * @param {number} [penumbra=0] - Percent of the spotlight cone that is attenuated due to penumbra. Value range is `[0,1]`.
   * @param {number} [decay=2] - The amount the light dims along the distance of the light.
   */
  constructor(e, t, n, r, s, a) {
    super(e, t, n, r, s, a), this.aspect = null;
  }
  copy(e, t) {
    return super.copy(e, t), this.aspect = e.aspect, this;
  }
}
class DV extends cT {
  /**
   * Constructs a new standard node library.
   */
  constructor() {
    super(), this.addMaterial(V3, "MeshPhongMaterial"), this.addMaterial($S, "MeshStandardMaterial"), this.addMaterial(OB, "MeshPhysicalMaterial"), this.addMaterial(zB, "MeshToonMaterial"), this.addMaterial(F3, "MeshBasicMaterial"), this.addMaterial(k3, "MeshLambertMaterial"), this.addMaterial(C3, "MeshNormalMaterial"), this.addMaterial(WB, "MeshMatcapMaterial"), this.addMaterial(E3, "LineBasicMaterial"), this.addMaterial(A3, "LineDashedMaterial"), this.addMaterial(KB, "PointsMaterial"), this.addMaterial(qS, "SpriteMaterial"), this.addMaterial(eO, "ShadowMaterial"), this.addLight(Dk, QE), this.addLight(lG, dy), this.addLight(pG, ew), this.addLight(Hg, sg), this.addLight(oG, fy), this.addLight(cG, YE), this.addLight(hG, nw), this.addLight(uG, NV), this.addLight(fG, PV), this.addToneMapping(BO, Cm), this.addToneMapping(OO, Nm), this.addToneMapping(kO, Pm), this.addToneMapping(VO, Dm), this.addToneMapping(WO, Lm), this.addToneMapping(qO, Fm);
  }
}
class LV extends IG {
  /**
   * WebGPURenderer options.
   *
   * @typedef {Object} WebGPURenderer~Options
   * @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not.
   * @property {boolean} [reversedDepthBuffer=false] - Whether reversed depth buffer is enabled or not.
   * @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque.
   * @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not.
   * @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not.
   * @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not.
   * @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default.
   * @property {boolean} [forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not.
   * @property {boolean} [multiview=false] - If set to `true`, the renderer will use multiview during WebXR rendering if supported.
   * @property {number} [outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead.
   * @property {number} [outputBufferType=HalfFloatType] - Defines the type of output buffers. The default `HalfFloatType` is recommend for best
   * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though.
   */
  /**
   * Constructs a new WebGPU renderer.
   *
   * @param {WebGPURenderer~Options} [parameters] - The configuration parameter.
   */
  constructor(e = {}) {
    let t;
    e.forceWebGL ? t = hv : (t = CV, e.getFallback = () => (oe("WebGPURenderer: WebGPU is not available, running under WebGL2 backend."), new hv(e)));
    const n = new t(e);
    super(n, e), this.library = new DV(), this.isWebGPURenderer = !0, typeof __THREE_DEVTOOLS__ < "u" && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this }));
  }
}
const gp = { type: "change" }, Wg = { type: "start" }, qg = { type: "end" }, Sv = 1e-6, At = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }, ph = new de(), ws = new de(), FV = new P(), mh = new P(), _p = new P(), So = new Gi(), Tv = new P(), gh = new P(), xp = new P(), _h = new P();
class IV extends dd {
  /**
   * Constructs a new controls instance.
   *
   * @param {Object3D} object - The object that is managed by the controls.
   * @param {?HTMLElement} domElement - The HTML element used for event listeners.
   */
  constructor(e, t = null) {
    super(e, t), this.screen = { left: 0, top: 0, width: 0, height: 0 }, this.rotateSpeed = 1, this.zoomSpeed = 1.2, this.panSpeed = 0.3, this.noRotate = !1, this.noZoom = !1, this.noPan = !1, this.staticMoving = !1, this.dynamicDampingFactor = 0.2, this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.keys = [
      "KeyA",
      "KeyS",
      "KeyD"
      /*D*/
    ], this.mouseButtons = { LEFT: Fn.ROTATE, MIDDLE: Fn.DOLLY, RIGHT: Fn.PAN }, this.target = new P(), this.state = At.NONE, this.keyState = At.NONE, this._lastPosition = new P(), this._lastZoom = 1, this._touchZoomDistanceStart = 0, this._touchZoomDistanceEnd = 0, this._lastAngle = 0, this._eye = new P(), this._movePrev = new de(), this._moveCurr = new de(), this._lastAxis = new P(), this._zoomStart = new de(), this._zoomEnd = new de(), this._panStart = new de(), this._panEnd = new de(), this._pointers = [], this._pointerPositions = {}, this._onPointerMove = BV.bind(this), this._onPointerDown = UV.bind(this), this._onPointerUp = OV.bind(this), this._onPointerCancel = kV.bind(this), this._onContextMenu = qV.bind(this), this._onMouseWheel = WV.bind(this), this._onKeyDown = VV.bind(this), this._onKeyUp = GV.bind(this), this._onTouchStart = XV.bind(this), this._onTouchMove = jV.bind(this), this._onTouchEnd = YV.bind(this), this._onMouseDown = zV.bind(this), this._onMouseMove = HV.bind(this), this._onMouseUp = $V.bind(this), this._target0 = this.target.clone(), this._position0 = this.object.position.clone(), this._up0 = this.object.up.clone(), this._zoom0 = this.object.zoom, t !== null && (this.connect(t), this.handleResize()), this.update();
  }
  connect(e) {
    super.connect(e), window.addEventListener("keydown", this._onKeyDown), window.addEventListener("keyup", this._onKeyUp), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointercancel", this._onPointerCancel), this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: !1 }), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.style.touchAction = "none";
  }
  disconnect() {
    window.removeEventListener("keydown", this._onKeyDown), window.removeEventListener("keyup", this._onKeyUp), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointercancel", this._onPointerCancel), this.domElement.removeEventListener("wheel", this._onMouseWheel), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.domElement.style.touchAction = "auto";
  }
  dispose() {
    this.disconnect();
  }
  /**
   * Must be called if the application window is resized.
   */
  handleResize() {
    const e = this.domElement.getBoundingClientRect(), t = this.domElement.ownerDocument.documentElement;
    this.screen.left = e.left + window.pageXOffset - t.clientLeft, this.screen.top = e.top + window.pageYOffset - t.clientTop, this.screen.width = e.width, this.screen.height = e.height;
  }
  update() {
    this._eye.subVectors(this.object.position, this.target), this.noRotate || this._rotateCamera(), this.noZoom || this._zoomCamera(), this.noPan || this._panCamera(), this.object.position.addVectors(this.target, this._eye), this.object.isPerspectiveCamera ? (this._checkDistances(), this.object.lookAt(this.target), this._lastPosition.distanceToSquared(this.object.position) > Sv && (this.dispatchEvent(gp), this._lastPosition.copy(this.object.position))) : this.object.isOrthographicCamera ? (this.object.lookAt(this.target), (this._lastPosition.distanceToSquared(this.object.position) > Sv || this._lastZoom !== this.object.zoom) && (this.dispatchEvent(gp), this._lastPosition.copy(this.object.position), this._lastZoom = this.object.zoom)) : console.warn("THREE.TrackballControls: Unsupported camera type.");
  }
  /**
   * Resets the controls to its initial state.
   */
  reset() {
    this.state = At.NONE, this.keyState = At.NONE, this.target.copy(this._target0), this.object.position.copy(this._position0), this.object.up.copy(this._up0), this.object.zoom = this._zoom0, this.object.updateProjectionMatrix(), this._eye.subVectors(this.object.position, this.target), this.object.lookAt(this.target), this.dispatchEvent(gp), this._lastPosition.copy(this.object.position), this._lastZoom = this.object.zoom;
  }
  _panCamera() {
    if (ws.copy(this._panEnd).sub(this._panStart), ws.lengthSq()) {
      if (this.object.isOrthographicCamera) {
        const e = (this.object.right - this.object.left) / this.object.zoom / this.domElement.clientWidth, t = (this.object.top - this.object.bottom) / this.object.zoom / this.domElement.clientWidth;
        ws.x *= e, ws.y *= t;
      }
      ws.multiplyScalar(this._eye.length() * this.panSpeed), mh.copy(this._eye).cross(this.object.up).setLength(ws.x), mh.add(FV.copy(this.object.up).setLength(ws.y)), this.object.position.add(mh), this.target.add(mh), this.staticMoving ? this._panStart.copy(this._panEnd) : this._panStart.add(ws.subVectors(this._panEnd, this._panStart).multiplyScalar(this.dynamicDampingFactor));
    }
  }
  _rotateCamera() {
    _h.set(this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0);
    let e = _h.length();
    e ? (this._eye.copy(this.object.position).sub(this.target), Tv.copy(this._eye).normalize(), gh.copy(this.object.up).normalize(), xp.crossVectors(gh, Tv).normalize(), gh.setLength(this._moveCurr.y - this._movePrev.y), xp.setLength(this._moveCurr.x - this._movePrev.x), _h.copy(gh.add(xp)), _p.crossVectors(_h, this._eye).normalize(), e *= this.rotateSpeed, So.setFromAxisAngle(_p, e), this._eye.applyQuaternion(So), this.object.up.applyQuaternion(So), this._lastAxis.copy(_p), this._lastAngle = e) : !this.staticMoving && this._lastAngle && (this._lastAngle *= Math.sqrt(1 - this.dynamicDampingFactor), this._eye.copy(this.object.position).sub(this.target), So.setFromAxisAngle(this._lastAxis, this._lastAngle), this._eye.applyQuaternion(So), this.object.up.applyQuaternion(So)), this._movePrev.copy(this._moveCurr);
  }
  _zoomCamera() {
    let e;
    this.state === At.TOUCH_ZOOM_PAN ? (e = this._touchZoomDistanceStart / this._touchZoomDistanceEnd, this._touchZoomDistanceStart = this._touchZoomDistanceEnd, this.object.isPerspectiveCamera ? this._eye.multiplyScalar(e) : this.object.isOrthographicCamera ? (this.object.zoom = Fh.clamp(this.object.zoom / e, this.minZoom, this.maxZoom), this._lastZoom !== this.object.zoom && this.object.updateProjectionMatrix()) : console.warn("THREE.TrackballControls: Unsupported camera type")) : (e = 1 + (this._zoomEnd.y - this._zoomStart.y) * this.zoomSpeed, e !== 1 && e > 0 && (this.object.isPerspectiveCamera ? this._eye.multiplyScalar(e) : this.object.isOrthographicCamera ? (this.object.zoom = Fh.clamp(this.object.zoom / e, this.minZoom, this.maxZoom), this._lastZoom !== this.object.zoom && this.object.updateProjectionMatrix()) : console.warn("THREE.TrackballControls: Unsupported camera type")), this.staticMoving ? this._zoomStart.copy(this._zoomEnd) : this._zoomStart.y += (this._zoomEnd.y - this._zoomStart.y) * this.dynamicDampingFactor);
  }
  _getMouseOnScreen(e, t) {
    return ph.set(
      (e - this.screen.left) / this.screen.width,
      (t - this.screen.top) / this.screen.height
    ), ph;
  }
  _getMouseOnCircle(e, t) {
    return ph.set(
      (e - this.screen.width * 0.5 - this.screen.left) / (this.screen.width * 0.5),
      (this.screen.height + 2 * (this.screen.top - t)) / this.screen.width
      // screen.width intentional
    ), ph;
  }
  _addPointer(e) {
    this._pointers.push(e);
  }
  _removePointer(e) {
    delete this._pointerPositions[e.pointerId];
    for (let t = 0; t < this._pointers.length; t++)
      if (this._pointers[t].pointerId == e.pointerId) {
        this._pointers.splice(t, 1);
        return;
      }
  }
  _trackPointer(e) {
    let t = this._pointerPositions[e.pointerId];
    t === void 0 && (t = new de(), this._pointerPositions[e.pointerId] = t), t.set(e.pageX, e.pageY);
  }
  _getSecondPointerPosition(e) {
    const t = e.pointerId === this._pointers[0].pointerId ? this._pointers[1] : this._pointers[0];
    return this._pointerPositions[t.pointerId];
  }
  _checkDistances() {
    (!this.noZoom || !this.noPan) && (this._eye.lengthSq() > this.maxDistance * this.maxDistance && (this.object.position.addVectors(this.target, this._eye.setLength(this.maxDistance)), this._zoomStart.copy(this._zoomEnd)), this._eye.lengthSq() < this.minDistance * this.minDistance && (this.object.position.addVectors(this.target, this._eye.setLength(this.minDistance)), this._zoomStart.copy(this._zoomEnd)));
  }
}
function UV(i) {
  this.enabled !== !1 && (this._pointers.length === 0 && (this.domElement.setPointerCapture(i.pointerId), this.domElement.ownerDocument.addEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.addEventListener("pointerup", this._onPointerUp)), this._addPointer(i), i.pointerType === "touch" ? this._onTouchStart(i) : this._onMouseDown(i));
}
function BV(i) {
  this.enabled !== !1 && (i.pointerType === "touch" ? this._onTouchMove(i) : this._onMouseMove(i));
}
function OV(i) {
  this.enabled !== !1 && (i.pointerType === "touch" ? this._onTouchEnd(i) : this._onMouseUp(), this._removePointer(i), this._pointers.length === 0 && (this.domElement.releasePointerCapture(i.pointerId), this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp)));
}
function kV(i) {
  this._removePointer(i);
}
function GV() {
  this.enabled !== !1 && (this.keyState = At.NONE, window.addEventListener("keydown", this._onKeyDown));
}
function VV(i) {
  this.enabled !== !1 && (window.removeEventListener("keydown", this._onKeyDown), this.keyState === At.NONE && (i.code === this.keys[At.ROTATE] && !this.noRotate ? this.keyState = At.ROTATE : i.code === this.keys[At.ZOOM] && !this.noZoom ? this.keyState = At.ZOOM : i.code === this.keys[At.PAN] && !this.noPan && (this.keyState = At.PAN)));
}
function zV(i) {
  let e;
  switch (i.button) {
    case 0:
      e = this.mouseButtons.LEFT;
      break;
    case 1:
      e = this.mouseButtons.MIDDLE;
      break;
    case 2:
      e = this.mouseButtons.RIGHT;
      break;
    default:
      e = -1;
  }
  switch (e) {
    case Fn.DOLLY:
      this.state = At.ZOOM;
      break;
    case Fn.ROTATE:
      this.state = At.ROTATE;
      break;
    case Fn.PAN:
      this.state = At.PAN;
      break;
    default:
      this.state = At.NONE;
  }
  const t = this.keyState !== At.NONE ? this.keyState : this.state;
  t === At.ROTATE && !this.noRotate ? (this._moveCurr.copy(this._getMouseOnCircle(i.pageX, i.pageY)), this._movePrev.copy(this._moveCurr)) : t === At.ZOOM && !this.noZoom ? (this._zoomStart.copy(this._getMouseOnScreen(i.pageX, i.pageY)), this._zoomEnd.copy(this._zoomStart)) : t === At.PAN && !this.noPan && (this._panStart.copy(this._getMouseOnScreen(i.pageX, i.pageY)), this._panEnd.copy(this._panStart)), this.dispatchEvent(Wg);
}
function HV(i) {
  const e = this.keyState !== At.NONE ? this.keyState : this.state;
  e === At.ROTATE && !this.noRotate ? (this._movePrev.copy(this._moveCurr), this._moveCurr.copy(this._getMouseOnCircle(i.pageX, i.pageY))) : e === At.ZOOM && !this.noZoom ? this._zoomEnd.copy(this._getMouseOnScreen(i.pageX, i.pageY)) : e === At.PAN && !this.noPan && this._panEnd.copy(this._getMouseOnScreen(i.pageX, i.pageY));
}
function $V() {
  this.state = At.NONE, this.dispatchEvent(qg);
}
function WV(i) {
  if (this.enabled !== !1 && this.noZoom !== !0) {
    switch (i.preventDefault(), i.deltaMode) {
      case 2:
        this._zoomStart.y -= i.deltaY * 0.025;
        break;
      case 1:
        this._zoomStart.y -= i.deltaY * 0.01;
        break;
      default:
        this._zoomStart.y -= i.deltaY * 25e-5;
        break;
    }
    this.dispatchEvent(Wg), this.dispatchEvent(qg);
  }
}
function qV(i) {
  this.enabled !== !1 && i.preventDefault();
}
function XV(i) {
  switch (this._trackPointer(i), this._pointers.length) {
    case 1:
      this.state = At.TOUCH_ROTATE, this._moveCurr.copy(this._getMouseOnCircle(this._pointers[0].pageX, this._pointers[0].pageY)), this._movePrev.copy(this._moveCurr);
      break;
    default:
      this.state = At.TOUCH_ZOOM_PAN;
      const e = this._pointers[0].pageX - this._pointers[1].pageX, t = this._pointers[0].pageY - this._pointers[1].pageY;
      this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt(e * e + t * t);
      const n = (this._pointers[0].pageX + this._pointers[1].pageX) / 2, r = (this._pointers[0].pageY + this._pointers[1].pageY) / 2;
      this._panStart.copy(this._getMouseOnScreen(n, r)), this._panEnd.copy(this._panStart);
      break;
  }
  this.dispatchEvent(Wg);
}
function jV(i) {
  switch (this._trackPointer(i), this._pointers.length) {
    case 1:
      this._movePrev.copy(this._moveCurr), this._moveCurr.copy(this._getMouseOnCircle(i.pageX, i.pageY));
      break;
    default:
      const e = this._getSecondPointerPosition(i), t = i.pageX - e.x, n = i.pageY - e.y;
      this._touchZoomDistanceEnd = Math.sqrt(t * t + n * n);
      const r = (i.pageX + e.x) / 2, s = (i.pageY + e.y) / 2;
      this._panEnd.copy(this._getMouseOnScreen(r, s));
      break;
  }
}
function YV(i) {
  switch (this._pointers.length) {
    case 0:
      this.state = At.NONE;
      break;
    case 1:
      this.state = At.TOUCH_ROTATE, this._moveCurr.copy(this._getMouseOnCircle(i.pageX, i.pageY)), this._movePrev.copy(this._moveCurr);
      break;
    case 2:
      this.state = At.TOUCH_ZOOM_PAN;
      for (let e = 0; e < this._pointers.length; e++)
        if (this._pointers[e].pointerId !== i.pointerId) {
          const t = this._pointerPositions[this._pointers[e].pointerId];
          this._moveCurr.copy(this._getMouseOnCircle(t.x, t.y)), this._movePrev.copy(this._moveCurr);
          break;
        }
      break;
  }
  this.dispatchEvent(qg);
}
const Mv = { type: "change" }, Xg = { type: "start" }, bT = { type: "end" }, xh = new cd(), Ev = new Zi(), KV = Math.cos(70 * Fh.DEG2RAD), yn = new P(), ci = 2 * Math.PI, Vt = {
  NONE: -1,
  ROTATE: 0,
  DOLLY: 1,
  PAN: 2,
  TOUCH_ROTATE: 3,
  TOUCH_PAN: 4,
  TOUCH_DOLLY_PAN: 5,
  TOUCH_DOLLY_ROTATE: 6
}, vp = 1e-6;
class ZV extends dd {
  /**
   * Constructs a new controls instance.
   *
   * @param {Object3D} object - The object that is managed by the controls.
   * @param {?HTMLElement} domElement - The HTML element used for event listeners.
   */
  constructor(e, t = null) {
    super(e, t), this.state = Vt.NONE, this.target = new P(), this.cursor = new P(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.keyRotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: Fn.ROTATE, MIDDLE: Fn.DOLLY, RIGHT: Fn.PAN }, this.touches = { ONE: es.ROTATE, TWO: es.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._cursorStyle = "auto", this._domElementKeyEvents = null, this._lastPosition = new P(), this._lastQuaternion = new Gi(), this._lastTargetPosition = new P(), this._quat = new Gi().setFromUnitVectors(e.up, new P(0, 1, 0)), this._quatInverse = this._quat.clone().invert(), this._spherical = new I_(), this._sphericalDelta = new I_(), this._scale = 1, this._panOffset = new P(), this._rotateStart = new de(), this._rotateEnd = new de(), this._rotateDelta = new de(), this._panStart = new de(), this._panEnd = new de(), this._panDelta = new de(), this._dollyStart = new de(), this._dollyEnd = new de(), this._dollyDelta = new de(), this._dollyDirection = new P(), this._mouse = new de(), this._performCursorZoom = !1, this._pointers = [], this._pointerPositions = {}, this._controlActive = !1, this._onPointerMove = JV.bind(this), this._onPointerDown = QV.bind(this), this._onPointerUp = ez.bind(this), this._onContextMenu = oz.bind(this), this._onMouseWheel = iz.bind(this), this._onKeyDown = rz.bind(this), this._onTouchStart = sz.bind(this), this._onTouchMove = az.bind(this), this._onMouseDown = tz.bind(this), this._onMouseMove = nz.bind(this), this._interceptControlDown = lz.bind(this), this._interceptControlUp = cz.bind(this), this.domElement !== null && this.connect(this.domElement), this.update();
  }
  /**
   * Defines the visual representation of the cursor.
   *
   * @type {('auto'|'grab')}
   * @default 'auto'
   */
  set cursorStyle(e) {
    this._cursorStyle = e, e === "grab" ? this.domElement.style.cursor = "grab" : this.domElement.style.cursor = "auto";
  }
  get cursorStyle() {
    return this._cursorStyle;
  }
  connect(e) {
    super.connect(e), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointercancel", this._onPointerUp), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: !1 }), this.domElement.getRootNode().addEventListener("keydown", this._interceptControlDown, { passive: !0, capture: !0 }), this.domElement.style.touchAction = "none";
  }
  disconnect() {
    this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointercancel", this._onPointerUp), this.domElement.removeEventListener("wheel", this._onMouseWheel), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.stopListenToKeyEvents(), this.domElement.getRootNode().removeEventListener("keydown", this._interceptControlDown, { capture: !0 }), this.domElement.style.touchAction = "auto";
  }
  dispose() {
    this.disconnect();
  }
  /**
   * Get the current vertical rotation, in radians.
   *
   * @return {number} The current vertical rotation, in radians.
   */
  getPolarAngle() {
    return this._spherical.phi;
  }
  /**
   * Get the current horizontal rotation, in radians.
   *
   * @return {number} The current horizontal rotation, in radians.
   */
  getAzimuthalAngle() {
    return this._spherical.theta;
  }
  /**
   * Returns the distance from the camera to the target.
   *
   * @return {number} The distance from the camera to the target.
   */
  getDistance() {
    return this.object.position.distanceTo(this.target);
  }
  /**
   * Adds key event listeners to the given DOM element.
   * `window` is a recommended argument for using this method.
   *
   * @param {HTMLElement} domElement - The DOM element
   */
  listenToKeyEvents(e) {
    e.addEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = e;
  }
  /**
   * Removes the key event listener previously defined with `listenToKeyEvents()`.
   */
  stopListenToKeyEvents() {
    this._domElementKeyEvents !== null && (this._domElementKeyEvents.removeEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = null);
  }
  /**
   * Save the current state of the controls. This can later be recovered with `reset()`.
   */
  saveState() {
    this.target0.copy(this.target), this.position0.copy(this.object.position), this.zoom0 = this.object.zoom;
  }
  /**
   * Reset the controls to their state from either the last time the `saveState()`
   * was called, or the initial state.
   */
  reset() {
    this.target.copy(this.target0), this.object.position.copy(this.position0), this.object.zoom = this.zoom0, this.object.updateProjectionMatrix(), this.dispatchEvent(Mv), this.update(), this.state = Vt.NONE;
  }
  /**
   * Programmatically pan the camera.
   *
   * @param {number} deltaX - The horizontal pan amount in pixels.
   * @param {number} deltaY - The vertical pan amount in pixels.
   */
  pan(e, t) {
    this._pan(e, t), this.update();
  }
  /**
   * Programmatically dolly in (zoom in for perspective camera).
   *
   * @param {number} dollyScale - The dolly scale factor.
   */
  dollyIn(e) {
    this._dollyIn(e), this.update();
  }
  /**
   * Programmatically dolly out (zoom out for perspective camera).
   *
   * @param {number} dollyScale - The dolly scale factor.
   */
  dollyOut(e) {
    this._dollyOut(e), this.update();
  }
  /**
   * Programmatically rotate the camera left (around the vertical axis).
   *
   * @param {number} angle - The rotation angle in radians.
   */
  rotateLeft(e) {
    this._rotateLeft(e), this.update();
  }
  /**
   * Programmatically rotate the camera up (around the horizontal axis).
   *
   * @param {number} angle - The rotation angle in radians.
   */
  rotateUp(e) {
    this._rotateUp(e), this.update();
  }
  update(e = null) {
    const t = this.object.position;
    yn.copy(t).sub(this.target), yn.applyQuaternion(this._quat), this._spherical.setFromVector3(yn), this.autoRotate && this.state === Vt.NONE && this._rotateLeft(this._getAutoRotationAngle(e)), this.enableDamping ? (this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor, this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor) : (this._spherical.theta += this._sphericalDelta.theta, this._spherical.phi += this._sphericalDelta.phi);
    let n = this.minAzimuthAngle, r = this.maxAzimuthAngle;
    isFinite(n) && isFinite(r) && (n < -Math.PI ? n += ci : n > Math.PI && (n -= ci), r < -Math.PI ? r += ci : r > Math.PI && (r -= ci), n <= r ? this._spherical.theta = Math.max(n, Math.min(r, this._spherical.theta)) : this._spherical.theta = this._spherical.theta > (n + r) / 2 ? Math.max(n, this._spherical.theta) : Math.min(r, this._spherical.theta)), this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi)), this._spherical.makeSafe(), this.enableDamping === !0 ? this.target.addScaledVector(this._panOffset, this.dampingFactor) : this.target.add(this._panOffset), this.target.sub(this.cursor), this.target.clampLength(this.minTargetRadius, this.maxTargetRadius), this.target.add(this.cursor);
    let s = !1;
    if (this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera)
      this._spherical.radius = this._clampDistance(this._spherical.radius);
    else {
      const a = this._spherical.radius;
      this._spherical.radius = this._clampDistance(this._spherical.radius * this._scale), s = a != this._spherical.radius;
    }
    if (yn.setFromSpherical(this._spherical), yn.applyQuaternion(this._quatInverse), t.copy(this.target).add(yn), this.object.lookAt(this.target), this.enableDamping === !0 ? (this._sphericalDelta.theta *= 1 - this.dampingFactor, this._sphericalDelta.phi *= 1 - this.dampingFactor, this._panOffset.multiplyScalar(1 - this.dampingFactor)) : (this._sphericalDelta.set(0, 0, 0), this._panOffset.set(0, 0, 0)), this.zoomToCursor && this._performCursorZoom) {
      let a = null;
      if (this.object.isPerspectiveCamera) {
        const o = yn.length();
        a = this._clampDistance(o * this._scale);
        const l = o - a;
        this.object.position.addScaledVector(this._dollyDirection, l), this.object.updateMatrixWorld(), s = !!l;
      } else if (this.object.isOrthographicCamera) {
        const o = new P(this._mouse.x, this._mouse.y, 0);
        o.unproject(this.object);
        const l = this.object.zoom;
        this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), this.object.updateProjectionMatrix(), s = l !== this.object.zoom;
        const c = new P(this._mouse.x, this._mouse.y, 0);
        c.unproject(this.object), this.object.position.sub(c).add(o), this.object.updateMatrixWorld(), a = yn.length();
      } else
        console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), this.zoomToCursor = !1;
      a !== null && (this.screenSpacePanning ? this.target.set(0, 0, -1).transformDirection(this.object.matrix).multiplyScalar(a).add(this.object.position) : (xh.origin.copy(this.object.position), xh.direction.set(0, 0, -1).transformDirection(this.object.matrix), Math.abs(this.object.up.dot(xh.direction)) < KV ? this.object.lookAt(this.target) : (Ev.setFromNormalAndCoplanarPoint(this.object.up, this.target), xh.intersectPlane(Ev, this.target))));
    } else if (this.object.isOrthographicCamera) {
      const a = this.object.zoom;
      this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), a !== this.object.zoom && (this.object.updateProjectionMatrix(), s = !0);
    }
    return this._scale = 1, this._performCursorZoom = !1, s || this._lastPosition.distanceToSquared(this.object.position) > vp || 8 * (1 - this._lastQuaternion.dot(this.object.quaternion)) > vp || this._lastTargetPosition.distanceToSquared(this.target) > vp ? (this.dispatchEvent(Mv), this._lastPosition.copy(this.object.position), this._lastQuaternion.copy(this.object.quaternion), this._lastTargetPosition.copy(this.target), !0) : !1;
  }
  _getAutoRotationAngle(e) {
    return e !== null ? ci / 60 * this.autoRotateSpeed * e : ci / 60 / 60 * this.autoRotateSpeed;
  }
  _getZoomScale(e) {
    const t = Math.abs(e * 0.01);
    return Math.pow(0.95, this.zoomSpeed * t);
  }
  _rotateLeft(e) {
    this._sphericalDelta.theta -= e;
  }
  _rotateUp(e) {
    this._sphericalDelta.phi -= e;
  }
  _panLeft(e, t) {
    yn.setFromMatrixColumn(t, 0), yn.multiplyScalar(-e), this._panOffset.add(yn);
  }
  _panUp(e, t) {
    this.screenSpacePanning === !0 ? yn.setFromMatrixColumn(t, 1) : (yn.setFromMatrixColumn(t, 0), yn.crossVectors(this.object.up, yn)), yn.multiplyScalar(e), this._panOffset.add(yn);
  }
  // deltaX and deltaY are in pixels; right and down are positive
  _pan(e, t) {
    const n = this.domElement;
    if (this.object.isPerspectiveCamera) {
      const r = this.object.position;
      yn.copy(r).sub(this.target);
      let s = yn.length();
      s *= Math.tan(this.object.fov / 2 * Math.PI / 180), this._panLeft(2 * e * s / n.clientHeight, this.object.matrix), this._panUp(2 * t * s / n.clientHeight, this.object.matrix);
    } else
      this.object.isOrthographicCamera ? (this._panLeft(e * (this.object.right - this.object.left) / this.object.zoom / n.clientWidth, this.object.matrix), this._panUp(t * (this.object.top - this.object.bottom) / this.object.zoom / n.clientHeight, this.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), this.enablePan = !1);
  }
  _dollyOut(e) {
    this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale /= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1);
  }
  _dollyIn(e) {
    this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale *= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1);
  }
  _updateZoomParameters(e, t) {
    if (!this.zoomToCursor)
      return;
    this._performCursorZoom = !0;
    const n = this.domElement.getBoundingClientRect(), r = e - n.left, s = t - n.top, a = n.width, o = n.height;
    this._mouse.x = r / a * 2 - 1, this._mouse.y = -(s / o) * 2 + 1, this._dollyDirection.set(this._mouse.x, this._mouse.y, 1).unproject(this.object).sub(this.object.position).normalize();
  }
  _clampDistance(e) {
    return Math.max(this.minDistance, Math.min(this.maxDistance, e));
  }
  //
  // event callbacks - update the object state
  //
  _handleMouseDownRotate(e) {
    this._rotateStart.set(e.clientX, e.clientY);
  }
  _handleMouseDownDolly(e) {
    this._updateZoomParameters(e.clientX, e.clientX), this._dollyStart.set(e.clientX, e.clientY);
  }
  _handleMouseDownPan(e) {
    this._panStart.set(e.clientX, e.clientY);
  }
  _handleMouseMoveRotate(e) {
    this._rotateEnd.set(e.clientX, e.clientY), this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
    const t = this.domElement;
    this._rotateLeft(ci * this._rotateDelta.x / t.clientHeight), this._rotateUp(ci * this._rotateDelta.y / t.clientHeight), this._rotateStart.copy(this._rotateEnd), this.update();
  }
  _handleMouseMoveDolly(e) {
    this._dollyEnd.set(e.clientX, e.clientY), this._dollyDelta.subVectors(this._dollyEnd, this._dollyStart), this._dollyDelta.y > 0 ? this._dollyOut(this._getZoomScale(this._dollyDelta.y)) : this._dollyDelta.y < 0 && this._dollyIn(this._getZoomScale(this._dollyDelta.y)), this._dollyStart.copy(this._dollyEnd), this.update();
  }
  _handleMouseMovePan(e) {
    this._panEnd.set(e.clientX, e.clientY), this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd), this.update();
  }
  _handleMouseWheel(e) {
    this._updateZoomParameters(e.clientX, e.clientY), e.deltaY < 0 ? this._dollyIn(this._getZoomScale(e.deltaY)) : e.deltaY > 0 && this._dollyOut(this._getZoomScale(e.deltaY)), this.update();
  }
  _handleKeyDown(e) {
    let t = !1;
    switch (e.code) {
      case this.keys.UP:
        e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateUp(ci * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(0, this.keyPanSpeed), t = !0;
        break;
      case this.keys.BOTTOM:
        e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateUp(-ci * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(0, -this.keyPanSpeed), t = !0;
        break;
      case this.keys.LEFT:
        e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateLeft(ci * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(this.keyPanSpeed, 0), t = !0;
        break;
      case this.keys.RIGHT:
        e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateLeft(-ci * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(-this.keyPanSpeed, 0), t = !0;
        break;
    }
    t && (e.preventDefault(), this.update());
  }
  _handleTouchStartRotate(e) {
    if (this._pointers.length === 1)
      this._rotateStart.set(e.pageX, e.pageY);
    else {
      const t = this._getSecondPointerPosition(e), n = 0.5 * (e.pageX + t.x), r = 0.5 * (e.pageY + t.y);
      this._rotateStart.set(n, r);
    }
  }
  _handleTouchStartPan(e) {
    if (this._pointers.length === 1)
      this._panStart.set(e.pageX, e.pageY);
    else {
      const t = this._getSecondPointerPosition(e), n = 0.5 * (e.pageX + t.x), r = 0.5 * (e.pageY + t.y);
      this._panStart.set(n, r);
    }
  }
  _handleTouchStartDolly(e) {
    const t = this._getSecondPointerPosition(e), n = e.pageX - t.x, r = e.pageY - t.y, s = Math.sqrt(n * n + r * r);
    this._dollyStart.set(0, s);
  }
  _handleTouchStartDollyPan(e) {
    this.enableZoom && this._handleTouchStartDolly(e), this.enablePan && this._handleTouchStartPan(e);
  }
  _handleTouchStartDollyRotate(e) {
    this.enableZoom && this._handleTouchStartDolly(e), this.enableRotate && this._handleTouchStartRotate(e);
  }
  _handleTouchMoveRotate(e) {
    if (this._pointers.length == 1)
      this._rotateEnd.set(e.pageX, e.pageY);
    else {
      const n = this._getSecondPointerPosition(e), r = 0.5 * (e.pageX + n.x), s = 0.5 * (e.pageY + n.y);
      this._rotateEnd.set(r, s);
    }
    this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
    const t = this.domElement;
    this._rotateLeft(ci * this._rotateDelta.x / t.clientHeight), this._rotateUp(ci * this._rotateDelta.y / t.clientHeight), this._rotateStart.copy(this._rotateEnd);
  }
  _handleTouchMovePan(e) {
    if (this._pointers.length === 1)
      this._panEnd.set(e.pageX, e.pageY);
    else {
      const t = this._getSecondPointerPosition(e), n = 0.5 * (e.pageX + t.x), r = 0.5 * (e.pageY + t.y);
      this._panEnd.set(n, r);
    }
    this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd);
  }
  _handleTouchMoveDolly(e) {
    const t = this._getSecondPointerPosition(e), n = e.pageX - t.x, r = e.pageY - t.y, s = Math.sqrt(n * n + r * r);
    this._dollyEnd.set(0, s), this._dollyDelta.set(0, Math.pow(this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed)), this._dollyOut(this._dollyDelta.y), this._dollyStart.copy(this._dollyEnd);
    const a = (e.pageX + t.x) * 0.5, o = (e.pageY + t.y) * 0.5;
    this._updateZoomParameters(a, o);
  }
  _handleTouchMoveDollyPan(e) {
    this.enableZoom && this._handleTouchMoveDolly(e), this.enablePan && this._handleTouchMovePan(e);
  }
  _handleTouchMoveDollyRotate(e) {
    this.enableZoom && this._handleTouchMoveDolly(e), this.enableRotate && this._handleTouchMoveRotate(e);
  }
  // pointers
  _addPointer(e) {
    this._pointers.push(e.pointerId);
  }
  _removePointer(e) {
    delete this._pointerPositions[e.pointerId];
    for (let t = 0; t < this._pointers.length; t++)
      if (this._pointers[t] == e.pointerId) {
        this._pointers.splice(t, 1);
        return;
      }
  }
  _isTrackingPointer(e) {
    for (let t = 0; t < this._pointers.length; t++)
      if (this._pointers[t] == e.pointerId)
        return !0;
    return !1;
  }
  _trackPointer(e) {
    let t = this._pointerPositions[e.pointerId];
    t === void 0 && (t = new de(), this._pointerPositions[e.pointerId] = t), t.set(e.pageX, e.pageY);
  }
  _getSecondPointerPosition(e) {
    const t = e.pointerId === this._pointers[0] ? this._pointers[1] : this._pointers[0];
    return this._pointerPositions[t];
  }
  //
  _customWheelEvent(e) {
    const t = e.deltaMode, n = {
      clientX: e.clientX,
      clientY: e.clientY,
      deltaY: e.deltaY
    };
    switch (t) {
      case 1:
        n.deltaY *= 16;
        break;
      case 2:
        n.deltaY *= 100;
        break;
    }
    return e.ctrlKey && !this._controlActive && (n.deltaY *= 10), n;
  }
}
function QV(i) {
  this.enabled !== !1 && (this._pointers.length === 0 && (this.domElement.setPointerCapture(i.pointerId), this.domElement.ownerDocument.addEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.addEventListener("pointerup", this._onPointerUp)), !this._isTrackingPointer(i) && (this._addPointer(i), i.pointerType === "touch" ? this._onTouchStart(i) : this._onMouseDown(i), this._cursorStyle === "grab" && (this.domElement.style.cursor = "grabbing")));
}
function JV(i) {
  this.enabled !== !1 && (i.pointerType === "touch" ? this._onTouchMove(i) : this._onMouseMove(i));
}
function ez(i) {
  switch (this._removePointer(i), this._pointers.length) {
    case 0:
      this.domElement.releasePointerCapture(i.pointerId), this.domElement.ownerDocument.removeEventListener("pointermove", this._onPointerMove), this.domElement.ownerDocument.removeEventListener("pointerup", this._onPointerUp), this.dispatchEvent(bT), this.state = Vt.NONE, this._cursorStyle === "grab" && (this.domElement.style.cursor = "grab");
      break;
    case 1:
      const e = this._pointers[0], t = this._pointerPositions[e];
      this._onTouchStart({ pointerId: e, pageX: t.x, pageY: t.y });
      break;
  }
}
function tz(i) {
  let e;
  switch (i.button) {
    case 0:
      e = this.mouseButtons.LEFT;
      break;
    case 1:
      e = this.mouseButtons.MIDDLE;
      break;
    case 2:
      e = this.mouseButtons.RIGHT;
      break;
    default:
      e = -1;
  }
  switch (e) {
    case Fn.DOLLY:
      if (this.enableZoom === !1)
        return;
      this._handleMouseDownDolly(i), this.state = Vt.DOLLY;
      break;
    case Fn.ROTATE:
      if (i.ctrlKey || i.metaKey || i.shiftKey) {
        if (this.enablePan === !1)
          return;
        this._handleMouseDownPan(i), this.state = Vt.PAN;
      } else {
        if (this.enableRotate === !1)
          return;
        this._handleMouseDownRotate(i), this.state = Vt.ROTATE;
      }
      break;
    case Fn.PAN:
      if (i.ctrlKey || i.metaKey || i.shiftKey) {
        if (this.enableRotate === !1)
          return;
        this._handleMouseDownRotate(i), this.state = Vt.ROTATE;
      } else {
        if (this.enablePan === !1)
          return;
        this._handleMouseDownPan(i), this.state = Vt.PAN;
      }
      break;
    default:
      this.state = Vt.NONE;
  }
  this.state !== Vt.NONE && this.dispatchEvent(Xg);
}
function nz(i) {
  switch (this.state) {
    case Vt.ROTATE:
      if (this.enableRotate === !1)
        return;
      this._handleMouseMoveRotate(i);
      break;
    case Vt.DOLLY:
      if (this.enableZoom === !1)
        return;
      this._handleMouseMoveDolly(i);
      break;
    case Vt.PAN:
      if (this.enablePan === !1)
        return;
      this._handleMouseMovePan(i);
      break;
  }
}
function iz(i) {
  this.enabled === !1 || this.enableZoom === !1 || this.state !== Vt.NONE || (i.preventDefault(), this.dispatchEvent(Xg), this._handleMouseWheel(this._customWheelEvent(i)), this.dispatchEvent(bT));
}
function rz(i) {
  this.enabled !== !1 && this._handleKeyDown(i);
}
function sz(i) {
  switch (this._trackPointer(i), this._pointers.length) {
    case 1:
      switch (this.touches.ONE) {
        case es.ROTATE:
          if (this.enableRotate === !1)
            return;
          this._handleTouchStartRotate(i), this.state = Vt.TOUCH_ROTATE;
          break;
        case es.PAN:
          if (this.enablePan === !1)
            return;
          this._handleTouchStartPan(i), this.state = Vt.TOUCH_PAN;
          break;
        default:
          this.state = Vt.NONE;
      }
      break;
    case 2:
      switch (this.touches.TWO) {
        case es.DOLLY_PAN:
          if (this.enableZoom === !1 && this.enablePan === !1)
            return;
          this._handleTouchStartDollyPan(i), this.state = Vt.TOUCH_DOLLY_PAN;
          break;
        case es.DOLLY_ROTATE:
          if (this.enableZoom === !1 && this.enableRotate === !1)
            return;
          this._handleTouchStartDollyRotate(i), this.state = Vt.TOUCH_DOLLY_ROTATE;
          break;
        default:
          this.state = Vt.NONE;
      }
      break;
    default:
      this.state = Vt.NONE;
  }
  this.state !== Vt.NONE && this.dispatchEvent(Xg);
}
function az(i) {
  switch (this._trackPointer(i), this.state) {
    case Vt.TOUCH_ROTATE:
      if (this.enableRotate === !1)
        return;
      this._handleTouchMoveRotate(i), this.update();
      break;
    case Vt.TOUCH_PAN:
      if (this.enablePan === !1)
        return;
      this._handleTouchMovePan(i), this.update();
      break;
    case Vt.TOUCH_DOLLY_PAN:
      if (this.enableZoom === !1 && this.enablePan === !1)
        return;
      this._handleTouchMoveDollyPan(i), this.update();
      break;
    case Vt.TOUCH_DOLLY_ROTATE:
      if (this.enableZoom === !1 && this.enableRotate === !1)
        return;
      this._handleTouchMoveDollyRotate(i), this.update();
      break;
    default:
      this.state = Vt.NONE;
  }
}
function oz(i) {
  this.enabled !== !1 && i.preventDefault();
}
function lz(i) {
  i.key === "Control" && (this._controlActive = !0, this.domElement.getRootNode().addEventListener("keyup", this._interceptControlUp, { passive: !0, capture: !0 }));
}
function cz(i) {
  i.key === "Control" && (this._controlActive = !1, this.domElement.getRootNode().removeEventListener("keyup", this._interceptControlUp, { passive: !0, capture: !0 }));
}
const uz = { type: "change" }, wv = 1e-6, Av = new Gi();
class hz extends dd {
  /**
   * Constructs a new controls instance.
   *
   * @param {Object3D} object - The object that is managed by the controls.
   * @param {?HTMLElement} domElement - The HTML element used for event listeners.
   */
  constructor(e, t = null) {
    super(e, t), this.movementSpeed = 1, this.rollSpeed = 5e-3, this.dragToLook = !1, this.autoForward = !1, this._moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 }, this._moveVector = new P(0, 0, 0), this._rotationVector = new P(0, 0, 0), this._lastQuaternion = new Gi(), this._lastPosition = new P(), this._status = 0, this._onKeyDown = dz.bind(this), this._onKeyUp = fz.bind(this), this._onPointerMove = mz.bind(this), this._onPointerDown = pz.bind(this), this._onPointerUp = gz.bind(this), this._onPointerCancel = _z.bind(this), this._onContextMenu = xz.bind(this), t !== null && this.connect(t);
  }
  connect(e) {
    super.connect(e), window.addEventListener("keydown", this._onKeyDown), window.addEventListener("keyup", this._onKeyUp), this.domElement.addEventListener("pointermove", this._onPointerMove), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointerup", this._onPointerUp), this.domElement.addEventListener("pointercancel", this._onPointerCancel), this.domElement.addEventListener("contextmenu", this._onContextMenu);
  }
  disconnect() {
    window.removeEventListener("keydown", this._onKeyDown), window.removeEventListener("keyup", this._onKeyUp), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointercancel", this._onPointerCancel), this.domElement.removeEventListener("contextmenu", this._onContextMenu);
  }
  dispose() {
    this.disconnect();
  }
  update(e) {
    if (this.enabled === !1)
      return;
    const t = this.object, n = e * this.movementSpeed, r = e * this.rollSpeed;
    t.translateX(this._moveVector.x * n), t.translateY(this._moveVector.y * n), t.translateZ(this._moveVector.z * n), Av.set(this._rotationVector.x * r, this._rotationVector.y * r, this._rotationVector.z * r, 1).normalize(), t.quaternion.multiply(Av), (this._lastPosition.distanceToSquared(t.position) > wv || 8 * (1 - this._lastQuaternion.dot(t.quaternion)) > wv) && (this.dispatchEvent(uz), this._lastQuaternion.copy(t.quaternion), this._lastPosition.copy(t.position));
  }
  // private
  _updateMovementVector() {
    const e = this._moveState.forward || this.autoForward && !this._moveState.back ? 1 : 0;
    this._moveVector.x = -this._moveState.left + this._moveState.right, this._moveVector.y = -this._moveState.down + this._moveState.up, this._moveVector.z = -e + this._moveState.back;
  }
  _updateRotationVector() {
    this._rotationVector.x = -this._moveState.pitchDown + this._moveState.pitchUp, this._rotationVector.y = -this._moveState.yawRight + this._moveState.yawLeft, this._rotationVector.z = -this._moveState.rollRight + this._moveState.rollLeft;
  }
  _getContainerDimensions() {
    return this.domElement != document ? {
      size: [this.domElement.offsetWidth, this.domElement.offsetHeight],
      offset: [this.domElement.offsetLeft, this.domElement.offsetTop]
    } : {
      size: [window.innerWidth, window.innerHeight],
      offset: [0, 0]
    };
  }
}
function dz(i) {
  if (!(i.altKey || this.enabled === !1)) {
    switch (i.code) {
      case "ShiftLeft":
      case "ShiftRight":
        this.movementSpeedMultiplier = 0.1;
        break;
      case "KeyW":
        this._moveState.forward = 1;
        break;
      case "KeyS":
        this._moveState.back = 1;
        break;
      case "KeyA":
        this._moveState.left = 1;
        break;
      case "KeyD":
        this._moveState.right = 1;
        break;
      case "KeyR":
        this._moveState.up = 1;
        break;
      case "KeyF":
        this._moveState.down = 1;
        break;
      case "ArrowUp":
        this._moveState.pitchUp = 1;
        break;
      case "ArrowDown":
        this._moveState.pitchDown = 1;
        break;
      case "ArrowLeft":
        this._moveState.yawLeft = 1;
        break;
      case "ArrowRight":
        this._moveState.yawRight = 1;
        break;
      case "KeyQ":
        this._moveState.rollLeft = 1;
        break;
      case "KeyE":
        this._moveState.rollRight = 1;
        break;
    }
    this._updateMovementVector(), this._updateRotationVector();
  }
}
function fz(i) {
  if (this.enabled !== !1) {
    switch (i.code) {
      case "ShiftLeft":
      case "ShiftRight":
        this.movementSpeedMultiplier = 1;
        break;
      case "KeyW":
        this._moveState.forward = 0;
        break;
      case "KeyS":
        this._moveState.back = 0;
        break;
      case "KeyA":
        this._moveState.left = 0;
        break;
      case "KeyD":
        this._moveState.right = 0;
        break;
      case "KeyR":
        this._moveState.up = 0;
        break;
      case "KeyF":
        this._moveState.down = 0;
        break;
      case "ArrowUp":
        this._moveState.pitchUp = 0;
        break;
      case "ArrowDown":
        this._moveState.pitchDown = 0;
        break;
      case "ArrowLeft":
        this._moveState.yawLeft = 0;
        break;
      case "ArrowRight":
        this._moveState.yawRight = 0;
        break;
      case "KeyQ":
        this._moveState.rollLeft = 0;
        break;
      case "KeyE":
        this._moveState.rollRight = 0;
        break;
    }
    this._updateMovementVector(), this._updateRotationVector();
  }
}
function pz(i) {
  if (this.enabled !== !1)
    if (this.dragToLook)
      this._status++;
    else {
      switch (i.button) {
        case 0:
          this._moveState.forward = 1;
          break;
        case 2:
          this._moveState.back = 1;
          break;
      }
      this._updateMovementVector();
    }
}
function mz(i) {
  if (this.enabled !== !1 && (!this.dragToLook || this._status > 0)) {
    const e = this._getContainerDimensions(), t = e.size[0] / 2, n = e.size[1] / 2;
    this._moveState.yawLeft = -(i.pageX - e.offset[0] - t) / t, this._moveState.pitchDown = (i.pageY - e.offset[1] - n) / n, this._updateRotationVector();
  }
}
function gz(i) {
  if (this.enabled !== !1) {
    if (this.dragToLook)
      this._status--, this._moveState.yawLeft = this._moveState.pitchDown = 0;
    else {
      switch (i.button) {
        case 0:
          this._moveState.forward = 0;
          break;
        case 2:
          this._moveState.back = 0;
          break;
      }
      this._updateMovementVector();
    }
    this._updateRotationVector();
  }
}
function _z() {
  this.enabled !== !1 && (this.dragToLook ? (this._status = 0, this._moveState.yawLeft = this._moveState.pitchDown = 0) : (this._moveState.forward = 0, this._moveState.back = 0, this._updateMovementVector()), this._updateRotationVector());
}
function xz(i) {
  this.enabled !== !1 && i.preventDefault();
}
const vz = {
  name: "CopyShader",
  uniforms: {
    tDiffuse: { value: null },
    opacity: { value: 1 }
  },
  vertexShader: (
    /* glsl */
    `

		varying vec2 vUv;

		void main() {

			vUv = uv;
			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

		}`
  ),
  fragmentShader: (
    /* glsl */
    `

		uniform float opacity;

		uniform sampler2D tDiffuse;

		varying vec2 vUv;

		void main() {

			vec4 texel = texture2D( tDiffuse, vUv );
			gl_FragColor = opacity * texel;


		}`
  )
};
class Pd {
  /**
   * Constructs a new pass.
   */
  constructor() {
    this.isPass = !0, this.enabled = !0, this.needsSwap = !0, this.clear = !1, this.renderToScreen = !1;
  }
  /**
   * Sets the size of the pass.
   *
   * @abstract
   * @param {number} width - The width to set.
   * @param {number} height - The height to set.
   */
  setSize() {
  }
  /**
   * This method holds the render logic of a pass. It must be implemented in all derived classes.
   *
   * @abstract
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
   * destination for the pass.
   * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
   * previous pass from this buffer.
   * @param {number} deltaTime - The delta time in seconds.
   * @param {boolean} maskActive - Whether masking is active or not.
   */
  render() {
    console.error("THREE.Pass: .render() must be implemented in derived pass.");
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever the pass is no longer used in your app.
   *
   * @abstract
   */
  dispose() {
  }
}
const yz = new bl(-1, 1, 1, -1, 0, 1);
class bz extends Pn {
  constructor() {
    super(), this.setAttribute("position", new an([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)), this.setAttribute("uv", new an([0, 2, 0, 0, 2, 0], 2));
  }
}
const Sz = new bz();
class Tz {
  /**
   * Constructs a new full screen quad.
   *
   * @param {?Material} material - The material to render te full screen quad with.
   */
  constructor(e) {
    this._mesh = new _n(Sz, e);
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever the instance is no longer used in your app.
   */
  dispose() {
    this._mesh.geometry.dispose();
  }
  /**
   * Renders the full screen quad.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   */
  render(e) {
    e.render(this._mesh, yz);
  }
  /**
   * The quad's material.
   *
   * @type {?Material}
   */
  get material() {
    return this._mesh.material;
  }
  set material(e) {
    this._mesh.material = e;
  }
}
class Mz extends Pd {
  /**
   * Constructs a new shader pass.
   *
   * @param {Object|ShaderMaterial} [shader] - A shader object holding vertex and fragment shader as well as
   * defines and uniforms. It's also valid to pass a custom shader material.
   * @param {string} [textureID='tDiffuse'] - The name of the texture uniform that should sample
   * the read buffer.
   */
  constructor(e, t = "tDiffuse") {
    super(), this.textureID = t, this.uniforms = null, this.material = null, e instanceof Vi ? (this.uniforms = e.uniforms, this.material = e) : e && (this.uniforms = ly.clone(e.uniforms), this.material = new Vi({
      name: e.name !== void 0 ? e.name : "unspecified",
      defines: Object.assign({}, e.defines),
      uniforms: this.uniforms,
      vertexShader: e.vertexShader,
      fragmentShader: e.fragmentShader
    })), this._fsQuad = new Tz(this.material);
  }
  /**
   * Performs the shader pass.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
   * destination for the pass.
   * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
   * previous pass from this buffer.
   * @param {number} deltaTime - The delta time in seconds.
   * @param {boolean} maskActive - Whether masking is active or not.
   */
  render(e, t, n) {
    this.uniforms[this.textureID] && (this.uniforms[this.textureID].value = n.texture), this._fsQuad.material = this.material, this.renderToScreen ? (e.setRenderTarget(null), this._fsQuad.render(e)) : (e.setRenderTarget(t), this.clear && e.clear(e.autoClearColor, e.autoClearDepth, e.autoClearStencil), this._fsQuad.render(e));
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever the pass is no longer used in your app.
   */
  dispose() {
    this.material.dispose(), this._fsQuad.dispose();
  }
}
class Rv extends Pd {
  /**
   * Constructs a new mask pass.
   *
   * @param {Scene} scene - The 3D objects in this scene will define the mask.
   * @param {Camera} camera - The camera.
   */
  constructor(e, t) {
    super(), this.scene = e, this.camera = t, this.clear = !0, this.needsSwap = !1, this.inverse = !1;
  }
  /**
   * Performs a mask pass with the configured scene and camera.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
   * destination for the pass.
   * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
   * previous pass from this buffer.
   * @param {number} deltaTime - The delta time in seconds.
   * @param {boolean} maskActive - Whether masking is active or not.
   */
  render(e, t, n) {
    const r = e.getContext(), s = e.state;
    s.buffers.color.setMask(!1), s.buffers.depth.setMask(!1), s.buffers.color.setLocked(!0), s.buffers.depth.setLocked(!0);
    let a, o;
    this.inverse ? (a = 0, o = 1) : (a = 1, o = 0), s.buffers.stencil.setTest(!0), s.buffers.stencil.setOp(r.REPLACE, r.REPLACE, r.REPLACE), s.buffers.stencil.setFunc(r.ALWAYS, a, 4294967295), s.buffers.stencil.setClear(o), s.buffers.stencil.setLocked(!0), e.setRenderTarget(n), this.clear && e.clear(), e.render(this.scene, this.camera), e.setRenderTarget(t), this.clear && e.clear(), e.render(this.scene, this.camera), s.buffers.color.setLocked(!1), s.buffers.depth.setLocked(!1), s.buffers.color.setMask(!0), s.buffers.depth.setMask(!0), s.buffers.stencil.setLocked(!1), s.buffers.stencil.setFunc(r.EQUAL, 1, 4294967295), s.buffers.stencil.setOp(r.KEEP, r.KEEP, r.KEEP), s.buffers.stencil.setLocked(!0);
  }
}
class Ez extends Pd {
  /**
   * Constructs a new clear mask pass.
   */
  constructor() {
    super(), this.needsSwap = !1;
  }
  /**
   * Performs the clear of the currently defined mask.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
   * destination for the pass.
   * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
   * previous pass from this buffer.
   * @param {number} deltaTime - The delta time in seconds.
   * @param {boolean} maskActive - Whether masking is active or not.
   */
  render(e) {
    e.state.buffers.stencil.setLocked(!1), e.state.buffers.stencil.setTest(!1);
  }
}
class wz {
  /**
   * Constructs a new effect composer.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} [renderTarget] - This render target and a clone will
   * be used as the internal read and write buffers. If not given, the composer creates
   * the buffers automatically.
   */
  constructor(e, t) {
    if (this.renderer = e, this._pixelRatio = e.getPixelRatio(), t === void 0) {
      const n = e.getSize(new de());
      this._width = n.width, this._height = n.height, t = new tr(this._width * this._pixelRatio, this._height * this._pixelRatio, { type: nn }), t.texture.name = "EffectComposer.rt1";
    } else
      this._width = t.width, this._height = t.height;
    this.renderTarget1 = t, this.renderTarget2 = t.clone(), this.renderTarget2.texture.name = "EffectComposer.rt2", this.writeBuffer = this.renderTarget1, this.readBuffer = this.renderTarget2, this.renderToScreen = !0, this.passes = [], this.copyPass = new Mz(vz), this.copyPass.material.blending = Nn, this.timer = new iw();
  }
  /**
   * Swaps the internal read/write buffers.
   */
  swapBuffers() {
    const e = this.readBuffer;
    this.readBuffer = this.writeBuffer, this.writeBuffer = e;
  }
  /**
   * Adds the given pass to the pass chain.
   *
   * @param {Pass} pass - The pass to add.
   */
  addPass(e) {
    this.passes.push(e), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
  }
  /**
   * Inserts the given pass at a given index.
   *
   * @param {Pass} pass - The pass to insert.
   * @param {number} index - The index into the pass chain.
   */
  insertPass(e, t) {
    this.passes.splice(t, 0, e), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
  }
  /**
   * Removes the given pass from the pass chain.
   *
   * @param {Pass} pass - The pass to remove.
   */
  removePass(e) {
    const t = this.passes.indexOf(e);
    t !== -1 && this.passes.splice(t, 1);
  }
  /**
   * Returns `true` if the pass for the given index is the last enabled pass in the pass chain.
   *
   * @param {number} passIndex - The pass index.
   * @return {boolean} Whether the pass for the given index is the last pass in the pass chain.
   */
  isLastEnabledPass(e) {
    for (let t = e + 1; t < this.passes.length; t++)
      if (this.passes[t].enabled)
        return !1;
    return !0;
  }
  /**
   * Executes all enabled post-processing passes in order to produce the final frame.
   *
   * @param {number} deltaTime - The delta time in seconds. If not given, the composer computes
   * its own time delta value.
   */
  render(e) {
    this.timer.update(), e === void 0 && (e = this.timer.getDelta());
    const t = this.renderer.getRenderTarget();
    let n = !1;
    for (let r = 0, s = this.passes.length; r < s; r++) {
      const a = this.passes[r];
      if (a.enabled !== !1) {
        if (a.renderToScreen = this.renderToScreen && this.isLastEnabledPass(r), a.render(this.renderer, this.writeBuffer, this.readBuffer, e, n), a.needsSwap) {
          if (n) {
            const o = this.renderer.getContext(), l = this.renderer.state.buffers.stencil;
            l.setFunc(o.NOTEQUAL, 1, 4294967295), this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, e), l.setFunc(o.EQUAL, 1, 4294967295);
          }
          this.swapBuffers();
        }
        Rv !== void 0 && (a instanceof Rv ? n = !0 : a instanceof Ez && (n = !1));
      }
    }
    this.renderer.setRenderTarget(t);
  }
  /**
   * Resets the internal state of the EffectComposer.
   *
   * @param {WebGLRenderTarget} [renderTarget] - This render target has the same purpose like
   * the one from the constructor. If set, it is used to setup the read and write buffers.
   */
  reset(e) {
    if (e === void 0) {
      const t = this.renderer.getSize(new de());
      this._pixelRatio = this.renderer.getPixelRatio(), this._width = t.width, this._height = t.height, e = this.renderTarget1.clone(), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
    }
    this.renderTarget1.dispose(), this.renderTarget2.dispose(), this.renderTarget1 = e, this.renderTarget2 = e.clone(), this.writeBuffer = this.renderTarget1, this.readBuffer = this.renderTarget2;
  }
  /**
   * Resizes the internal read and write buffers as well as all passes. Similar to {@link WebGLRenderer#setSize},
   * this method honors the current pixel ration.
   *
   * @param {number} width - The width in logical pixels.
   * @param {number} height - The height in logical pixels.
   */
  setSize(e, t) {
    this._width = e, this._height = t;
    const n = this._width * this._pixelRatio, r = this._height * this._pixelRatio;
    this.renderTarget1.setSize(n, r), this.renderTarget2.setSize(n, r);
    for (let s = 0; s < this.passes.length; s++)
      this.passes[s].setSize(n, r);
  }
  /**
   * Sets device pixel ratio. This is usually used for HiDPI device to prevent blurring output.
   * Setting the pixel ratio will automatically resize the composer.
   *
   * @param {number} pixelRatio - The pixel ratio to set.
   */
  setPixelRatio(e) {
    this._pixelRatio = e, this.setSize(this._width, this._height);
  }
  /**
   * Frees the GPU-related resources allocated by this instance. Call this
   * method whenever the composer is no longer used in your app.
   */
  dispose() {
    this.renderTarget1.dispose(), this.renderTarget2.dispose(), this.copyPass.dispose();
  }
}
class Az extends Pd {
  /**
   * Constructs a new render pass.
   *
   * @param {Scene} scene - The scene to render.
   * @param {Camera} camera - The camera.
   * @param {?Material} [overrideMaterial=null] - The override material. If set, this material is used
   * for all objects in the scene.
   * @param {?(number|Color|string)} [clearColor=null] - The clear color of the render pass.
   * @param {?number} [clearAlpha=null] - The clear alpha of the render pass.
   */
  constructor(e, t, n = null, r = null, s = null) {
    super(), this.scene = e, this.camera = t, this.overrideMaterial = n, this.clearColor = r, this.clearAlpha = s, this.clear = !0, this.clearDepth = !1, this.needsSwap = !1, this.isRenderPass = !0, this._oldClearColor = new He();
  }
  /**
   * Performs a beauty pass with the configured scene and camera.
   *
   * @param {WebGLRenderer} renderer - The renderer.
   * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
   * destination for the pass.
   * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
   * previous pass from this buffer.
   * @param {number} deltaTime - The delta time in seconds.
   * @param {boolean} maskActive - Whether masking is active or not.
   */
  render(e, t, n) {
    const r = e.autoClear;
    e.autoClear = !1;
    let s, a;
    this.overrideMaterial !== null && (a = this.scene.overrideMaterial, this.scene.overrideMaterial = this.overrideMaterial), this.clearColor !== null && (e.getClearColor(this._oldClearColor), e.setClearColor(this.clearColor, e.getClearAlpha())), this.clearAlpha !== null && (s = e.getClearAlpha(), e.setClearAlpha(this.clearAlpha)), this.clearDepth == !0 && e.clearDepth(), e.setRenderTarget(this.renderToScreen ? null : n), this.clear === !0 && e.clear(e.autoClearColor, e.autoClearDepth, e.autoClearStencil), e.render(this.scene, this.camera), this.clearColor !== null && e.setClearColor(this._oldClearColor), this.clearAlpha !== null && e.setClearAlpha(s), this.overrideMaterial !== null && (this.scene.overrideMaterial = a), e.autoClear = r;
  }
}
function xi() {
  return xi = Object.assign ? Object.assign.bind() : function(i) {
    for (var e = 1; e < arguments.length; e++) {
      var t = arguments[e];
      for (var n in t)
        ({}).hasOwnProperty.call(t, n) && (i[n] = t[n]);
    }
    return i;
  }, xi.apply(null, arguments);
}
function Rz(i) {
  if (i === void 0)
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  return i;
}
function Kc(i, e) {
  return Kc = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t, n) {
    return t.__proto__ = n, t;
  }, Kc(i, e);
}
function Cz(i, e) {
  i.prototype = Object.create(e.prototype), i.prototype.constructor = i, Kc(i, e);
}
function om(i) {
  return om = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e) {
    return e.__proto__ || Object.getPrototypeOf(e);
  }, om(i);
}
function Nz(i) {
  try {
    return Function.toString.call(i).indexOf("[native code]") !== -1;
  } catch {
    return typeof i == "function";
  }
}
function ST() {
  try {
    var i = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {
    }));
  } catch {
  }
  return (ST = function() {
    return !!i;
  })();
}
function Pz(i, e, t) {
  if (ST())
    return Reflect.construct.apply(null, arguments);
  var n = [null];
  n.push.apply(n, e);
  var r = new (i.bind.apply(i, n))();
  return t && Kc(r, t.prototype), r;
}
function lm(i) {
  var e = typeof Map == "function" ? /* @__PURE__ */ new Map() : void 0;
  return lm = function(n) {
    if (n === null || !Nz(n))
      return n;
    if (typeof n != "function")
      throw new TypeError("Super expression must either be null or a function");
    if (e !== void 0) {
      if (e.has(n))
        return e.get(n);
      e.set(n, r);
    }
    function r() {
      return Pz(n, arguments, om(this).constructor);
    }
    return r.prototype = Object.create(n.prototype, {
      constructor: {
        value: r,
        enumerable: !1,
        writable: !0,
        configurable: !0
      }
    }), Kc(r, n);
  }, lm(i);
}
var Dz = {
  1: `Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).

`,
  2: `Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).

`,
  3: `Passed an incorrect argument to a color function, please pass a string representation of a color.

`,
  4: `Couldn't generate valid rgb string from %s, it returned %s.

`,
  5: `Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.

`,
  6: `Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).

`,
  7: `Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).

`,
  8: `Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.

`,
  9: `Please provide a number of steps to the modularScale helper.

`,
  10: `Please pass a number or one of the predefined scales to the modularScale helper as the ratio.

`,
  11: `Invalid value passed as base to modularScale, expected number or em string but got "%s"

`,
  12: `Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.

`,
  13: `Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.

`,
  14: `Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.

`,
  15: `Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.

`,
  16: `You must provide a template to this method.

`,
  17: `You passed an unsupported selector state to this method.

`,
  18: `minScreen and maxScreen must be provided as stringified numbers with the same units.

`,
  19: `fromSize and toSize must be provided as stringified numbers with the same units.

`,
  20: `expects either an array of objects or a single object with the properties prop, fromSize, and toSize.

`,
  21: "expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n",
  22: "expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n",
  23: `fontFace expects a name of a font-family.

`,
  24: `fontFace expects either the path to the font file(s) or a name of a local copy.

`,
  25: `fontFace expects localFonts to be an array.

`,
  26: `fontFace expects fileFormats to be an array.

`,
  27: `radialGradient requries at least 2 color-stops to properly render.

`,
  28: `Please supply a filename to retinaImage() as the first argument.

`,
  29: `Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.

`,
  30: "Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",
  31: `The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation

`,
  32: `To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])
To pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')

`,
  33: `The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation

`,
  34: `borderRadius expects a radius value as a string or number as the second argument.

`,
  35: `borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.

`,
  36: `Property must be a string value.

`,
  37: `Syntax Error at %s.

`,
  38: `Formula contains a function that needs parentheses at %s.

`,
  39: `Formula is missing closing parenthesis at %s.

`,
  40: `Formula has too many closing parentheses at %s.

`,
  41: `All values in a formula must have the same unit or be unitless.

`,
  42: `Please provide a number of steps to the modularScale helper.

`,
  43: `Please pass a number or one of the predefined scales to the modularScale helper as the ratio.

`,
  44: `Invalid value passed as base to modularScale, expected number or em/rem string but got %s.

`,
  45: `Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.

`,
  46: `Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.

`,
  47: `minScreen and maxScreen must be provided as stringified numbers with the same units.

`,
  48: `fromSize and toSize must be provided as stringified numbers with the same units.

`,
  49: `Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.

`,
  50: `Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.

`,
  51: `Expects the first argument object to have the properties prop, fromSize, and toSize.

`,
  52: `fontFace expects either the path to the font file(s) or a name of a local copy.

`,
  53: `fontFace expects localFonts to be an array.

`,
  54: `fontFace expects fileFormats to be an array.

`,
  55: `fontFace expects a name of a font-family.

`,
  56: `linearGradient requries at least 2 color-stops to properly render.

`,
  57: `radialGradient requries at least 2 color-stops to properly render.

`,
  58: `Please supply a filename to retinaImage() as the first argument.

`,
  59: `Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.

`,
  60: "Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",
  61: `Property must be a string value.

`,
  62: `borderRadius expects a radius value as a string or number as the second argument.

`,
  63: `borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.

`,
  64: `The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.

`,
  65: `To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').

`,
  66: `The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.

`,
  67: `You must provide a template to this method.

`,
  68: `You passed an unsupported selector state to this method.

`,
  69: `Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.

`,
  70: `Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.

`,
  71: `Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.

`,
  72: `Passed invalid base value %s to %s(), please pass a value like "12px" or 12.

`,
  73: `Please provide a valid CSS variable.

`,
  74: `CSS variable not found and no default was provided.

`,
  75: `important requires a valid style object, got a %s instead.

`,
  76: `fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.

`,
  77: `remToPx expects a value in "rem" but you provided it in "%s".

`,
  78: `base must be set in "px" or "%" but you set it in "%s".
`
};
function Lz() {
  for (var i = arguments.length, e = new Array(i), t = 0; t < i; t++)
    e[t] = arguments[t];
  var n = e[0], r = [], s;
  for (s = 1; s < e.length; s += 1)
    r.push(e[s]);
  return r.forEach(function(a) {
    n = n.replace(/%[a-z]/, a);
  }), n;
}
var Mr = /* @__PURE__ */ function(i) {
  Cz(e, i);
  function e(t) {
    var n;
    if (process.env.NODE_ENV === "production")
      n = i.call(this, "An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#" + t + " for more information.") || this;
    else {
      for (var r = arguments.length, s = new Array(r > 1 ? r - 1 : 0), a = 1; a < r; a++)
        s[a - 1] = arguments[a];
      n = i.call(this, Lz.apply(void 0, [Dz[t]].concat(s))) || this;
    }
    return Rz(n);
  }
  return e;
}(/* @__PURE__ */ lm(Error));
function yp(i) {
  return Math.round(i * 255);
}
function Fz(i, e, t) {
  return yp(i) + "," + yp(e) + "," + yp(t);
}
function Zc(i, e, t, n) {
  if (n === void 0 && (n = Fz), e === 0)
    return n(t, t, t);
  var r = (i % 360 + 360) % 360 / 60, s = (1 - Math.abs(2 * t - 1)) * e, a = s * (1 - Math.abs(r % 2 - 1)), o = 0, l = 0, c = 0;
  r >= 0 && r < 1 ? (o = s, l = a) : r >= 1 && r < 2 ? (o = a, l = s) : r >= 2 && r < 3 ? (l = s, c = a) : r >= 3 && r < 4 ? (l = a, c = s) : r >= 4 && r < 5 ? (o = a, c = s) : r >= 5 && r < 6 && (o = s, c = a);
  var u = t - s / 2, h = o + u, d = l + u, f = c + u;
  return n(h, d, f);
}
var Cv = {
  aliceblue: "f0f8ff",
  antiquewhite: "faebd7",
  aqua: "00ffff",
  aquamarine: "7fffd4",
  azure: "f0ffff",
  beige: "f5f5dc",
  bisque: "ffe4c4",
  black: "000",
  blanchedalmond: "ffebcd",
  blue: "0000ff",
  blueviolet: "8a2be2",
  brown: "a52a2a",
  burlywood: "deb887",
  cadetblue: "5f9ea0",
  chartreuse: "7fff00",
  chocolate: "d2691e",
  coral: "ff7f50",
  cornflowerblue: "6495ed",
  cornsilk: "fff8dc",
  crimson: "dc143c",
  cyan: "00ffff",
  darkblue: "00008b",
  darkcyan: "008b8b",
  darkgoldenrod: "b8860b",
  darkgray: "a9a9a9",
  darkgreen: "006400",
  darkgrey: "a9a9a9",
  darkkhaki: "bdb76b",
  darkmagenta: "8b008b",
  darkolivegreen: "556b2f",
  darkorange: "ff8c00",
  darkorchid: "9932cc",
  darkred: "8b0000",
  darksalmon: "e9967a",
  darkseagreen: "8fbc8f",
  darkslateblue: "483d8b",
  darkslategray: "2f4f4f",
  darkslategrey: "2f4f4f",
  darkturquoise: "00ced1",
  darkviolet: "9400d3",
  deeppink: "ff1493",
  deepskyblue: "00bfff",
  dimgray: "696969",
  dimgrey: "696969",
  dodgerblue: "1e90ff",
  firebrick: "b22222",
  floralwhite: "fffaf0",
  forestgreen: "228b22",
  fuchsia: "ff00ff",
  gainsboro: "dcdcdc",
  ghostwhite: "f8f8ff",
  gold: "ffd700",
  goldenrod: "daa520",
  gray: "808080",
  green: "008000",
  greenyellow: "adff2f",
  grey: "808080",
  honeydew: "f0fff0",
  hotpink: "ff69b4",
  indianred: "cd5c5c",
  indigo: "4b0082",
  ivory: "fffff0",
  khaki: "f0e68c",
  lavender: "e6e6fa",
  lavenderblush: "fff0f5",
  lawngreen: "7cfc00",
  lemonchiffon: "fffacd",
  lightblue: "add8e6",
  lightcoral: "f08080",
  lightcyan: "e0ffff",
  lightgoldenrodyellow: "fafad2",
  lightgray: "d3d3d3",
  lightgreen: "90ee90",
  lightgrey: "d3d3d3",
  lightpink: "ffb6c1",
  lightsalmon: "ffa07a",
  lightseagreen: "20b2aa",
  lightskyblue: "87cefa",
  lightslategray: "789",
  lightslategrey: "789",
  lightsteelblue: "b0c4de",
  lightyellow: "ffffe0",
  lime: "0f0",
  limegreen: "32cd32",
  linen: "faf0e6",
  magenta: "f0f",
  maroon: "800000",
  mediumaquamarine: "66cdaa",
  mediumblue: "0000cd",
  mediumorchid: "ba55d3",
  mediumpurple: "9370db",
  mediumseagreen: "3cb371",
  mediumslateblue: "7b68ee",
  mediumspringgreen: "00fa9a",
  mediumturquoise: "48d1cc",
  mediumvioletred: "c71585",
  midnightblue: "191970",
  mintcream: "f5fffa",
  mistyrose: "ffe4e1",
  moccasin: "ffe4b5",
  navajowhite: "ffdead",
  navy: "000080",
  oldlace: "fdf5e6",
  olive: "808000",
  olivedrab: "6b8e23",
  orange: "ffa500",
  orangered: "ff4500",
  orchid: "da70d6",
  palegoldenrod: "eee8aa",
  palegreen: "98fb98",
  paleturquoise: "afeeee",
  palevioletred: "db7093",
  papayawhip: "ffefd5",
  peachpuff: "ffdab9",
  peru: "cd853f",
  pink: "ffc0cb",
  plum: "dda0dd",
  powderblue: "b0e0e6",
  purple: "800080",
  rebeccapurple: "639",
  red: "f00",
  rosybrown: "bc8f8f",
  royalblue: "4169e1",
  saddlebrown: "8b4513",
  salmon: "fa8072",
  sandybrown: "f4a460",
  seagreen: "2e8b57",
  seashell: "fff5ee",
  sienna: "a0522d",
  silver: "c0c0c0",
  skyblue: "87ceeb",
  slateblue: "6a5acd",
  slategray: "708090",
  slategrey: "708090",
  snow: "fffafa",
  springgreen: "00ff7f",
  steelblue: "4682b4",
  tan: "d2b48c",
  teal: "008080",
  thistle: "d8bfd8",
  tomato: "ff6347",
  turquoise: "40e0d0",
  violet: "ee82ee",
  wheat: "f5deb3",
  white: "fff",
  whitesmoke: "f5f5f5",
  yellow: "ff0",
  yellowgreen: "9acd32"
};
function Iz(i) {
  if (typeof i != "string")
    return i;
  var e = i.toLowerCase();
  return Cv[e] ? "#" + Cv[e] : i;
}
var Uz = /^#[a-fA-F0-9]{6}$/, Bz = /^#[a-fA-F0-9]{8}$/, Oz = /^#[a-fA-F0-9]{3}$/, kz = /^#[a-fA-F0-9]{4}$/, bp = /^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i, Gz = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i, Vz = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i, zz = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;
function Va(i) {
  if (typeof i != "string")
    throw new Mr(3);
  var e = Iz(i);
  if (e.match(Uz))
    return {
      red: parseInt("" + e[1] + e[2], 16),
      green: parseInt("" + e[3] + e[4], 16),
      blue: parseInt("" + e[5] + e[6], 16)
    };
  if (e.match(Bz)) {
    var t = parseFloat((parseInt("" + e[7] + e[8], 16) / 255).toFixed(2));
    return {
      red: parseInt("" + e[1] + e[2], 16),
      green: parseInt("" + e[3] + e[4], 16),
      blue: parseInt("" + e[5] + e[6], 16),
      alpha: t
    };
  }
  if (e.match(Oz))
    return {
      red: parseInt("" + e[1] + e[1], 16),
      green: parseInt("" + e[2] + e[2], 16),
      blue: parseInt("" + e[3] + e[3], 16)
    };
  if (e.match(kz)) {
    var n = parseFloat((parseInt("" + e[4] + e[4], 16) / 255).toFixed(2));
    return {
      red: parseInt("" + e[1] + e[1], 16),
      green: parseInt("" + e[2] + e[2], 16),
      blue: parseInt("" + e[3] + e[3], 16),
      alpha: n
    };
  }
  var r = bp.exec(e);
  if (r)
    return {
      red: parseInt("" + r[1], 10),
      green: parseInt("" + r[2], 10),
      blue: parseInt("" + r[3], 10)
    };
  var s = Gz.exec(e.substring(0, 50));
  if (s)
    return {
      red: parseInt("" + s[1], 10),
      green: parseInt("" + s[2], 10),
      blue: parseInt("" + s[3], 10),
      alpha: parseFloat("" + s[4]) > 1 ? parseFloat("" + s[4]) / 100 : parseFloat("" + s[4])
    };
  var a = Vz.exec(e);
  if (a) {
    var o = parseInt("" + a[1], 10), l = parseInt("" + a[2], 10) / 100, c = parseInt("" + a[3], 10) / 100, u = "rgb(" + Zc(o, l, c) + ")", h = bp.exec(u);
    if (!h)
      throw new Mr(4, e, u);
    return {
      red: parseInt("" + h[1], 10),
      green: parseInt("" + h[2], 10),
      blue: parseInt("" + h[3], 10)
    };
  }
  var d = zz.exec(e.substring(0, 50));
  if (d) {
    var f = parseInt("" + d[1], 10), p = parseInt("" + d[2], 10) / 100, _ = parseInt("" + d[3], 10) / 100, g = "rgb(" + Zc(f, p, _) + ")", m = bp.exec(g);
    if (!m)
      throw new Mr(4, e, g);
    return {
      red: parseInt("" + m[1], 10),
      green: parseInt("" + m[2], 10),
      blue: parseInt("" + m[3], 10),
      alpha: parseFloat("" + d[4]) > 1 ? parseFloat("" + d[4]) / 100 : parseFloat("" + d[4])
    };
  }
  throw new Mr(5);
}
function Hz(i) {
  var e = i.red / 255, t = i.green / 255, n = i.blue / 255, r = Math.max(e, t, n), s = Math.min(e, t, n), a = (r + s) / 2;
  if (r === s)
    return i.alpha !== void 0 ? {
      hue: 0,
      saturation: 0,
      lightness: a,
      alpha: i.alpha
    } : {
      hue: 0,
      saturation: 0,
      lightness: a
    };
  var o, l = r - s, c = a > 0.5 ? l / (2 - r - s) : l / (r + s);
  switch (r) {
    case e:
      o = (t - n) / l + (t < n ? 6 : 0);
      break;
    case t:
      o = (n - e) / l + 2;
      break;
    default:
      o = (e - t) / l + 4;
      break;
  }
  return o *= 60, i.alpha !== void 0 ? {
    hue: o,
    saturation: c,
    lightness: a,
    alpha: i.alpha
  } : {
    hue: o,
    saturation: c,
    lightness: a
  };
}
function Qs(i) {
  return Hz(Va(i));
}
var $z = function(e) {
  return e.length === 7 && e[1] === e[2] && e[3] === e[4] && e[5] === e[6] ? "#" + e[1] + e[3] + e[5] : e;
}, cm = $z;
function fa(i) {
  var e = i.toString(16);
  return e.length === 1 ? "0" + e : e;
}
function Sp(i) {
  return fa(Math.round(i * 255));
}
function Wz(i, e, t) {
  return cm("#" + Sp(i) + Sp(e) + Sp(t));
}
function Qh(i, e, t) {
  return Zc(i, e, t, Wz);
}
function qz(i, e, t) {
  if (typeof i == "number" && typeof e == "number" && typeof t == "number")
    return Qh(i, e, t);
  if (typeof i == "object" && e === void 0 && t === void 0)
    return Qh(i.hue, i.saturation, i.lightness);
  throw new Mr(1);
}
function Xz(i, e, t, n) {
  if (typeof i == "number" && typeof e == "number" && typeof t == "number" && typeof n == "number")
    return n >= 1 ? Qh(i, e, t) : "rgba(" + Zc(i, e, t) + "," + n + ")";
  if (typeof i == "object" && e === void 0 && t === void 0 && n === void 0)
    return i.alpha >= 1 ? Qh(i.hue, i.saturation, i.lightness) : "rgba(" + Zc(i.hue, i.saturation, i.lightness) + "," + i.alpha + ")";
  throw new Mr(2);
}
function um(i, e, t) {
  if (typeof i == "number" && typeof e == "number" && typeof t == "number")
    return cm("#" + fa(i) + fa(e) + fa(t));
  if (typeof i == "object" && e === void 0 && t === void 0)
    return cm("#" + fa(i.red) + fa(i.green) + fa(i.blue));
  throw new Mr(6);
}
function Dd(i, e, t, n) {
  if (typeof i == "string" && typeof e == "number") {
    var r = Va(i);
    return "rgba(" + r.red + "," + r.green + "," + r.blue + "," + e + ")";
  } else {
    if (typeof i == "number" && typeof e == "number" && typeof t == "number" && typeof n == "number")
      return n >= 1 ? um(i, e, t) : "rgba(" + i + "," + e + "," + t + "," + n + ")";
    if (typeof i == "object" && e === void 0 && t === void 0 && n === void 0)
      return i.alpha >= 1 ? um(i.red, i.green, i.blue) : "rgba(" + i.red + "," + i.green + "," + i.blue + "," + i.alpha + ")";
  }
  throw new Mr(7);
}
var jz = function(e) {
  return typeof e.red == "number" && typeof e.green == "number" && typeof e.blue == "number" && (typeof e.alpha != "number" || typeof e.alpha > "u");
}, Yz = function(e) {
  return typeof e.red == "number" && typeof e.green == "number" && typeof e.blue == "number" && typeof e.alpha == "number";
}, Kz = function(e) {
  return typeof e.hue == "number" && typeof e.saturation == "number" && typeof e.lightness == "number" && (typeof e.alpha != "number" || typeof e.alpha > "u");
}, Zz = function(e) {
  return typeof e.hue == "number" && typeof e.saturation == "number" && typeof e.lightness == "number" && typeof e.alpha == "number";
};
function Js(i) {
  if (typeof i != "object")
    throw new Mr(8);
  if (Yz(i))
    return Dd(i);
  if (jz(i))
    return um(i);
  if (Zz(i))
    return Xz(i);
  if (Kz(i))
    return qz(i);
  throw new Mr(8);
}
function TT(i, e, t) {
  return function() {
    var r = t.concat(Array.prototype.slice.call(arguments));
    return r.length >= e ? i.apply(this, r) : TT(i, e, r);
  };
}
function Ni(i) {
  return TT(i, i.length, []);
}
function Qz(i, e) {
  if (e === "transparent")
    return e;
  var t = Qs(e);
  return Js(xi({}, t, {
    hue: t.hue + parseFloat(i)
  }));
}
Ni(Qz);
function Ll(i, e, t) {
  return Math.max(i, Math.min(e, t));
}
function Jz(i, e) {
  if (e === "transparent")
    return e;
  var t = Qs(e);
  return Js(xi({}, t, {
    lightness: Ll(0, 1, t.lightness - parseFloat(i))
  }));
}
Ni(Jz);
function e4(i, e) {
  if (e === "transparent")
    return e;
  var t = Qs(e);
  return Js(xi({}, t, {
    saturation: Ll(0, 1, t.saturation - parseFloat(i))
  }));
}
Ni(e4);
function t4(i, e) {
  if (e === "transparent")
    return e;
  var t = Qs(e);
  return Js(xi({}, t, {
    lightness: Ll(0, 1, t.lightness + parseFloat(i))
  }));
}
Ni(t4);
function n4(i, e, t) {
  if (e === "transparent")
    return t;
  if (t === "transparent")
    return e;
  if (i === 0)
    return t;
  var n = Va(e), r = xi({}, n, {
    alpha: typeof n.alpha == "number" ? n.alpha : 1
  }), s = Va(t), a = xi({}, s, {
    alpha: typeof s.alpha == "number" ? s.alpha : 1
  }), o = r.alpha - a.alpha, l = parseFloat(i) * 2 - 1, c = l * o === -1 ? l : l + o, u = 1 + l * o, h = (c / u + 1) / 2, d = 1 - h, f = {
    red: Math.floor(r.red * h + a.red * d),
    green: Math.floor(r.green * h + a.green * d),
    blue: Math.floor(r.blue * h + a.blue * d),
    alpha: r.alpha * parseFloat(i) + a.alpha * (1 - parseFloat(i))
  };
  return Dd(f);
}
var i4 = Ni(n4), MT = i4;
function r4(i, e) {
  if (e === "transparent")
    return e;
  var t = Va(e), n = typeof t.alpha == "number" ? t.alpha : 1, r = xi({}, t, {
    alpha: Ll(0, 1, (n * 100 + parseFloat(i) * 100) / 100)
  });
  return Dd(r);
}
var s4 = Ni(r4), a4 = s4;
function o4(i, e) {
  if (e === "transparent")
    return e;
  var t = Qs(e);
  return Js(xi({}, t, {
    saturation: Ll(0, 1, t.saturation + parseFloat(i))
  }));
}
Ni(o4);
function l4(i, e) {
  return e === "transparent" ? e : Js(xi({}, Qs(e), {
    hue: parseFloat(i)
  }));
}
Ni(l4);
function c4(i, e) {
  return e === "transparent" ? e : Js(xi({}, Qs(e), {
    lightness: parseFloat(i)
  }));
}
Ni(c4);
function u4(i, e) {
  return e === "transparent" ? e : Js(xi({}, Qs(e), {
    saturation: parseFloat(i)
  }));
}
Ni(u4);
function h4(i, e) {
  return e === "transparent" ? e : MT(parseFloat(i), "rgb(0, 0, 0)", e);
}
Ni(h4);
function d4(i, e) {
  return e === "transparent" ? e : MT(parseFloat(i), "rgb(255, 255, 255)", e);
}
Ni(d4);
function f4(i, e) {
  if (e === "transparent")
    return e;
  var t = Va(e), n = typeof t.alpha == "number" ? t.alpha : 1, r = xi({}, t, {
    alpha: Ll(0, 1, +(n * 100 - parseFloat(i) * 100).toFixed(2) / 100)
  });
  return Dd(r);
}
Ni(f4);
var Aa = Object.freeze({
  Linear: Object.freeze({
    None: function(i) {
      return i;
    },
    In: function(i) {
      return i;
    },
    Out: function(i) {
      return i;
    },
    InOut: function(i) {
      return i;
    }
  }),
  Quadratic: Object.freeze({
    In: function(i) {
      return i * i;
    },
    Out: function(i) {
      return i * (2 - i);
    },
    InOut: function(i) {
      return (i *= 2) < 1 ? 0.5 * i * i : -0.5 * (--i * (i - 2) - 1);
    }
  }),
  Cubic: Object.freeze({
    In: function(i) {
      return i * i * i;
    },
    Out: function(i) {
      return --i * i * i + 1;
    },
    InOut: function(i) {
      return (i *= 2) < 1 ? 0.5 * i * i * i : 0.5 * ((i -= 2) * i * i + 2);
    }
  }),
  Quartic: Object.freeze({
    In: function(i) {
      return i * i * i * i;
    },
    Out: function(i) {
      return 1 - --i * i * i * i;
    },
    InOut: function(i) {
      return (i *= 2) < 1 ? 0.5 * i * i * i * i : -0.5 * ((i -= 2) * i * i * i - 2);
    }
  }),
  Quintic: Object.freeze({
    In: function(i) {
      return i * i * i * i * i;
    },
    Out: function(i) {
      return --i * i * i * i * i + 1;
    },
    InOut: function(i) {
      return (i *= 2) < 1 ? 0.5 * i * i * i * i * i : 0.5 * ((i -= 2) * i * i * i * i + 2);
    }
  }),
  Sinusoidal: Object.freeze({
    In: function(i) {
      return 1 - Math.sin((1 - i) * Math.PI / 2);
    },
    Out: function(i) {
      return Math.sin(i * Math.PI / 2);
    },
    InOut: function(i) {
      return 0.5 * (1 - Math.sin(Math.PI * (0.5 - i)));
    }
  }),
  Exponential: Object.freeze({
    In: function(i) {
      return i === 0 ? 0 : Math.pow(1024, i - 1);
    },
    Out: function(i) {
      return i === 1 ? 1 : 1 - Math.pow(2, -10 * i);
    },
    InOut: function(i) {
      return i === 0 ? 0 : i === 1 ? 1 : (i *= 2) < 1 ? 0.5 * Math.pow(1024, i - 1) : 0.5 * (-Math.pow(2, -10 * (i - 1)) + 2);
    }
  }),
  Circular: Object.freeze({
    In: function(i) {
      return 1 - Math.sqrt(1 - i * i);
    },
    Out: function(i) {
      return Math.sqrt(1 - --i * i);
    },
    InOut: function(i) {
      return (i *= 2) < 1 ? -0.5 * (Math.sqrt(1 - i * i) - 1) : 0.5 * (Math.sqrt(1 - (i -= 2) * i) + 1);
    }
  }),
  Elastic: Object.freeze({
    In: function(i) {
      return i === 0 ? 0 : i === 1 ? 1 : -Math.pow(2, 10 * (i - 1)) * Math.sin((i - 1.1) * 5 * Math.PI);
    },
    Out: function(i) {
      return i === 0 ? 0 : i === 1 ? 1 : Math.pow(2, -10 * i) * Math.sin((i - 0.1) * 5 * Math.PI) + 1;
    },
    InOut: function(i) {
      return i === 0 ? 0 : i === 1 ? 1 : (i *= 2, i < 1 ? -0.5 * Math.pow(2, 10 * (i - 1)) * Math.sin((i - 1.1) * 5 * Math.PI) : 0.5 * Math.pow(2, -10 * (i - 1)) * Math.sin((i - 1.1) * 5 * Math.PI) + 1);
    }
  }),
  Back: Object.freeze({
    In: function(i) {
      var e = 1.70158;
      return i === 1 ? 1 : i * i * ((e + 1) * i - e);
    },
    Out: function(i) {
      var e = 1.70158;
      return i === 0 ? 0 : --i * i * ((e + 1) * i + e) + 1;
    },
    InOut: function(i) {
      var e = 2.5949095;
      return (i *= 2) < 1 ? 0.5 * (i * i * ((e + 1) * i - e)) : 0.5 * ((i -= 2) * i * ((e + 1) * i + e) + 2);
    }
  }),
  Bounce: Object.freeze({
    In: function(i) {
      return 1 - Aa.Bounce.Out(1 - i);
    },
    Out: function(i) {
      return i < 1 / 2.75 ? 7.5625 * i * i : i < 2 / 2.75 ? 7.5625 * (i -= 1.5 / 2.75) * i + 0.75 : i < 2.5 / 2.75 ? 7.5625 * (i -= 2.25 / 2.75) * i + 0.9375 : 7.5625 * (i -= 2.625 / 2.75) * i + 0.984375;
    },
    InOut: function(i) {
      return i < 0.5 ? Aa.Bounce.In(i * 2) * 0.5 : Aa.Bounce.Out(i * 2 - 1) * 0.5 + 0.5;
    }
  }),
  generatePow: function(i) {
    return i === void 0 && (i = 4), i = i < Number.EPSILON ? Number.EPSILON : i, i = i > 1e4 ? 1e4 : i, {
      In: function(e) {
        return Math.pow(e, i);
      },
      Out: function(e) {
        return 1 - Math.pow(1 - e, i);
      },
      InOut: function(e) {
        return e < 0.5 ? Math.pow(e * 2, i) / 2 : (1 - Math.pow(2 - e * 2, i)) / 2 + 0.5;
      }
    };
  }
}), dc = function() {
  return performance.now();
}, ET = (
  /** @class */
  function() {
    function i() {
      for (var e = [], t = 0; t < arguments.length; t++)
        e[t] = arguments[t];
      this._tweens = {}, this._tweensAddedDuringUpdate = {}, this.add.apply(this, e);
    }
    return i.prototype.getAll = function() {
      var e = this;
      return Object.keys(this._tweens).map(function(t) {
        return e._tweens[t];
      });
    }, i.prototype.removeAll = function() {
      this._tweens = {};
    }, i.prototype.add = function() {
      for (var e, t = [], n = 0; n < arguments.length; n++)
        t[n] = arguments[n];
      for (var r = 0, s = t; r < s.length; r++) {
        var a = s[r];
        (e = a._group) === null || e === void 0 || e.remove(a), a._group = this, this._tweens[a.getId()] = a, this._tweensAddedDuringUpdate[a.getId()] = a;
      }
    }, i.prototype.remove = function() {
      for (var e = [], t = 0; t < arguments.length; t++)
        e[t] = arguments[t];
      for (var n = 0, r = e; n < r.length; n++) {
        var s = r[n];
        s._group = void 0, delete this._tweens[s.getId()], delete this._tweensAddedDuringUpdate[s.getId()];
      }
    }, i.prototype.allStopped = function() {
      return this.getAll().every(function(e) {
        return !e.isPlaying();
      });
    }, i.prototype.update = function(e, t) {
      e === void 0 && (e = dc()), t === void 0 && (t = !0);
      var n = Object.keys(this._tweens);
      if (n.length !== 0)
        for (; n.length > 0; ) {
          this._tweensAddedDuringUpdate = {};
          for (var r = 0; r < n.length; r++) {
            var s = this._tweens[n[r]], a = !t;
            s && s.update(e, a) === !1 && !t && this.remove(s);
          }
          n = Object.keys(this._tweensAddedDuringUpdate);
        }
    }, i;
  }()
), Ao = {
  Linear: function(i, e) {
    var t = i.length - 1, n = t * e, r = Math.floor(n), s = Ao.Utils.Linear;
    return e < 0 ? s(i[0], i[1], n) : e > 1 ? s(i[t], i[t - 1], t - n) : s(i[r], i[r + 1 > t ? t : r + 1], n - r);
  },
  Bezier: function(i, e) {
    for (var t = 0, n = i.length - 1, r = Math.pow, s = Ao.Utils.Bernstein, a = 0; a <= n; a++)
      t += r(1 - e, n - a) * r(e, a) * i[a] * s(n, a);
    return t;
  },
  CatmullRom: function(i, e) {
    var t = i.length - 1, n = t * e, r = Math.floor(n), s = Ao.Utils.CatmullRom;
    return i[0] === i[t] ? (e < 0 && (r = Math.floor(n = t * (1 + e))), s(i[(r - 1 + t) % t], i[r], i[(r + 1) % t], i[(r + 2) % t], n - r)) : e < 0 ? i[0] - (s(i[0], i[0], i[1], i[1], -n) - i[0]) : e > 1 ? i[t] - (s(i[t], i[t], i[t - 1], i[t - 1], n - t) - i[t]) : s(i[r ? r - 1 : 0], i[r], i[t < r + 1 ? t : r + 1], i[t < r + 2 ? t : r + 2], n - r);
  },
  Utils: {
    Linear: function(i, e, t) {
      return (e - i) * t + i;
    },
    Bernstein: function(i, e) {
      var t = Ao.Utils.Factorial;
      return t(i) / t(e) / t(i - e);
    },
    Factorial: /* @__PURE__ */ function() {
      var i = [1];
      return function(e) {
        var t = 1;
        if (i[e])
          return i[e];
        for (var n = e; n > 1; n--)
          t *= n;
        return i[e] = t, t;
      };
    }(),
    CatmullRom: function(i, e, t, n, r) {
      var s = (t - i) * 0.5, a = (n - e) * 0.5, o = r * r, l = r * o;
      return (2 * e - 2 * t + s + a) * l + (-3 * e + 3 * t - 2 * s - a) * o + s * r + e;
    }
  }
}, p4 = (
  /** @class */
  function() {
    function i() {
    }
    return i.nextId = function() {
      return i._nextId++;
    }, i._nextId = 0, i;
  }()
), hm = new ET(), Nv = (
  /** @class */
  function() {
    function i(e, t) {
      this._isPaused = !1, this._pauseStart = 0, this._valuesStart = {}, this._valuesEnd = {}, this._valuesStartRepeat = {}, this._duration = 1e3, this._isDynamic = !1, this._initialRepeat = 0, this._repeat = 0, this._yoyo = !1, this._isPlaying = !1, this._reversed = !1, this._delayTime = 0, this._startTime = 0, this._easingFunction = Aa.Linear.None, this._interpolationFunction = Ao.Linear, this._chainedTweens = [], this._onStartCallbackFired = !1, this._onEveryStartCallbackFired = !1, this._id = p4.nextId(), this._isChainStopped = !1, this._propertiesAreSetUp = !1, this._goToEnd = !1, this._object = e, typeof t == "object" ? (this._group = t, t.add(this)) : t === !0 && (this._group = hm, hm.add(this));
    }
    return i.prototype.getId = function() {
      return this._id;
    }, i.prototype.isPlaying = function() {
      return this._isPlaying;
    }, i.prototype.isPaused = function() {
      return this._isPaused;
    }, i.prototype.getDuration = function() {
      return this._duration;
    }, i.prototype.to = function(e, t) {
      if (t === void 0 && (t = 1e3), this._isPlaying)
        throw new Error("Can not call Tween.to() while Tween is already started or paused. Stop the Tween first.");
      return this._valuesEnd = e, this._propertiesAreSetUp = !1, this._duration = t < 0 ? 0 : t, this;
    }, i.prototype.duration = function(e) {
      return e === void 0 && (e = 1e3), this._duration = e < 0 ? 0 : e, this;
    }, i.prototype.dynamic = function(e) {
      return e === void 0 && (e = !1), this._isDynamic = e, this;
    }, i.prototype.start = function(e, t) {
      if (e === void 0 && (e = dc()), t === void 0 && (t = !1), this._isPlaying)
        return this;
      if (this._repeat = this._initialRepeat, this._reversed) {
        this._reversed = !1;
        for (var n in this._valuesStartRepeat)
          this._swapEndStartRepeatValues(n), this._valuesStart[n] = this._valuesStartRepeat[n];
      }
      if (this._isPlaying = !0, this._isPaused = !1, this._onStartCallbackFired = !1, this._onEveryStartCallbackFired = !1, this._isChainStopped = !1, this._startTime = e, this._startTime += this._delayTime, !this._propertiesAreSetUp || t) {
        if (this._propertiesAreSetUp = !0, !this._isDynamic) {
          var r = {};
          for (var s in this._valuesEnd)
            r[s] = this._valuesEnd[s];
          this._valuesEnd = r;
        }
        this._setupProperties(this._object, this._valuesStart, this._valuesEnd, this._valuesStartRepeat, t);
      }
      return this;
    }, i.prototype.startFromCurrentValues = function(e) {
      return this.start(e, !0);
    }, i.prototype._setupProperties = function(e, t, n, r, s) {
      for (var a in n) {
        var o = e[a], l = Array.isArray(o), c = l ? "array" : typeof o, u = !l && Array.isArray(n[a]);
        if (!(c === "undefined" || c === "function")) {
          if (u) {
            var h = n[a];
            if (h.length === 0)
              continue;
            for (var d = [o], f = 0, p = h.length; f < p; f += 1) {
              var _ = this._handleRelativeValue(o, h[f]);
              if (isNaN(_)) {
                u = !1, console.warn("Found invalid interpolation list. Skipping.");
                break;
              }
              d.push(_);
            }
            u && (n[a] = d);
          }
          if ((c === "object" || l) && o && !u) {
            t[a] = l ? [] : {};
            var g = o;
            for (var m in g)
              t[a][m] = g[m];
            r[a] = l ? [] : {};
            var h = n[a];
            if (!this._isDynamic) {
              var x = {};
              for (var m in h)
                x[m] = h[m];
              n[a] = h = x;
            }
            this._setupProperties(g, t[a], h, r[a], s);
          } else
            (typeof t[a] > "u" || s) && (t[a] = o), l || (t[a] *= 1), u ? r[a] = n[a].slice().reverse() : r[a] = t[a] || 0;
        }
      }
    }, i.prototype.stop = function() {
      return this._isChainStopped || (this._isChainStopped = !0, this.stopChainedTweens()), this._isPlaying ? (this._isPlaying = !1, this._isPaused = !1, this._onStopCallback && this._onStopCallback(this._object), this) : this;
    }, i.prototype.end = function() {
      return this._goToEnd = !0, this.update(this._startTime + this._duration), this;
    }, i.prototype.pause = function(e) {
      return e === void 0 && (e = dc()), this._isPaused || !this._isPlaying ? this : (this._isPaused = !0, this._pauseStart = e, this);
    }, i.prototype.resume = function(e) {
      return e === void 0 && (e = dc()), !this._isPaused || !this._isPlaying ? this : (this._isPaused = !1, this._startTime += e - this._pauseStart, this._pauseStart = 0, this);
    }, i.prototype.stopChainedTweens = function() {
      for (var e = 0, t = this._chainedTweens.length; e < t; e++)
        this._chainedTweens[e].stop();
      return this;
    }, i.prototype.group = function(e) {
      return e ? (e.add(this), this) : (console.warn("tween.group() without args has been removed, use group.add(tween) instead."), this);
    }, i.prototype.remove = function() {
      var e;
      return (e = this._group) === null || e === void 0 || e.remove(this), this;
    }, i.prototype.delay = function(e) {
      return e === void 0 && (e = 0), this._delayTime = e, this;
    }, i.prototype.repeat = function(e) {
      return e === void 0 && (e = 0), this._initialRepeat = e, this._repeat = e, this;
    }, i.prototype.repeatDelay = function(e) {
      return this._repeatDelayTime = e, this;
    }, i.prototype.yoyo = function(e) {
      return e === void 0 && (e = !1), this._yoyo = e, this;
    }, i.prototype.easing = function(e) {
      return e === void 0 && (e = Aa.Linear.None), this._easingFunction = e, this;
    }, i.prototype.interpolation = function(e) {
      return e === void 0 && (e = Ao.Linear), this._interpolationFunction = e, this;
    }, i.prototype.chain = function() {
      for (var e = [], t = 0; t < arguments.length; t++)
        e[t] = arguments[t];
      return this._chainedTweens = e, this;
    }, i.prototype.onStart = function(e) {
      return this._onStartCallback = e, this;
    }, i.prototype.onEveryStart = function(e) {
      return this._onEveryStartCallback = e, this;
    }, i.prototype.onUpdate = function(e) {
      return this._onUpdateCallback = e, this;
    }, i.prototype.onRepeat = function(e) {
      return this._onRepeatCallback = e, this;
    }, i.prototype.onComplete = function(e) {
      return this._onCompleteCallback = e, this;
    }, i.prototype.onStop = function(e) {
      return this._onStopCallback = e, this;
    }, i.prototype.update = function(e, t) {
      var n = this, r;
      if (e === void 0 && (e = dc()), t === void 0 && (t = i.autoStartOnUpdate), this._isPaused)
        return !0;
      var s;
      if (!this._goToEnd && !this._isPlaying)
        if (t)
          this.start(e, !0);
        else
          return !1;
      if (this._goToEnd = !1, e < this._startTime)
        return !0;
      this._onStartCallbackFired === !1 && (this._onStartCallback && this._onStartCallback(this._object), this._onStartCallbackFired = !0), this._onEveryStartCallbackFired === !1 && (this._onEveryStartCallback && this._onEveryStartCallback(this._object), this._onEveryStartCallbackFired = !0);
      var a = e - this._startTime, o = this._duration + ((r = this._repeatDelayTime) !== null && r !== void 0 ? r : this._delayTime), l = this._duration + this._repeat * o, c = function() {
        if (n._duration === 0 || a > l)
          return 1;
        var _ = Math.trunc(a / o), g = a - _ * o, m = Math.min(g / n._duration, 1);
        return m === 0 && a === n._duration ? 1 : m;
      }, u = c(), h = this._easingFunction(u);
      if (this._updateProperties(this._object, this._valuesStart, this._valuesEnd, h), this._onUpdateCallback && this._onUpdateCallback(this._object, u), this._duration === 0 || a >= this._duration)
        if (this._repeat > 0) {
          var d = Math.min(Math.trunc((a - this._duration) / o) + 1, this._repeat);
          isFinite(this._repeat) && (this._repeat -= d);
          for (s in this._valuesStartRepeat)
            !this._yoyo && typeof this._valuesEnd[s] == "string" && (this._valuesStartRepeat[s] = // eslint-disable-next-line
            // @ts-ignore FIXME?
            this._valuesStartRepeat[s] + parseFloat(this._valuesEnd[s])), this._yoyo && this._swapEndStartRepeatValues(s), this._valuesStart[s] = this._valuesStartRepeat[s];
          return this._yoyo && (this._reversed = !this._reversed), this._startTime += o * d, this._onRepeatCallback && this._onRepeatCallback(this._object), this._onEveryStartCallbackFired = !1, !0;
        } else {
          this._onCompleteCallback && this._onCompleteCallback(this._object);
          for (var f = 0, p = this._chainedTweens.length; f < p; f++)
            this._chainedTweens[f].start(this._startTime + this._duration, !1);
          return this._isPlaying = !1, !1;
        }
      return !0;
    }, i.prototype._updateProperties = function(e, t, n, r) {
      for (var s in n)
        if (t[s] !== void 0) {
          var a = t[s] || 0, o = n[s], l = Array.isArray(e[s]), c = Array.isArray(o), u = !l && c;
          u ? e[s] = this._interpolationFunction(o, r) : typeof o == "object" && o ? this._updateProperties(e[s], a, o, r) : (o = this._handleRelativeValue(a, o), typeof o == "number" && (e[s] = a + (o - a) * r));
        }
    }, i.prototype._handleRelativeValue = function(e, t) {
      return typeof t != "string" ? t : t.charAt(0) === "+" || t.charAt(0) === "-" ? e + parseFloat(t) : parseFloat(t);
    }, i.prototype._swapEndStartRepeatValues = function(e) {
      var t = this._valuesStartRepeat[e], n = this._valuesEnd[e];
      typeof n == "string" ? this._valuesStartRepeat[e] = this._valuesStartRepeat[e] + parseFloat(n) : this._valuesStartRepeat[e] = this._valuesEnd[e], this._valuesEnd[e] = t;
    }, i.autoStartOnUpdate = !1, i;
  }()
), Lr = hm;
Lr.getAll.bind(Lr);
Lr.removeAll.bind(Lr);
Lr.add.bind(Lr);
Lr.remove.bind(Lr);
Lr.update.bind(Lr);
var dm = "http://www.w3.org/1999/xhtml";
const Pv = {
  svg: "http://www.w3.org/2000/svg",
  xhtml: dm,
  xlink: "http://www.w3.org/1999/xlink",
  xml: "http://www.w3.org/XML/1998/namespace",
  xmlns: "http://www.w3.org/2000/xmlns/"
};
function wT(i) {
  var e = i += "", t = e.indexOf(":");
  return t >= 0 && (e = i.slice(0, t)) !== "xmlns" && (i = i.slice(t + 1)), Pv.hasOwnProperty(e) ? { space: Pv[e], local: i } : i;
}
function m4(i) {
  return function() {
    var e = this.ownerDocument, t = this.namespaceURI;
    return t === dm && e.documentElement.namespaceURI === dm ? e.createElement(i) : e.createElementNS(t, i);
  };
}
function g4(i) {
  return function() {
    return this.ownerDocument.createElementNS(i.space, i.local);
  };
}
function AT(i) {
  var e = wT(i);
  return (e.local ? g4 : m4)(e);
}
function _4() {
}
function RT(i) {
  return i == null ? _4 : function() {
    return this.querySelector(i);
  };
}
function x4(i) {
  typeof i != "function" && (i = RT(i));
  for (var e = this._groups, t = e.length, n = new Array(t), r = 0; r < t; ++r)
    for (var s = e[r], a = s.length, o = n[r] = new Array(a), l, c, u = 0; u < a; ++u)
      (l = s[u]) && (c = i.call(l, l.__data__, u, s)) && ("__data__" in l && (c.__data__ = l.__data__), o[u] = c);
  return new Hi(n, this._parents);
}
function v4(i) {
  return i == null ? [] : Array.isArray(i) ? i : Array.from(i);
}
function y4() {
  return [];
}
function b4(i) {
  return i == null ? y4 : function() {
    return this.querySelectorAll(i);
  };
}
function S4(i) {
  return function() {
    return v4(i.apply(this, arguments));
  };
}
function T4(i) {
  typeof i == "function" ? i = S4(i) : i = b4(i);
  for (var e = this._groups, t = e.length, n = [], r = [], s = 0; s < t; ++s)
    for (var a = e[s], o = a.length, l, c = 0; c < o; ++c)
      (l = a[c]) && (n.push(i.call(l, l.__data__, c, a)), r.push(l));
  return new Hi(n, r);
}
function M4(i) {
  return function() {
    return this.matches(i);
  };
}
function CT(i) {
  return function(e) {
    return e.matches(i);
  };
}
var E4 = Array.prototype.find;
function w4(i) {
  return function() {
    return E4.call(this.children, i);
  };
}
function A4() {
  return this.firstElementChild;
}
function R4(i) {
  return this.select(i == null ? A4 : w4(typeof i == "function" ? i : CT(i)));
}
var C4 = Array.prototype.filter;
function N4() {
  return Array.from(this.children);
}
function P4(i) {
  return function() {
    return C4.call(this.children, i);
  };
}
function D4(i) {
  return this.selectAll(i == null ? N4 : P4(typeof i == "function" ? i : CT(i)));
}
function L4(i) {
  typeof i != "function" && (i = M4(i));
  for (var e = this._groups, t = e.length, n = new Array(t), r = 0; r < t; ++r)
    for (var s = e[r], a = s.length, o = n[r] = [], l, c = 0; c < a; ++c)
      (l = s[c]) && i.call(l, l.__data__, c, s) && o.push(l);
  return new Hi(n, this._parents);
}
function NT(i) {
  return new Array(i.length);
}
function F4() {
  return new Hi(this._enter || this._groups.map(NT), this._parents);
}
function Jh(i, e) {
  this.ownerDocument = i.ownerDocument, this.namespaceURI = i.namespaceURI, this._next = null, this._parent = i, this.__data__ = e;
}
Jh.prototype = {
  constructor: Jh,
  appendChild: function(i) {
    return this._parent.insertBefore(i, this._next);
  },
  insertBefore: function(i, e) {
    return this._parent.insertBefore(i, e);
  },
  querySelector: function(i) {
    return this._parent.querySelector(i);
  },
  querySelectorAll: function(i) {
    return this._parent.querySelectorAll(i);
  }
};
function I4(i) {
  return function() {
    return i;
  };
}
function U4(i, e, t, n, r, s) {
  for (var a = 0, o, l = e.length, c = s.length; a < c; ++a)
    (o = e[a]) ? (o.__data__ = s[a], n[a] = o) : t[a] = new Jh(i, s[a]);
  for (; a < l; ++a)
    (o = e[a]) && (r[a] = o);
}
function B4(i, e, t, n, r, s, a) {
  var o, l, c = /* @__PURE__ */ new Map(), u = e.length, h = s.length, d = new Array(u), f;
  for (o = 0; o < u; ++o)
    (l = e[o]) && (d[o] = f = a.call(l, l.__data__, o, e) + "", c.has(f) ? r[o] = l : c.set(f, l));
  for (o = 0; o < h; ++o)
    f = a.call(i, s[o], o, s) + "", (l = c.get(f)) ? (n[o] = l, l.__data__ = s[o], c.delete(f)) : t[o] = new Jh(i, s[o]);
  for (o = 0; o < u; ++o)
    (l = e[o]) && c.get(d[o]) === l && (r[o] = l);
}
function O4(i) {
  return i.__data__;
}
function k4(i, e) {
  if (!arguments.length)
    return Array.from(this, O4);
  var t = e ? B4 : U4, n = this._parents, r = this._groups;
  typeof i != "function" && (i = I4(i));
  for (var s = r.length, a = new Array(s), o = new Array(s), l = new Array(s), c = 0; c < s; ++c) {
    var u = n[c], h = r[c], d = h.length, f = G4(i.call(u, u && u.__data__, c, n)), p = f.length, _ = o[c] = new Array(p), g = a[c] = new Array(p), m = l[c] = new Array(d);
    t(u, h, _, g, m, f, e);
    for (var x = 0, y = 0, b, T; x < p; ++x)
      if (b = _[x]) {
        for (x >= y && (y = x + 1); !(T = g[y]) && ++y < p; )
          ;
        b._next = T || null;
      }
  }
  return a = new Hi(a, n), a._enter = o, a._exit = l, a;
}
function G4(i) {
  return typeof i == "object" && "length" in i ? i : Array.from(i);
}
function V4() {
  return new Hi(this._exit || this._groups.map(NT), this._parents);
}
function z4(i, e, t) {
  var n = this.enter(), r = this, s = this.exit();
  return typeof i == "function" ? (n = i(n), n && (n = n.selection())) : n = n.append(i + ""), e != null && (r = e(r), r && (r = r.selection())), t == null ? s.remove() : t(s), n && r ? n.merge(r).order() : r;
}
function H4(i) {
  for (var e = i.selection ? i.selection() : i, t = this._groups, n = e._groups, r = t.length, s = n.length, a = Math.min(r, s), o = new Array(r), l = 0; l < a; ++l)
    for (var c = t[l], u = n[l], h = c.length, d = o[l] = new Array(h), f, p = 0; p < h; ++p)
      (f = c[p] || u[p]) && (d[p] = f);
  for (; l < r; ++l)
    o[l] = t[l];
  return new Hi(o, this._parents);
}
function $4() {
  for (var i = this._groups, e = -1, t = i.length; ++e < t; )
    for (var n = i[e], r = n.length - 1, s = n[r], a; --r >= 0; )
      (a = n[r]) && (s && a.compareDocumentPosition(s) ^ 4 && s.parentNode.insertBefore(a, s), s = a);
  return this;
}
function W4(i) {
  i || (i = q4);
  function e(h, d) {
    return h && d ? i(h.__data__, d.__data__) : !h - !d;
  }
  for (var t = this._groups, n = t.length, r = new Array(n), s = 0; s < n; ++s) {
    for (var a = t[s], o = a.length, l = r[s] = new Array(o), c, u = 0; u < o; ++u)
      (c = a[u]) && (l[u] = c);
    l.sort(e);
  }
  return new Hi(r, this._parents).order();
}
function q4(i, e) {
  return i < e ? -1 : i > e ? 1 : i >= e ? 0 : NaN;
}
function X4() {
  var i = arguments[0];
  return arguments[0] = this, i.apply(null, arguments), this;
}
function j4() {
  return Array.from(this);
}
function Y4() {
  for (var i = this._groups, e = 0, t = i.length; e < t; ++e)
    for (var n = i[e], r = 0, s = n.length; r < s; ++r) {
      var a = n[r];
      if (a)
        return a;
    }
  return null;
}
function K4() {
  let i = 0;
  for (const e of this)
    ++i;
  return i;
}
function Z4() {
  return !this.node();
}
function Q4(i) {
  for (var e = this._groups, t = 0, n = e.length; t < n; ++t)
    for (var r = e[t], s = 0, a = r.length, o; s < a; ++s)
      (o = r[s]) && i.call(o, o.__data__, s, r);
  return this;
}
function J4(i) {
  return function() {
    this.removeAttribute(i);
  };
}
function e5(i) {
  return function() {
    this.removeAttributeNS(i.space, i.local);
  };
}
function t5(i, e) {
  return function() {
    this.setAttribute(i, e);
  };
}
function n5(i, e) {
  return function() {
    this.setAttributeNS(i.space, i.local, e);
  };
}
function i5(i, e) {
  return function() {
    var t = e.apply(this, arguments);
    t == null ? this.removeAttribute(i) : this.setAttribute(i, t);
  };
}
function r5(i, e) {
  return function() {
    var t = e.apply(this, arguments);
    t == null ? this.removeAttributeNS(i.space, i.local) : this.setAttributeNS(i.space, i.local, t);
  };
}
function s5(i, e) {
  var t = wT(i);
  if (arguments.length < 2) {
    var n = this.node();
    return t.local ? n.getAttributeNS(t.space, t.local) : n.getAttribute(t);
  }
  return this.each((e == null ? t.local ? e5 : J4 : typeof e == "function" ? t.local ? r5 : i5 : t.local ? n5 : t5)(t, e));
}
function PT(i) {
  return i.ownerDocument && i.ownerDocument.defaultView || i.document && i || i.defaultView;
}
function a5(i) {
  return function() {
    this.style.removeProperty(i);
  };
}
function o5(i, e, t) {
  return function() {
    this.style.setProperty(i, e, t);
  };
}
function l5(i, e, t) {
  return function() {
    var n = e.apply(this, arguments);
    n == null ? this.style.removeProperty(i) : this.style.setProperty(i, n, t);
  };
}
function c5(i, e, t) {
  return arguments.length > 1 ? this.each((e == null ? a5 : typeof e == "function" ? l5 : o5)(i, e, t ?? "")) : u5(this.node(), i);
}
function u5(i, e) {
  return i.style.getPropertyValue(e) || PT(i).getComputedStyle(i, null).getPropertyValue(e);
}
function h5(i) {
  return function() {
    delete this[i];
  };
}
function d5(i, e) {
  return function() {
    this[i] = e;
  };
}
function f5(i, e) {
  return function() {
    var t = e.apply(this, arguments);
    t == null ? delete this[i] : this[i] = t;
  };
}
function p5(i, e) {
  return arguments.length > 1 ? this.each((e == null ? h5 : typeof e == "function" ? f5 : d5)(i, e)) : this.node()[i];
}
function DT(i) {
  return i.trim().split(/^|\s+/);
}
function jg(i) {
  return i.classList || new LT(i);
}
function LT(i) {
  this._node = i, this._names = DT(i.getAttribute("class") || "");
}
LT.prototype = {
  add: function(i) {
    var e = this._names.indexOf(i);
    e < 0 && (this._names.push(i), this._node.setAttribute("class", this._names.join(" ")));
  },
  remove: function(i) {
    var e = this._names.indexOf(i);
    e >= 0 && (this._names.splice(e, 1), this._node.setAttribute("class", this._names.join(" ")));
  },
  contains: function(i) {
    return this._names.indexOf(i) >= 0;
  }
};
function FT(i, e) {
  for (var t = jg(i), n = -1, r = e.length; ++n < r; )
    t.add(e[n]);
}
function IT(i, e) {
  for (var t = jg(i), n = -1, r = e.length; ++n < r; )
    t.remove(e[n]);
}
function m5(i) {
  return function() {
    FT(this, i);
  };
}
function g5(i) {
  return function() {
    IT(this, i);
  };
}
function _5(i, e) {
  return function() {
    (e.apply(this, arguments) ? FT : IT)(this, i);
  };
}
function x5(i, e) {
  var t = DT(i + "");
  if (arguments.length < 2) {
    for (var n = jg(this.node()), r = -1, s = t.length; ++r < s; )
      if (!n.contains(t[r]))
        return !1;
    return !0;
  }
  return this.each((typeof e == "function" ? _5 : e ? m5 : g5)(t, e));
}
function v5() {
  this.textContent = "";
}
function y5(i) {
  return function() {
    this.textContent = i;
  };
}
function b5(i) {
  return function() {
    var e = i.apply(this, arguments);
    this.textContent = e ?? "";
  };
}
function S5(i) {
  return arguments.length ? this.each(i == null ? v5 : (typeof i == "function" ? b5 : y5)(i)) : this.node().textContent;
}
function T5() {
  this.innerHTML = "";
}
function M5(i) {
  return function() {
    this.innerHTML = i;
  };
}
function E5(i) {
  return function() {
    var e = i.apply(this, arguments);
    this.innerHTML = e ?? "";
  };
}
function w5(i) {
  return arguments.length ? this.each(i == null ? T5 : (typeof i == "function" ? E5 : M5)(i)) : this.node().innerHTML;
}
function A5() {
  this.nextSibling && this.parentNode.appendChild(this);
}
function R5() {
  return this.each(A5);
}
function C5() {
  this.previousSibling && this.parentNode.insertBefore(this, this.parentNode.firstChild);
}
function N5() {
  return this.each(C5);
}
function P5(i) {
  var e = typeof i == "function" ? i : AT(i);
  return this.select(function() {
    return this.appendChild(e.apply(this, arguments));
  });
}
function D5() {
  return null;
}
function L5(i, e) {
  var t = typeof i == "function" ? i : AT(i), n = e == null ? D5 : typeof e == "function" ? e : RT(e);
  return this.select(function() {
    return this.insertBefore(t.apply(this, arguments), n.apply(this, arguments) || null);
  });
}
function F5() {
  var i = this.parentNode;
  i && i.removeChild(this);
}
function I5() {
  return this.each(F5);
}
function U5() {
  var i = this.cloneNode(!1), e = this.parentNode;
  return e ? e.insertBefore(i, this.nextSibling) : i;
}
function B5() {
  var i = this.cloneNode(!0), e = this.parentNode;
  return e ? e.insertBefore(i, this.nextSibling) : i;
}
function O5(i) {
  return this.select(i ? B5 : U5);
}
function k5(i) {
  return arguments.length ? this.property("__data__", i) : this.node().__data__;
}
function G5(i) {
  return function(e) {
    i.call(this, e, this.__data__);
  };
}
function V5(i) {
  return i.trim().split(/^|\s+/).map(function(e) {
    var t = "", n = e.indexOf(".");
    return n >= 0 && (t = e.slice(n + 1), e = e.slice(0, n)), { type: e, name: t };
  });
}
function z5(i) {
  return function() {
    var e = this.__on;
    if (e) {
      for (var t = 0, n = -1, r = e.length, s; t < r; ++t)
        s = e[t], (!i.type || s.type === i.type) && s.name === i.name ? this.removeEventListener(s.type, s.listener, s.options) : e[++n] = s;
      ++n ? e.length = n : delete this.__on;
    }
  };
}
function H5(i, e, t) {
  return function() {
    var n = this.__on, r, s = G5(e);
    if (n) {
      for (var a = 0, o = n.length; a < o; ++a)
        if ((r = n[a]).type === i.type && r.name === i.name) {
          this.removeEventListener(r.type, r.listener, r.options), this.addEventListener(r.type, r.listener = s, r.options = t), r.value = e;
          return;
        }
    }
    this.addEventListener(i.type, s, t), r = { type: i.type, name: i.name, value: e, listener: s, options: t }, n ? n.push(r) : this.__on = [r];
  };
}
function $5(i, e, t) {
  var n = V5(i + ""), r, s = n.length, a;
  if (arguments.length < 2) {
    var o = this.node().__on;
    if (o) {
      for (var l = 0, c = o.length, u; l < c; ++l)
        for (r = 0, u = o[l]; r < s; ++r)
          if ((a = n[r]).type === u.type && a.name === u.name)
            return u.value;
    }
    return;
  }
  for (o = e ? H5 : z5, r = 0; r < s; ++r)
    this.each(o(n[r], e, t));
  return this;
}
function UT(i, e, t) {
  var n = PT(i), r = n.CustomEvent;
  typeof r == "function" ? r = new r(e, t) : (r = n.document.createEvent("Event"), t ? (r.initEvent(e, t.bubbles, t.cancelable), r.detail = t.detail) : r.initEvent(e, !1, !1)), i.dispatchEvent(r);
}
function W5(i, e) {
  return function() {
    return UT(this, i, e);
  };
}
function q5(i, e) {
  return function() {
    return UT(this, i, e.apply(this, arguments));
  };
}
function X5(i, e) {
  return this.each((typeof e == "function" ? q5 : W5)(i, e));
}
function* j5() {
  for (var i = this._groups, e = 0, t = i.length; e < t; ++e)
    for (var n = i[e], r = 0, s = n.length, a; r < s; ++r)
      (a = n[r]) && (yield a);
}
var Y5 = [null];
function Hi(i, e) {
  this._groups = i, this._parents = e;
}
function K5() {
  return this;
}
Hi.prototype = {
  constructor: Hi,
  select: x4,
  selectAll: T4,
  selectChild: R4,
  selectChildren: D4,
  filter: L4,
  data: k4,
  enter: F4,
  exit: V4,
  join: z4,
  merge: H4,
  selection: K5,
  order: $4,
  sort: W4,
  call: X4,
  nodes: j4,
  node: Y4,
  size: K4,
  empty: Z4,
  each: Q4,
  attr: s5,
  style: c5,
  property: p5,
  classed: x5,
  text: S5,
  html: w5,
  raise: R5,
  lower: N5,
  append: P5,
  insert: L5,
  remove: I5,
  clone: O5,
  datum: k5,
  on: $5,
  dispatch: X5,
  [Symbol.iterator]: j5
};
function Z5(i) {
  return typeof i == "string" ? new Hi([[document.querySelector(i)]], [document.documentElement]) : new Hi([[i]], Y5);
}
function Q5(i) {
  let e;
  for (; e = i.sourceEvent; )
    i = e;
  return i;
}
function J5(i, e) {
  if (i = Q5(i), e === void 0 && (e = i.currentTarget), e) {
    var t = e.ownerSVGElement || e;
    if (t.createSVGPoint) {
      var n = t.createSVGPoint();
      return n.x = i.clientX, n.y = i.clientY, n = n.matrixTransform(e.getScreenCTM().inverse()), [n.x, n.y];
    }
    if (e.getBoundingClientRect) {
      var r = e.getBoundingClientRect();
      return [i.clientX - r.left - e.clientLeft, i.clientY - r.top - e.clientTop];
    }
  }
  return [i.pageX, i.pageY];
}
var hu, rn, BT, OT, As, Dv, kT, GT, VT, Yg, fm, pm, ed = {}, td = [], eH = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i, Ld = Array.isArray;
function Er(i, e) {
  for (var t in e)
    i[t] = e[t];
  return i;
}
function Kg(i) {
  i && i.parentNode && i.parentNode.removeChild(i);
}
function tH(i, e, t) {
  var n, r, s, a = {};
  for (s in e)
    s == "key" ? n = e[s] : s == "ref" ? r = e[s] : a[s] = e[s];
  if (arguments.length > 2 && (a.children = arguments.length > 3 ? hu.call(arguments, 2) : t), typeof i == "function" && i.defaultProps != null)
    for (s in i.defaultProps)
      a[s] === void 0 && (a[s] = i.defaultProps[s]);
  return Ac(i, a, n, r, null);
}
function Ac(i, e, t, n, r) {
  var s = { type: i, props: e, key: t, ref: n, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: r ?? ++BT, __i: -1, __u: 0 };
  return r == null && rn.vnode != null && rn.vnode(s), s;
}
function Fd(i) {
  return i.children;
}
function Nh(i, e) {
  this.props = i, this.context = e;
}
function gl(i, e) {
  if (e == null)
    return i.__ ? gl(i.__, i.__i + 1) : null;
  for (var t; e < i.__k.length; e++)
    if ((t = i.__k[e]) != null && t.__e != null)
      return t.__e;
  return typeof i.type == "function" ? gl(i) : null;
}
function nH(i) {
  if (i.__P && i.__d) {
    var e = i.__v, t = e.__e, n = [], r = [], s = Er({}, e);
    s.__v = e.__v + 1, rn.vnode && rn.vnode(s), Zg(i.__P, s, e, i.__n, i.__P.namespaceURI, 32 & e.__u ? [t] : null, n, t ?? gl(e), !!(32 & e.__u), r), s.__v = e.__v, s.__.__k[s.__i] = s, WT(n, s, r), e.__e = e.__ = null, s.__e != t && zT(s);
  }
}
function zT(i) {
  if ((i = i.__) != null && i.__c != null)
    return i.__e = i.__c.base = null, i.__k.some(function(e) {
      if (e != null && e.__e != null)
        return i.__e = i.__c.base = e.__e;
    }), zT(i);
}
function Lv(i) {
  (!i.__d && (i.__d = !0) && As.push(i) && !nd.__r++ || Dv != rn.debounceRendering) && ((Dv = rn.debounceRendering) || kT)(nd);
}
function nd() {
  try {
    for (var i, e = 1; As.length; )
      As.length > e && As.sort(GT), i = As.shift(), e = As.length, nH(i);
  } finally {
    As.length = nd.__r = 0;
  }
}
function HT(i, e, t, n, r, s, a, o, l, c, u) {
  var h, d, f, p, _, g, m, x = n && n.__k || td, y = e.length;
  for (l = iH(t, e, x, l, y), h = 0; h < y; h++)
    (f = t.__k[h]) != null && (d = f.__i != -1 && x[f.__i] || ed, f.__i = h, g = Zg(i, f, d, r, s, a, o, l, c, u), p = f.__e, f.ref && d.ref != f.ref && (d.ref && Qg(d.ref, null, f), u.push(f.ref, f.__c || p, f)), _ == null && p != null && (_ = p), (m = !!(4 & f.__u)) || d.__k === f.__k ? l = $T(f, l, i, m) : typeof f.type == "function" && g !== void 0 ? l = g : p && (l = p.nextSibling), f.__u &= -7);
  return t.__e = _, l;
}
function iH(i, e, t, n, r) {
  var s, a, o, l, c, u = t.length, h = u, d = 0;
  for (i.__k = new Array(r), s = 0; s < r; s++)
    (a = e[s]) != null && typeof a != "boolean" && typeof a != "function" ? (typeof a == "string" || typeof a == "number" || typeof a == "bigint" || a.constructor == String ? a = i.__k[s] = Ac(null, a, null, null, null) : Ld(a) ? a = i.__k[s] = Ac(Fd, { children: a }, null, null, null) : a.constructor === void 0 && a.__b > 0 ? a = i.__k[s] = Ac(a.type, a.props, a.key, a.ref ? a.ref : null, a.__v) : i.__k[s] = a, l = s + d, a.__ = i, a.__b = i.__b + 1, o = null, (c = a.__i = rH(a, t, l, h)) != -1 && (h--, (o = t[c]) && (o.__u |= 2)), o == null || o.__v == null ? (c == -1 && (r > u ? d-- : r < u && d++), typeof a.type != "function" && (a.__u |= 4)) : c != l && (c == l - 1 ? d-- : c == l + 1 ? d++ : (c > l ? d-- : d++, a.__u |= 4))) : i.__k[s] = null;
  if (h)
    for (s = 0; s < u; s++)
      (o = t[s]) != null && !(2 & o.__u) && (o.__e == n && (n = gl(o)), XT(o, o));
  return n;
}
function $T(i, e, t, n) {
  var r, s;
  if (typeof i.type == "function") {
    for (r = i.__k, s = 0; r && s < r.length; s++)
      r[s] && (r[s].__ = i, e = $T(r[s], e, t, n));
    return e;
  }
  i.__e != e && (n && (e && i.type && !e.parentNode && (e = gl(i)), t.insertBefore(i.__e, e || null)), e = i.__e);
  do
    e = e && e.nextSibling;
  while (e != null && e.nodeType == 8);
  return e;
}
function rH(i, e, t, n) {
  var r, s, a, o = i.key, l = i.type, c = e[t], u = c != null && (2 & c.__u) == 0;
  if (c === null && o == null || u && o == c.key && l == c.type)
    return t;
  if (n > (u ? 1 : 0)) {
    for (r = t - 1, s = t + 1; r >= 0 || s < e.length; )
      if ((c = e[a = r >= 0 ? r-- : s++]) != null && !(2 & c.__u) && o == c.key && l == c.type)
        return a;
  }
  return -1;
}
function Fv(i, e, t) {
  e[0] == "-" ? i.setProperty(e, t ?? "") : i[e] = t == null ? "" : typeof t != "number" || eH.test(e) ? t : t + "px";
}
function vh(i, e, t, n, r) {
  var s, a;
  e:
    if (e == "style")
      if (typeof t == "string")
        i.style.cssText = t;
      else {
        if (typeof n == "string" && (i.style.cssText = n = ""), n)
          for (e in n)
            t && e in t || Fv(i.style, e, "");
        if (t)
          for (e in t)
            n && t[e] == n[e] || Fv(i.style, e, t[e]);
      }
    else if (e[0] == "o" && e[1] == "n")
      s = e != (e = e.replace(VT, "$1")), a = e.toLowerCase(), e = a in i || e == "onFocusOut" || e == "onFocusIn" ? a.slice(2) : e.slice(2), i.l || (i.l = {}), i.l[e + s] = t, t ? n ? t.u = n.u : (t.u = Yg, i.addEventListener(e, s ? pm : fm, s)) : i.removeEventListener(e, s ? pm : fm, s);
    else {
      if (r == "http://www.w3.org/2000/svg")
        e = e.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
      else if (e != "width" && e != "height" && e != "href" && e != "list" && e != "form" && e != "tabIndex" && e != "download" && e != "rowSpan" && e != "colSpan" && e != "role" && e != "popover" && e in i)
        try {
          i[e] = t ?? "";
          break e;
        } catch {
        }
      typeof t == "function" || (t == null || t === !1 && e[4] != "-" ? i.removeAttribute(e) : i.setAttribute(e, e == "popover" && t == 1 ? "" : t));
    }
}
function Iv(i) {
  return function(e) {
    if (this.l) {
      var t = this.l[e.type + i];
      if (e.t == null)
        e.t = Yg++;
      else if (e.t < t.u)
        return;
      return t(rn.event ? rn.event(e) : e);
    }
  };
}
function Zg(i, e, t, n, r, s, a, o, l, c) {
  var u, h, d, f, p, _, g, m, x, y, b, T, S, E, v, M = e.type;
  if (e.constructor !== void 0)
    return null;
  128 & t.__u && (l = !!(32 & t.__u), s = [o = e.__e = t.__e]), (u = rn.__b) && u(e);
  e:
    if (typeof M == "function")
      try {
        if (m = e.props, x = M.prototype && M.prototype.render, y = (u = M.contextType) && n[u.__c], b = u ? y ? y.props.value : u.__ : n, t.__c ? g = (h = e.__c = t.__c).__ = h.__E : (x ? e.__c = h = new M(m, b) : (e.__c = h = new Nh(m, b), h.constructor = M, h.render = aH), y && y.sub(h), h.state || (h.state = {}), h.__n = n, d = h.__d = !0, h.__h = [], h._sb = []), x && h.__s == null && (h.__s = h.state), x && M.getDerivedStateFromProps != null && (h.__s == h.state && (h.__s = Er({}, h.__s)), Er(h.__s, M.getDerivedStateFromProps(m, h.__s))), f = h.props, p = h.state, h.__v = e, d)
          x && M.getDerivedStateFromProps == null && h.componentWillMount != null && h.componentWillMount(), x && h.componentDidMount != null && h.__h.push(h.componentDidMount);
        else {
          if (x && M.getDerivedStateFromProps == null && m !== f && h.componentWillReceiveProps != null && h.componentWillReceiveProps(m, b), e.__v == t.__v || !h.__e && h.shouldComponentUpdate != null && h.shouldComponentUpdate(m, h.__s, b) === !1) {
            e.__v != t.__v && (h.props = m, h.state = h.__s, h.__d = !1), e.__e = t.__e, e.__k = t.__k, e.__k.some(function(F) {
              F && (F.__ = e);
            }), td.push.apply(h.__h, h._sb), h._sb = [], h.__h.length && a.push(h);
            break e;
          }
          h.componentWillUpdate != null && h.componentWillUpdate(m, h.__s, b), x && h.componentDidUpdate != null && h.__h.push(function() {
            h.componentDidUpdate(f, p, _);
          });
        }
        if (h.context = b, h.props = m, h.__P = i, h.__e = !1, T = rn.__r, S = 0, x)
          h.state = h.__s, h.__d = !1, T && T(e), u = h.render(h.props, h.state, h.context), td.push.apply(h.__h, h._sb), h._sb = [];
        else
          do
            h.__d = !1, T && T(e), u = h.render(h.props, h.state, h.context), h.state = h.__s;
          while (h.__d && ++S < 25);
        h.state = h.__s, h.getChildContext != null && (n = Er(Er({}, n), h.getChildContext())), x && !d && h.getSnapshotBeforeUpdate != null && (_ = h.getSnapshotBeforeUpdate(f, p)), E = u != null && u.type === Fd && u.key == null ? qT(u.props.children) : u, o = HT(i, Ld(E) ? E : [E], e, t, n, r, s, a, o, l, c), h.base = e.__e, e.__u &= -161, h.__h.length && a.push(h), g && (h.__E = h.__ = null);
      } catch (F) {
        if (e.__v = null, l || s != null)
          if (F.then) {
            for (e.__u |= l ? 160 : 128; o && o.nodeType == 8 && o.nextSibling; )
              o = o.nextSibling;
            s[s.indexOf(o)] = null, e.__e = o;
          } else {
            for (v = s.length; v--; )
              Kg(s[v]);
            mm(e);
          }
        else
          e.__e = t.__e, e.__k = t.__k, F.then || mm(e);
        rn.__e(F, e, t);
      }
    else
      s == null && e.__v == t.__v ? (e.__k = t.__k, e.__e = t.__e) : o = e.__e = sH(t.__e, e, t, n, r, s, a, l, c);
  return (u = rn.diffed) && u(e), 128 & e.__u ? void 0 : o;
}
function mm(i) {
  i && (i.__c && (i.__c.__e = !0), i.__k && i.__k.some(mm));
}
function WT(i, e, t) {
  for (var n = 0; n < t.length; n++)
    Qg(t[n], t[++n], t[++n]);
  rn.__c && rn.__c(e, i), i.some(function(r) {
    try {
      i = r.__h, r.__h = [], i.some(function(s) {
        s.call(r);
      });
    } catch (s) {
      rn.__e(s, r.__v);
    }
  });
}
function qT(i) {
  return typeof i != "object" || i == null || i.__b > 0 ? i : Ld(i) ? i.map(qT) : Er({}, i);
}
function sH(i, e, t, n, r, s, a, o, l) {
  var c, u, h, d, f, p, _, g = t.props || ed, m = e.props, x = e.type;
  if (x == "svg" ? r = "http://www.w3.org/2000/svg" : x == "math" ? r = "http://www.w3.org/1998/Math/MathML" : r || (r = "http://www.w3.org/1999/xhtml"), s != null) {
    for (c = 0; c < s.length; c++)
      if ((f = s[c]) && "setAttribute" in f == !!x && (x ? f.localName == x : f.nodeType == 3)) {
        i = f, s[c] = null;
        break;
      }
  }
  if (i == null) {
    if (x == null)
      return document.createTextNode(m);
    i = document.createElementNS(r, x, m.is && m), o && (rn.__m && rn.__m(e, s), o = !1), s = null;
  }
  if (x == null)
    g === m || o && i.data == m || (i.data = m);
  else {
    if (s = s && hu.call(i.childNodes), !o && s != null)
      for (g = {}, c = 0; c < i.attributes.length; c++)
        g[(f = i.attributes[c]).name] = f.value;
    for (c in g)
      f = g[c], c == "dangerouslySetInnerHTML" ? h = f : c == "children" || c in m || c == "value" && "defaultValue" in m || c == "checked" && "defaultChecked" in m || vh(i, c, null, f, r);
    for (c in m)
      f = m[c], c == "children" ? d = f : c == "dangerouslySetInnerHTML" ? u = f : c == "value" ? p = f : c == "checked" ? _ = f : o && typeof f != "function" || g[c] === f || vh(i, c, f, g[c], r);
    if (u)
      o || h && (u.__html == h.__html || u.__html == i.innerHTML) || (i.innerHTML = u.__html), e.__k = [];
    else if (h && (i.innerHTML = ""), HT(e.type == "template" ? i.content : i, Ld(d) ? d : [d], e, t, n, x == "foreignObject" ? "http://www.w3.org/1999/xhtml" : r, s, a, s ? s[0] : t.__k && gl(t, 0), o, l), s != null)
      for (c = s.length; c--; )
        Kg(s[c]);
    o || (c = "value", x == "progress" && p == null ? i.removeAttribute("value") : p != null && (p !== i[c] || x == "progress" && !p || x == "option" && p != g[c]) && vh(i, c, p, g[c], r), c = "checked", _ != null && _ != i[c] && vh(i, c, _, g[c], r));
  }
  return i;
}
function Qg(i, e, t) {
  try {
    if (typeof i == "function") {
      var n = typeof i.__u == "function";
      n && i.__u(), n && e == null || (i.__u = i(e));
    } else
      i.current = e;
  } catch (r) {
    rn.__e(r, t);
  }
}
function XT(i, e, t) {
  var n, r;
  if (rn.unmount && rn.unmount(i), (n = i.ref) && (n.current && n.current != i.__e || Qg(n, null, e)), (n = i.__c) != null) {
    if (n.componentWillUnmount)
      try {
        n.componentWillUnmount();
      } catch (s) {
        rn.__e(s, e);
      }
    n.base = n.__P = null;
  }
  if (n = i.__k)
    for (r = 0; r < n.length; r++)
      n[r] && XT(n[r], e, t || typeof i.type != "function");
  t || Kg(i.__e), i.__c = i.__ = i.__e = void 0;
}
function aH(i, e, t) {
  return this.constructor(i, t);
}
function oH(i, e, t) {
  var n, r, s, a;
  e == document && (e = document.documentElement), rn.__ && rn.__(i, e), r = (n = typeof t == "function") ? null : t && t.__k || e.__k, s = [], a = [], Zg(e, i = (!n && t || e).__k = tH(Fd, null, [i]), r || ed, ed, e.namespaceURI, !n && t ? [t] : r ? null : e.firstChild ? hu.call(e.childNodes) : null, s, !n && t ? t : r ? r.__e : e.firstChild, n, a), WT(s, i, a);
}
function jT(i, e, t) {
  var n, r, s, a, o = Er({}, i.props);
  for (s in i.type && i.type.defaultProps && (a = i.type.defaultProps), e)
    s == "key" ? n = e[s] : s == "ref" ? r = e[s] : o[s] = e[s] === void 0 && a != null ? a[s] : e[s];
  return arguments.length > 2 && (o.children = arguments.length > 3 ? hu.call(arguments, 2) : t), Ac(i.type, o, n || i.key, r || i.ref, null);
}
hu = td.slice, rn = { __e: function(i, e, t, n) {
  for (var r, s, a; e = e.__; )
    if ((r = e.__c) && !r.__)
      try {
        if ((s = r.constructor) && s.getDerivedStateFromError != null && (r.setState(s.getDerivedStateFromError(i)), a = r.__d), r.componentDidCatch != null && (r.componentDidCatch(i, n || {}), a = r.__d), a)
          return r.__E = r;
      } catch (o) {
        i = o;
      }
  throw i;
} }, BT = 0, OT = function(i) {
  return i != null && i.constructor === void 0;
}, Nh.prototype.setState = function(i, e) {
  var t;
  t = this.__s != null && this.__s != this.state ? this.__s : this.__s = Er({}, this.state), typeof i == "function" && (i = i(Er({}, t), this.props)), i && Er(t, i), i != null && this.__v && (e && this._sb.push(e), Lv(this));
}, Nh.prototype.forceUpdate = function(i) {
  this.__v && (this.__e = !0, i && this.__h.push(i), Lv(this));
}, Nh.prototype.render = Fd, As = [], kT = typeof Promise == "function" ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, GT = function(i, e) {
  return i.__v.__b - e.__v.__b;
}, nd.__r = 0, VT = /(PointerCapture)$|Capture$/i, Yg = 0, fm = Iv(!1), pm = Iv(!0);
function Uv(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function lH(i) {
  if (Array.isArray(i))
    return i;
}
function cH(i, e, t) {
  return (e = mH(e)) in i ? Object.defineProperty(i, e, {
    value: t,
    enumerable: !0,
    configurable: !0,
    writable: !0
  }) : i[e] = t, i;
}
function uH(i, e) {
  var t = i == null ? null : typeof Symbol < "u" && i[Symbol.iterator] || i["@@iterator"];
  if (t != null) {
    var n, r, s, a, o = [], l = !0, c = !1;
    try {
      if (s = (t = t.call(i)).next, e !== 0)
        for (; !(l = (n = s.call(t)).done) && (o.push(n.value), o.length !== e); l = !0)
          ;
    } catch (u) {
      c = !0, r = u;
    } finally {
      try {
        if (!l && t.return != null && (a = t.return(), Object(a) !== a))
          return;
      } finally {
        if (c)
          throw r;
      }
    }
    return o;
  }
}
function hH() {
  throw new TypeError(`Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function Bv(i, e) {
  var t = Object.keys(i);
  if (Object.getOwnPropertySymbols) {
    var n = Object.getOwnPropertySymbols(i);
    e && (n = n.filter(function(r) {
      return Object.getOwnPropertyDescriptor(i, r).enumerable;
    })), t.push.apply(t, n);
  }
  return t;
}
function dH(i) {
  for (var e = 1; e < arguments.length; e++) {
    var t = arguments[e] != null ? arguments[e] : {};
    e % 2 ? Bv(Object(t), !0).forEach(function(n) {
      cH(i, n, t[n]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(i, Object.getOwnPropertyDescriptors(t)) : Bv(Object(t)).forEach(function(n) {
      Object.defineProperty(i, n, Object.getOwnPropertyDescriptor(t, n));
    });
  }
  return i;
}
function fH(i, e) {
  return lH(i) || uH(i, e) || gH(i, e) || hH();
}
function pH(i, e) {
  if (typeof i != "object" || !i)
    return i;
  var t = i[Symbol.toPrimitive];
  if (t !== void 0) {
    var n = t.call(i, e);
    if (typeof n != "object")
      return n;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (e === "string" ? String : Number)(i);
}
function mH(i) {
  var e = pH(i, "string");
  return typeof e == "symbol" ? e : e + "";
}
function id(i) {
  "@babel/helpers - typeof";
  return id = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
    return typeof e;
  } : function(e) {
    return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
  }, id(i);
}
function gH(i, e) {
  if (i) {
    if (typeof i == "string")
      return Uv(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? Uv(i, e) : void 0;
  }
}
var gm = function(e) {
  if (id(e) !== "object")
    return e;
  var t = jT(e);
  if (t.props) {
    var n;
    t.props = dH({}, t.props), t != null && (n = t.props) !== null && n !== void 0 && n.children && (t.props.children = Array.isArray(t.props.children) ? t.props.children.map(gm) : gm(t.props.children));
  }
  return t;
}, _H = function(e) {
  return OT(jT(e));
}, xH = function(e, t) {
  delete t.__k, oH(gm(e), t);
};
function vH(i, e) {
  e === void 0 && (e = {});
  var t = e.insertAt;
  if (!(typeof document > "u")) {
    var n = document.head || document.getElementsByTagName("head")[0], r = document.createElement("style");
    r.type = "text/css", t === "top" && n.firstChild ? n.insertBefore(r, n.firstChild) : n.appendChild(r), r.styleSheet ? r.styleSheet.cssText = i : r.appendChild(document.createTextNode(i));
  }
}
var yH = `.float-tooltip-kap {
  position: absolute;
  width: max-content; /* prevent shrinking near right edge */
  max-width: max(50%, 150px);
  padding: 3px 5px;
  border-radius: 3px;
  font: 12px sans-serif;
  color: #eee;
  background: rgba(0,0,0,0.6);
  pointer-events: none;
}
`;
vH(yH);
var bH = gd({
  props: {
    content: {
      default: !1
    },
    offsetX: {
      triggerUpdate: !1
    },
    // null or number
    offsetY: {
      triggerUpdate: !1
    }
    // null or number
  },
  init: function(e, t) {
    var n = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, r = n.style, s = r === void 0 ? {} : r, a = !!e && id(e) === "object" && !!e.node && typeof e.node == "function", o = Z5(a ? e.node() : e);
    o.style("position") === "static" && o.style("position", "relative"), t.tooltipEl = o.append("div").attr("class", "float-tooltip-kap"), Object.entries(s).forEach(function(c) {
      var u = fH(c, 2), h = u[0], d = u[1];
      return t.tooltipEl.style(h, d);
    }), t.tooltipEl.style("left", "-10000px").style("display", "none");
    var l = "tooltip-".concat(Math.round(Math.random() * 1e12));
    t.mouseInside = !1, o.on("mousemove.".concat(l), function(c) {
      t.mouseInside = !0;
      var u = J5(c), h = o.node(), d = h.offsetWidth, f = h.offsetHeight, p = [t.offsetX === null || t.offsetX === void 0 ? "-".concat(u[0] / d * 100, "%") : typeof t.offsetX == "number" ? "calc(-50% + ".concat(t.offsetX, "px)") : t.offsetX, t.offsetY === null || t.offsetY === void 0 ? f > 130 && f - u[1] < 100 ? "calc(-100% - 6px)" : "21px" : typeof t.offsetY == "number" ? t.offsetY < 0 ? "calc(-100% - ".concat(Math.abs(t.offsetY), "px)") : "".concat(t.offsetY, "px") : t.offsetY];
      t.tooltipEl.style("left", u[0] + "px").style("top", u[1] + "px").style("transform", "translate(".concat(p.join(","), ")")), t.content && t.tooltipEl.style("display", "inline");
    }), o.on("mouseover.".concat(l), function() {
      t.mouseInside = !0, t.content && t.tooltipEl.style("display", "inline");
    }), o.on("mouseout.".concat(l), function() {
      t.mouseInside = !1, t.tooltipEl.style("display", "none");
    });
  },
  update: function(e) {
    e.tooltipEl.style("display", e.content && e.mouseInside ? "inline" : "none"), e.content ? e.content instanceof HTMLElement ? (e.tooltipEl.text(""), e.tooltipEl.append(function() {
      return e.content;
    })) : typeof e.content == "string" ? e.tooltipEl.html(e.content) : _H(e.content) ? (e.tooltipEl.text(""), xH(e.content, e.tooltipEl.node())) : (e.tooltipEl.style("display", "none"), console.warn("Tooltip content is invalid, skipping.", e.content, e.content.toString())) : e.tooltipEl.text("");
  }
});
function SH(i, e) {
  e === void 0 && (e = {});
  var t = e.insertAt;
  if (!(typeof document > "u")) {
    var n = document.head || document.getElementsByTagName("head")[0], r = document.createElement("style");
    r.type = "text/css", t === "top" && n.firstChild ? n.insertBefore(r, n.firstChild) : n.appendChild(r), r.styleSheet ? r.styleSheet.cssText = i : r.appendChild(document.createTextNode(i));
  }
}
var TH = `.scene-nav-info {
  position: absolute;
  bottom: 5px;
  width: 100%;
  text-align: center;
  color: slategrey;
  opacity: 0.7;
  font-size: 10px;
  font-family: sans-serif;
  pointer-events: none;
  user-select: none;
}

.scene-container canvas:focus {
  outline: none;
}`;
SH(TH);
function _m(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function MH(i) {
  if (Array.isArray(i))
    return i;
}
function EH(i) {
  if (Array.isArray(i))
    return _m(i);
}
function wH(i, e, t) {
  return (e = LH(e)) in i ? Object.defineProperty(i, e, {
    value: t,
    enumerable: !0,
    configurable: !0,
    writable: !0
  }) : i[e] = t, i;
}
function AH(i) {
  if (typeof Symbol < "u" && i[Symbol.iterator] != null || i["@@iterator"] != null)
    return Array.from(i);
}
function RH(i, e) {
  var t = i == null ? null : typeof Symbol < "u" && i[Symbol.iterator] || i["@@iterator"];
  if (t != null) {
    var n, r, s, a, o = [], l = !0, c = !1;
    try {
      if (s = (t = t.call(i)).next, e !== 0)
        for (; !(l = (n = s.call(t)).done) && (o.push(n.value), o.length !== e); l = !0)
          ;
    } catch (u) {
      c = !0, r = u;
    } finally {
      try {
        if (!l && t.return != null && (a = t.return(), Object(a) !== a))
          return;
      } finally {
        if (c)
          throw r;
      }
    }
    return o;
  }
}
function CH() {
  throw new TypeError(`Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function NH() {
  throw new TypeError(`Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function PH(i, e) {
  return MH(i) || RH(i, e) || YT(i, e) || CH();
}
function ua(i) {
  return EH(i) || AH(i) || YT(i) || NH();
}
function DH(i, e) {
  if (typeof i != "object" || !i)
    return i;
  var t = i[Symbol.toPrimitive];
  if (t !== void 0) {
    var n = t.call(i, e);
    if (typeof n != "object")
      return n;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (e === "string" ? String : Number)(i);
}
function LH(i) {
  var e = DH(i, "string");
  return typeof e == "symbol" ? e : e + "";
}
function YT(i, e) {
  if (i) {
    if (typeof i == "string")
      return _m(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _m(i, e) : void 0;
  }
}
var en = window.THREE ? window.THREE : {
  WebGLRenderer: eN,
  Scene: Xm,
  PerspectiveCamera: An,
  Raycaster: gy,
  SRGBColorSpace: Jn,
  TextureLoader: jE,
  Vector2: de,
  Vector3: P,
  Box3: Ha,
  Color: He,
  Mesh: _n,
  SphereGeometry: su,
  MeshBasicMaterial: xr,
  BackSide: Ft,
  Clock: aw
}, KT = gd({
  props: {
    width: {
      default: window.innerWidth,
      onChange: function(e, t, n) {
        isNaN(e) && (t.width = n);
      }
    },
    height: {
      default: window.innerHeight,
      onChange: function(e, t, n) {
        isNaN(e) && (t.height = n);
      }
    },
    viewOffset: {
      default: [0, 0]
    },
    backgroundColor: {
      default: "#000011"
    },
    backgroundImageUrl: {},
    onBackgroundImageLoaded: {},
    showNavInfo: {
      default: !0
    },
    skyRadius: {
      default: 5e4
    },
    objects: {
      default: []
    },
    lights: {
      default: []
    },
    enablePointerInteraction: {
      default: !0,
      onChange: function(e, t) {
        t.hoverObj = null, t.tooltip && t.tooltip.content(null);
      },
      triggerUpdate: !1
    },
    pointerRaycasterThrottleMs: {
      default: 50,
      triggerUpdate: !1
    },
    lineHoverPrecision: {
      default: 1,
      triggerUpdate: !1
    },
    pointsHoverPrecision: {
      default: 1,
      triggerUpdate: !1
    },
    hoverOrderComparator: {
      triggerUpdate: !1
    },
    // keep existing order by default
    hoverFilter: {
      default: function() {
        return !0;
      },
      triggerUpdate: !1
    },
    // exclude objects from interaction
    tooltipContent: {
      triggerUpdate: !1
    },
    hoverDuringDrag: {
      default: !1,
      triggerUpdate: !1
    },
    clickAfterDrag: {
      default: !1,
      triggerUpdate: !1
    },
    onHover: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onClick: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onRightClick: {
      triggerUpdate: !1
    }
  },
  methods: {
    tick: function(e) {
      if (e.initialised) {
        e.controls.enabled && e.controls.update && e.controls.update(Math.min(1, e.clock.getDelta())), e.postProcessingComposer ? e.postProcessingComposer.render() : e.renderer.render(e.scene, e.camera), e.extraRenderers.forEach(function(a) {
          return a.render(e.scene, e.camera);
        });
        var t = +/* @__PURE__ */ new Date();
        if (e.enablePointerInteraction && t - e.lastRaycasterCheck >= e.pointerRaycasterThrottleMs) {
          e.lastRaycasterCheck = t;
          var n = null;
          if (e.hoverDuringDrag || !e.isPointerDragging) {
            var r = this.intersectingObjects(e.pointerPos.x, e.pointerPos.y);
            e.hoverOrderComparator && r.sort(function(a, o) {
              return e.hoverOrderComparator(a.object, o.object);
            });
            var s = r.find(function(a) {
              return e.hoverFilter(a.object);
            }) || null;
            n = s ? s.object : null, e.intersection = s || null;
          }
          n !== e.hoverObj && (e.onHover(n, e.hoverObj, e.intersection), e.tooltip.content(n && xt(e.tooltipContent)(n, e.intersection) || null), e.hoverObj = n);
        }
        e.tweenGroup.update();
      }
      return this;
    },
    getPointerPos: function(e) {
      var t = e.pointerPos, n = t.x, r = t.y;
      return {
        x: n,
        y: r
      };
    },
    cameraPosition: function(e, t, n, r) {
      var s = e.camera;
      if (t && e.initialised) {
        var a = t, o = n || {
          x: 0,
          y: 0,
          z: 0
        };
        if (!r)
          u(a), h(o);
        else {
          var l = Object.assign({}, s.position), c = d();
          e.tweenGroup.add(new Nv(l).to(a, r).easing(Aa.Quadratic.Out).onUpdate(u).start()), e.tweenGroup.add(new Nv(c).to(o, r / 3).easing(Aa.Quadratic.Out).onUpdate(h).start());
        }
        return this;
      }
      return Object.assign({}, s.position, {
        lookAt: d()
      });
      function u(f) {
        var p = f.x, _ = f.y, g = f.z;
        p !== void 0 && (s.position.x = p), _ !== void 0 && (s.position.y = _), g !== void 0 && (s.position.z = g);
      }
      function h(f) {
        var p = new en.Vector3(f.x, f.y, f.z);
        e.controls.enabled && e.controls.target ? e.controls.target = p : s.lookAt(p);
      }
      function d() {
        return Object.assign(new en.Vector3(0, 0, -1e3).applyQuaternion(s.quaternion).add(s.position));
      }
    },
    zoomToFit: function(e) {
      for (var t = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0, n = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 10, r = arguments.length, s = new Array(r > 3 ? r - 3 : 0), a = 3; a < r; a++)
        s[a - 3] = arguments[a];
      return this.fitToBbox(this.getBbox.apply(this, s), t, n);
    },
    fitToBbox: function(e, t) {
      var n = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 0, r = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 10, s = e.camera;
      if (t) {
        var a = new en.Vector3(0, 0, 0), o = Math.max.apply(Math, ua(Object.entries(t).map(function(f) {
          var p = PH(f, 2), _ = p[0], g = p[1];
          return Math.max.apply(Math, ua(g.map(function(m) {
            return Math.abs(a[_] - m);
          })));
        }))) * 2, l = (1 - r * 2 / e.height) * s.fov, c = o / Math.atan(l * Math.PI / 180), u = c / s.aspect, h = Math.max(c, u);
        if (h > 0) {
          var d = a.clone().sub(s.position).normalize().multiplyScalar(-h);
          this.cameraPosition(d, a, n);
        }
      }
      return this;
    },
    getBbox: function(e) {
      var t = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : function() {
        return !0;
      }, n = new en.Box3(new en.Vector3(0, 0, 0), new en.Vector3(0, 0, 0)), r = e.objects.filter(t);
      return r.length ? (r.forEach(function(s) {
        return n.expandByObject(s);
      }), Object.assign.apply(Object, ua(["x", "y", "z"].map(function(s) {
        return wH({}, s, [n.min[s], n.max[s]]);
      })))) : null;
    },
    getScreenCoords: function(e, t, n, r) {
      var s = new en.Vector3(t, n, r);
      return s.project(this.camera()), {
        // align relative pos to canvas dimensions
        x: (s.x + 1) * e.width / 2,
        y: -(s.y - 1) * e.height / 2
      };
    },
    getSceneCoords: function(e, t, n) {
      var r = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 0, s = new en.Vector2(t / e.width * 2 - 1, -(n / e.height) * 2 + 1), a = new en.Raycaster();
      return a.setFromCamera(s, e.camera), Object.assign({}, a.ray.at(r, new en.Vector3()));
    },
    intersectingObjects: function(e, t, n) {
      var r = new en.Vector2(t / e.width * 2 - 1, -(n / e.height) * 2 + 1), s = new en.Raycaster();
      return s.params.Line.threshold = e.lineHoverPrecision, s.params.Points.threshold = e.pointsHoverPrecision, s.setFromCamera(r, e.camera), s.intersectObjects(e.objects, !0);
    },
    renderer: function(e) {
      return e.renderer;
    },
    scene: function(e) {
      return e.scene;
    },
    camera: function(e) {
      return e.camera;
    },
    postProcessingComposer: function(e) {
      return e.postProcessingComposer;
    },
    controls: function(e) {
      return e.controls;
    },
    tbControls: function(e) {
      return e.controls;
    }
    // to be deprecated
  },
  stateInit: function() {
    return {
      scene: new en.Scene(),
      camera: new en.PerspectiveCamera(),
      clock: new en.Clock(),
      tweenGroup: new ET(),
      lastRaycasterCheck: 0
    };
  },
  init: function(e, t) {
    var n = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, r = n.controlType, s = r === void 0 ? "trackball" : r, a = n.useWebGPU, o = a === void 0 ? !1 : a, l = n.rendererConfig, c = l === void 0 ? {} : l, u = n.extraRenderers, h = u === void 0 ? [] : u, d = n.waitForLoadComplete, f = d === void 0 ? !0 : d;
    e.innerHTML = "", e.appendChild(t.container = document.createElement("div")), t.container.className = "scene-container", t.container.style.position = "relative", t.container.appendChild(t.navInfo = document.createElement("div")), t.navInfo.className = "scene-nav-info", t.navInfo.textContent = {
      orbit: "Left-click: rotate, Mouse-wheel/middle-click: zoom, Right-click: pan",
      trackball: "Left-click: rotate, Mouse-wheel/middle-click: zoom, Right-click: pan",
      fly: "WASD: move, R|F: up | down, Q|E: roll, up|down: pitch, left|right: yaw"
    }[s] || "", t.navInfo.style.display = t.showNavInfo ? null : "none", t.tooltip = new bH(t.container), t.pointerPos = new en.Vector2(), t.pointerPos.x = -2, t.pointerPos.y = -2, ["pointermove", "pointerdown"].forEach(function(p) {
      return t.container.addEventListener(p, function(_) {
        if (p === "pointerdown" && (t.isPointerPressed = !0), !t.isPointerDragging && _.type === "pointermove" && (_.pressure > 0 || t.isPointerPressed) && (_.pointerType === "mouse" || _.movementX === void 0 || [_.movementX, _.movementY].some(function(x) {
          return Math.abs(x) > 1;
        })) && (t.isPointerDragging = !0), t.enablePointerInteraction) {
          var g = m(t.container);
          t.pointerPos.x = _.pageX - g.left, t.pointerPos.y = _.pageY - g.top;
        }
        function m(x) {
          var y = x.getBoundingClientRect(), b = window.pageXOffset || document.documentElement.scrollLeft, T = window.pageYOffset || document.documentElement.scrollTop;
          return {
            top: y.top + T,
            left: y.left + b
          };
        }
      }, {
        passive: !0
      });
    }), t.container.addEventListener("pointerup", function(p) {
      t.isPointerPressed && (t.isPointerPressed = !1, !(t.isPointerDragging && (t.isPointerDragging = !1, !t.clickAfterDrag)) && requestAnimationFrame(function() {
        p.button === 0 && t.onClick(t.hoverObj || null, p, t.intersection), p.button === 2 && t.onRightClick && t.onRightClick(t.hoverObj || null, p, t.intersection);
      }));
    }, {
      passive: !0,
      capture: !0
    }), t.container.addEventListener("contextmenu", function(p) {
      t.onRightClick && p.preventDefault();
    }), t.renderer = new (o ? LV : en.WebGLRenderer)(Object.assign({
      antialias: !0,
      alpha: !0
    }, c)), t.renderer.setPixelRatio(Math.min(2, window.devicePixelRatio)), t.container.appendChild(t.renderer.domElement), t.extraRenderers = h, t.extraRenderers.forEach(function(p) {
      p.domElement.style.position = "absolute", p.domElement.style.top = "0px", p.domElement.style.pointerEvents = "none", t.container.appendChild(p.domElement);
    }), t.postProcessingComposer = new wz(t.renderer), t.postProcessingComposer.addPass(new Az(t.scene, t.camera)), t.controls = new {
      trackball: IV,
      orbit: ZV,
      fly: hz
    }[s](t.camera, t.renderer.domElement), s === "fly" && (t.controls.movementSpeed = 300, t.controls.rollSpeed = Math.PI / 6, t.controls.dragToLook = !0), (s === "trackball" || s === "orbit") && (t.controls.minDistance = 0.1, t.controls.maxDistance = t.skyRadius, t.controls.addEventListener("start", function() {
      t.controlsEngaged = !0;
    }), t.controls.addEventListener("change", function() {
      t.controlsEngaged && (t.controlsDragging = !0);
    }), t.controls.addEventListener("end", function() {
      t.controlsEngaged = !1, t.controlsDragging = !1;
    })), [t.renderer, t.postProcessingComposer].concat(ua(t.extraRenderers)).forEach(function(p) {
      return p.setSize(t.width, t.height);
    }), t.camera.aspect = t.width / t.height, t.camera.updateProjectionMatrix(), t.camera.position.z = 1e3, t.scene.add(t.skysphere = new en.Mesh()), t.skysphere.visible = !1, t.loadComplete = t.scene.visible = !f, window.scene = t.scene;
  },
  update: function(e, t) {
    if (e.width && e.height && (t.hasOwnProperty("width") || t.hasOwnProperty("height"))) {
      var n, r = e.width, s = e.height;
      e.container.style.width = "".concat(r, "px"), e.container.style.height = "".concat(s, "px"), [e.renderer, e.postProcessingComposer].concat(ua(e.extraRenderers)).forEach(function(f) {
        return f.setSize(r, s);
      }), e.camera.aspect = r / s;
      var a = e.viewOffset.slice(0, 2);
      a.some(function(f) {
        return f;
      }) && (n = e.camera).setViewOffset.apply(n, [r, s].concat(ua(a), [r, s])), e.camera.updateProjectionMatrix();
    }
    if (t.hasOwnProperty("viewOffset")) {
      var o, l = e.width, c = e.height, u = e.viewOffset.slice(0, 2);
      u.some(function(f) {
        return f;
      }) ? (o = e.camera).setViewOffset.apply(o, [l, c].concat(ua(u), [l, c])) : e.camera.clearViewOffset();
    }
    if (t.hasOwnProperty("skyRadius") && e.skyRadius && (e.controls.hasOwnProperty("maxDistance") && t.skyRadius && (e.controls.maxDistance = Math.min(e.controls.maxDistance, e.skyRadius)), e.camera.far = e.skyRadius * 2.5, e.camera.updateProjectionMatrix(), e.skysphere.geometry = new en.SphereGeometry(e.skyRadius)), t.hasOwnProperty("backgroundColor")) {
      var h = Va(e.backgroundColor).alpha;
      h === void 0 && (h = 1), e.renderer.setClearColor(new en.Color(a4(1, e.backgroundColor)), h);
    }
    t.hasOwnProperty("backgroundImageUrl") && (e.backgroundImageUrl ? new en.TextureLoader().load(e.backgroundImageUrl, function(f) {
      f.colorSpace = en.SRGBColorSpace, e.skysphere.material = new en.MeshBasicMaterial({
        map: f,
        side: en.BackSide
      }), e.skysphere.visible = !0, e.onBackgroundImageLoaded && setTimeout(e.onBackgroundImageLoaded), !e.loadComplete && d();
    }) : (e.skysphere.visible = !1, e.skysphere.material.map = null, !e.loadComplete && d())), t.hasOwnProperty("showNavInfo") && (e.navInfo.style.display = e.showNavInfo ? null : "none"), t.hasOwnProperty("lights") && ((t.lights || []).forEach(function(f) {
      return e.scene.remove(f);
    }), e.lights.forEach(function(f) {
      return e.scene.add(f);
    })), t.hasOwnProperty("objects") && ((t.objects || []).forEach(function(f) {
      return e.scene.remove(f);
    }), e.objects.forEach(function(f) {
      return e.scene.add(f);
    }));
    function d() {
      e.loadComplete = e.scene.visible = !0;
    }
  }
});
function FH(i, e) {
  e === void 0 && (e = {});
  var t = e.insertAt;
  if (!(typeof document > "u")) {
    var n = document.head || document.getElementsByTagName("head")[0], r = document.createElement("style");
    r.type = "text/css", t === "top" && n.firstChild ? n.insertBefore(r, n.firstChild) : n.appendChild(r), r.styleSheet ? r.styleSheet.cssText = i : r.appendChild(document.createTextNode(i));
  }
}
var IH = `.graph-info-msg {
  top: 50%;
  width: 100%;
  text-align: center;
  color: lavender;
  opacity: 0.7;
  font-size: 22px;
  position: absolute;
  font-family: Sans-serif;
}

.scene-container .clickable {
  cursor: pointer;
}

.scene-container .grabbable {
  cursor: move;
  cursor: grab;
  cursor: -moz-grab;
  cursor: -webkit-grab;
}

.scene-container .grabbable:active {
  cursor: grabbing;
  cursor: -moz-grabbing;
  cursor: -webkit-grabbing;
}`;
FH(IH);
function xm(i, e) {
  (e == null || e > i.length) && (e = i.length);
  for (var t = 0, n = Array(e); t < e; t++)
    n[t] = i[t];
  return n;
}
function UH(i) {
  if (Array.isArray(i))
    return xm(i);
}
function du(i, e, t) {
  return (e = GH(e)) in i ? Object.defineProperty(i, e, {
    value: t,
    enumerable: !0,
    configurable: !0,
    writable: !0
  }) : i[e] = t, i;
}
function BH(i) {
  if (typeof Symbol < "u" && i[Symbol.iterator] != null || i["@@iterator"] != null)
    return Array.from(i);
}
function OH() {
  throw new TypeError(`Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`);
}
function Ov(i, e) {
  var t = Object.keys(i);
  if (Object.getOwnPropertySymbols) {
    var n = Object.getOwnPropertySymbols(i);
    e && (n = n.filter(function(r) {
      return Object.getOwnPropertyDescriptor(i, r).enumerable;
    })), t.push.apply(t, n);
  }
  return t;
}
function yh(i) {
  for (var e = 1; e < arguments.length; e++) {
    var t = arguments[e] != null ? arguments[e] : {};
    e % 2 ? Ov(Object(t), !0).forEach(function(n) {
      du(i, n, t[n]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(i, Object.getOwnPropertyDescriptors(t)) : Ov(Object(t)).forEach(function(n) {
      Object.defineProperty(i, n, Object.getOwnPropertyDescriptor(t, n));
    });
  }
  return i;
}
function Id(i) {
  return UH(i) || BH(i) || VH(i) || OH();
}
function kH(i, e) {
  if (typeof i != "object" || !i)
    return i;
  var t = i[Symbol.toPrimitive];
  if (t !== void 0) {
    var n = t.call(i, e);
    if (typeof n != "object")
      return n;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (e === "string" ? String : Number)(i);
}
function GH(i) {
  var e = kH(i, "string");
  return typeof e == "symbol" ? e : e + "";
}
function VH(i, e) {
  if (i) {
    if (typeof i == "string")
      return xm(i, e);
    var t = {}.toString.call(i).slice(8, -1);
    return t === "Object" && i.constructor && (t = i.constructor.name), t === "Map" || t === "Set" ? Array.from(i) : t === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? xm(i, e) : void 0;
  }
}
function ZT(i, e) {
  var t = new e();
  return t._destructor && t._destructor(), {
    linkProp: function(r) {
      return {
        default: t[r](),
        onChange: function(a, o) {
          o[i][r](a);
        },
        triggerUpdate: !1
      };
    },
    linkMethod: function(r) {
      return function(s) {
        for (var a = s[i], o = arguments.length, l = new Array(o > 1 ? o - 1 : 0), c = 1; c < o; c++)
          l[c - 1] = arguments[c];
        var u = a[r].apply(a, l);
        return u === a ? this : u;
      };
    }
  };
}
var Tp = window.THREE ? window.THREE : {
  AmbientLight: fy,
  DirectionalLight: dy,
  REVISION: za
}, zH = 170, QT = ZT("forceGraph", xb), HH = Object.assign.apply(Object, Id(["jsonUrl", "graphData", "numDimensions", "dagMode", "dagLevelDistance", "dagNodeFilter", "onDagError", "nodeRelSize", "nodeId", "nodeVal", "nodeResolution", "nodeColor", "nodeAutoColorBy", "nodeOpacity", "nodeVisibility", "nodeThreeObject", "nodeThreeObjectExtend", "nodePositionUpdate", "linkSource", "linkTarget", "linkVisibility", "linkColor", "linkAutoColorBy", "linkOpacity", "linkWidth", "linkResolution", "linkCurvature", "linkCurveRotation", "linkMaterial", "linkThreeObject", "linkThreeObjectExtend", "linkPositionUpdate", "linkDirectionalArrowLength", "linkDirectionalArrowColor", "linkDirectionalArrowRelPos", "linkDirectionalArrowResolution", "linkDirectionalParticles", "linkDirectionalParticleSpeed", "linkDirectionalParticleOffset", "linkDirectionalParticleWidth", "linkDirectionalParticleColor", "linkDirectionalParticleResolution", "linkDirectionalParticleThreeObject", "forceEngine", "d3AlphaDecay", "d3VelocityDecay", "d3AlphaMin", "ngraphPhysics", "warmupTicks", "cooldownTicks", "cooldownTime", "onEngineTick", "onEngineStop"].map(function(i) {
  return du({}, i, QT.linkProp(i));
}))), $H = Object.assign.apply(Object, Id(["refresh", "getGraphBbox", "d3Force", "d3ReheatSimulation", "emitParticle"].map(function(i) {
  return du({}, i, QT.linkMethod(i));
}))), Ph = ZT("renderObjs", KT), WH = Object.assign.apply(Object, Id(["width", "height", "backgroundColor", "showNavInfo", "enablePointerInteraction"].map(function(i) {
  return du({}, i, Ph.linkProp(i));
}))), qH = Object.assign.apply(Object, Id(["lights", "cameraPosition", "postProcessingComposer"].map(function(i) {
  return du({}, i, Ph.linkMethod(i));
})).concat([{
  graph2ScreenCoords: Ph.linkMethod("getScreenCoords"),
  screen2GraphCoords: Ph.linkMethod("getSceneCoords")
}])), XH = gd({
  props: yh(yh({
    nodeLabel: {
      default: "name",
      triggerUpdate: !1
    },
    linkLabel: {
      default: "name",
      triggerUpdate: !1
    },
    linkHoverPrecision: {
      default: 1,
      onChange: function(e, t) {
        return t.renderObjs.lineHoverPrecision(e);
      },
      triggerUpdate: !1
    },
    enableNavigationControls: {
      default: !0,
      onChange: function(e, t) {
        var n = t.renderObjs.controls();
        n && (n.enabled = e, e && n.domElement && n.domElement.dispatchEvent(new PointerEvent("pointerup")));
      },
      triggerUpdate: !1
    },
    enableNodeDrag: {
      default: !0,
      triggerUpdate: !1
    },
    onNodeDrag: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onNodeDragEnd: {
      default: function() {
      },
      triggerUpdate: !1
    },
    onNodeClick: {
      triggerUpdate: !1
    },
    onNodeRightClick: {
      triggerUpdate: !1
    },
    onNodeHover: {
      triggerUpdate: !1
    },
    onLinkClick: {
      triggerUpdate: !1
    },
    onLinkRightClick: {
      triggerUpdate: !1
    },
    onLinkHover: {
      triggerUpdate: !1
    },
    onBackgroundClick: {
      triggerUpdate: !1
    },
    onBackgroundRightClick: {
      triggerUpdate: !1
    },
    showPointerCursor: {
      default: !0,
      triggerUpdate: !1
    }
  }, HH), WH),
  methods: yh(yh({
    zoomToFit: function(e, t, n) {
      for (var r, s = arguments.length, a = new Array(s > 3 ? s - 3 : 0), o = 3; o < s; o++)
        a[o - 3] = arguments[o];
      return e.renderObjs.fitToBbox((r = e.forceGraph).getGraphBbox.apply(r, a), t, n), this;
    },
    pauseAnimation: function(e) {
      return e.animationFrameRequestId !== null && (cancelAnimationFrame(e.animationFrameRequestId), e.animationFrameRequestId = null), this;
    },
    resumeAnimation: function(e) {
      return e.animationFrameRequestId === null && this._animationCycle(), this;
    },
    _animationCycle: function(e) {
      e.enablePointerInteraction && (this.renderer().domElement.style.cursor = null), e.forceGraph.tickFrame(), e.renderObjs.tick(), e.animationFrameRequestId = requestAnimationFrame(this._animationCycle);
    },
    scene: function(e) {
      return e.renderObjs.scene();
    },
    // Expose scene
    camera: function(e) {
      return e.renderObjs.camera();
    },
    // Expose camera
    renderer: function(e) {
      return e.renderObjs.renderer();
    },
    // Expose renderer
    controls: function(e) {
      return e.renderObjs.controls();
    },
    // Expose controls
    tbControls: function(e) {
      return e.renderObjs.tbControls();
    },
    // To be deprecated
    _destructor: function() {
      this.pauseAnimation(), this.graphData({
        nodes: [],
        links: []
      });
    }
  }, $H), qH),
  stateInit: function(e) {
    var t = e.controlType, n = e.rendererConfig, r = e.extraRenderers, s = new xb();
    return {
      forceGraph: s,
      renderObjs: KT({
        controlType: t,
        rendererConfig: n,
        extraRenderers: r
      }).objects([s]).lights([new Tp.AmbientLight(13421772, Math.PI), new Tp.DirectionalLight(16777215, 0.6 * Math.PI)])
    };
  },
  init: function(e, t) {
    e.innerHTML = "", e.appendChild(t.container = document.createElement("div")), t.container.style.position = "relative";
    var n = document.createElement("div");
    t.container.appendChild(n), t.renderObjs(n);
    var r = t.renderObjs.camera(), s = t.renderObjs.renderer(), a = t.renderObjs.controls();
    a.enabled = !!t.enableNavigationControls, t.lastSetCameraZ = r.position.z;
    var o;
    t.container.appendChild(o = document.createElement("div")), o.className = "graph-info-msg", o.textContent = "", t.forceGraph.onLoading(function() {
      o.textContent = "Loading...";
    }).onFinishLoading(function() {
      o.textContent = "";
    }).onUpdate(function() {
      t.graphData = t.forceGraph.graphData(), r.position.x === 0 && r.position.y === 0 && r.position.z === t.lastSetCameraZ && t.graphData.nodes.length && (r.lookAt(t.forceGraph.position), t.lastSetCameraZ = r.position.z = Math.cbrt(t.graphData.nodes.length) * zH);
    }).onFinishUpdate(function() {
      if (t._dragControls) {
        var l = t.graphData.nodes.find(function(u) {
          return u.__initialFixedPos && !u.__disposeControlsAfterDrag;
        });
        l ? l.__disposeControlsAfterDrag = !0 : t._dragControls.dispose(), t._dragControls = void 0;
      }
      if (t.enableNodeDrag && t.enablePointerInteraction && t.forceEngine === "d3") {
        var c = t._dragControls = new tN(t.graphData.nodes.map(function(u) {
          return u.__threeObj;
        }).filter(function(u) {
          return u;
        }), r, s.domElement);
        c.addEventListener("dragstart", function(u) {
          var h = Xr(u.object);
          if (h) {
            a.enabled = !1, u.object.__initialPos = u.object.position.clone(), u.object.__prevPos = u.object.position.clone();
            var d = h.__data;
            !d.__initialFixedPos && (d.__initialFixedPos = {
              fx: d.fx,
              fy: d.fy,
              fz: d.fz
            }), !d.__initialPos && (d.__initialPos = {
              x: d.x,
              y: d.y,
              z: d.z
            }), ["x", "y", "z"].forEach(function(f) {
              return d["f".concat(f)] = d[f];
            }), s.domElement.classList.add("grabbable");
          }
        }), c.addEventListener("drag", function(u) {
          var h = Xr(u.object);
          if (h) {
            if (!u.object.hasOwnProperty("__graphObjType")) {
              var d = u.object.__initialPos, f = u.object.__prevPos, p = u.object.position;
              h.position.add(p.clone().sub(f)), f.copy(p), p.copy(d);
            }
            var _ = h.__data, g = h.position, m = {
              x: g.x - _.x,
              y: g.y - _.y,
              z: g.z - _.z
            };
            ["x", "y", "z"].forEach(function(x) {
              return _["f".concat(x)] = _[x] = g[x];
            }), t.forceGraph.d3AlphaTarget(0.3).resetCountdown(), _.__dragged = !0, t.onNodeDrag(_, m);
          }
        }), c.addEventListener("dragend", function(u) {
          var h = Xr(u.object);
          if (h) {
            delete u.object.__initialPos, delete u.object.__prevPos;
            var d = h.__data;
            d.__disposeControlsAfterDrag && (c.dispose(), delete d.__disposeControlsAfterDrag);
            var f = d.__initialFixedPos, p = d.__initialPos, _ = {
              x: p.x - d.x,
              y: p.y - d.y,
              z: p.z - d.z
            };
            if (f && (["x", "y", "z"].forEach(function(m) {
              var x = "f".concat(m);
              f[x] === void 0 && delete d[x];
            }), delete d.__initialFixedPos, delete d.__initialPos, d.__dragged && (delete d.__dragged, t.onNodeDragEnd(d, _))), t.forceGraph.d3AlphaTarget(0).resetCountdown(), t.enableNavigationControls) {
              var g;
              a.enabled = !0, a._status && ((g = a._onPointerCancel) === null || g === void 0 || g.call(a)), a.domElement && a.domElement.ownerDocument && a.domElement.ownerDocument.dispatchEvent(
                // simulate mouseup to ensure the controls don't take over after dragend
                new PointerEvent("pointerup", {
                  pointerType: "touch"
                })
              );
            }
            s.domElement.classList.remove("grabbable");
          }
        });
      }
    }), Tp.REVISION < 155 && (t.renderObjs.renderer().useLegacyLights = !1), t.renderObjs.hoverOrderComparator(function(l, c) {
      var u = Xr(l);
      if (!u)
        return 1;
      var h = Xr(c);
      if (!h)
        return -1;
      var d = function(p) {
        return p.__graphObjType === "node";
      };
      return d(h) - d(u);
    }).tooltipContent(function(l) {
      var c = Xr(l);
      return c && xt(t["".concat(c.__graphObjType, "Label")])(c.__data) || "";
    }).hoverDuringDrag(!1).onHover(function(l) {
      var c = Xr(l);
      if (c !== t.hoverObj) {
        var u = t.hoverObj ? t.hoverObj.__graphObjType : null, h = t.hoverObj ? t.hoverObj.__data : null, d = c ? c.__graphObjType : null, f = c ? c.__data : null;
        if (u && u !== d) {
          var p = t["on".concat(u === "node" ? "Node" : "Link", "Hover")];
          p && p(null, h);
        }
        if (d) {
          var _ = t["on".concat(d === "node" ? "Node" : "Link", "Hover")];
          _ && _(f, u === d ? h : null);
        }
        s.domElement.classList[(c && t["on".concat(d === "node" ? "Node" : "Link", "Click")] || !c && t.onBackgroundClick) && xt(t.showPointerCursor)(f) ? "add" : "remove"]("clickable"), t.hoverObj = c;
      }
    }).clickAfterDrag(!1).onClick(function(l, c) {
      var u = Xr(l);
      if (u) {
        var h = t["on".concat(u.__graphObjType === "node" ? "Node" : "Link", "Click")];
        h && h(u.__data, c);
      } else
        t.onBackgroundClick && t.onBackgroundClick(c);
    }).onRightClick(function(l, c) {
      var u = Xr(l);
      if (u) {
        var h = t["on".concat(u.__graphObjType === "node" ? "Node" : "Link", "RightClick")];
        h && h(u.__data, c);
      } else
        t.onBackgroundRightClick && t.onBackgroundRightClick(c);
    }), this._animationCycle();
  }
});
function Xr(i) {
  for (var e = i; e && !e.hasOwnProperty("__graphObjType"); )
    e = e.parent;
  return e;
}
function jH({ model: i, el: e }) {
  let t = document.createElement("div");
  e.appendChild(t);
  let n;
  new ResizeObserver((s) => {
    for (const a of s) {
      const o = a.contentRect.width;
      if (o > 0)
        if (n)
          n.width(o).height(o / 2);
        else {
          let l = JSON.parse(i.get("_model_rep"));
          n = new XH(t).graphData(l).nodeLabel("id").linkOpacity(1).linkAutoColorBy("value").linkDirectionalParticles(1).linkDirectionalParticleSpeed((c) => c.value * 1e-3).linkDirectionalParticleWidth(4).warmupTicks(100).cooldownTicks(0).width(o).height(o / 2), i.on("change:_model_rep", () => {
            n.graphData(JSON.parse(i.get("_model_rep")));
          }), i.on("msg:custom", (c) => {
            switch (c.type) {
              case "create_layout":
                let u = {};
                n.graphData().nodes.forEach((d) => {
                  u[d.id] = { x: d.x, y: d.y, z: d.z };
                }), i.send({ type: "layout", positions: u });
                break;
              case "load_layout":
                let h = c.positions;
                n.graphData().nodes.forEach((d) => {
                  let f = h[d.id];
                  d.fx = f.x, d.fy = f.y, d.fz = f.z;
                }), n.cooldownTicks(1), n.d3ReheatSimulation();
                break;
              default:
                console.log(`Unknown ${c}.`);
            }
          });
        }
    }
  }).observe(e);
}
const JH = { render: jH };
export {
  JH as default
};
