const pc = window.pc;
import { AvatarOpacityRenderer as pi, BaseModule as pt, calculateAvatarCapsule as Se, Debugger as E, loadAsset as H, getBoundingBox as Ee, UVScroll as _i, ConditionVerifier as mi, getLocalPlayer as _t, createLayer as Ae, setsEqual as fi, PlayerNameTag as gi, BaseSystem as yi, AudioProcessor as vi, registerModule as Si, createAvatarCollision as Ei, loadAssetFromUrl as Ai, loadFontAsset as Ti, Billboard as Ot, EntityStateEmitter as Kt, createFallbackGripBone as wi, updateFallbackGripBonePosition as xi } from "./core.mjs";
import { LocomotionStateType as x, AvatarFacingMode as K, ModuleName as q, AvatarHorizontalDirection as b, AvatarVerticalState as F, PostureType as S, PostEffectType as te, CameraEntityKeys as nt, XrLocomotionType as tt, HardwareType as bi, SystemName as Mi, XrInputDeviceType as $, XrUiAnchorType as Ii } from "./types.mjs";
import { resolveAssetPath as Vt } from "./config.mjs";
const ee = (a) => {
  let t;
  const e = /* @__PURE__ */ new Set(), i = (c, h) => {
    const u = typeof c == "function" ? c(t) : c;
    if (!Object.is(u, t)) {
      const d = t;
      t = h ?? (typeof u != "object" || u === null) ? u : Object.assign({}, t, u), e.forEach((p) => p(t, d));
    }
  }, n = () => t, o = { setState: i, getState: n, getInitialState: () => l, subscribe: (c) => (e.add(c), () => e.delete(c)) }, l = t = a(i, n, o);
  return o;
}, Pi = (a) => a ? ee(a) : ee;
function Ci(a) {
  return a && a.__esModule && Object.prototype.hasOwnProperty.call(a, "default") ? a.default : a;
}
const Li = (a) => (t, e, i) => {
  const n = i.subscribe;
  return i.subscribe = (r, o, l) => {
    let c = r;
    if (o) {
      const h = l?.equalityFn || Object.is;
      let u = r(i.getState());
      c = (d) => {
        const p = r(d);
        if (!h(u, p)) {
          const m = u;
          o(u = p, m);
        }
      }, l?.fireImmediately && o(u, u);
    }
    return n(c);
  }, a(t, e, i);
}, Ri = Li, Di = () => Pi()(
  Ri((a) => ({
    playerEntity: null,
    boundingBox: new pc.BoundingBox(),
    headHeight: 1.6,
    // Default view height in meters
    setHeadHeight: (t) => a({ headHeight: t }),
    viewAxes: new pc.Mat3(),
    setViewAxes: (t) => a({ viewAxes: t }),
    viewPosition: new pc.Vec3(0, 0, 0),
    setViewPosition: (t) => a({ viewPosition: t }),
    yaw: 0,
    pitch: 0,
    setYaw: (t) => a({ yaw: t }),
    setPitch: (t) => a({ pitch: t }),
    canInputRotateYawPitch: !0,
    setCanInputRotateYawPitch: (t) => a({ canInputRotateYawPitch: t }),
    avatarFacingMode: K.Movement,
    setAvatarFacingMode: (t) => a({ avatarFacingMode: t }),
    avatarFacingModeEnabled: !0,
    setAvatarFacingModeEnabled: (t) => a({ avatarFacingModeEnabled: t }),
    inputStates: {
      forward: !1,
      back: !1,
      left: !1,
      right: !1,
      up: !1,
      down: !1,
      jump: !1,
      sprint: !1,
      joystick: new pc.Vec2(0, 0)
    },
    setInputStates: (t) => a((e) => ({ inputStates: { ...e.inputStates, ...t } })),
    moveIntent: new pc.Vec3(0, 0, 0),
    setMoveIntent: (t) => a({ moveIntent: t }),
    locomotionState: x.Grounded,
    setLocomotionState: (t) => a({ locomotionState: t }),
    canFly: !1,
    setCanFly: (t) => a({ canFly: t }),
    canSprint: !0,
    setCanSprint: (t) => a({ canSprint: t }),
    canJump: !0,
    setCanJump: (t) => a({ canJump: t }),
    overriddenForward: null,
    setOverriddenForward: (t) => a({ overriddenForward: t }),
    canCameraSeeAvatar: !0,
    setCanCameraSeeAvatar: (t) => a({ canCameraSeeAvatar: t }),
    isXrActive: !1,
    setIsXrActive: (t) => a({ isXrActive: t }),
    walkSpeedMultiplier: 1,
    setWalkSpeedMultiplier: (t) => a({ walkSpeedMultiplier: t }),
    runSpeedMultiplier: 1,
    setRunSpeedMultiplier: (t) => a({ runSpeedMultiplier: t })
  }))
), Ni = {
  type: pc.BODYTYPE_DYNAMIC,
  mass: 60,
  linearDamping: 0,
  angularDamping: 0,
  linearFactor: new pc.Vec3(1, 1, 1),
  angularFactor: new pc.Vec3(0, 0, 0),
  friction: 0,
  restitution: 0
}, ie = (a) => Symbol.iterator in a, ne = (a) => (
  // HACK: avoid checking entries type
  "entries" in a
), se = (a, t) => {
  const e = a instanceof Map ? a : new Map(a.entries()), i = t instanceof Map ? t : new Map(t.entries());
  if (e.size !== i.size)
    return !1;
  for (const [n, s] of e)
    if (!Object.is(s, i.get(n)))
      return !1;
  return !0;
}, Oi = (a, t) => {
  const e = a[Symbol.iterator](), i = t[Symbol.iterator]();
  let n = e.next(), s = i.next();
  for (; !n.done && !s.done; ) {
    if (!Object.is(n.value, s.value))
      return !1;
    n = e.next(), s = i.next();
  }
  return !!n.done && !!s.done;
};
function Pt(a, t) {
  return Object.is(a, t) ? !0 : typeof a != "object" || a === null || typeof t != "object" || t === null || Object.getPrototypeOf(a) !== Object.getPrototypeOf(t) ? !1 : ie(a) && ie(t) ? ne(a) && ne(t) ? se(a, t) : Oi(a, t) : se(
    { entries: () => Object.entries(a) },
    { entries: () => Object.entries(t) }
  );
}
class Ct {
  _avatar = null;
  _store = null;
  _unsubscribes = [];
  _module;
  constructor(t, e) {
    this._module = t, e && (this._store = e, this._setupStoreSubscriptions());
  }
  setActiveAvatar(t) {
    const e = this._avatar;
    this._avatar = t, this._onAvatarChanged(t, e);
  }
  _setupStoreSubscriptions() {
  }
  _onAvatarChanged(t, e) {
  }
  _addSubscription(t, e, i) {
    if (!this._store) return;
    const n = this._store.subscribe(t, e, i);
    this._unsubscribes.push(n);
  }
  destroy() {
    this._unsubscribes.forEach((t) => t()), this._unsubscribes = [], this._avatar = null, this._store = null;
  }
}
class Vi extends Ct {
  _renderer;
  constructor(t, e) {
    super(t), this._renderer = new pi(e), this._avatar && this._renderer.setAvatar(this._avatar);
  }
  _onAvatarChanged(t) {
    this._renderer.setAvatar(t);
  }
  updateProximityOpacity(t, e, i) {
    const n = this._renderer.getOpacityFromDistance(e, i);
    this._renderer.updateOpacity(t, n);
  }
}
class Fi {
  _registry = /* @__PURE__ */ new Map();
  registerHandler(t, e) {
    if (this._registry.has(t))
      throw new Error(`Handler with name '${t}' is already registered`);
    this._registry.set(t, e);
  }
  unregisterHandler(t) {
    const e = this._registry.get(t);
    e && (e.destroy(), this._registry.delete(t));
  }
  getHandler(t) {
    return this._registry.get(t);
  }
  setActiveAvatar(t) {
    this._registry.forEach((e) => {
      e.setActiveAvatar(t);
    });
  }
  destroy() {
    this._registry.forEach((t) => {
      t.destroy();
    }), this._registry.clear();
  }
}
class ki extends pt {
  /** @hidden */
  static moduleName = q.LocalAvatar;
  _centerAnchor = new pc.Entity("CenterAnchor");
  _avatars = /* @__PURE__ */ new Map();
  _avatarOrders = [];
  _activeAvatar = null;
  _isSetup = !1;
  _avatarContainerEntity = null;
  _switchController = null;
  _setupPromise = null;
  _handlers = new Fi();
  constructor(t, e) {
    super(t), e = { ...this._getDefaultOptions(), ...e }, this._setupOptions(e), this._registerHandlers();
  }
  _registerHandlers() {
    this._handlers.registerHandler(
      "opacity",
      new Vi(this, {
        nearClip: 0.1,
        smoothSpeed: 6
      })
    );
  }
  get _opacityHandler() {
    return this._handlers.getHandler("opacity");
  }
  get avatars() {
    return this._avatars;
  }
  get activeAvatar() {
    return this._activeAvatar;
  }
  get avatarContainerEntity() {
    return this._avatarContainerEntity;
  }
  _getAvatar(t) {
    return this._avatars.get(t);
  }
  _hasAvatar(t) {
    return this._avatars.has(t);
  }
  _getDefaultOptions() {
    return Is;
  }
  _setupOptions(t) {
    t.avatars && t.avatars.forEach((e) => this.addAvatar(e));
  }
  /** @hidden */
  async setupAvatars(t) {
    if (this._isSetup)
      throw Error("Avatar module is already set up.");
    this._avatarContainerEntity = new pc.Entity("AvatarEntity"), this._setupPromise = this._performSetup(t), t.addChild(this._avatarContainerEntity);
    try {
      await this._setupPromise;
    } finally {
      this._setupPromise = null;
    }
  }
  async _performSetup(t) {
    this._isSetup = !0;
    let e = null;
    if (this._avatarOrders.length > 0 && (e = this._getAvatar(this._avatarOrders[0]) || null), !e)
      throw new Error("No initial avatar provided and no configured avatar found.");
    await this.setActiveAvatar(e), t.addChild(this._centerAnchor);
  }
  _activateAvatar(t) {
    if (!t.entity)
      throw new Error(`Avatar entity for '${t.name}' is not created.`);
    if (!this._avatarContainerEntity)
      throw new Error("Avatar entity container is not initialized.");
    this._avatarContainerEntity.addChild(t.entity), this._updatePlayerBoundingBox(t), this._handlers.setActiveAvatar(t);
    const e = this._getAvatarStates();
    e ? t.activate?.(e) : t.activate?.();
  }
  _updatePlayerBoundingBox(t) {
    const e = this._playerBoundingBox, i = this.system.playerEntity;
    if (!e || !i) return;
    const n = i.getPosition(), { capsuleHeight: s, capsuleRadius: r } = Se(
      t.boundingBox,
      n
    );
    this._centerAnchor.setLocalPosition(0, s / 2, 0), e.halfExtents.set(r, s / 2, r), e.center.copy(t.boundingBox.center), this._updateBoundingBoxCenter();
  }
  async _createAvatar(t) {
    if (!!!this._getAvatar(t.name))
      throw new Error(`'${t.name}' is not configured in the avatar module.`);
    const i = this._getAvatar(t.name);
    if (i && i.entity)
      return i.entity;
    if (await t.create(this.pcApp), !t.entity)
      throw new Error("Avatar entity could not be created by the factory.");
    return t.entity;
  }
  _deactivatePreviousAvatar(t) {
    if (!t.entity) return;
    const e = t.entity;
    this._avatarContainerEntity && this._avatarContainerEntity.removeChild(e), t.deactivate?.();
  }
  async setActiveAvatarByName(t) {
    const e = this._getAvatar(t);
    if (!e)
      throw new Error(`Avatar with name '${t}' is not configured.`);
    return this.setActiveAvatar(e);
  }
  async setActiveAvatar(t) {
    if (!this._isSetup)
      throw new Error("Avatar module is not set up. Please call setupAvatars() first.");
    this._setupPromise && await this._setupPromise, this._switchController && this._switchController.abort();
    const e = new AbortController();
    this._switchController = e;
    try {
      const i = await this._createAvatar(t);
      if (e.signal.aborted)
        return null;
      const n = t !== this._activeAvatar ? this._activeAvatar : null;
      return this.system.emit("local-avatar:before-change", { previousAvatar: n, newAvatar: t }), this._activeAvatar = t, this._activateAvatar(t), this.system.emit("local-avatar:changed", { previousAvatar: n, newAvatar: t }), n && this._deactivatePreviousAvatar(n), this._switchController = null, i;
    } catch (i) {
      throw this._switchController = null, i;
    }
  }
  addAvatar(t) {
    return this._hasAvatar(t.name) ? (E.error(`Avatar with name ${t.name} already exists.`), null) : (this._avatars.set(t.name, t), this._avatarOrders.push(t.name), t.name);
  }
  removeAvatar(t) {
    this.removeAvatarByName(t.name);
  }
  removeAvatarByName(t) {
    if (!this._getAvatar(t)) {
      E.warn(`Avatar with name ${t} does not exist.`);
      return;
    }
    if (this._activeAvatar?.name === t) {
      E.warn(`Cannot remove active avatar '${t}'.`);
      return;
    }
    this._avatars.delete(t), this._avatarOrders = this._avatarOrders.filter((i) => i !== t);
  }
  _updateCameraProximityOpacity(t) {
    !this._activeAvatar || !this._playerBoundingBox || this._opacityHandler.updateProximityOpacity(t, this._viewPosition, this._playerBoundingBox);
  }
  _updateBoundingBoxCenter() {
    if (!this._playerBoundingBox) return;
    const t = this._playerBoundingBox, e = this._centerAnchor.getPosition();
    t.center.copy(e);
  }
  _getAvatarStates() {
    return null;
  }
  getBoneEntity(t) {
    return this._activeAvatar ? this._activeAvatar.getBoneEntity ? this._activeAvatar.getBoneEntity?.(t) || null : (E.warn("Active avatar does not support getBoneEntity method."), null) : (E.warn("No active avatar. Can not get bone entity."), null);
  }
  /** @hidden */
  update(t) {
    if (this._activeAvatar && this._activeAvatar.update) {
      const e = this._isIntenseMoving();
      this._activeAvatar.update(t, e);
    }
    this._updateBoundingBoxCenter(), this._updateCameraProximityOpacity(t);
  }
  /** @hidden */
  destroy() {
    this._handlers.destroy();
  }
}
function Bi(a, t) {
  const e = Object.entries(t).map(([i, n]) => new Promise((s, r) => {
    const o = new pc.Asset(i, "container", {
      url: Vt("local-player", n)
    });
    o.ready(() => {
      s({ stateName: i, asset: o });
    }), o.once("error", (l) => {
      r(`Failed to load animation asset: ${n}. Error: ${l}`);
    }), a.assets.add(o), a.assets.load(o);
  }));
  return Promise.all(e);
}
const xt = [
  "hips",
  "spine",
  "chest",
  "upperChest",
  "neck",
  "head",
  "leftEye",
  "rightEye",
  "jaw",
  "leftUpperLeg",
  "leftLowerLeg",
  "leftFoot",
  "leftToes",
  "rightUpperLeg",
  "rightLowerLeg",
  "rightFoot",
  "rightToes",
  "leftShoulder",
  "leftUpperArm",
  "leftLowerArm",
  "leftHand",
  "rightShoulder",
  "rightUpperArm",
  "rightLowerArm",
  "rightHand",
  "leftThumbMetacarpal",
  "leftThumbProximal",
  "leftThumbDistal",
  "leftIndexProximal",
  "leftIndexIntermediate",
  "leftIndexDistal",
  "leftMiddleProximal",
  "leftMiddleIntermediate",
  "leftMiddleDistal",
  "leftRingProximal",
  "leftRingIntermediate",
  "leftRingDistal",
  "leftLittleProximal",
  "leftLittleIntermediate",
  "leftLittleDistal",
  "rightThumbMetacarpal",
  "rightThumbProximal",
  "rightThumbDistal",
  "rightIndexProximal",
  "rightIndexIntermediate",
  "rightIndexDistal",
  "rightMiddleProximal",
  "rightMiddleIntermediate",
  "rightMiddleDistal",
  "rightRingProximal",
  "rightRingIntermediate",
  "rightRingDistal",
  "rightLittleProximal",
  "rightLittleIntermediate",
  "rightLittleDistal"
], It = {
  hips: null,
  spine: "hips",
  chest: "spine",
  upperChest: "chest",
  neck: "upperChest",
  head: "neck",
  leftEye: "head",
  rightEye: "head",
  jaw: "head",
  leftUpperLeg: "hips",
  leftLowerLeg: "leftUpperLeg",
  leftFoot: "leftLowerLeg",
  leftToes: "leftFoot",
  rightUpperLeg: "hips",
  rightLowerLeg: "rightUpperLeg",
  rightFoot: "rightLowerLeg",
  rightToes: "rightFoot",
  leftShoulder: "upperChest",
  leftUpperArm: "leftShoulder",
  leftLowerArm: "leftUpperArm",
  leftHand: "leftLowerArm",
  rightShoulder: "upperChest",
  rightUpperArm: "rightShoulder",
  rightLowerArm: "rightUpperArm",
  rightHand: "rightLowerArm",
  leftThumbMetacarpal: "leftHand",
  leftThumbProximal: "leftThumbMetacarpal",
  leftThumbDistal: "leftThumbProximal",
  leftIndexProximal: "leftHand",
  leftIndexIntermediate: "leftIndexProximal",
  leftIndexDistal: "leftIndexIntermediate",
  leftMiddleProximal: "leftHand",
  leftMiddleIntermediate: "leftMiddleProximal",
  leftMiddleDistal: "leftMiddleIntermediate",
  leftRingProximal: "leftHand",
  leftRingIntermediate: "leftRingProximal",
  leftRingDistal: "leftRingIntermediate",
  leftLittleProximal: "leftHand",
  leftLittleIntermediate: "leftLittleProximal",
  leftLittleDistal: "leftLittleIntermediate",
  rightThumbMetacarpal: "rightHand",
  rightThumbProximal: "rightThumbMetacarpal",
  rightThumbDistal: "rightThumbProximal",
  rightIndexProximal: "rightHand",
  rightIndexIntermediate: "rightIndexProximal",
  rightIndexDistal: "rightIndexIntermediate",
  rightMiddleProximal: "rightHand",
  rightMiddleIntermediate: "rightMiddleProximal",
  rightMiddleDistal: "rightMiddleIntermediate",
  rightRingProximal: "rightHand",
  rightRingIntermediate: "rightRingProximal",
  rightRingDistal: "rightRingIntermediate",
  rightLittleProximal: "rightHand",
  rightLittleIntermediate: "rightLittleProximal",
  rightLittleDistal: "rightLittleIntermediate"
}, dt = {
  hips: "hips",
  spine: "spine",
  chest: "chest",
  upperChest: "upperChest",
  neck: "neck",
  head: "head",
  leftEye: "leftEye",
  leftShoulder: "leftShoulder",
  leftUpperArm: "leftUpperArm",
  leftLowerArm: "leftLowerArm",
  leftHand: "leftHand",
  leftUpperLeg: "leftUpperLeg",
  leftLowerLeg: "leftLowerLeg",
  leftFoot: "leftFoot",
  leftToes: "leftToes",
  leftThumbMetacarpal: "leftThumbMetacarpal",
  leftThumbProximal: "leftThumbProximal",
  leftThumbDistal: "leftThumbDistal",
  leftIndexProximal: "leftIndexProximal",
  leftIndexIntermediate: "leftIndexIntermediate",
  leftIndexDistal: "leftIndexDistal",
  leftMiddleProximal: "leftMiddleProximal",
  leftMiddleIntermediate: "leftMiddleIntermediate",
  leftMiddleDistal: "leftMiddleDistal",
  leftRingProximal: "leftRingProximal",
  leftRingIntermediate: "leftRingIntermediate",
  leftRingDistal: "leftRingDistal",
  leftLittleProximal: "leftLittleProximal",
  leftLittleIntermediate: "leftLittleIntermediate",
  leftLittleDistal: "leftLittleDistal",
  rightEye: "rightEye",
  rightUpperArm: "rightUpperArm",
  rightShoulder: "rightShoulder",
  rightLowerArm: "rightLowerArm",
  rightHand: "rightHand",
  rightUpperLeg: "rightUpperLeg",
  rightLowerLeg: "rightLowerLeg",
  rightFoot: "rightFoot",
  rightToes: "rightToes",
  rightThumbMetacarpal: "rightThumbMetacarpal",
  rightThumbProximal: "rightThumbProximal",
  rightThumbDistal: "rightThumbDistal",
  rightIndexProximal: "rightIndexProximal",
  rightIndexIntermediate: "rightIndexIntermediate",
  rightIndexDistal: "rightIndexDistal",
  rightMiddleProximal: "rightMiddleProximal",
  rightMiddleIntermediate: "rightMiddleIntermediate",
  rightMiddleDistal: "rightMiddleDistal",
  rightRingProximal: "rightRingProximal",
  rightRingIntermediate: "rightRingIntermediate",
  rightRingDistal: "rightRingDistal",
  rightLittleProximal: "rightLittleProximal",
  rightLittleIntermediate: "rightLittleIntermediate",
  rightLittleDistal: "rightLittleDistal"
}, Te = {
  leftThumbProximal: "leftThumbMetacarpal",
  leftThumbIntermediate: "leftThumbProximal",
  rightThumbProximal: "rightThumbMetacarpal",
  rightThumbIntermediate: "rightThumbProximal"
}, we = {
  a: "aa",
  e: "ee",
  i: "ih",
  o: "oh",
  u: "ou",
  blink: "blink",
  joy: "happy",
  angry: "angry",
  sorrow: "sad",
  fun: "relaxed",
  lookup: "lookUp",
  lookdown: "lookDown",
  lookleft: "lookLeft",
  lookright: "lookRight",
  blink_l: "blinkLeft",
  blink_r: "blinkRight",
  neutral: "neutral"
}, kt = {
  Aa: "aa",
  Ih: "ih",
  Ou: "ou",
  Ee: "ee",
  Oh: "oh",
  Blink: "blink",
  Happy: "happy",
  Angry: "angry",
  Sad: "sad",
  Relaxed: "relaxed",
  LookUp: "lookUp",
  Surprised: "surprised",
  LookDown: "lookDown",
  LookLeft: "lookLeft",
  LookRight: "lookRight",
  BlinkLeft: "blinkLeft",
  BlinkRight: "blinkRight",
  Neutral: "neutral"
}, Bt = /* @__PURE__ */ new Set(["1.0", "1.0-beta"]), Ui = {
  _Color: "color",
  _EmissionColor: "emissionColor",
  _ShadeColor: "shadeColor",
  _RimColor: "rimColor",
  _OutlineColor: "outlineColor"
}, Hi = {
  isMeshStandardMaterial: {
    color: "color",
    emissionColor: "emissive"
  },
  isMeshBasicMaterial: {
    color: "color"
  },
  isMToonMaterial: {
    color: "color",
    emissionColor: "emissive",
    outlineColor: "outlineColorFactor",
    matcapColor: "matcapFactor",
    rimColor: "parametricRimColorFactor",
    shadeColor: "shadeColorFactor"
  }
}, zi = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  POSSIBLE_SPEC_VERSIONS: Bt,
  VRMExpressionPresetName: kt,
  VRMHumanBoneList: xt,
  VRMHumanBoneParentMap: It,
  VRMRigMap: dt,
  expressionMateriaPropertyNameMapMap: Hi,
  thumbBoneNameMap: Te,
  v0ExpressionMaterialColorMap: Ui,
  v0v1PresetNameMap: we
}, Symbol.toStringTag, { value: "Module" }));
class Gi {
  constructor(t) {
    this.duration = 0, this.restHipsPosition = new t.Vec3(), this.humanoidTracks = {
      translation: /* @__PURE__ */ new Map(),
      rotation: /* @__PURE__ */ new Map()
    }, this.expressionTracks = {
      preset: /* @__PURE__ */ new Map(),
      custom: /* @__PURE__ */ new Map()
    }, this.lookAtTrack = null;
  }
}
function re(a, t) {
  const e = a.length, i = [];
  let n = [], s = 0;
  for (let r = 0; r < e; r++) {
    const o = a[r];
    s <= 0 && (s = t, n = [], i.push(n)), n.push(o), s--;
  }
  return i;
}
function Wi(a, t, e) {
  const i = e.data, n = 1 / (i[3] * t.x + i[7] * t.y + i[11] * t.z + i[15]), s = (i[0] * t.x + i[4] * t.y + i[8] * t.z + i[12]) * n, r = (i[1] * t.x + i[5] * t.y + i[9] * t.z + i[13]) * n, o = (i[2] * t.x + i[6] * t.y + i[10] * t.z + i[14]) * n;
  return new a.Vec3(s, r, o);
}
function xe(a, t) {
  const e = t.inputs.map(
    (s) => new a.AnimData(s.components, s.data)
  ), i = t.outputs.map(
    (s) => new a.AnimData(s.components, s.data)
  ), n = t.curves.map((s) => {
    const r = s.paths.map((o) => {
      const l = o;
      return {
        component: l.component,
        entityPath: [...l.entityPath],
        propertyPath: [...l.propertyPath]
      };
    });
    return new a.AnimCurve(r, s.input, s.output, s.interpolation);
  });
  return new a.AnimTrack(t.name, t.duration, e, i, n);
}
const ji = /* @__PURE__ */ new Set(["1.0", "1.0-draft"]), Yi = new Set(Object.values(kt));
class Xi {
  constructor(t) {
    this.pcRef = t;
  }
  loadVRMA(t) {
    var e, i, n;
    const s = t.resource, r = s.data.gltf, o = r.extensionsUsed;
    if (o == null || o.indexOf("VRMC_vrm_animation") == -1) {
      console.warn("CreateVRMAnimation: Please check. It is not a vrma.");
      return;
    }
    const l = (e = r.extensions) == null ? void 0 : e.VRMC_vrm_animation;
    if (l == null) {
      console.warn("CreateVRMAnimation: Please check. It is not a vrma.");
      return;
    }
    const c = l.specVersion;
    if (!ji.has(c)) {
      console.warn(`CreateVRMAnimation: Unknown VRMC_vrm_animation spec version: ${c}`);
      return;
    }
    c === "1.0-draft" && console.warn(
      "CreateVRMAnimation: Using a draft spec version: 1.0-draft. Some behaviors may be different. Consider updating the animation file."
    );
    const h = s.data.nodes, u = this._createNodeMap(r, l), d = this._createBoneWorldMatrixMap(h, l), p = (n = (i = l.humanoid) == null ? void 0 : i.humanBones.hips) == null ? void 0 : n.node, m = p != null ? h[p] : null, f = m ? m.getPosition() : new this.pcRef.Vec3();
    return s.data.animations.map((v, y) => {
      const T = r.animations[y], A = this._parseAnimation(v, T, u, d);
      return A.restHipsPosition = f, A;
    });
  }
  _createNodeMap(t, e) {
    var i, n, s, r;
    const o = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), h = t.nodes;
    h && h.forEach((f, _) => {
      f.name && o.set(f.name, _);
    });
    const u = (i = e.humanoid) == null ? void 0 : i.humanBones;
    u && Object.entries(u).forEach(([f, _]) => {
      const g = _?.node;
      g != null && l.set(g, f);
    });
    const d = (n = e.expressions) == null ? void 0 : n.preset;
    d && Object.entries(d).forEach(([f, _]) => {
      const g = _?.node;
      g != null && c.set(g, f);
    });
    const p = (s = e.expressions) == null ? void 0 : s.custom;
    p && Object.entries(p).forEach(([f, _]) => {
      const { node: g } = _;
      c.set(g, f);
    });
    const m = ((r = e.lookAt) == null ? void 0 : r.node) ?? null;
    return { origNameToHumanoidIndex: o, humanoidIndexToName: l, expressionsIndexToName: c, lookAtIndex: m };
  }
  //In THREE, it's async
  _createBoneWorldMatrixMap(t, e) {
    var i;
    const n = /* @__PURE__ */ new Map();
    if (e.humanoid == null)
      return n;
    for (const [s, r] of Object.entries(e.humanoid.humanBones)) {
      const o = r?.node;
      if (o != null) {
        const l = t[o];
        n.set(s, l.getWorldTransform());
        const c = new this.pcRef.Mat4();
        s === "hips" && n.set("hipsParent", ((i = l.parent) == null ? void 0 : i.getWorldTransform()) ?? c);
      }
    }
    return n;
  }
  _parseAnimation(t, e, i, n) {
    const { inputs: s, outputs: r, curves: o } = xe(this.pcRef, t), l = e.channels, c = new Gi(this.pcRef);
    return c.duration = t.duration, l.forEach((h, u) => {
      const { node: d, path: p } = h.target, m = o[u], f = s[m.input], _ = r[m.output];
      if (d == null)
        return;
      const g = i.humanoidIndexToName.get(d);
      if (g != null) {
        let y = It[g];
        for (; y != null && n.get(y) == null; )
          y = It[y];
        if (y ?? (y = "hipsParent"), m.paths.forEach((T) => {
          const A = T, w = A.entityPath.map((M) => {
            const P = i.origNameToHumanoidIndex.get(M);
            if (P) {
              const C = i.humanoidIndexToName.get(P);
              return C || g;
            } else
              return g;
          });
          A.entityPath = w;
        }), p === "translation")
          if (g !== "hips")
            console.warn(
              `The loading animation contains a translation track for ${g}, which is not permitted in the VRMC_vrm_animation spec. ignoring the track`
            );
          else {
            const T = n.get("hipsParent"), A = re(_.data, 3).flatMap((C) => {
              let L = new this.pcRef.Vec3(C[0], C[1], C[2]);
              return L = Wi(this.pcRef, L, T), [L.x, L.y, L.z];
            }), w = new Float32Array(A), M = new this.pcRef.AnimData(_.components, w), P = { curve: m, input: f, output: M };
            c.humanoidTracks.translation.set(g, P);
          }
        else if (p === "rotation") {
          const T = n.get(g), A = n.get(y), w = new this.pcRef.Quat();
          w.setFromMat4(T), w.invert();
          const M = new this.pcRef.Quat();
          M.setFromMat4(A);
          const P = re(_.data, 4).flatMap((k) => {
            let D = new this.pcRef.Quat(k[0], k[1], k[2], k[3]);
            return D = D.mul2(M, D).mul(w), [D.x, D.y, D.z, D.w];
          }), C = new Float32Array(P), L = new this.pcRef.AnimData(_.components, C), z = { curve: m, input: f, output: L };
          c.humanoidTracks.rotation.set(g, z);
        } else
          throw new Error(`Invalid path "${p}"`);
        return;
      }
      const v = i.expressionsIndexToName.get(d);
      if (v != null) {
        if (p === "translation") {
          const y = new Float32Array(_.data.length / 3);
          for (let A = 0; A < y.length; A++)
            y[A] = _.data[3 * A];
          const T = {
            times: f.data,
            values: y,
            loop: !0
          };
          Yi.has(v) ? c.expressionTracks.preset.set(
            v,
            T
          ) : c.expressionTracks.custom.set(v, T);
        } else
          throw new Error(`Invalid path "${p}"`);
        return;
      }
      if (d === i.lookAtIndex)
        if (p === "rotation") {
          const y = { curve: m, input: f, output: _ };
          c.lookAtTrack = y;
        } else
          throw new Error(`Invalid path "${p}"`);
    }), c;
  }
}
class Zi {
  constructor(t, e, i, n, s, r = "v0") {
    this.pcRef = t, this.vrmAnimation = n, this.stateName = e, this.name = i, this.humanoid = s, this.metaVersion = r;
  }
  get result() {
    return this.createVRMAnimTrack();
  }
  createVRMAnimTrack() {
    const t = [], e = [], i = [], n = [], s = this._createHumanoidTracks();
    n.push(...s.translation.values()), n.push(...s.rotation.values());
    const r = this._createLookAtTracks() ?? this._resetLookAtTrack(n[0].input);
    n.push(...r.values());
    for (let l = 0; l < n.length; l++) {
      t.push(n[l].input), e.push(n[l].output);
      const c = new this.pcRef.AnimCurve(
        n[l].curve.paths,
        l,
        l,
        n[l].curve.interpolation
      );
      i.push(c), n[l].curve.paths.forEach((u) => {
        const d = u, p = d.entityPath;
        p.unshift("SkeletonRoot");
        const m = p.map((f) => {
          var _;
          const v = dt[f], y = (_ = this.humanoid.getRawBoneNode(v)) == null ? void 0 : _.name;
          return !v || !y ? f : y;
        });
        d.entityPath = m;
      });
    }
    const o = new this.pcRef.AnimEvents([
      { name: `anim-track:${this.stateName}-start`, time: 0 }
    ]);
    return new this.pcRef.AnimTrack(
      this.name,
      this.vrmAnimation.duration,
      t,
      e,
      i,
      o
    );
  }
  _createHumanoidTracks() {
    var t, e, i;
    const n = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
    for (const [r, o] of this.vrmAnimation.humanoidTracks.translation.entries())
      if (((t = this.humanoid.getNormalizedBoneNode(r)) == null ? void 0 : t.name) != null) {
        const c = this.vrmAnimation.restHipsPosition.y, d = (((e = this.humanoid.normalizedHumanBones.hips) == null ? void 0 : e.node.getLocalPosition()) || new this.pcRef.Vec3()).y / c, p = o.output.data.map(
          (g, v) => (this.metaVersion === "v0" && v % 3 !== 1 ? -g : g) * d
        ), m = new Float32Array(p), f = new this.pcRef.AnimData(o.output.components, m), _ = {
          curve: o.curve,
          input: o.input,
          output: f
        };
        n.set(r, _);
      }
    for (const [r, o] of this.vrmAnimation.humanoidTracks.rotation.entries())
      if (((i = this.humanoid.getNormalizedBoneNode(r)) == null ? void 0 : i.name) != null) {
        const c = o.output.data.map(
          (p, m) => this.metaVersion === "v0" && m % 2 === 0 ? -p : p
        ), h = new Float32Array(c), u = new this.pcRef.AnimData(o.output.components, h), d = {
          curve: o.curve,
          input: o.input,
          output: u
        };
        s.set(r, d);
      }
    return { translation: n, rotation: s };
  }
  _createLookAtTracks() {
    const t = this.vrmAnimation.lookAtTrack;
    if (!t)
      return null;
    const e = /* @__PURE__ */ new Map(), i = ["leftEye", "rightEye"], n = (c, h) => {
      const u = h % 4, d = t.output.data[h + 3 - u], p = d === 0 ? 1 : d;
      switch (u) {
        case 0:
          return c / p * 0.06;
        case 1:
          return c / p * 0.08;
        default:
          return 1;
      }
    }, s = t.output.data.map((c, h) => (this.metaVersion === "v0" && h % 4 == 0 ? -c : c) * n(c, h)), r = new Float32Array(s), o = new this.pcRef.AnimData(t.output.components, r), l = t.curve;
    return l.paths.forEach((c) => {
      const h = c;
      i.forEach((u) => {
        h.entityPath = [u];
        const d = [{ ...h }], m = {
          curve: new this.pcRef.AnimCurve(
            d,
            l.input,
            l.output,
            l.interpolation
          ),
          input: t.input,
          output: o
        };
        e.set(u, m);
      });
    }), e;
  }
  _resetLookAtTrack(t) {
    const e = /* @__PURE__ */ new Map(), i = ["leftEye", "rightEye"], n = new Float32Array(t.data.length * 4);
    for (let r = 0; r < n.length; r++)
      r % 4 === 3 && (n[r] = 1);
    const s = new this.pcRef.AnimData(4, n);
    return i.forEach((r) => {
      const o = {
        entityPath: [r],
        component: "graph",
        propertyPath: ["localRotation"]
      }, c = {
        curve: new this.pcRef.AnimCurve([{ ...o }], 0, 0, 1),
        input: t,
        output: s
      };
      e.set(r, c);
    }), e;
  }
}
class $i {
  constructor(t, e, i, n = "v0", s, r) {
    this.pcRef = t, this.animationAsset = e, this.humanoid = i, this.metaVersion = n, this.extraSettings = s, this.origAnimTrack = r;
  }
  get result() {
    return this.createViverseAnimTrack();
  }
  createViverseAnimTrack() {
    var t;
    const e = ((t = this.humanoid.rawHumanBones.hips) == null ? void 0 : t.node.getPosition()) || new this.pcRef.Vec3(), i = e.y, n = Math.abs(i - 0), s = e.z, r = Math.abs(s - 0), o = {}, l = {};
    let { motionHipsHeight: c, negativeZAnimNames: h } = this.extraSettings;
    h || (h = []);
    const u = xe(this.pcRef, this.origAnimTrack), p = h.includes(this.origAnimTrack.name) ? "v1" : "v0";
    let m = 0;
    if (this.animationAsset.asset.type === "container") {
      const v = this.animationAsset.asset.resource.data.nodes.find(
        (y) => y.name === dt.hips
      );
      v && (m = v.getLocalPosition().y);
    }
    c = c || m || 0.855;
    const f = n / c;
    u.curves.forEach((g) => {
      g.paths.forEach((v) => {
        const y = v, T = y.propertyPath.find((w) => w === "localPosition"), A = y.entityPath[y.entityPath.length - 1] === dt.hips;
        T && A && !o[g.output] && (o[g.output] = !0);
      });
    }), u.curves.forEach((g) => {
      let v = !1;
      g.paths.forEach((y) => {
        const T = y, A = T.entityPath.map((w) => {
          var M;
          const C = dt[w], L = (M = this.humanoid.getRawBoneNode(C)) == null ? void 0 : M.name;
          return !C || !L ? w : L;
        });
        T.entityPath = A, T.propertyPath.find((w) => w === "localScale") && (v = !0);
      }), v && !l[g.output] && (l[g.output] = !0);
    }), u.outputs.forEach((g, v) => {
      const y = l[v];
      if (g.components === 3) {
        if (!y) {
          const T = g.data.map((A, w) => {
            let M = A;
            return this.metaVersion === p && w % 3 !== 1 && (M *= -1), o[v] && w % 3 === 1 && (this.animationAsset.removeY || this.animationAsset.removeUpperY && A * f > n) ? n : o[v] && w % 3 === 2 && this.animationAsset.removeZ ? r : M * f;
          });
          g._data = T;
        }
      } else if (g.components === 4) {
        const T = g.data.map((A, w) => this.metaVersion === p && w % 2 === 0 ? -A : A);
        g._data = T;
      }
    });
    const _ = new this.pcRef.AnimEvents([
      { name: `anim-track:${this.animationAsset.stateName}-start`, time: 0 }
    ]);
    return u.events = _, u;
  }
}
class qi {
  constructor(t) {
    this.preset = t.expressionTracks.preset, this.custom = t.expressionTracks.custom;
  }
  createCustomExpression() {
    console.log(this.custom);
  }
}
function Ji(a, t, e, i, {
  motionHipsHeight: n,
  negativeZAnimNames: s
} = {}) {
  const r = { motionHipsHeight: n, negativeZAnimNames: s };
  return console.warn(
    "Warning: createVRMAnimation is deprecated. Please use createVRMAnimResources instead."
  ), be(a, t, e, i, r);
}
function be(a, t, e, i, n = {}) {
  var s, r;
  if (!e) {
    console.error('CreateVRMAnimResources: Please provide "vrm asset".');
    return;
  }
  if (!t) {
    console.error('CreateVRMAnimResources: Please provide "animation assets".');
    return;
  }
  if (!i) {
    console.error('CreateVRMAnimResources: Please provide "humanoid" or "asset and entity".');
    return;
  }
  const o = e.resource, l = (s = o.data.gltf.extensions) == null ? void 0 : s.VRMC_vrm, c = (r = o.data.gltf.extensions) == null ? void 0 : r.VRM, h = l ? "v1" : c ? "v0" : null, u = (p, m) => p == "animation" ? !1 : p == "container" ? !!(m && m.includes("VRMC_vrm_animation") && m.indexOf("VRMC_vrm_animation") !== -1) : !1, d = [];
  return t.forEach((p) => {
    var m;
    const f = p.asset.resource, _ = p.asset.type;
    let g;
    if (!f)
      g = null, console.warn(
        `createVRMAnimResources: loadAnimation can't find available resource from ${p.stateName} asset.`
      );
    else {
      const v = (m = f.data) == null ? void 0 : m.gltf.extensionsUsed;
      u(_, v) ? g = tn(a, p, i, h) : g = en(
        a,
        p,
        i,
        h,
        n
      );
    }
    g && d.push(g);
  }), d;
}
const Qi = (a, t) => {
  a.anim ? a.anim.assignAnimation(
    t.name,
    t.resource,
    t.setting && t.setting.layerName !== void 0 ? t.setting.layerName : void 0,
    t.setting && t.setting.speed !== void 0 ? t.setting.speed : 1,
    t.setting && t.setting.loop !== void 0 ? t.setting.loop : !0
  ) : console.error("AssignAnimation: Please set the anim component on the entity.");
};
function Ki(a, t, e) {
  const n = (e ?? a).anim;
  n && n.on(`anim-track:${t.name}-start`, () => {
    var s, r, o;
    if (!n)
      return;
    let l;
    if (n.vrmaExpressionLayerName) {
      const d = n.layers.find(
        (p) => p.name === n.vrmaExpressionLayerName
      );
      l = d?.activeState;
    } else
      l = (s = n.baseLayer) == null ? void 0 : s.activeState;
    if (l !== t.name)
      return;
    const c = (((r = t.expression) == null ? void 0 : r.custom.size) ?? 0) > 0, h = (((o = t.expression) == null ? void 0 : o.preset.size) ?? 0) > 0;
    c || h ? a.fire("vrm-expression:vrma-start", t.expression) : a.fire("vrm-expression:vrma-reset");
  });
}
function tn(a, t, e, i) {
  var n, s, r, o;
  const c = new Xi(a).loadVRMA(t.asset);
  let u = (o = (r = (s = (n = t.asset.resource.data.gltf.animations) == null ? void 0 : n[0]) == null ? void 0 : s.resources) == null ? void 0 : r[0]) == null ? void 0 : o.name;
  if (u || (u = ""), c) {
    const d = new Zi(
      a,
      t.stateName,
      u,
      c[0],
      e,
      i
    ).result, p = new qi(c[0]);
    return {
      name: t.stateName,
      resource: d,
      expression: p,
      ...t.setting && { setting: t.setting }
    };
  }
  return null;
}
function en(a, t, e, i, n) {
  var s, r;
  const o = t.asset.resource, l = t.asset.type === "container" ? (r = (s = o.animations) == null ? void 0 : s[0]) == null ? void 0 : r.resource : t.asset.resource;
  if (l) {
    const c = new $i(
      a,
      t,
      e,
      i,
      n,
      l
    ).result;
    return {
      name: t.stateName,
      resource: c,
      ...t.setting && {
        setting: t.setting
      }
    };
  } else
    return console.error(
      `CreateViverseAnimResource: loadAnimation can't find valid resource from ${t.stateName} asset.`
    ), null;
}
const Me = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  assignAnimation: Qi,
  bindVRMAExpression: Ki,
  createVRMAnimResources: be,
  createVRMAnimation: Ji
}, Symbol.toStringTag, { value: "Module" }));
class oe {
  constructor(t) {
    this.name = t, this._timers = {}, this._nextFreeId = 0, this.timer = {}, this.handle = null, this.isPausing = !0;
  }
  add(t, e, i) {
    if (t > 0) {
      this.isPausing = !1;
      const n = { id: this._nextFreeId };
      this._timers[this._nextFreeId] = {
        secsLeft: t,
        callback: e,
        scope: i
      }, this._nextFreeId += 1, this.handle = n;
    } else
      this.handle = null;
  }
  pause() {
    this.isPausing = !0, this.handle = null, this._timers = {};
  }
  update(t) {
    for (let e in this._timers) {
      const i = this._timers[e];
      i.secsLeft !== void 0 && (i.secsLeft -= t, i.secsLeft <= 0 && (delete this._timers[e], i.callback && i.callback.call(i.scope)));
    }
  }
}
function Ie(a) {
  return Math.max(Math.min(a, 1), 0);
}
function nn(a, t) {
  return a = Math.ceil(a), t = Math.floor(t), Math.floor(Math.random() * (t - a) + a);
}
function ht(a, t) {
  return Math.random() * (t - a) + a;
}
class ae {
  constructor() {
    this.managerName = "expression", this.blinkExpressionNames = /* @__PURE__ */ new Set(["blink", "blinkLeft", "blinkRight"]), this.lookAtExpressionNames = /* @__PURE__ */ new Set(["lookLeft", "lookRight", "lookUp", "lookDown"]), this.mouthExpressionNames = /* @__PURE__ */ new Set(["aa", "ee", "ih", "oh", "ou"]), this.emotionExpressionNames = /* @__PURE__ */ new Set([
      "neutral",
      "happy",
      "angry",
      "sad",
      "relaxed",
      "surprised"
    ]), this._expressions = [], this._expressionMap = {}, this.talkExpressions = [], this.previousTalkName = "", this.isBackToBlink = !1;
  }
  registerExpression(t) {
    this._expressions.push(t), this._expressionMap[t.expressionName] = t;
  }
  getExpression(t) {
    return this._expressionMap[t] ?? null;
  }
  getTalkingExpression() {
    const t = this.getExpression("aa"), e = this.getExpression("ee"), i = this.getExpression("ih"), n = this.getExpression("oh"), s = this.getExpression("ou");
    return [t, e, i, n, s].filter(
      (r) => r
    );
  }
  setValue(t, e) {
    const i = this.getExpression(t);
    i && (i.weight = Ie(e));
  }
  // Specific expression animations
  startBlink(t, e) {
    const i = e || {
      times: [0, t - 0.2, t - 0.1, t],
      values: [0, 0, 1, 0]
    }, n = this.getExpression("blink");
    n && (n.animatedMorph = i, n.isPausing = !1, this.clearAllAppliedWeight(!0));
  }
  stopBlink() {
    const t = this.getExpression("blink");
    t && t.stop();
  }
  startEmotion(t, e) {
    const i = e || {
      times: [0, 1, 2.5, 3],
      values: [0, 1, 1, 0]
    }, n = this.getExpression(t);
    n && (n.animatedMorph = i, n.isPausing = !1, this.clearAllAppliedWeight(!0));
  }
  stopEmotions(t) {
    t.forEach((e) => {
      const i = this.getExpression(e);
      i && i.stop();
    });
  }
  stopAllEmotions() {
    this._expressions.forEach((t) => {
      t.stop();
    });
  }
  getNextTalking() {
    if (this.talkExpressions.length === 0)
      return null;
    const t = nn(0, this.talkExpressions.length - 1);
    return this.talkExpressions[t].name === this.previousTalkName && this.talkExpressions.length > 1 ? this.getNextTalking() : (this.previousTalkName = this.talkExpressions[t].expressionName, this.talkExpressions[t]);
  }
  startTalking(t, e) {
    this.talkExpressions.length === 0 && (this.talkExpressions = this.getTalkingExpression());
    const i = this.getNextTalking();
    i && (i.animatedMorph = {
      times: t,
      values: e
    });
  }
  stopTalking() {
    this.talkExpressions.forEach((t) => {
      t && t.stop();
    });
  }
  clearAllAppliedWeight(t) {
    for (const e of this._expressions)
      e.clearAppliedWeight(t);
  }
  update(t) {
    for (const i of this._expressions)
      i.updateBlendShape(t);
    const e = this._calculateWeightMultipliers();
    this.clearAllAppliedWeight(), this.isBackToBlink = !0;
    for (const i of this._expressions) {
      let n = 1;
      const s = i.expressionName;
      this.blinkExpressionNames.has(s) && (n *= e.blink), this.lookAtExpressionNames.has(s) && (n *= e.lookAt), this.mouthExpressionNames.has(s) && (n *= e.mouth), i.applyWeight({ multiplier: n }), i.weight !== 0 && (this.isBackToBlink = !1);
    }
  }
  /**
   * Calculate sum of override amounts to see how much we should multiply weights of certain expressions.
   */
  _calculateWeightMultipliers() {
    let t = 1, e = 1, i = 1;
    return this._expressions.forEach((n) => {
      t -= n.overrideBlinkAmount, e -= n.overrideLookAtAmount, i -= n.overrideMouthAmount;
    }), t = Math.max(0, t), e = Math.max(0, e), i = Math.max(0, i), { blink: t, lookAt: e, mouth: i };
  }
}
class le {
  constructor(t) {
    this._binds = [], this.overrideLookAt = "none", this.overrideMouth = "none", this.name = `VRMExpression_${t}`, this.expressionName = t, this.type = "VRMExpression", this.isBinary = !1, this.weight = 0, this._animatedMorph = null, this.time = 0, this.currentValue = 0, this.currentTimeIndex = null, this.isPausing = !1, this._binds = [], this.overrideBlink = "none", this.overrideLookAt = "none", this.overrideMouth = "none";
  }
  get animatedMorph() {
    return this._animatedMorph;
  }
  set animatedMorph(t) {
    this.resetAnimatedMorph(), this._animatedMorph = t;
  }
  addBind(t) {
    this._binds.push(t);
  }
  applyWeight({ multiplier: t }) {
    let e = this.isBinary ? this.weight <= 0.5 ? 0 : 1 : this.weight;
    e *= t ?? 1, this._binds.forEach((i) => i.applyWeight(e));
  }
  /**
   * Clear previously assigned blend shapes.
   */
  clearAppliedWeight(t) {
    t && (this.weight = 0), this._binds.forEach((e) => e.clearAppliedWeight());
  }
  /**
   * A value represents how much it should override blink expressions.
   * `0.0` == no override at all, `1.0` == completely block the expressions.
   */
  get overrideBlinkAmount() {
    return this.overrideBlink === "block" ? 0 < this.weight ? 1 : 0 : this.overrideBlink === "blend" ? this.weight : 0;
  }
  /**
   * A value represents how much it should override lookAt expressions.
   * `0.0` == no override at all, `1.0` == completely block the expressions.
   */
  get overrideLookAtAmount() {
    return this.overrideLookAt === "block" ? 0 < this.weight ? 1 : 0 : this.overrideLookAt === "blend" ? this.weight : 0;
  }
  /**
   * A value represents how much it should override mouth expressions.
   * `0.0` == no override at all, `1.0` == completely block the expressions.
   */
  get overrideMouthAmount() {
    return this.overrideMouth === "block" ? 0 < this.weight ? 1 : 0 : this.overrideMouth === "blend" ? this.weight : 0;
  }
  setValue(t) {
    this.currentValue = t, this.weight = Ie(t);
  }
  resetAnimatedMorph() {
    this.time = 0, this._animatedMorph = null, this.currentTimeIndex = null;
  }
  stop() {
    this.resetAnimatedMorph();
  }
  pause() {
    this.isPausing = !0;
  }
  play() {
    this.isPausing = !1;
  }
  _findTimeIndex(t, e) {
    if (t < e[1])
      return 0;
    for (let i = 1; i < e.length - 1; i++)
      if (e[i - 1] < t && e[i + 1] > t)
        return i;
    return -1;
  }
  updateBlendShape(t) {
    if (!this._animatedMorph || this.isPausing)
      return;
    const { times: e, values: i } = this._animatedMorph;
    if (this.time === 0 && this.currentTimeIndex === null) {
      const s = i[0];
      this.setValue(s);
    }
    if (this.time >= e[e.length - 1]) {
      this.resetAnimatedMorph();
      const s = i[i.length - 1];
      this.setValue(s);
      return;
    }
    this.time += t;
    const n = this._findTimeIndex(this.time, e);
    if (n !== -1) {
      this.currentTimeIndex !== n && (this.currentValue = i[n]), this.currentTimeIndex = n;
      const s = i[this.currentTimeIndex + 1], r = e[this.currentTimeIndex] - e[this.currentTimeIndex + 1], l = (i[this.currentTimeIndex] - i[this.currentTimeIndex + 1]) / r, c = this.currentValue + l * t;
      l > 0 && c >= s || l < 0 && s >= c ? this.setValue(s) : this.setValue(c);
    }
  }
}
class ce {
  constructor({
    primitives: t,
    targetIndex: e,
    weight: i
  }) {
    this.primitives = t, this.targetIndex = e, this.weight = i;
  }
  applyWeight(t) {
    this.primitives.forEach((e) => {
      var i;
      if (((i = e.morphInstance) == null ? void 0 : i.morph.targets[this.targetIndex]) != null) {
        let n = e.morphInstance.getWeight(this.targetIndex);
        e.morphInstance.setWeight(this.targetIndex, n += this.weight * t);
      }
    });
  }
  clearAppliedWeight() {
    this.primitives.forEach((t) => {
      var e;
      ((e = t.morphInstance) == null ? void 0 : e.morph.targets[this.targetIndex]) != null && t.morphInstance.setWeight(this.targetIndex, 0);
    });
  }
}
class sn {
  constructor(t, e) {
    this.asset = t, this.meshInstances = e;
  }
  import() {
    const e = this.asset.resource.data.gltf, i = this._v1Import(e);
    if (i)
      return i;
    const n = this._v0Import(e);
    return n || null;
  }
  _v1Import(t) {
    var e;
    if (!(t?.extensionsUsed.indexOf("VRMC_vrm") !== -1))
      return null;
    const n = (e = t?.extensions) == null ? void 0 : e.VRMC_vrm;
    if (!n)
      return null;
    const s = n.expressions;
    if (!s)
      return null;
    const r = new Set(Object.values(kt)), o = /* @__PURE__ */ new Map();
    s.preset != null && Object.entries(s.preset).forEach(([c, h]) => {
      if (h != null) {
        if (!r.has(c)) {
          console.warn(
            `VRMExpressionLoaderPlugin: Unknown preset name "${c}" detected. Ignoring the expression`
          );
          return;
        }
        o.set(c, h);
      }
    }), s.custom != null && Object.entries(s.custom).forEach(([c, h]) => {
      if (r.has(c)) {
        console.warn(
          `VRMExpressionLoaderPlugin: Custom expression cannot have preset name "${c}". Ignoring the expression`
        );
        return;
      }
      o.set(c, h);
    });
    const l = new ae();
    return Array.from(o.entries()).map(([c, h]) => {
      const u = new le(c);
      u.isBinary = h.isBinary ?? !1, u.overrideBlink = h.overrideBlink ?? "none", u.overrideLookAt = h.overrideLookAt ?? "none", u.overrideMouth = h.overrideMouth ?? "none", h.morphTargetBinds && h.morphTargetBinds.forEach((d) => {
        if (d.node === void 0 || d.index === void 0)
          return;
        const p = this.meshInstances.filter((f) => f.node.tags.has(`node_${d.node}`)), m = d.index;
        u.addBind(
          new ce({
            primitives: p,
            targetIndex: m,
            weight: d.weight ?? 1
          })
        );
      }), l.registerExpression(u);
    }), l;
  }
  _v0Import(t) {
    var e, i;
    if (!(((e = t.extensionsUsed) == null ? void 0 : e.indexOf("VRM")) !== -1))
      return null;
    const s = (i = t.extensions) == null ? void 0 : i.VRM;
    if (!s)
      return null;
    const r = s.blendShapeMaster;
    if (!r)
      return null;
    const o = new ae(), l = r.blendShapeGroups;
    if (!l)
      return o;
    const c = /* @__PURE__ */ new Set();
    return l.map((h) => {
      const u = h.presetName, p = (u != null && we[u] || null) ?? h.name;
      if (p == null) {
        console.warn(
          "VRMExpressionLoaderPlugin: One of custom expressions has no name. Ignoring the expression"
        );
        return;
      }
      if (c.has(p)) {
        console.warn(
          `VRMExpressionLoaderPlugin: An expression preset ${u} has duplicated entries. Ignoring the expression`
        );
        return;
      }
      c.add(p);
      const m = new le(p);
      m.isBinary = h.isBinary ?? !1, h.binds && (h.binds.forEach((f) => {
        if (f.mesh === void 0 || f.index === void 0)
          return;
        const _ = [];
        t.nodes.forEach((v, y) => {
          v.mesh === f.mesh && _.push({ gltfNode: v, index: y });
        });
        const g = f.index;
        _.map((v) => {
          const y = this.meshInstances.filter((T) => T.node.tags.has(`node_${v.index}`));
          m.addBind(
            new ce({
              primitives: y,
              targetIndex: g,
              weight: 0.01 * (f.weight ?? 100)
              // narrowing the range from [ 0.0 - 100.0 ] to [ 0.0 - 1.0 ]
            })
          );
        });
      }), o.registerExpression(m));
    }), o;
  }
}
const rn = (a) => {
  const t = [];
  if (a) {
    const e = a.findComponents("render");
    for (let i = 0; i < e.length; i++) {
      const n = e[i];
      if (n.meshInstances)
        for (let s = 0; s < n.meshInstances.length; s++) {
          const r = n.meshInstances[s];
          t.push(r);
        }
    }
  }
  return t;
}, on = (a) => {
  class t extends a.ScriptType {
    constructor() {
      super(...arguments), this.previousTalkName = "", this.vrmaEmotionWasPlaying = !1;
    }
    initialize() {
      const i = rn(this.entity), n = new sn(this.asset, i);
      this.expressionManager = n.import(), this.blinkTimer = new oe("blink"), this.talkTimer = new oe("talk"), this.startBlink(), this.entity.on("vrm-expression:start-emotion", this.startEmotion, this), this.entity.on("vrm-expression:vrma-start", this._startVRMAExpression, this), this.entity.on("vrm-expression:talking-state-changed", this.onTalkingStateChanged, this), this.entity.on("audio:is-talking-change", this.onTalkingStateChanged, this), this.on("destroy", () => {
        this.entity.off("vrm-expression:start-emotion", this.startEmotion, this), this.entity.off("vrm-expression:vrma-start", this._startVRMAExpression, this), this.entity.off("vrm-expression:vrma-reset", this._resetVRMAExpression, this), this.entity.off("vrm-expression:talking-state-changed", this.onTalkingStateChanged, this), this.entity.off("audio:is-talking-change", this.onTalkingStateChanged, this);
      });
    }
    // Specific Automatic Start Expressions
    startBlink(i) {
      if (!this.expressionManager)
        return;
      this.expressionManager.startBlink(1, i);
      const n = ht(1, 5);
      this.blinkTimer.add(n, this.startBlink, this);
    }
    stopBlink() {
      this.expressionManager && (this.blinkTimer.pause(), this.expressionManager.stopBlink());
    }
    startEmotion(i, n) {
      var s;
      (s = this.expressionManager) == null || s.startEmotion(i, n);
    }
    startTalking(i = 0.25) {
      if (!this.expressionManager)
        return;
      const n = Math.random() * 0.5, s = Math.random() * 0.5 + 0.5, r = ht(0.5, 1), o = ht(0.4, 0.6) * r, l = ht(0.4, 0.6) * r, c = [0, n, 0.5, s, 1].map((d) => d * i), h = [0, o, r, l, 0], u = ht(0.5, 1);
      this.expressionManager.startTalking(c, h), this.talkTimer.add(u, this.startTalking, this);
    }
    stopTalking(i) {
      this.talkTimer.pause(), i && this.talkTimer.add(i, this.startTalking, this);
    }
    onTalkingStateChanged(i) {
      const n = this.talkTimer.isPausing || !this.talkTimer.handle;
      i && n ? this.startTalking() : this.stopTalking();
    }
    update(i) {
      this.expressionManager && (this.expressionManager.update(i), this.blinkTimer.update(i), this.talkTimer.update(i));
    }
    _startVRMAExpression(i) {
      if (this.expressionManager) {
        this.stopBlink(), this.expressionManager.stopAllEmotions();
        for (const [n, s] of i.preset.entries())
          this.startEmotion(n, s);
        this.entity.hasEvent("vrm-expression:vrma-reset") || this.entity.once("vrm-expression:vrma-reset", this._resetVRMAExpression, this), this.vrmaEmotionWasPlaying = !0;
      }
    }
    _resetVRMAExpression() {
      var i;
      this.vrmaEmotionWasPlaying && ((i = this.expressionManager) == null || i.stopAllEmotions(), this.startBlink(), this.vrmaEmotionWasPlaying = !1);
    }
  }
  a.registerScript(t, "vrmExpression"), t.attributes.add("asset", {
    type: "asset",
    description: "Set the container asset loaded from vrm avatar."
  });
}, Pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  importScript: on
}, Symbol.toStringTag, { value: "Module" }));
function an(a) {
  const t = /* @__PURE__ */ new Map();
  for (const e of a) {
    let i = e;
    do {
      const n = (t.get(i) ?? 0) + 1;
      if (n === a.size)
        return i;
      t.set(i, n), i = i.parent;
    } while (i !== null);
  }
  return null;
}
function ln(a, t) {
  const e = [];
  let i = a;
  for (; i !== null; )
    e.unshift(i), i = i.parent;
  e.forEach((n) => {
    t(n);
  });
}
function Ce(a, t) {
  a.children.forEach((e) => {
    t(e) || Ce(e, t);
  });
}
class he {
  constructor() {
    this.managerName = "springBone", this._joints = /* @__PURE__ */ new Set(), this._hasWarnedCircularDependency = !1, this._sortedJoints = [], this._limitedStrength = 0.3, this._normalStrength = 1, this._ancestors = [], this._objectSpringBonesMap = /* @__PURE__ */ new Map(), this._isSortedJointsDirty = !1;
  }
  get joints() {
    return this._joints;
  }
  get limitedStrength() {
    return this._limitedStrength;
  }
  get normalStrength() {
    return this._normalStrength;
  }
  get colliderGroups() {
    const t = /* @__PURE__ */ new Set();
    return this._joints.forEach((e) => {
      e.colliderGroups.forEach((i) => {
        t.add(i);
      });
    }), Array.from(t);
  }
  addJoint(t) {
    this._joints.add(t);
    let e = this._objectSpringBonesMap.get(t.bone);
    e == null && (e = /* @__PURE__ */ new Set(), this._objectSpringBonesMap.set(t.bone, e)), e.add(t), this._isSortedJointsDirty = !0;
  }
  setInitState() {
    this._sortJoints();
    for (let t = 0; t < this._sortedJoints.length; t++)
      this._sortedJoints[t].setInitState();
  }
  reset() {
    this._sortJoints();
    for (let t = 0; t < this._sortedJoints.length; t++)
      this._sortedJoints[t].reset();
  }
  /**
   * Sorts the joints ensuring they are updated in the correct order taking dependencies into account.
   *
   * This method updates {@link _sortedJoints} and {@link _ancestors}.
   * Make sure to call this before using them.
   */
  _sortJoints() {
    if (!this._isSortedJointsDirty)
      return;
    const t = [], e = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
    for (const r of this._joints)
      this._insertJointSort(
        r,
        e,
        i,
        t,
        n
      );
    this._sortedJoints = t;
    const s = an(n);
    this._ancestors = [], s && (this._ancestors.push(s), Ce(s, (r) => {
      var o;
      return (((o = this._objectSpringBonesMap.get(r)) == null ? void 0 : o.size) ?? 0) > 0 ? !0 : (this._ancestors.push(r), !1);
    })), this._isSortedJointsDirty = !1;
  }
  _insertJointSort(t, e, i, n, s) {
    if (i.has(t))
      return;
    if (e.has(t)) {
      this._hasWarnedCircularDependency || (console.warn("VRMSpringBoneManager: Circular dependency detected"), this._hasWarnedCircularDependency = !0);
      return;
    }
    e.add(t);
    const r = t.dependencies;
    for (const o of r) {
      let l = !1, c = null;
      ln(o, (h) => {
        const u = this._objectSpringBonesMap.get(h);
        if (u)
          for (const d of u)
            l = !0, this._insertJointSort(
              d,
              e,
              i,
              n,
              s
            );
        else l || (c = h);
      }), c && s.add(c);
    }
    n.push(t), i.add(t);
  }
  update(t, e = !1) {
    this._sortJoints();
    const i = e ? this._limitedStrength : this._normalStrength;
    for (let n = 0; n < this._sortedJoints.length; n++)
      this._sortedJoints[n].update(t, i);
  }
}
class cn {
  constructor(t, e) {
    this.offset = e?.offset ?? new t.Vec3(), this.radius = e?.radius ?? 0, this.inside = e?.inside ?? !1;
  }
  get type() {
    return "sphere";
  }
  calculateCollision(t, e, i, n, s) {
    n.sub2(e, t.getTranslation(s));
    const r = n.length(), o = this.inside ? this.radius - i - r : r - i - this.radius;
    return o < 0 && (n.mulScalar(1 / r), this.inside && n.mulScalar(-1)), o;
  }
}
class hn {
  constructor(t, e = {}) {
    this.offset = e?.offset ?? new t.Vec3(), this.tail = e?.tail ?? new t.Vec3(), this.radius = e?.radius ?? 0, this._v3A = new t.Vec3(), this._v3B = new t.Vec3(), this.inside = e?.inside ?? !1;
  }
  get type() {
    return "capsule";
  }
  calculateCollision(t, e, i, n, s) {
    this._v3A.copy(t.getTranslation(s)), t.transformPoint(s.sub2(this.tail, this.offset), this._v3B), this._v3B.sub(this._v3A);
    const r = this._v3B.lengthSq();
    n.copy(e).sub(this._v3A);
    const o = this._v3B.dot(n);
    o <= 0 || (r <= o ? n.sub(this._v3B) : (this._v3B.mulScalar(o / r), n.sub(this._v3B)));
    const l = n.length(), c = this.inside ? this.radius - i - l : l - i - this.radius;
    return c < 0 && (n.mulScalar(1 / l), this.inside && n.mulScalar(-1)), c;
  }
}
class un {
  constructor(t, e, i, n = {}, s = []) {
    var r;
    this.id = crypto.randomUUID(), this._center = null, this._worldSpaceBoneLength = 0, this._pcRef = t, this._v3A = new this._pcRef.Vec3(), this._v3B = new this._pcRef.Vec3(), this._nextTail = new this._pcRef.Vec3(), this._quatA = new this._pcRef.Quat(), this._quatB = new this._pcRef.Quat(), this._quatC = new this._pcRef.Quat(), this._quatD = new this._pcRef.Quat(), this._matA = new this._pcRef.Mat4(), this._identityMat4 = new this._pcRef.Mat4(), this._worldSpacePosition = new this._pcRef.Vec3(), this._worldSpaceBoneLength = 0, this.bone = e, this.child = i, this.settings = {
      hitRadius: n.hitRadius ?? 0,
      stiffness: n.stiffness ?? 1,
      gravityPower: n.gravityPower ?? 0,
      gravityDir: ((r = n.gravityDir) == null ? void 0 : r.clone()) ?? new this._pcRef.Vec3(0, -1, 0),
      dragForce: n.dragForce ?? 0.4
    }, this.colliderGroups = s, this._initialLocalMatrix = new this._pcRef.Mat4(), this._initialLocalRotation = new this._pcRef.Quat(), this._initialLocalChildPosition = new this._pcRef.Vec3(), this._currentTail = new this._pcRef.Vec3(), this._prevTail = new this._pcRef.Vec3(), this._boneAxis = new this._pcRef.Vec3(), this._center = null;
  }
  get center() {
    return this._center;
  }
  set center(t) {
    this._center = t;
  }
  get _parentMatrixWorld() {
    return this.bone.parent ? this.bone.parent.getWorldTransform() : this._identityMat4;
  }
  /**
   * Set of dependencies that need to be updated before this joint.
   */
  get dependencies() {
    const t = /* @__PURE__ */ new Set(), e = this.bone.parent;
    e && t.add(e);
    for (let i = 0; i < this.colliderGroups.length; i++)
      for (let n = 0; n < this.colliderGroups[i].colliders.length; n++)
        t.add(this.colliderGroups[i].colliders[n]);
    return t;
  }
  _calcWorldSpaceBoneLength() {
    const t = this.bone.getWorldTransform();
    t.getTranslation(this._v3A), this.child ? this.child.getWorldTransform().getTranslation(this._v3B) : (this._v3B.copy(this._initialLocalChildPosition), t.transformPoint(this._v3B, this._v3B)), this._worldSpaceBoneLength = this._v3A.sub(this._v3B).length();
  }
  setInitState() {
    this._initialLocalMatrix.copy(this.bone.getLocalTransform()), this._initialLocalRotation.copy(this.bone.getLocalRotation()), this.child ? this._initialLocalChildPosition.copy(this.child.getLocalPosition()) : this._initialLocalChildPosition.copy(this.bone.getLocalPosition()).normalize().mulScalar(0.07), this.bone.getWorldTransform().transformPoint(
      this._currentTail.copy(this._initialLocalChildPosition),
      this._currentTail
    ), this._transformPointWorldToCenter(this._currentTail), this._prevTail.copy(this._currentTail), this._boneAxis.copy(this._initialLocalChildPosition).normalize();
  }
  reset() {
    this.bone.setLocalRotation(this._initialLocalRotation), this.bone.getWorldTransform().transformPoint(
      this._currentTail.copy(this._initialLocalChildPosition),
      this._currentTail
    ), this._transformPointWorldToCenter(this._currentTail), this._prevTail.copy(this._currentTail);
  }
  update(t, e = 1) {
    if (t <= 0)
      return;
    this._calcWorldSpaceBoneLength();
    const i = this._v3A.copy(this._boneAxis);
    this._initialLocalMatrix.transformVector(i, i), i.normalize(), this._parentMatrixWorld.transformVector(i, i), i.normalize(), this._nextTail.copy(this._currentTail).add(
      this._v3B.sub2(this._currentTail, this._prevTail).mulScalar(1 - this.settings.dragForce)
    ), this._transformPointCenterToWorld(this._nextTail), this._nextTail.add(this._v3B.copy(i).mulScalar(this.settings.stiffness * t)), this._nextTail.add(
      this._v3B.copy(this.settings.gravityDir).mulScalar(this.settings.gravityPower * t)
    ), this._worldSpacePosition.copy(this.bone.getPosition()), this._nextTail.sub(this._worldSpacePosition).normalize().mulScalar(this._worldSpaceBoneLength).add(this._worldSpacePosition), this._collision(this._nextTail), this._prevTail.copy(this._currentTail), this._currentTail.copy(this._nextTail), this._transformPointWorldToCenter(this._currentTail);
    const n = this._v3A.copy(this._nextTail).sub(this._worldSpacePosition).normalize(), s = this.bone.parent ? this.bone.parent.getRotation() : this._quatC.set(0, 0, 0, 1);
    this._quatD.mul2(s, this._initialLocalRotation).invert().transformVector(n, n), n.normalize();
    const o = this._quatA.setFromDirections(this._boneAxis, n);
    if (e !== 1) {
      const c = this._quatC.set(0, 0, 0, 1), h = this._quatD.copy(o);
      o.slerp(c, h, e);
    }
    const l = this._quatB.mul2(this._initialLocalRotation, o);
    this.bone.setLocalRotation(l);
  }
  _transformPointCenterToWorld(t) {
    this._center && this._center.getWorldTransform().transformPoint(t, t);
  }
  _transformPointWorldToCenter(t) {
    this._center && (this._matA.copy(this._center.getWorldTransform()).invert(), this._matA.transformPoint(t, t));
  }
  _collision(t) {
    if (this.colliderGroups)
      for (let e = 0; e < this.colliderGroups.length; e++) {
        const n = this.colliderGroups[e].colliders;
        for (let s = 0; s < n.length; s++) {
          const r = n[s], o = r.shape.calculateCollision(
            r.getWorldTransform(),
            t,
            this.settings.hitRadius,
            this._v3A,
            this._v3B
          );
          if (o < 0) {
            t.add(this._v3A.mulScalar(-o)), t.sub(this._worldSpacePosition);
            const l = t.length();
            t.mulScalar(this._worldSpaceBoneLength / l).add(this._worldSpacePosition);
          }
        }
      }
  }
}
function ue(a, t) {
  const e = new a.Entity();
  return e.shape = t, e.setLocalPosition(t.offset), e;
}
const Le = class bt {
  constructor(t, e, i) {
    this.asset = e, this.entity = i, this._pcRef = t;
  }
  import() {
    const t = this.asset.resource, e = t.data.gltf, i = t.data;
    if (!e)
      return null;
    const n = this._v1Import(e);
    if (n)
      return n;
    const s = this._v0Import(e, i);
    return s || null;
  }
  _v1Import(t) {
    var e, i, n;
    if (!(((e = t.extensionsUsed) == null ? void 0 : e.indexOf(bt.EXTENSION_NAME)) !== -1) || !(((i = t?.extensionsUsed) == null ? void 0 : i.indexOf("VRMC_vrm")) !== -1))
      return null;
    const o = new he(), l = (n = t.extensions) == null ? void 0 : n[bt.EXTENSION_NAME];
    if (!l)
      return null;
    const c = l.specVersion;
    if (!Bt.has(c))
      return console.warn(
        `VRMSpringBoneLoaderPlugin: Unknown ${bt.EXTENSION_NAME} specVersion "${c}"`
      ), null;
    const h = l.colliders || [], u = h?.map((f, _) => {
      var g;
      const v = (g = this.entity.findByTag(`node_${f.node}`)) == null ? void 0 : g[0], y = f.shape;
      if (!v) {
        console.error(
          "VRMSpringBoneLoaderPlugin Error: Did not find the node map to schemaColliderGroup"
        );
        return;
      }
      if (y) {
        if (y.sphere)
          return this._importSphereCollider(v, {
            offset: new this._pcRef.Vec3().fromArray(y.sphere.offset ?? [0, 0, 0]),
            radius: y.sphere.radius ?? 0
          });
        if (y.capsule)
          return this._importCapsuleCollider(v, {
            offset: new this._pcRef.Vec3().fromArray(y.capsule.offset ?? [0, 0, 0]),
            radius: y.capsule.radius ?? 0,
            tail: new this._pcRef.Vec3().fromArray(y.capsule.tail ?? [0, 0, 0])
          });
      }
      throw new Error(`VRMSpringBoneLoaderPlugin: The collider #${_} has no valid shape`);
    }), d = l.colliderGroups || [], p = d?.map((f, _) => ({
      colliders: (f.colliders ?? []).map((v) => {
        const y = u?.[v];
        if (y == null)
          throw new Error(
            `VRMSpringBoneLoaderPlugin: The colliderGroup #${_} attempted to use a collider #${v} but not found`
          );
        return y;
      }),
      name: f.name
    }));
    return (l.springs || []).forEach((f, _) => {
      var g, v;
      const y = f.joints, T = (g = f.colliderGroups) == null ? void 0 : g.map((M) => {
        const P = p?.[M];
        if (P == null)
          throw new Error(
            `VRMSpringBoneLoaderPlugin: The spring #${_} attempted to use a colliderGroup ${M} but not found`
          );
        return P;
      }), A = (v = this.entity.findByTag(`node_${f.center}`)) == null ? void 0 : v[0];
      let w;
      y.forEach((M) => {
        var P, C;
        if (w) {
          const L = w.node, z = (P = this.entity.findByTag(`node_${L}`)) == null ? void 0 : P[0], k = M.node, D = (C = this.entity.findByTag(`node_${k}`)) == null ? void 0 : C[0], I = {
            hitRadius: w.hitRadius,
            dragForce: w.dragForce,
            gravityPower: w.gravityPower,
            stiffness: w.stiffness,
            gravityDir: w.gravityDir != null ? new this._pcRef.Vec3().fromArray(w.gravityDir) : void 0
          }, G = this._importJoint(z, D, I, T);
          A && (G.center = A), o.addJoint(G);
        }
        w = M;
      });
    }), o.setInitState(), o;
  }
  _v0Import(t, e) {
    var i, n, s;
    const r = (i = t.extensions) == null ? void 0 : i.VRM;
    if (!(((n = t.extensionsUsed) == null ? void 0 : n.indexOf("VRM")) !== -1))
      return null;
    const l = r?.secondaryAnimation;
    if (!l)
      return null;
    const c = l?.boneGroups;
    if (!c)
      return null;
    const h = new he(), u = (s = l.colliderGroups) == null ? void 0 : s.map((d) => {
      var p;
      const m = (p = this.entity.findByTag(`node_${d.node}`)) == null ? void 0 : p[0];
      if (!m) {
        console.error(
          "VRMSpringBoneLoaderPlugin Error: Did not find the node map to schemaColliderGroup"
        );
        return;
      }
      return { colliders: (d.colliders ?? []).map((_) => {
        const g = new this._pcRef.Vec3(0, 0, 0);
        return _.offset && g.set(
          _.offset.x ?? 0,
          _.offset.y ?? 0,
          _.offset.z ? -_.offset.z : 0
          // z is opposite in VRM0.0
        ), this._importSphereCollider(m, {
          offset: g,
          radius: _.radius ?? 0
        });
      }) };
    });
    return c?.forEach((d, p) => {
      const m = d.bones;
      m && m.forEach((f) => {
        var _, g;
        const v = (_ = this.entity.findByTag(`node_${f}`)) == null ? void 0 : _[0];
        if (!v) {
          console.error(
            "VRMSpringBoneLoaderPlugin Error: Did not find the node map to schemaColliderGroup"
          );
          return;
        }
        const y = new this._pcRef.Vec3();
        d.gravityDir ? y.set(
          d.gravityDir.x ?? 0,
          d.gravityDir.y ?? 0,
          d.gravityDir.z ?? 0
        ) : y.set(0, -1, 0);
        const T = d.center != null ? e.nodes[d.center] : void 0, A = {
          hitRadius: d.hitRadius,
          dragForce: d.dragForce,
          gravityPower: d.gravityPower,
          stiffness: d.stiffiness,
          gravityDir: y
        }, w = (g = d.colliderGroups) == null ? void 0 : g.map((M) => {
          const P = u?.[M];
          if (P == null)
            throw new Error(
              `VRMSpringBoneLoaderPlugin: The spring #${p} attempted to use a colliderGroup ${M} but not found`
            );
          return P;
        });
        v.forEach((M) => {
          const P = M.children[0] ?? null, C = this._importJoint(M, P, A, w);
          T && (C.center = T), h.addJoint(C);
        });
      });
    }), h.setInitState(), h;
  }
  _importSphereCollider(t, { offset: e, radius: i }) {
    const n = new cn(this._pcRef, { offset: e, radius: i }), s = ue(this._pcRef, n);
    return t.addChild(s), s;
  }
  _importCapsuleCollider(t, { offset: e, radius: i, tail: n }) {
    const s = new hn(this._pcRef, {
      offset: e,
      radius: i,
      tail: n
    }), r = ue(this._pcRef, s);
    return t.addChild(r), r;
  }
  _importJoint(t, e, i, n) {
    return new un(
      this._pcRef,
      t,
      e,
      i,
      n
    );
  }
};
Le.EXTENSION_NAME = "VRMC_springBone";
let dn = Le;
const pn = (a) => {
  class t extends a.ScriptType {
    constructor() {
      super(...arguments), this.activeSpringBone = !0, this.isLimitedStrength = !1, this.updateInterval = 1 / 90, this.timeSinceLastUpdate = 0;
    }
    initialize() {
      const i = new dn(a, this.asset, this.entity);
      this.springBoneManager = i.import(), this.isLimitedStrength = !1, this.entity.on("vrm-spring-bone:set-enabled ", this.setEnabled, this), this.entity.on("toggle-spring-bone", this.setEnabled, this), this.entity.on("vrm-spring-bone:set-strength-limit", this.setStrengthLimit, this), this.on("destroy", () => {
        this.entity.on("vrm-spring-bone:set-enabled ", this.setEnabled, this), this.entity.off("toggle-spring-bone", this.setEnabled, this), this.entity.off("vrm-spring-bone:set-strength-limit", this.setStrengthLimit, this);
      });
    }
    setEnabled(i) {
      this.activeSpringBone = i;
    }
    setStrengthLimit(i) {
      this.isLimitedStrength = i;
    }
    update(i) {
      !this.springBoneManager || !this.activeSpringBone || (this.timeSinceLastUpdate += i, !(this.timeSinceLastUpdate < this.updateInterval) && (this.springBoneManager.update(i, this.isLimitedStrength), this.timeSinceLastUpdate = 0));
    }
  }
  a.registerScript(t, "vrmSpringBone"), t.attributes.add("activeSpringBone", {
    type: "boolean",
    default: !0
  }), t.attributes.add("asset", {
    type: "asset",
    description: "Set the container asset loaded from vrm avatar."
  }), t.attributes.add("updateInterval", {
    type: "number",
    default: 1 / 90
    // 90 FPS
  });
}, Re = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  importScript: pn
}, Symbol.toStringTag, { value: "Module" })), ut = (a) => Math.pow(a, 2.2), At = (a, t, e) => {
  if (!e)
    return;
  const i = new a.Vec2(0, 0), n = new a.Vec2(1, 1), s = new a.Vec2(0.5, 0.5);
  let r = 0;
  return e.scale && (n.x = e.scale[0], n.y = e.scale[1]), e.offset && (i.x = e.offset[0], i.y = 1 - n.y - e.offset[1]), e.rotation && (r = e.rotation), _n(t, i.x, i.y, n.x, n.y, r, s.x, s.y), t;
}, _n = (a, t, e, i, n, s, r, o) => {
  const l = Math.cos(s), c = Math.sin(s);
  a.set([
    i * l,
    i * c,
    -i * (l * r + c * o) + r + t,
    -n * c,
    n * l,
    -n * (-c * r + l * o) + o + e,
    0,
    0,
    1
  ]);
};
class mn {
  constructor(t, e) {
    this._pcRef = t, this.asset = e, this._renderQueueMapTransparent = /* @__PURE__ */ new Map(), this._renderQueueMapTransparentZWrite = /* @__PURE__ */ new Map();
  }
  parseMaterials() {
    var t, e;
    const i = this.asset.resource, n = (t = i?.data) == null ? void 0 : t.gltf;
    if (!n) {
      console.error("VRMMaterialsV0CompatPlugin: gltf data is undefined");
      return;
    }
    const s = (e = n?.extensions) == null ? void 0 : e.VRM, r = s?.materialProperties;
    r && (this._populateRenderQueueMap(r), r.forEach((o, l) => {
      var c;
      if (!n.materials) {
        console.error("parseMaterials: gltf.materials is undefined");
        return;
      }
      const h = n.materials[l];
      if (!h) {
        console.warn(
          `VRMMaterialsV0CompatPlugin: Attempt to use materials[${l}] of glTF but the material doesn't exist`
        );
        return;
      }
      if (o.shader === "VRM/MToon") {
        const u = this._parseV0MToonProperties(o, h);
        n.materials[l] = u;
      } else (c = o.shader) != null && c.startsWith("VRM/Unlit") || o.shader === "VRM_USE_GLTFSHADER" || console.warn(`parseMaterials: Unknown shader: ${o.shader}`);
    }));
  }
  _parseV0MToonProperties(t, e) {
    var i, n, s, r, o, l, c, h, u, d, p, m, f, _, g, v, y, T, A, w, M, P, C, L, z, k, D, I, G, et, W, N, R, U;
    if (e.v0Compat)
      return e;
    const B = ((i = t.keywordMap) == null ? void 0 : i._ALPHABLEND_ON) ?? !1, it = ((n = t.floatProperties) == null ? void 0 : n._ZWrite) === 1 && B, Z = this._v0ParseRenderQueue(t), at = ((s = t.keywordMap) == null ? void 0 : s._ALPHATEST_ON) ?? !1, mt = B ? "BLEND" : at ? "MASK" : "OPAQUE", lt = at ? ((r = t.floatProperties) == null ? void 0 : r._Cutoff) ?? 0.5 : void 0, ft = (((o = t.floatProperties) == null ? void 0 : o._CullMode) ?? 2) === 0, J = this._portTextureTransform(t), gt = (((l = t.vectorProperties) == null ? void 0 : l._Color) ?? [1, 1, 1, 1]).map(
      (Qt, di) => di === 3 ? Qt : ut(Qt)
      // alpha channel is stored in linear
    ), ct = (c = t.textureProperties) == null ? void 0 : c._MainTex, yt = ct != null ? {
      index: ct,
      extensions: {
        ...J
      }
    } : void 0, V = ((h = t.floatProperties) == null ? void 0 : h._BumpScale) ?? 1, O = (u = t.textureProperties) == null ? void 0 : u._BumpMap, je = O != null ? {
      index: O,
      scale: V,
      extensions: {
        ...J
      }
    } : void 0, Ye = (p = (d = t.vectorProperties) == null ? void 0 : d._EmissionColor) == null ? void 0 : p.map(ut), Yt = (m = t.textureProperties) == null ? void 0 : m._EmissionMap, Xe = Yt != null ? {
      index: Yt,
      extensions: {
        ...J
      }
    } : void 0, Ze = (_ = (f = t.vectorProperties) == null ? void 0 : f._ShadeColor) == null ? void 0 : _.map(ut), Xt = (g = t.textureProperties) == null ? void 0 : g._ShadeTexture, $e = Xt != null ? {
      index: Xt,
      extensions: {
        ...J
      }
    } : void 0;
    let vt = ((v = t.floatProperties) == null ? void 0 : v._ShadeShift) ?? 0, St = ((y = t.floatProperties) == null ? void 0 : y._ShadeToony) ?? 0.9;
    St = this._pcRef.math.lerp(
      St,
      1,
      0.5 + 0.5 * vt
    ), vt = -vt - (1 - St);
    const Zt = ((T = t.floatProperties) == null ? void 0 : T._IndirectLightIntensity) ?? 0.1, qe = Zt ? 1 - Zt : void 0, Rt = (A = t.textureProperties) == null ? void 0 : A._SphereAdd, Je = Rt != null ? [1, 1, 1] : void 0, Qe = Rt != null ? {
      index: Rt
    } : void 0, Ke = ((w = t.floatProperties) == null ? void 0 : w._RimLightingMix) ?? 0, $t = (M = t.textureProperties) == null ? void 0 : M._RimTexture, ti = $t != null ? {
      index: $t,
      extensions: {
        ...J
      }
    } : void 0, ei = (((P = t.vectorProperties) == null ? void 0 : P._RimColor) ?? [0, 0, 0, 1]).map(ut), ii = ((C = t.floatProperties) == null ? void 0 : C._RimFresnelPower) ?? 1, ni = ((L = t.floatProperties) == null ? void 0 : L._RimLift) ?? 0, si = ["none", "worldCoordinates", "screenCoordinates"][((z = t.floatProperties) == null ? void 0 : z._OutlineWidthMode) ?? 0];
    let Dt = ((k = t.floatProperties) == null ? void 0 : k._OutlineWidth) ?? 0;
    Dt = 0.01 * Dt;
    const qt = (D = t.textureProperties) == null ? void 0 : D._OutlineWidthTexture, ri = qt != null ? {
      index: qt,
      extensions: {
        ...J
      }
    } : void 0, oi = (((I = t.vectorProperties) == null ? void 0 : I._OutlineColor) ?? [0, 0, 0]).map(ut), ai = (((G = t.floatProperties) == null ? void 0 : G._OutlineColorMode) ?? 0) === 1 ? ((et = t.floatProperties) == null ? void 0 : et._OutlineLightingMix) ?? 1 : 0, Jt = (W = t.textureProperties) == null ? void 0 : W._UvAnimMaskTexture, li = Jt != null ? {
      index: Jt,
      extensions: {
        ...J
      }
    } : void 0, ci = ((N = t.floatProperties) == null ? void 0 : N._UvAnimScrollX) ?? 0;
    let Et = ((R = t.floatProperties) == null ? void 0 : R._UvAnimScrollY) ?? 0;
    Et != null && (Et = -Et);
    const hi = ((U = t.floatProperties) == null ? void 0 : U._UvAnimRotation) ?? 0, ui = {
      specVersion: "1.0",
      transparentWithZWrite: it,
      renderQueueOffsetNumber: Z,
      shadeColorFactor: Ze,
      shadeMultiplyTexture: $e,
      shadingShiftFactor: vt,
      shadingToonyFactor: St,
      giEqualizationFactor: qe,
      matcapFactor: Je,
      matcapTexture: Qe,
      rimLightingMixFactor: Ke,
      rimMultiplyTexture: ti,
      parametricRimColorFactor: ei,
      parametricRimFresnelPowerFactor: ii,
      parametricRimLiftFactor: ni,
      outlineWidthMode: si,
      outlineWidthFactor: Dt,
      outlineWidthMultiplyTexture: ri,
      outlineColorFactor: oi,
      outlineLightingMixFactor: ai,
      uvAnimationMaskTexture: li,
      uvAnimationScrollXSpeedFactor: ci,
      uvAnimationScrollYSpeedFactor: Et,
      uvAnimationRotationSpeedFactor: hi
    };
    return e.v0Compat = !0, {
      ...e,
      pbrMetallicRoughness: {
        baseColorFactor: gt,
        baseColorTexture: yt
      },
      normalTexture: je,
      emissiveTexture: Xe,
      emissiveFactor: Ye,
      alphaMode: mt,
      alphaCutoff: lt,
      doubleSided: ft,
      extensions: {
        VRMC_materials_mtoon: ui
      }
    };
  }
  _portTextureTransform(t) {
    var e;
    const i = (e = t.vectorProperties) == null ? void 0 : e._MainTex;
    if (i == null)
      return {};
    const n = [i?.[0] ?? 0, i?.[1] ?? 0], s = [i?.[2] ?? 1, i?.[3] ?? 1];
    return n[1] = 1 - s[1] - n[1], {
      // eslint-disable-next-line @typescript-eslint/naming-convention
      KHR_texture_transform: { offset: n, scale: s }
    };
  }
  /**
   * Convert v0 render order into v1 render order.
   * This uses a map from v0 render queue to v1 compliant render queue offset which is generated in {@link _populateRenderQueueMap}.
   */
  _v0ParseRenderQueue(t) {
    var e, i;
    const n = ((e = t.keywordMap) == null ? void 0 : e._ALPHABLEND_ON) ?? !1, s = ((i = t.floatProperties) == null ? void 0 : i._ZWrite) === 1;
    let r = 0;
    if (n) {
      const o = t.renderQueue;
      o != null && (s ? r = this._renderQueueMapTransparentZWrite.get(o) : r = this._renderQueueMapTransparent.get(o));
    }
    return r;
  }
  /**
   * Create a map which maps v0 render queue to v1 compliant render queue offset.
   * This lists up all render queues the model use and creates a map to new render queue offsets in the same order.
   */
  _populateRenderQueueMap(t) {
    const e = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
    t.forEach((n) => {
      var s, r;
      const o = ((s = n.keywordMap) == null ? void 0 : s._ALPHABLEND_ON) ?? !1, l = ((r = n.floatProperties) == null ? void 0 : r._ZWrite) === 1;
      if (o) {
        const c = n.renderQueue;
        c != null && (l ? i.add(c) : e.add(c));
      }
    }), e.size > 10 && console.warn(
      `VRMMaterialsV0CompatPlugin: This VRM uses ${e.size} render queues for Transparent materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`
    ), i.size > 10 && console.warn(
      `VRMMaterialsV0CompatPlugin: This VRM uses ${i.size} render queues for TransparentZWrite materials while VRM 1.0 only supports up to 10 render queues. The model might not be rendered correctly.`
    ), Array.from(e).sort().forEach((n, s) => {
      const r = Math.min(Math.max(s - e.size + 1, -9), 0);
      this._renderQueueMapTransparent.set(n, r);
    }), Array.from(i).sort().forEach((n, s) => {
      const r = Math.min(Math.max(s, 0), 9);
      this._renderQueueMapTransparentZWrite.set(n, r);
    });
  }
}
const De = "VRMC_materials_mtoon", Mt = {
  None: "none",
  WorldCoordinates: "worldCoordinates",
  ScreenCoordinates: "screenCoordinates"
}, fn = (
  /* glsl */
  `
#ifdef FORWARD_PASS
  varying vec3 vViewPosition;
  varying vec3 vViewDirection;
  varying vec3 vNormal;

  // engine supplied uniforms
  uniform vec3 view_position;

  #ifdef OUTLINE
    uniform float outlineWidthFactor;

    #ifdef USE_OUTLINEWIDTHMULTIPLYTEXTURE
      uniform sampler2D outlineWidthMultiplyTexture;
      uniform mat3 outlineWidthMultiplyTextureUvTransform;
    #endif
  #endif

#endif
`
), gn = (
  /* glsl */
  `
#ifdef FORWARD_PASS
    vec4 worldPosition = vec4(vPositionW, 1.0);
    vViewDirection = normalize(view_position - worldPosition.xyz);
    vViewPosition = -worldPosition.xyz;

    vec3 objectNormal = vec3(0.0, 0.0, 1.0);
    vec3 transformedNormal = vec3(0.0, 0.0, 1.0);

    #ifdef NORMALS
        objectNormal = vertex_normal;
        objectNormal = normalize( objectNormal );
        transformedNormal = vNormalW;
    #endif

    vNormal = transformedNormal;

    #ifdef OUTLINE
        float outlineTex = 1.0;
        
        #ifdef USE_OUTLINEWIDTHMULTIPLYTEXTURE
            #ifdef UV0
                vec2 outlineWidthMultiplyTextureUv = ( outlineWidthMultiplyTextureUvTransform * vec3( vUv0, 1 ) ).xy;
                outlineTex = texture2D( outlineWidthMultiplyTexture, outlineWidthMultiplyTextureUv ).g;
            #endif
        #endif

        #ifdef OUTLINE_WIDTH_WORLD
            float worldNormalLength = length( transformedNormal );
            vec3 outlineOffset = outlineWidthFactor * outlineTex * worldNormalLength * objectNormal;
            vec3 localPos = getLocalPosition(vertex_position.xyz);

            // From playcanvas transform.js vertex shader
            #ifdef MORPHING
            #ifdef MORPHING_POS03
            localPos.xyz += morph_weights_a[0] * morph_pos0;
            localPos.xyz += morph_weights_a[1] * morph_pos1;
            localPos.xyz += morph_weights_a[2] * morph_pos2;
            localPos.xyz += morph_weights_a[3] * morph_pos3;
            #endif // MORPHING_POS03
            #ifdef MORPHING_POS47
            localPos.xyz += morph_weights_b[0] * morph_pos4;
            localPos.xyz += morph_weights_b[1] * morph_pos5;
            localPos.xyz += morph_weights_b[2] * morph_pos6;
            localPos.xyz += morph_weights_b[3] * morph_pos7;
            #endif // MORPHING_POS47
            #endif // MORPHING

            #ifdef MORPHING_TEXTURE_BASED_POSITION
                vec2 morphUV = getTextureMorphCoords();
                    vec3 morphPos = texture2D(morphPositionTex, morphUV).xyz;
                localPos += morphPos;
            #endif

            gl_Position = matrix_viewProjection * getModelMatrix() * vec4( localPos + outlineOffset, 1.0 );
        #endif

        #ifdef OUTLINE_WIDTH_SCREEN
            // TODO: Wait until an avatar containing this information is found before proceeding with the implementation.
        #endif

        gl_Position.z += 1E-6 * gl_Position.w; // anti-artifact magic
    #endif
#endif
`
), yn = (
  /* glsl */
  `
#ifdef FORWARD_PASS
    #define RECIPROCAL_PI 0.3183098861837907

    uniform vec3 shadeColorFactor;
    uniform vec3 ambientLightColor;

    varying vec3 vNormal;
    varying vec3 vViewDirection;

    #ifdef USE_SHADEMULTIPLYTEXTURE
        uniform sampler2D shadeMultiplyTexture;
        uniform mat3 shadeMultiplyTextureUvTransform;
    #endif

    uniform float shadingShiftFactor;
    uniform float shadingToonyFactor;

    #ifdef USE_SHADINGSHIFTTEXTURE
        uniform sampler2D shadingShiftTexture;
        uniform mat3 shadingShiftTextureUvTransform;
        uniform float shadingShiftTextureScale;
    #endif

    uniform float giEqualizationFactor;
    uniform vec3 parametricRimColorFactor;
    #ifdef USE_RIMMULTIPLYTEXTURE
        uniform sampler2D rimMultiplyTexture;
        uniform mat3 rimMultiplyTextureUvTransform;
    #endif

    uniform float rimLightingMixFactor;
    uniform float parametricRimFresnelPowerFactor;
    uniform float parametricRimLiftFactor;

    #ifdef USE_MATCAPTEXTURE
        uniform vec3 matcapFactor;
        uniform sampler2D matcapTexture;
        uniform mat3 matcapTextureUvTransform;
    #endif

    uniform vec3 emissive;
    uniform float emissiveIntensity;

    uniform vec3 outlineColorFactor;
    uniform float outlineLightingMixFactor;


    uniform mat3 mapUvTransform;
    uniform mat3 emissiveMapUvTransform;

    varying vec3 vViewPosition;

    struct MToonMaterial {
        vec3 diffuseColor;
        vec3 shadeColor;
        float shadingShift;
    };

    struct GeometricContext {
	    vec3 position;
	    vec3 normal;
	    vec3 viewDir;
    };
    
    float linearstep( float a, float b, float t ) {
        return clamp( ( t - a ) / ( b - a ), 0.0, 1.0 );
    }

    vec3 BRDF_Lambert( const in vec3 diffuseColor ) {
        return RECIPROCAL_PI * diffuseColor;
    }

    /**
    * Convert NdotL into toon shading factor using shadingShift and shadingToony
    */
    float getShading(
        const in float dotNL,
        const in float shadow,
        const in float shadingShift
    ) {
        float shading = dotNL;
        shading = shading + shadingShift;
        shading = linearstep( -1.0 + shadingToonyFactor, 1.0 - shadingToonyFactor, shading );
        shading *= shadow;
        return shading;
    }

    vec3 getDiffuse(
        const in MToonMaterial material,
        const in float shading,
            in vec3 lightColor
    ) {
        vec3 col = lightColor * BRDF_Lambert( mix( material.shadeColor, material.diffuseColor, shading ) );
        
        // The "comment out if you want to PBR absolutely" line
        #ifdef V0_COMPAT_SHADE
            col = min( col, material.diffuseColor );
        #endif
        
        return col;
    }


    #ifdef USE_NORMALMAP
        uniform sampler2D normalMap;
        uniform mat3 normalMapUvTransform;
        uniform vec2 normalScale;
    #endif

    uniform mat3 normalMatrix;


    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 );
    }


    struct ReflectedLight {
	    vec3 directDiffuse;
	    vec3 directSpecular;
	    vec3 indirectDiffuse;
	    vec3 indirectSpecular;
    };

    struct IncidentLight {
	    vec3 color;
	    vec3 direction;
	    bool visible;
    };


    void RE_Direct_MToon( const in IncidentLight directLight, const in GeometricContext geometry, const in MToonMaterial material, const in float shadow, inout ReflectedLight reflectedLight ) {
        float dotNL = clamp( dot( geometry.normal, directLight.direction ), -1.0, 1.0 );
        vec3 irradiance = directLight.color;

        // directSpecular will be used for rim lighting, not an actual specular
        reflectedLight.directSpecular += irradiance;

        irradiance *= dotNL;

        float shading = getShading( dotNL, shadow, material.shadingShift );

        // toon shaded diffuse
        reflectedLight.directDiffuse += getDiffuse( material, shading, directLight.color );
    }

    void RE_IndirectDiffuse_MToon( const in vec3 irradiance, const in GeometricContext geometry, const in MToonMaterial material, inout ReflectedLight reflectedLight ) {
        // indirect diffuse will use diffuseColor, no shadeColor involved
        reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );

        // directSpecular will be used for rim lighting, not an actual specular
        reflectedLight.directSpecular += irradiance;
    }

    #define RE_Direct RE_Direct_MToon
    #define RE_IndirectDiffuse RE_IndirectDiffuse_MToon

    vec3 perturbNormal2Arb( vec2 uv, vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {
        vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
        vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
        vec2 st0 = dFdx( uv.st );
        vec2 st1 = dFdy( uv.st );

        vec3 N = normalize( 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;

        // From three-vrm specific change: Workaround for the issue that happens when delta of uv = 0.0
        // TODO: Is this still required? Or shall I make a PR about it?
        if ( length( T ) == 0.0 || length( B ) == 0.0 ) {
          return surf_norm;
        }

        float det = max( dot( T, T ), dot( B, B ) );
        float scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );

        return normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );
    }
#endif


#ifdef USE_UVANIMATIONMASKTEXTURE
    uniform sampler2D uvAnimationMaskTexture;
    uniform mat3 uvAnimationMaskTextureUvTransform;
#endif

uniform float uvAnimationScrollXOffset;
uniform float uvAnimationScrollYOffset;
uniform float uvAnimationRotationPhase;

// Apply UV Animation to a given UV coordinate
vec2 applyUvAnimation(vec2 uv) {
    #ifdef USE_UVANIMATIONMASKTEXTURE
        vec2 uvAnimationMaskTextureUv = ( uvAnimationMaskTextureUvTransform * vec3( uv, 1 ) ).xy;
        float uvAnimMask = texture2D( uvAnimationMaskTexture, uvAnimationMaskTextureUv ).b;
    #else
        float uvAnimMask = 1.0;
    #endif

    float uvRotCos = cos( uvAnimationRotationPhase * uvAnimMask );
    float uvRotSin = sin( uvAnimationRotationPhase * uvAnimMask );
    uv = mat2( uvRotCos, -uvRotSin, uvRotSin, uvRotCos ) * ( uv - 0.5 ) + 0.5;
    uv = uv + vec2( uvAnimationScrollXOffset, uvAnimationScrollYOffset ) * uvAnimMask;
    
    return uv;
}
`
), vn = (
  /* glsl */
  `
#ifdef FORWARD_PASS
    float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
	    return smoothstep( coneCosine, penumbraCosine, angleCosine );
    }

    float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
		// based upon Frostbite 3 Moving to Physically-based Rendering
		// page 32, equation 26: E[window1]
		// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
		float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );

		if ( cutoffDistance > 0.0 ) {
            distanceFalloff *= pow( saturate( 1.0 - pow( lightDistance / cutoffDistance, 4.0 ) ), 2.0 );
		};

		return distanceFalloff;
    }

	vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
        vec3 irradiance = ambientLightColor;
		return irradiance;
	}
	vec3 getIBLIrradiance( const in vec3 envMapColor ) {
        return envMapColor.rgb;
	}

    // Point Lights
    #ifdef USE_POINT_LIGHTS
    #ifndef NUM_POINT_LIGHTS
    #define NUM_POINT_LIGHTS 0
    #endif
    struct PointLight {
        vec3 position;
        vec3 color;
        float distance;
        float decay;
    };
    #if NUM_POINT_LIGHTS > 0
    uniform PointLight pointLights[NUM_POINT_LIGHTS];
    #endif

    void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {
        vec3 lVector = pointLight.position - geometry.position;
        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

    // Spot Lights
    #ifdef USE_SPOT_LIGHTS
    #ifndef NUM_SPOT_LIGHTS
    #define NUM_SPOT_LIGHTS 0
    #endif
    struct SpotLight {
        vec3 position;
        vec3 direction;
        vec3 color;
        float distance;
        float decay;
        float coneCos;
        float penumbraCos;
    };
    #if NUM_SPOT_LIGHTS > 0
    uniform SpotLight spotLights[NUM_SPOT_LIGHTS];
    #endif

    void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {
        vec3 lVector = spotLight.position - geometry.position;
        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

    // Directional Lights
    #ifdef USE_DIR_LIGHTS
    #ifndef NUM_DIR_LIGHTS
    #define NUM_DIR_LIGHTS 0
    #endif
    struct DirectionalLight {
        vec3 direction;
        vec3 color;
    };
    #if NUM_DIR_LIGHTS > 0
        uniform DirectionalLight directionalLights[NUM_DIR_LIGHTS];
    #endif

    void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {
        light.color = directionalLight.color;

        light.direction = directionalLight.direction;
        light.visible = true;
    }
    #endif
    
#endif
`
), Sn = (
  /* glsl */
  `
#ifdef FORWARD_PASS

    vec2 uv = vec2(0.5, 0.5);
    #ifdef VARYING_VUV0
        uv = vUv0;
        uv = applyUvAnimation(uv);
    #endif

    float finalOpacity = gl_FragColor.a; // result from "outputAlphaPS"
    vec4 diffuseColor = vec4( material_diffuse, finalOpacity );
    #if LIT_BLEND_TYPE == PREMULTIPLIED
        diffuseColor.rgb *= litArgs_opacity; // get premultiplied rgb
    #endif

    #ifdef STD_DIFFUSE_TEXTURE
        vec2 colorMapUv = ( mapUvTransform * vec3( uv, 1 ) ).xy;
        vec3 albedoTexture = {STD_DIFFUSE_TEXTURE_DECODE}(texture2DBias({STD_DIFFUSE_TEXTURE_NAME}, colorMapUv, textureBias)).{STD_DIFFUSE_TEXTURE_CHANNEL};
        diffuseColor.rgb *= albedoTexture;
    #endif

    float faceDirection = gl_FrontFacing ? 1.0 : -1.0;
    vec3 normal = normalize( vNormal );
    normal *= faceDirection;

    #ifdef OUTLINE
        normal *= -1.0;
    #endif

    #ifdef USE_NORMALMAP
        vec2 normalMapUv = ( normalMapUvTransform * vec3( uv, 1 ) ).xy;

        #ifdef SHADERDEF_TANGENTS
            mat3 tbn = mat3( normalize( vTangentW ), normalize( vBinormalW ), normal );
        #else
            mat3 tbn = getTangentFrame( - vViewPosition, normal, normalMapUv );
        #endif

        vec3 mapN = texture2D( normalMap, normalMapUv ).xyz * 2.0 - 1.0;
        mapN.xy *= normalScale;

        #if defined(SHADERDEF_TANGENTS)
            normal = normalize( tbn * mapN );
        #else
            normal = perturbNormal2Arb( uv, -vViewPosition, normal, mapN, faceDirection );
        #endif
    #endif

    vec3 totalEmissiveRadiance = material_emissive * material_emissiveIntensity;
    #ifdef STD_EMISSIVE_TEXTURE
        vec2 emissiveMapUv = (emissiveMapUvTransform * vec3( uv, 1 )).xy;
        vec3 emissiveTexture = {STD_EMISSIVE_TEXTURE_DECODE}(texture2DBias({STD_EMISSIVE_TEXTURE_NAME}, emissiveMapUv, textureBias)).{STD_EMISSIVE_TEXTURE_CHANNEL};
        totalEmissiveRadiance *= emissiveTexture;
    #endif


    // -- MToon: lighting --------------------------------------------------------
    MToonMaterial material;
    material.diffuseColor = diffuseColor.rgb;
    material.shadeColor = shadeColorFactor;

    #ifdef USE_SHADEMULTIPLYTEXTURE
        vec2 shadeMultiplyTextureUv = ( shadeMultiplyTextureUvTransform * vec3( uv, 1 ) ).xy;
        vec3 shadeMultiply = texture2D( shadeMultiplyTexture, shadeMultiplyTextureUv ).rgb;
        shadeMultiply = decodeGamma(shadeMultiply); // convert to linear
        material.shadeColor *= shadeMultiply;
    #endif

    material.shadingShift = shadingShiftFactor;
    #ifdef USE_SHADINGSHIFTTEXTURE
        vec2 shadingShiftTextureUv = ( shadingShiftTextureUvTransform * vec3( uv, 1 ) ).xy;
        material.shadingShift += texture2D( shadingShiftTexture, shadingShiftTextureUv ).r * shadingShiftTextureScale;
    #endif    


    GeometricContext geometry;
    geometry.position = - vViewPosition;
    geometry.normal = normal;
    geometry.viewDir = normalize( vViewPosition );

    ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
    IncidentLight directLight;
    // since these variables will be used in unrolled loop, we have to define in prior
    float shadow = 1.0;

    // Point Lights - loop controlled by define
    #ifdef USE_POINT_LIGHTS
    #if NUM_POINT_LIGHTS > 0
    {
        PointLight pointLight;
        for ( int i = 0; i < NUM_POINT_LIGHTS; i++ ) {
            pointLight = pointLights[i];
            getPointLightInfo( pointLight, geometry, directLight );
            RE_Direct( directLight, geometry, material, shadow, reflectedLight );
        }
    }
    #endif
    #endif

    // Spot Lights - loop controlled by define
    #ifdef USE_SPOT_LIGHTS
    #if NUM_SPOT_LIGHTS > 0
    {
        SpotLight spotLight;
        for ( int i = 0; i < NUM_SPOT_LIGHTS; i++ ) {
            spotLight = spotLights[i];
            getSpotLightInfo( spotLight, geometry, directLight );
            RE_Direct( directLight, geometry, material, shadow, reflectedLight );
        }
    }
    #endif
    #endif

    // Directional Lights - loop controlled by define
    #ifdef USE_DIR_LIGHTS
    #if NUM_DIR_LIGHTS > 0
    {
        DirectionalLight directionalLight;
        for ( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {
            directionalLight = directionalLights[i];
            getDirectionalLightInfo( directionalLight, directLight );  
            RE_Direct( directLight, geometry, material, shadow, reflectedLight );
        }
    }
    #endif
    #endif 

    // -- MToon: Ambient --------------------------------------------------------
    vec3 iblIrradiance = vec3( 0.0 );
    vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );


    // From three.js #include <lights_fragment_maps>
    // -- MToon: Environment --------------------------------------------------------
	#ifdef USE_ENV_LIGHTS
		vec3 dir = normalize(cubeMapRotate(vNormal) * vec3(-1.0, 1.0, 1.0));
        vec2 envuv = mapUv(toSphericalUv(dir), vec4(128.0, 256.0 + 128.0, 64.0, 32.0) / atlasSize);
        vec4 raw = texture2D(texture_envAtlas, envuv);
        vec3 linear = decodeLinear(raw);
        irradiance += getIBLIrradiance(linear);
	#endif


    // From three.js #include <lights_fragment_end>
    RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );

    float directDiffuseIntensity = 2.5; // Boost the effect of direct light
    reflectedLight.directDiffuse *= directDiffuseIntensity;
    vec3 col = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;
    col = min( col, material.diffuseColor * 1.2 ); // Slightly boost the cap to allow brighter lighting

 
    // -- MToon: rim lighting -----------------------------------------
    vec3 viewDir = normalize( vViewDirection );

    vec3 rimMix = mix( vec3( 1.0 ), reflectedLight.directSpecular, rimLightingMixFactor );
    vec3 rim = parametricRimColorFactor * pow( saturate( 1.0 - dot( viewDir, normal ) + parametricRimLiftFactor ), parametricRimFresnelPowerFactor );

    #ifdef USE_MATCAPTEXTURE
        {
          vec3 x = normalize( vec3( viewDir.z, 0.0, -viewDir.x ) );
          vec3 y = cross( viewDir, x ); // guaranteed to be normalized
          vec2 sphereUv = vec2(dot(x, normal), dot(y, normal)) * 0.5 + 0.5;
          sphereUv = ( matcapTextureUvTransform * vec3( sphereUv, 1 ) ).xy;
          vec3 matcap = texture2D( matcapTexture, sphereUv ).rgb;
          matcap = decodeGamma(matcap); // convert to linear
          rim += matcapFactor * matcap;
        }
    #endif


    #ifdef USE_RIMMULTIPLYTEXTURE
        vec2 rimMultiplyTextureUv = ( rimMultiplyTextureUvTransform * vec3( uv, 1 ) ).xy;
        vec3 rimMultiply = texture2D( rimMultiplyTexture, rimMultiplyTextureUv ).rgb;
        rimMultiply = decodeGamma(rimMultiply); // convert to linear
        rim *= rimMultiply;
    #endif


    col += rimMix * rim;

    // -- MToon: Emission --------------------------------------------------------
    col += totalEmissiveRadiance;

    // -- MToon: Outline --------------------------------------------------------
    #ifdef OUTLINE
        col = outlineColorFactor.rgb * mix( vec3( 1.0 ), col, outlineLightingMixFactor );
    #endif

    gl_FragColor = vec4( col, diffuseColor.a );
    gl_FragColor.rgb = addFog(gl_FragColor.rgb);
    gl_FragColor.rgb = toneMap(gl_FragColor.rgb);
    gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);
#endif
`
), En = (
  /* glsl */
  `
uniform float material_opacity;

void getOpacity() {
    dAlpha = material_opacity;

    #ifdef STD_OPACITY_TEXTURE
    vec2 opacityUv = {STD_OPACITY_TEXTURE_UV};
    opacityUv = applyUvAnimation(opacityUv);

    dAlpha *= texture2DBias({STD_OPACITY_TEXTURE_NAME}, opacityUv, textureBias).{STD_OPACITY_TEXTURE_CHANNEL};
    #endif

    #ifdef STD_OPACITY_VERTEX
    dAlpha *= clamp(vVertexColor.{STD_OPACITY_VERTEX_CHANNEL}, 0.0, 1.0);
    #endif
}
`
), An = `${vn}`, st = {
  litUserDeclarationVS: fn,
  litUserMainEndVS: gn,
  litUserDeclarationPS: yn,
  litUserCodePS: An,
  litUserMainEndPS: Sn,
  opacityPS: En
};
class Tn {
  constructor(t) {
    this._pcRef = t, this._app = null, this.lightStateInfo = null, this.defaultInfoSetting = {
      directionalLight: {
        direction: new t.Vec3(0, 0, 0),
        color: new t.Color(0, 0, 0)
      },
      spotLight: {
        position: new t.Vec3(0, 0, 0),
        direction: new t.Vec3(0, 0, 0),
        color: new t.Color(0, 0, 0),
        distance: 0,
        decay: 0,
        coneCos: 0,
        penumbraCos: 0
      },
      pointLight: {
        position: new t.Vec3(0, 0, 0),
        color: new t.Color(0, 0, 0),
        distance: 0,
        decay: 0
      }
    };
  }
  _updateLightInfo(t) {
    this.lightStateInfo = this.convertLightStateInfo(t);
  }
  setApp(t) {
    this._app || (this._app = t);
  }
  convertLightStateInfo(t) {
    const e = t[this._pcRef.LIGHTTYPE_DIRECTIONAL], i = t[this._pcRef.LIGHTTYPE_SPOT], n = t[this._pcRef.LIGHTTYPE_POINT], s = {
      directionalLights: [],
      spotLights: [],
      pointLights: [],
      ...this._app && {
        scene: {
          envAtlas: this._app.scene.envAtlas || null,
          ambientLight: this._app.scene.ambientLight
        }
      }
    };
    return s.directionalLights = e.map((r) => {
      if (r._node === null)
        return this.defaultInfoSetting.directionalLight;
      const o = r._node.light, l = new this._pcRef.Color(
        o.color.r * o.intensity,
        o.color.g * o.intensity,
        o.color.b * o.intensity
      );
      return {
        direction: r._direction,
        color: l
      };
    }), s.spotLights = i.map((r) => {
      if (r._node === null)
        return this.defaultInfoSetting.spotLight;
      const o = r._node.light, l = new this._pcRef.Color(
        o.color.r * o.intensity,
        o.color.g * o.intensity,
        o.color.b * o.intensity
      );
      return {
        position: r._node.getPosition(),
        direction: r._node.forward,
        color: l,
        distance: o.range,
        decay: r.falloffMode === this._pcRef.LIGHTFALLOFF_LINEAR ? 1 : 2,
        coneCos: Math.cos(o.innerConeAngle),
        penumbraCos: Math.cos(o.outerConeAngle)
      };
    }), s.pointLights = n.map((r) => {
      if (r._node === null)
        return this.defaultInfoSetting.pointLight;
      const o = r._node.light, l = new this._pcRef.Color(
        o.color.r * o.intensity,
        o.color.g * o.intensity,
        o.color.b * o.intensity
      );
      return {
        position: r._node.getPosition(),
        color: l,
        distance: o.range,
        decay: r.falloffMode === this._pcRef.LIGHTFALLOFF_LINEAR ? 1 : 2
      };
    }), s;
  }
  update() {
    if (!this._app)
      return;
    const t = this._app.scene.layers.getLayerById(this._pcRef.LAYERID_WORLD);
    if (t) {
      const e = t.splitLights;
      this._updateLightInfo(e);
    }
  }
}
class wn {
  /**
   * Applies preprocessed material settings to the given PlayCanvas material.
   * Reference: playcanvas glb-parser.js implementation
   *
   * Note: Playcanvas dose not have beforeRoot timing to remove this extension like three.js,
   * only way is to restore here as a workaround.
   */
  static applyToMaterial(t, e, i, n) {
    var s, r;
    if (((s = e?.extensions) == null ? void 0 : s.KHR_materials_unlit) !== void 0 || ((r = i.extensionsUsed) == null ? void 0 : r.includes("KHR_materials_unlit"))) {
      if (t.diffuseMap = t.emissiveMap, t.diffuseMapUv = t.emissiveMapUv, t.diffuseMapTiling.copy(t.emissiveMapTiling), t.diffuseMapOffset.copy(t.emissiveMapOffset), t.diffuseMapRotation = t.emissiveMapRotation, t.diffuseMapChannel = t.emissiveMapChannel, t.diffuse.copy(t.emissive), e.hasOwnProperty("pbrMetallicRoughness")) {
        const l = e.pbrMetallicRoughness;
        if (l && l.hasOwnProperty("baseColorFactor")) {
          const [c, h, u, d] = l.baseColorFactor;
          t.diffuse.set(c, h, u).gamma(), t.opacity = d;
        }
      }
      if (e.hasOwnProperty("emissiveFactor")) {
        const [l, c, h] = e.emissiveFactor.map((u) => Math.max(1e-4, u));
        t.emissive.set(l, c, h).gamma();
      }
    }
    if (e.hasOwnProperty("alphaMode"))
      switch (e.alphaMode) {
        case "MASK":
          t.blendType = n.BLEND_NONE, e.hasOwnProperty("alphaCutoff") ? t.alphaTest = e.alphaCutoff : t.alphaTest = 0.5;
          break;
        case "BLEND":
          t.blendType = n.BLEND_NORMAL, t.depthWrite = !1;
          break;
        default:
        case "OPAQUE":
          t.blendType = n.BLEND_NONE;
          break;
      }
    else
      t.blendType = n.BLEND_NONE;
    e.hasOwnProperty("doubleSided") && e.doubleSided !== void 0 ? (t.twoSidedLighting = e.doubleSided, t.cull = e.doubleSided ? n.CULLFACE_NONE : n.CULLFACE_BACK) : (t.twoSidedLighting = !1, t.cull = n.CULLFACE_BACK);
  }
}
const Tt = "KHR_texture_transform";
function Ft(a) {
  const { pcApp: t, pcRef: e, asset: i, isOutline: n = !1 } = a, s = new e.StandardMaterial();
  return s.isMtoonMaterial = !0, s.isOutline = n, s.mapUvTransform = new e.Mat3(), s.normalMapUvTransform = new e.Mat3(), s.normalScale = new e.Vec2(1, 1), s.emissiveMapUvTransform = new e.Mat3(), s.shadeColorFactor = new e.Color(0, 0, 0, 1), s.shadeMultiplyTexture = null, s.shadeMultiplyTextureUvTransform = new e.Mat3(), s.shadingShiftFactor = 0, s.shadingShiftTexture = null, s.shadingShiftTextureUvTransform = new e.Mat3(), s.shadingShiftTextureScale = 1, s.shadingToonyFactor = 0.9, s.giEqualizationFactor = 0, s.matcapFactor = new e.Color(1, 1, 1, 1), s.matcapTexture = null, s.matcapTextureUvTransform = new e.Mat3(), s.parametricRimColorFactor = new e.Color(0, 0, 0, 1), s.rimMultiplyTexture = null, s.rimMultiplyTextureUvTransform = new e.Mat3(), s.rimLightingMixFactor = 0, s.parametricRimFresnelPowerFactor = 5, s.parametricRimLiftFactor = 0, s.uvAnimationMaskTexture = null, s.uvAnimationMaskTextureUvTransform = new e.Mat3(), s.uvAnimationScrollXOffset = 0, s.uvAnimationScrollYOffset = 0, s.uvAnimationRotationPhase = 0, s.uvAnimationScrollXSpeed = 0, s.uvAnimationScrollYSpeed = 0, s.uvAnimationRotationSpeed = 0, s.v0CompatShade = !1, s.outlineWidthMode = Mt.None, s.outlineWidthMultiplyTexture = null, s.outlineWidthMultiplyTextureUvTransform = new e.Mat3(), s.outlineWidthFactor = 0.02, s.outlineColorFactor = new e.Color(1, 0.5, 0, 1), s.outlineLightingMixFactor = 0, s._asset = i, s._vec3A = new e.Vec3(), s._currentDirLights = 0, s._currentSpotLights = 0, s._currentPointLights = 0, s._pcApp = t, s._renderStates = new Tn(e), s.parse = function() {
    var r, o, l, c, h, u, d, p, m, f, _, g, v, y, T;
    const { gltfMaterial: A, gltf: w, sourceMaterial: M, isOutline: P } = a;
    s.copy(M), P && (this.name = M.name + "_outline"), wn.applyToMaterial(this, A, w, e);
    const C = (r = A?.extensions) == null ? void 0 : r[De], {
      shadeColorFactor: L,
      shadeMultiplyTexture: z,
      shadingShiftFactor: k,
      shadingToonyFactor: D,
      parametricRimColorFactor: I,
      rimLightingMixFactor: G,
      parametricRimFresnelPowerFactor: et,
      parametricRimLiftFactor: W,
      shadingShiftTexture: N,
      giEqualizationFactor: R,
      rimMultiplyTexture: U,
      matcapTexture: B,
      matcapFactor: j,
      outlineWidthFactor: it,
      outlineColorFactor: Z,
      outlineLightingMixFactor: at,
      outlineWidthMode: mt,
      outlineWidthMultiplyTexture: lt,
      transparentWithZWrite: jt,
      v0CompatShade: ft,
      uvAnimationMaskTexture: J,
      uvAnimationScrollXSpeedFactor: gt,
      uvAnimationScrollYSpeedFactor: ct,
      uvAnimationRotationSpeedFactor: yt
    } = C;
    if (ft !== void 0 && (this.v0CompatShade = ft), gt !== void 0 && (this.uvAnimationScrollXSpeed = gt), ct !== void 0 && (this.uvAnimationScrollYSpeed = ct), yt !== void 0 && (this.uvAnimationRotationSpeed = yt), R !== void 0 && (this.giEqualizationFactor = R), L && (this.shadeColorFactor = new e.Color(
      L[0],
      L[1],
      L[2],
      1
    )), z !== void 0) {
      const V = this._asset.resource, O = (l = (o = V?.textures) == null ? void 0 : o[z.index]) == null ? void 0 : l.resource;
      O && (this.shadeMultiplyTexture = O, At(
        e,
        this.shadeMultiplyTextureUvTransform,
        (c = z.extensions) == null ? void 0 : c[Tt]
      ));
    }
    if (U !== void 0) {
      const V = this._asset.resource, O = (u = (h = V?.textures) == null ? void 0 : h[U.index]) == null ? void 0 : u.resource;
      O && (this.rimMultiplyTexture = O, At(
        e,
        this.rimMultiplyTextureUvTransform,
        (d = U.extensions) == null ? void 0 : d[Tt]
      ));
    }
    if (B !== void 0) {
      const V = this._asset.resource, O = (m = (p = V?.textures) == null ? void 0 : p[B.index]) == null ? void 0 : m.resource;
      O && (this.matcapTexture = O);
    }
    if (N !== void 0) {
      const V = this._asset.resource, O = (_ = (f = V?.textures) == null ? void 0 : f[N.index]) == null ? void 0 : _.resource;
      O && (this.shadingShiftTexture = O, At(
        e,
        this.shadingShiftTextureUvTransform,
        (g = N.extensions) == null ? void 0 : g[Tt]
      )), N.scale !== void 0 && (this.shadingShiftTextureScale = N.scale);
    }
    if (j && (this.matcapFactor = new e.Color(j[0], j[1], j[2], 1)), this.shadingShiftFactor = k, this.shadingToonyFactor = D, I && (this.parametricRimColorFactor = new e.Color(
      I[0],
      I[1],
      I[2],
      1
    )), this.rimLightingMixFactor = G, this.parametricRimFresnelPowerFactor = et, this.parametricRimLiftFactor = W, jt && (this.depthWrite = !0), it !== void 0 && (this.outlineWidthFactor = it), Z && (this.outlineColorFactor = new e.Color(
      Z[0],
      Z[1],
      Z[2],
      1
    )), mt && (this.outlineWidthMode = mt), lt !== void 0) {
      const V = this._asset.resource, O = (y = (v = V?.textures) == null ? void 0 : v[lt.index]) == null ? void 0 : y.resource;
      O && (this.outlineWidthMultiplyTexture = O, At(
        e,
        this.outlineWidthMultiplyTextureUvTransform,
        (T = lt.extensions) == null ? void 0 : T[Tt]
      ));
    }
    at !== void 0 && (this.outlineLightingMixFactor = at), this.isOutline && (this.cull = e.CULLFACE_FRONT), this._setShaderChunks(), this._setShaderUniforms(), this._setRenderStateUpdater(), this.update();
  }, s._setRenderStateUpdater = function() {
    this._renderStates.setApp(this._pcApp), this._updateCallback = (r) => {
      this._renderStates.update();
      const o = this._renderStates.lightStateInfo;
      o && this.updateLightState(o), this.updateUvAnimation(r);
    }, this._pcApp.on("update", this._updateCallback), this._updateCallback(0);
  }, s.onUpdateShader = function(r) {
    return this.shadeMultiplyTexture && r.defines.set("USE_SHADEMULTIPLYTEXTURE", ""), this.normalMap && r.defines.set("USE_NORMALMAP", ""), this.matcapTexture && r.defines.set("USE_MATCAPTEXTURE", ""), this.v0CompatShade && r.defines.set("V0_COMPAT_SHADE", ""), this.rimMultiplyTexture && r.defines.set("USE_RIMMULTIPLYTEXTURE", ""), this.uvAnimationMaskTexture !== null && r.defines.set("USE_UVANIMATIONMASKTEXTURE", ""), this.outlineWidthMultiplyTexture !== null && r.defines.set("USE_OUTLINEWIDTHMULTIPLYTEXTURE", ""), this.outlineWidthMode === Mt.WorldCoordinates && r.defines.set("OUTLINE_WIDTH_WORLD", ""), this.outlineWidthMode === Mt.ScreenCoordinates && r.defines.set("OUTLINE_WIDTH_SCREEN", ""), this.isOutline && r.defines.set("OUTLINE", ""), this.envAtlas && r.defines.set("USE_ENV_LIGHTS", ""), r.defines.set("NUM_DIR_LIGHTS", this._currentDirLights.toString()), r.defines.set("NUM_SPOT_LIGHTS", this._currentSpotLights.toString()), r.defines.set("NUM_POINT_LIGHTS", this._currentPointLights.toString()), this._currentDirLights > 0 && r.defines.set("USE_DIR_LIGHTS", ""), this._currentSpotLights > 0 && r.defines.set("USE_SPOT_LIGHTS", ""), this._currentPointLights > 0 && r.defines.set("USE_POINT_LIGHTS", ""), r;
  }, s._setShaderChunks = function() {
    this.shaderChunksVersion = "2.8";
    const r = e.SHADERLANGUAGE_GLSL;
    this.getShaderChunks(r).set("litUserDeclarationVS", st.litUserDeclarationVS), this.getShaderChunks(r).set("litUserMainEndVS", st.litUserMainEndVS), this.getShaderChunks(r).set("litUserDeclarationPS", st.litUserDeclarationPS), this.getShaderChunks(r).set("litUserCodePS", st.litUserCodePS), this.getShaderChunks(r).set("litUserMainEndPS", st.litUserMainEndPS), this.getShaderChunks(r).set("opacityPS", st.opacityPS);
  }, s._setShaderUniforms = function() {
    this.setParameters("giEqualizationFactor", this.giEqualizationFactor), this.setParameter("shadeColorFactor", [
      this.shadeColorFactor.r,
      this.shadeColorFactor.g,
      this.shadeColorFactor.b
    ]), this.shadeMultiplyTexture && (this.setParameter("shadeMultiplyTexture", this.shadeMultiplyTexture), this.setParameter(
      "shadeMultiplyTextureUvTransform",
      this.shadeMultiplyTextureUvTransform.data
    )), this.matcapTexture && (this.setParameter("matcapTexture", this.matcapTexture), this.setParameter("matcapTextureUvTransform", this.matcapTextureUvTransform.data)), this.setParameter("matcapFactor", [
      this.matcapFactor.r,
      this.matcapFactor.g,
      this.matcapFactor.b
    ]), this.shadingShiftTexture && this.setParameter("shadingShiftTexture", this.shadingShiftTexture), this.setParameter("shadingShiftTextureUvTransform", this.shadingShiftTextureUvTransform.data), this.setParameter("mapUvTransform", this.mapUvTransform.data), this.setParameter("shadingShiftFactor", this.shadingShiftFactor), this.setParameter("shadingToonyFactor", this.shadingToonyFactor), this.setParameter("parametricRimColorFactor", [
      this.parametricRimColorFactor.r,
      this.parametricRimColorFactor.g,
      this.parametricRimColorFactor.b
    ]), this.setParameter("rimLightingMixFactor", this.rimLightingMixFactor), this.setParameter("parametricRimFresnelPowerFactor", this.parametricRimFresnelPowerFactor), this.setParameter("parametricRimLiftFactor", this.parametricRimLiftFactor), this.normalMap && (this.setParameter("normalMap", this.normalMap), this.setParameter("normalScale", [this.normalScale.x, this.normalScale.y])), this.setParameter("normalMapUvTransform", this.normalMapUvTransform.data), this.setParameter("emissiveMapUvTransform", this.emissiveMapUvTransform.data), this.setParameter("shadingShiftTextureScale", this.shadingShiftTextureScale), this.matcapTexture && this.setParameter("matcapTexture", this.matcapTexture), this.rimMultiplyTexture && (this.setParameter("rimMultiplyTexture", this.rimMultiplyTexture), this.setParameter("rimMultiplyTextureUvTransform", this.rimMultiplyTextureUvTransform.data)), this.outlineWidthMultiplyTexture && (this.setParameter("outlineWidthMultiplyTexture", this.outlineWidthMultiplyTexture), this.setParameter(
      "outlineWidthMultiplyTextureUvTransform",
      this.outlineWidthMultiplyTextureUvTransform.data
    )), this.setParameter("outlineWidthFactor", this.outlineWidthFactor), this.setParameter("outlineLightingMixFactor", this.outlineLightingMixFactor), this.setParameter("outlineColorFactor", [
      this.outlineColorFactor.r,
      this.outlineColorFactor.g,
      this.outlineColorFactor.b
    ]), this.setParameter("uvAnimationScrollXOffset", this.uvAnimationScrollXOffset), this.setParameter("uvAnimationScrollYOffset", this.uvAnimationScrollYOffset), this.setParameter("uvAnimationRotationPhase", this.uvAnimationRotationPhase);
  }, s.updateLightState = function(r) {
    const { directionalLights: o, spotLights: l, pointLights: c, scene: h } = r;
    this._updateIndirectLightUniforms(h), o.forEach((f, _) => {
      const g = f.direction;
      this._vec3A.copy(g), this._vec3A.mulScalar(-1), this._vec3A.normalize();
      const v = f.color;
      this.setParameter(`directionalLights[${_}].color`, [v.r, v.g, v.b]), this.setParameter(`directionalLights[${_}].direction`, [
        this._vec3A.x,
        this._vec3A.y,
        this._vec3A.z
      ]);
    }), l.forEach((f, _) => {
      const g = f.position, v = f.direction, y = f.color, T = f.distance, A = f.decay, w = f.coneCos, M = f.penumbraCos;
      this.setParameter(`spotLights[${_}].position`, [g.x, g.y, g.z]), this.setParameter(`spotLights[${_}].direction`, [v.x, v.y, v.z]), this.setParameter(`spotLights[${_}].color`, [y.r, y.g, y.b]), this.setParameter(`spotLights[${_}].distance`, T), this.setParameter(`spotLights[${_}].decay`, A), this.setParameter(`spotLights[${_}].coneCos`, w), this.setParameter(`spotLights[${_}].penumbraCos`, M);
    }), c.forEach((f, _) => {
      const g = f.position, v = f.color, y = f.distance, T = f.decay;
      this.setParameter(`pointLights[${_}].position`, [g.x, g.y, g.z]), this.setParameter(`pointLights[${_}].color`, [v.r, v.g, v.b]), this.setParameter(`pointLights[${_}].distance`, y), this.setParameter(`pointLights[${_}].decay`, T);
    });
    const u = o.length, d = l.length, p = c.length;
    (u !== this._currentDirLights || d !== this._currentSpotLights || p !== this._currentPointLights) && (this._currentDirLights = u, this._currentSpotLights = d, this._currentPointLights = p, this.update());
  }, s._updateIndirectLightUniforms = function(r) {
    r && (!this.envAtlas && r.envAtlas && (this.envAtlas = r.envAtlas), this.envAtlas ? this.setParameter("ambientLightColor", [0, 0, 0]) : (this.ambient.copy(r.ambientLight), this.setParameter("ambientLightColor", [this.ambient.r, this.ambient.g, this.ambient.b])));
  }, s.updateUvAnimation = function(r) {
    this.uvAnimationScrollXOffset += this.uvAnimationScrollXSpeed * r, this.setParameter("uvAnimationScrollXOffset", this.uvAnimationScrollXOffset), this.uvAnimationScrollYOffset += this.uvAnimationScrollYSpeed * r, this.setParameter("uvAnimationScrollYOffset", this.uvAnimationScrollYOffset), this.uvAnimationRotationPhase += this.uvAnimationRotationSpeed * r, this.setParameter("uvAnimationRotationPhase", this.uvAnimationRotationPhase);
  }, s.destroy = function() {
    e.StandardMaterial.prototype.destroy.call(this), this._updateCallback && (this._pcApp.off("update", this._updateCallback), this._updateCallback = void 0);
  }, s.clone = function() {
    return Ft(a);
  }, s.parse(), s;
}
const de = De;
class xn {
  constructor(t, e, i) {
    this._pcApp = t, this._pcRef = e, this.asset = i;
  }
  instantiated(t) {
    var e;
    const i = this.asset.resource;
    if (!((e = i?.data) != null && e.gltf))
      return console.error("applyMaterialMtoon: gltf is undefined"), [];
    const n = i.data.gltf, s = [];
    return this._applyVRMCOutlineShader(t, n, s), this._applyVRMCMtoonShader(t, n, s), s;
  }
  _applyVRMCOutlineShader(t, e, i) {
    const n = t.findComponents("render"), s = /* @__PURE__ */ new Map();
    n.forEach((r) => {
      const o = r, l = o.meshInstances;
      l.forEach((c) => {
        var h, u, d;
        const p = c.material;
        let m = s.get(p);
        if (!m) {
          const _ = ((h = p.userId.split("_")) == null ? void 0 : h[1]) ?? -1, g = parseInt(_);
          if (g === -1)
            return;
          const v = (u = e.materials) == null ? void 0 : u[g];
          if (!v) {
            console.error("applyVRMCOutlineShader: gltfMaterial is undefined");
            return;
          }
          const y = (d = v?.extensions) == null ? void 0 : d[de];
          if (!y || y.outlineWidthMode === Mt.None)
            return;
          m = Ft({
            pcApp: this._pcApp,
            pcRef: this._pcRef,
            asset: this.asset,
            isOutline: !0,
            sourceMaterial: p,
            gltfMaterial: v,
            gltf: e
          }), s.set(p, m);
        }
        const f = new this._pcRef.MeshInstance(
          c.mesh,
          m,
          o.entity
        );
        if (c.morphInstance) {
          const _ = c.morphInstance.clone();
          f.morphInstance = _;
        }
        l.push(f), i.push({
          meshInstance: f,
          sourceMaterial: p,
          shaderMaterial: m
        });
      });
    });
  }
  _applyVRMCMtoonShader(t, e, i) {
    const n = /* @__PURE__ */ new Map();
    t.findComponents("render").forEach((r) => {
      r.meshInstances.forEach((c) => {
        var h, u, d;
        if (c.material.isMtoonMaterial)
          return;
        const p = c.material;
        let m = n.get(p);
        const f = ((h = p.userId.split("_")) == null ? void 0 : h[1]) ?? -1, _ = parseInt(f);
        if (_ === -1)
          return;
        const g = (u = e.materials) == null ? void 0 : u[_];
        if (!g) {
          console.error("applyVRMCMtoonShader: gltfMaterial is undefined");
          return;
        }
        (d = g?.extensions) != null && d[de] && (m || (m = Ft({
          pcApp: this._pcApp,
          pcRef: this._pcRef,
          asset: this.asset,
          sourceMaterial: p,
          gltfMaterial: g,
          gltf: e
        }), n.set(p, m)), i.push({
          meshInstance: c,
          sourceMaterial: p,
          shaderMaterial: m
        }), c.material = m);
      });
    });
  }
}
const bn = (a) => {
  class t extends a.ScriptType {
    constructor() {
      super(...arguments), this.autoInitialize = !0, this.materialMappings = [];
    }
    initialize() {
      this._initializeMtoon(), this._setEnabled(this.autoInitialize), this.entity.on("vrm-mtoon:set-enabled", this._setEnabled, this), this.on("destroy", () => {
        this.entity.off("vrm-mtoon:set-enabled", this._setEnabled, this);
      });
    }
    _initializeMtoon() {
      this._convertVRMMtoonMaterials(a, this.asset);
      const n = new xn(this.app, a, this.asset).instantiated(this.entity);
      this.materialMappings = n;
    }
    _setEnabled(i) {
      i ? this._activateMtoon() : this._deactivateMtoon(), this.entity.fire("vrm-mtoon:materials-changed", i);
    }
    _activateMtoon() {
      this.materialMappings.forEach(({ meshInstance: i, shaderMaterial: n }) => {
        i.material = n, i.material.update(), n.isOutline && (i.visible = !0);
      });
    }
    _deactivateMtoon() {
      this.materialMappings.forEach(({ meshInstance: i, sourceMaterial: n, shaderMaterial: s }) => {
        i.material = n, i.material.update(), s.isOutline && (i.visible = !1);
      });
    }
    _convertVRMMtoonMaterials(i, n) {
      var s, r;
      new mn(i, n).parseMaterials();
      const l = n.resource;
      (r = (s = l?.data) == null ? void 0 : s.materials) == null || r.forEach((c, h) => {
        c.userId = `material_${h}`;
      });
    }
  }
  a.registerScript(t, "vrmMtoon"), t.attributes.add("asset", {
    type: "asset",
    description: "Set the container asset loaded from vrm avatar."
  }), t.attributes.add("autoInitialize", {
    type: "boolean",
    description: "Initialize MToon materials on script initialization.",
    default: !0
  });
}, Ne = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  importScript: bn
}, Symbol.toStringTag, { value: "Module" }));
class Oe {
  constructor(t) {
    this.humanBones = t;
  }
  /**
   * Return a bone bound to a specified {@link VRMHumanBoneName}, as a {@link VRMHumanBone}.
   *
   * @param name Name of the bone you want
   */
  getBone(t) {
    return this.humanBones[t] ?? void 0;
  }
  getBoneNode(t) {
    var e;
    return ((e = this.humanBones[t]) == null ? void 0 : e.node) ?? null;
  }
}
class Ut extends Oe {
  static _setupTransforms(t, e) {
    const i = new t.Entity();
    i.name = "VRMHumanoidRig";
    const n = {}, s = {}, r = {};
    xt.forEach((l) => {
      const c = e.getBoneNode(l);
      if (c) {
        n[l] = c.getPosition().clone(), c.getRotation().clone(), s[l] = c.getLocalRotation().clone();
        const h = new t.Quat();
        c.parent && h.copy(c.parent.getRotation()), r[l] = h;
      }
    });
    const o = {};
    return xt.forEach((l) => {
      var c;
      const h = e.getBoneNode(l);
      if (h) {
        const u = n[l];
        let d = l, p;
        for (; p == null && (d = It[d], d != null); )
          p = n[d];
        const m = new t.Entity();
        m.name = h.name, (d ? (c = o[d]) == null ? void 0 : c.node : i).addChild(m);
        const _ = new t.Vec3().copy(u);
        p && _.sub(p), m.setLocalPosition(_), o[l] = { node: m };
      }
    }), {
      rigBones: o,
      root: i,
      parentWorldRotations: r,
      boneRotations: s
    };
  }
  constructor(t, e) {
    const { rigBones: i, root: n, parentWorldRotations: s, boneRotations: r } = Ut._setupTransforms(
      t,
      e
    );
    super(i), this.pcRef = t, this.original = e, this.root = n, this._parentWorldRotations = s, this._boneRotations = r, this._quatA = new t.Quat(), this._quatB = new t.Quat(), this._vec3A = new t.Vec3(), this._mat4A = new t.Mat4();
  }
  applyMatrix4(t, e) {
    const i = t.x, n = t.y, s = t.z, r = e.data, o = 1 / (r[3] * i + r[7] * n + r[11] * s + r[15]);
    return t.x = (r[0] * i + r[4] * n + r[8] * s + r[12]) * o, t.y = (r[1] * i + r[5] * n + r[9] * s + r[13]) * o, t.z = (r[2] * i + r[6] * n + r[10] * s + r[14]) * o, t;
  }
  update() {
    xt.forEach((t) => {
      var e;
      const i = (e = this.original.humanBones[t]) == null ? void 0 : e.entity, n = this.getBoneNode(t);
      if (i != null && n) {
        const s = this._parentWorldRotations[t], r = this._quatB.copy(s).invert(), o = this._boneRotations[t];
        if (this._quatA.copy(n.getLocalRotation()), this._quatA.mul(s), this._quatA.copy(r.mul(this._quatA)), this._quatA.mul(o), i.setLocalRotation(this._quatA), t === "hips") {
          const l = this._vec3A.copy(n.getPosition()), c = this._mat4A.copy(i.parent.getWorldTransform()), h = this.applyMatrix4(l, c.invert());
          i.setLocalPosition(h);
        }
      }
    });
  }
}
class Mn {
  constructor(t, e, i) {
    this.autoUpdateHumanBones = i?.autoUpdateHumanBones ?? !0, this._rawHumanBones = new Oe(e), this._normalizedHumanBones = new Ut(t, this._rawHumanBones);
  }
  get humanBones() {
    return this._rawHumanBones.humanBones;
  }
  get rawHumanBones() {
    return this._rawHumanBones.humanBones;
  }
  get normalizedHumanBones() {
    return this._normalizedHumanBones.humanBones;
  }
  get normalizedHumanBonesRoot() {
    return this._normalizedHumanBones.root;
  }
  get animatedEntity() {
    return this.normalizedHumanBonesRoot;
  }
  /**
   * Return a raw {@link VRMHumanBone} bound to a specified {@link VRMHumanBoneName}.
   *
   * @param name Name of the bone you want
   */
  getRawBone(t) {
    return this._rawHumanBones.getBone(t);
  }
  /**
   * Return a normalized {@link VRMHumanBone} bound to a specified {@link VRMHumanBoneName}.
   *
   * @param name Name of the bone you want
   */
  getNormalizedBone(t) {
    return this._normalizedHumanBones.getBone(t);
  }
  /**
   * Return a raw bone as a `THREE.Object3D` bound to a specified {@link VRMHumanBoneName}.
   *
   * @param name Name of the bone you want
   */
  getRawBoneNode(t) {
    return this._rawHumanBones.getBoneNode(t);
  }
  /**
   * Return a normalized bone as a `THREE.Object3D` bound to a specified {@link VRMHumanBoneName}.
   *
   * @param name Name of the bone you want
   */
  getNormalizedBoneNode(t) {
    return this._normalizedHumanBones.getBoneNode(t);
  }
  getBoneEntity(t) {
    var e;
    return ((e = this._rawHumanBones.humanBones[t]) == null ? void 0 : e.entity) || null;
  }
  /**
   * Update the humanoid component.
   *
   * If {@link autoUpdateHumanBones} is `true`, it transfers the pose of normalized human bones to raw human bones.
   * Default is `true` to follow the animation set to normalized human bones
   */
  update() {
    this.autoUpdateHumanBones && this._normalizedHumanBones.update();
  }
}
function In(a, t, e) {
  const i = a.humanBones, n = {};
  return a.humanBones != null && Object.entries(i).map(([, s]) => {
    var r;
    let o = s.bone;
    const l = s.node;
    if (o == null || l == null)
      return;
    const h = t.resource.data.nodes[l];
    if (h == null) {
      console.warn(
        `A glTF node bound to the humanoid bone ${o} (index = ${l}) does not exist`
      );
      return;
    }
    n[o] = {
      node: h,
      entity: ((r = e.findByTag(`node_${l}`)) == null ? void 0 : r[0]) || null
    };
  }), n;
}
function Pn(a, t, e) {
  var i;
  const n = {}, s = a.humanBones.leftThumbIntermediate != null || a.humanBones.rightThumbIntermediate != null;
  if (a.humanBones)
    for (const r in a.humanBones) {
      let o = r;
      const l = a.humanBones[r].node, h = t.resource.data.nodes[l];
      if (s) {
        const u = Te[o];
        u != null && (o = u);
      }
      if (h == null)
        return console.warn(
          `A glTF node bound to the humanoid bone ${o} (index = ${l}) does not exist`
        ), null;
      n[o] = {
        node: h,
        entity: ((i = e.findByTag(`node_${l}`)) == null ? void 0 : i[0]) || null
      };
    }
  return n;
}
function Ve(a, t, e, i) {
  var n, s, r, o, l, c, h, u, d, p;
  const m = t.resource, f = (s = (n = m.data.gltf) == null ? void 0 : n.extensions) == null ? void 0 : s.VRM, _ = (o = (r = m.data.gltf) == null ? void 0 : r.extensions) == null ? void 0 : o.VRMC_vrm;
  if (!f && !_)
    return console.warn("CreateFormattedVRMHumanoid: Please check. It is not a vrm avatar."), null;
  let g = null;
  if (f) {
    const v = (h = (c = (l = m.data.gltf) == null ? void 0 : l.extensions) == null ? void 0 : c.VRM) == null ? void 0 : h.humanoid;
    g = In(v, t, e);
  } else if (_) {
    const v = _.specVersion;
    if (!Bt.has(v))
      return console.warn(`Unknown VRMC_vrm specVersion "${v}"`), null;
    const y = (p = (d = (u = m.data.gltf) == null ? void 0 : u.extensions) == null ? void 0 : d.VRMC_vrm) == null ? void 0 : p.humanoid;
    g = Pn(y, t, e);
  }
  if (g) {
    const v = i?.autoUpdateHumanBones ?? !0, y = new Mn(a, g, { autoUpdateHumanBones: v });
    return e.addChild(y.normalizedHumanBonesRoot), y;
  }
  return null;
}
const Fe = (a) => {
  if (!a.resource) {
    console.error("addIndexToNodeTags Error: asset.resource is not available");
    return;
  }
  const t = a.resource;
  if (!(t.data && t.data.gltf)) {
    console.error("addIndexToNodeTags Error: asset.resource.data.gltf is not available");
    return;
  }
  t.data.nodes.forEach((n, s) => {
    n.tags.add(`node_${s}`);
  });
}, Cn = (a) => {
  var t, e;
  const i = a.resource, n = (t = i.data.gltf.extensions) == null ? void 0 : t.VRMC_vrm, s = (e = i.data.gltf.extensions) == null ? void 0 : e.VRM;
  return n ? "v1" : s ? "v0" : null;
};
window.VRMLoader = {
  VrmAnimation: Me,
  VrmExpression: Pe,
  VrmSpringBone: Re,
  VrmMtoon: Ne,
  VrmMapList: zi,
  createFormattedVRMHumanoid: Ve,
  addIndexToNodeTags: Fe,
  getVersion: Cn
};
class Ln {
  _vrmEntity;
  _asset;
  _humanoid;
  _expressionScript;
  _springBoneScript;
  _defaultMtoonShading;
  constructor(t, e, i) {
    this._vrmEntity = t, this._asset = e, this._humanoid = Ve(pc, this._asset, this._vrmEntity), this._defaultMtoonShading = i?.mtoonShading ?? !0, this._createScripts();
  }
  get humanoid() {
    return this._humanoid;
  }
  get expressionManager() {
    return this._expressionScript?.expressionManager;
  }
  get springBoneManager() {
    return this._springBoneScript?.springBoneManager;
  }
  get asset() {
    return this._asset;
  }
  get version() {
    const t = this._asset.resource, e = t.data.gltf.extensions?.VRMC_vrm, i = t.data.gltf.extensions?.VRM;
    return e ? "v1" : "v0";
  }
  _createScripts() {
    this._vrmEntity.script || this._vrmEntity.addComponent("script"), this._vrmEntity.script && (this._createMtoonScript(this._vrmEntity.script), this._createExpressionScript(this._vrmEntity.script), this._createSpringBoneScript(this._vrmEntity.script));
  }
  _createExpressionScript(t) {
    const e = t.create("vrmExpression", {
      attributes: {
        asset: this._asset
      }
    });
    e && (this._expressionScript = e);
  }
  _createSpringBoneScript(t) {
    const e = t.create("vrmSpringBone", {
      attributes: {
        asset: this._asset
      }
    });
    e && (this._springBoneScript = e);
  }
  _createMtoonScript(t) {
    t.create("vrmMtoon", {
      attributes: {
        asset: this._asset,
        autoInitialize: this._defaultMtoonShading
      }
    });
  }
}
const X = {
  [b.Stop]: 0,
  [b.Forward]: 1,
  [b.Backward]: 2,
  [b.StrafeLeft]: 3,
  [b.StrafeRight]: 4,
  [b.ForwardDiagonalLeft]: 5,
  [b.ForwardDiagonalRight]: 6,
  [b.BackwardDiagonalLeft]: 7,
  [b.BackwardDiagonalRight]: 8
}, Lt = {
  [F.Up]: 1,
  [F.Neutral]: 0,
  [F.Down]: -1
};
class Rn {
  _vrmHelper;
  _pcApp;
  constructor(t, e) {
    this._vrmHelper = t, this._pcApp = e;
  }
  createVrmAnimResources(t) {
    const e = this._vrmHelper;
    if (!e)
      throw new Error("VRM plugin helper is not initialized.");
    const i = Me.createVRMAnimResources(
      pc,
      t,
      e.asset,
      e.humanoid
    );
    if (!i)
      throw new Error("Failed to create VRM animation resources.");
    return i;
  }
  async loadAnimation(t, e) {
    e.loaded || await new Promise((n, s) => {
      e.ready(() => n(e)), e.once(
        "error",
        (r) => s(new Error(`Failed to load ${e.name}: ${r}`))
      ), this._pcApp.assets.load(e);
    });
    const i = this.createVrmAnimResources([{ stateName: t, asset: e }]);
    return i && i.length > 0 ? i[0] : null;
  }
  async getSittingAsset() {
    return await H(
      this._pcApp,
      "sitting.vrma",
      "/animations/",
      "local-player",
      "container"
    );
  }
}
const Dn = [
  { direction: b.Stop, posture: S.Idle },
  { direction: b.Forward, posture: S.Forward },
  { direction: b.Backward, posture: S.Backward },
  { direction: b.StrafeLeft, posture: S.StrafeLeft },
  { direction: b.StrafeRight, posture: S.StrafeRight }
].flatMap(({ direction: a, posture: t }) => [
  // Higher priority: must be placed first in array
  // Consumes horizontalDirChanged trigger to prevent immediate loop back
  {
    from: "GROUND_ENTRY",
    to: t,
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      { parameterName: "horizontalDirChanged", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      {
        parameterName: "horizontalDir",
        predicate: pc.ANIM_EQUAL_TO,
        value: X[a]
      }
    ]
  },
  // Normal transition without consuming trigger
  {
    from: "GROUND_ENTRY",
    to: t,
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      {
        parameterName: "horizontalDir",
        predicate: pc.ANIM_EQUAL_TO,
        value: X[a]
      }
    ]
  }
]), Nn = [
  S.Idle,
  S.Forward,
  S.Backward,
  S.StrafeLeft,
  S.StrafeRight,
  S.Sprint
].map((a) => ({
  from: a,
  to: "GROUND_ENTRY",
  time: 0.1,
  interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
  conditions: [
    { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    { parameterName: "horizontalDirChanged", predicate: pc.ANIM_EQUAL_TO, value: !0 }
  ]
})), On = [
  {
    from: "ANY",
    to: S.Sprint,
    time: 0.1,
    conditions: [
      { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      { parameterName: "isSprinting", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      {
        parameterName: "horizontalDir",
        predicate: pc.ANIM_EQUAL_TO,
        value: X[b.Forward]
      }
    ]
  },
  {
    from: S.Sprint,
    to: "GROUND_ENTRY",
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [{ parameterName: "isSprinting", predicate: pc.ANIM_EQUAL_TO, value: !1 }]
  }
], Vn = [
  ...Dn,
  ...Nn,
  ...On
], Fn = [
  {
    from: "ANY",
    to: S.JumpingUp,
    time: 0.2,
    conditions: [{ parameterName: "jump", predicate: pc.ANIM_EQUAL_TO, value: !0 }]
  },
  {
    from: S.JumpingUp,
    to: S.JumpingLoop,
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NONE
  }
], kn = [
  {
    from: "ANY",
    to: S.JumpingLoop,
    time: 0.1,
    conditions: [{ parameterName: "isFalling", predicate: pc.ANIM_EQUAL_TO, value: !0 }]
  }
], Bn = [
  {
    from: S.JumpingLoop,
    to: S.JumpingDown,
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [{ parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 }]
  },
  {
    from: S.JumpingDown,
    to: "GROUND_ENTRY",
    time: 0.2,
    exitTime: 1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      {
        parameterName: "horizontalDir",
        predicate: pc.ANIM_EQUAL_TO,
        value: X[b.Stop]
      },
      { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 }
    ]
  },
  {
    from: S.JumpingDown,
    to: "GROUND_ENTRY",
    time: 0.1,
    exitTime: 0,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      {
        parameterName: "horizontalDir",
        predicate: pc.ANIM_NOT_EQUAL_TO,
        value: X[b.Stop]
      },
      { parameterName: "isGrounded", predicate: pc.ANIM_EQUAL_TO, value: !0 }
    ]
  }
], Un = [
  {
    from: "ANY",
    to: "FLY_ENTRY",
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      { parameterName: "horizontalDirChanged", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 }
    ]
  },
  {
    from: "ANY",
    to: "FLY_ENTRY",
    time: 0.1,
    interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
    conditions: [
      { parameterName: "verticalStateChanged", predicate: pc.ANIM_EQUAL_TO, value: !0 },
      { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 }
    ]
  }
], Hn = [
  { verticalState: F.Neutral, posture: S.FlyFloat },
  { verticalState: F.Up, posture: S.FlyUp },
  { verticalState: F.Down, posture: S.FlyDown }
].map(({ verticalState: a, posture: t }) => ({
  from: "FLY_ENTRY",
  to: t,
  time: 0.1,
  conditions: [
    { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    {
      parameterName: "horizontalDir",
      predicate: pc.ANIM_EQUAL_TO,
      value: X[b.Stop]
    },
    {
      parameterName: "verticalState",
      predicate: pc.ANIM_EQUAL_TO,
      value: Lt[a]
    }
  ]
})), zn = [
  { direction: b.Backward, posture: S.FlyBackward },
  { direction: b.StrafeLeft, posture: S.FlyStrafeLeft },
  { direction: b.StrafeRight, posture: S.FlyStrafeRight }
].map(({ direction: a, posture: t }) => ({
  from: "FLY_ENTRY",
  to: t,
  time: 0.1,
  conditions: [
    { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    {
      parameterName: "horizontalDir",
      predicate: pc.ANIM_EQUAL_TO,
      value: X[a]
    }
  ]
})), Gn = [
  { verticalState: F.Neutral, posture: S.FlyForward },
  { verticalState: F.Up, posture: S.FlyUpForward },
  { verticalState: F.Down, posture: S.FlyDownForward }
].map(({ verticalState: a, posture: t }) => ({
  from: "FLY_ENTRY",
  to: t,
  time: 0.1,
  conditions: [
    { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    { parameterName: "isSprinting", predicate: pc.ANIM_EQUAL_TO, value: !1 },
    {
      parameterName: "horizontalDir",
      predicate: pc.ANIM_EQUAL_TO,
      value: X[b.Forward]
    },
    {
      parameterName: "verticalState",
      predicate: pc.ANIM_EQUAL_TO,
      value: Lt[a]
    }
  ]
})), Wn = [
  { verticalState: F.Neutral, posture: S.FlyForwardSprint },
  { verticalState: F.Up, posture: S.FlyUpForwardSprint },
  { verticalState: F.Down, posture: S.FlyDownForwardSprint }
].map(({ verticalState: a, posture: t }) => ({
  from: "ANY",
  to: t,
  time: 0.1,
  conditions: [
    { parameterName: "isFlying", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    { parameterName: "isSprinting", predicate: pc.ANIM_EQUAL_TO, value: !0 },
    {
      parameterName: "horizontalDir",
      predicate: pc.ANIM_EQUAL_TO,
      value: X[b.Forward]
    },
    {
      parameterName: "verticalState",
      predicate: pc.ANIM_EQUAL_TO,
      value: Lt[a]
    }
  ]
})), jn = [
  S.FlyForwardSprint,
  S.FlyUpForwardSprint,
  S.FlyDownForwardSprint
].map((a) => ({
  from: a,
  to: "FLY_ENTRY",
  time: 0.1,
  interruptionSource: pc.ANIM_INTERRUPTION_NEXT,
  conditions: [{ parameterName: "isSprinting", predicate: pc.ANIM_EQUAL_TO, value: !1 }]
})), Yn = [
  ...Un,
  ...Hn,
  ...zn,
  ...Gn,
  ...Wn,
  ...jn
], Xn = (a, t) => ({
  layers: [
    {
      name: "base",
      states: [
        { name: "START" },
        { name: "ANY" },
        { name: "END" },
        { name: "GROUND_ENTRY" },
        { name: "FLY_ENTRY" },
        { name: S.Idle, loop: !0, speed: 1 },
        { name: S.Forward, loop: !0, speed: a },
        { name: S.Backward, loop: !0, speed: a },
        { name: S.StrafeLeft, loop: !0, speed: a },
        { name: S.StrafeRight, loop: !0, speed: a },
        { name: S.Sprint, loop: !0, speed: t },
        { name: S.JumpingUp, loop: !1, speed: 1 },
        { name: S.JumpingLoop, loop: !0, speed: 1 },
        { name: S.JumpingDown, loop: !1, speed: 1 },
        { name: S.FlyFloat, loop: !0, speed: 1 },
        { name: S.FlyForward, loop: !0, speed: 1 },
        { name: S.FlyBackward, loop: !0, speed: 1 },
        { name: S.FlyStrafeLeft, loop: !0, speed: 1 },
        { name: S.FlyStrafeRight, loop: !0, speed: 1 },
        { name: S.FlyUp, loop: !0, speed: 1 },
        { name: S.FlyUpForward, loop: !0, speed: 1 },
        { name: S.FlyDown, loop: !0, speed: 1 },
        { name: S.FlyDownForward, loop: !0, speed: 1 },
        { name: S.FlyForwardSprint, loop: !0, speed: 1 },
        { name: S.FlyUpForwardSprint, loop: !0, speed: 1 },
        { name: S.FlyDownForwardSprint, loop: !0, speed: 1 }
      ],
      transitions: [
        { from: "START", to: S.Idle, time: 0 },
        ...Vn,
        ...Fn,
        ...kn,
        ...Bn,
        ...Yn
      ]
    }
  ],
  parameters: {
    isGrounded: {
      type: pc.ANIM_PARAMETER_BOOLEAN,
      value: !0
    },
    isSprinting: {
      type: pc.ANIM_PARAMETER_BOOLEAN,
      value: !1
    },
    isFlying: {
      type: pc.ANIM_PARAMETER_BOOLEAN,
      value: !1
    },
    isFalling: {
      type: pc.ANIM_PARAMETER_BOOLEAN,
      value: !1
    },
    jump: {
      type: pc.ANIM_PARAMETER_TRIGGER,
      value: !1
    },
    horizontalDir: {
      type: pc.ANIM_PARAMETER_INTEGER,
      value: 0
    },
    horizontalDirChanged: {
      type: pc.ANIM_PARAMETER_TRIGGER,
      value: !1
    },
    verticalState: {
      type: pc.ANIM_PARAMETER_INTEGER,
      value: 0
    },
    verticalStateChanged: {
      type: pc.ANIM_PARAMETER_TRIGGER,
      value: !1
    }
  }
});
class Zn {
  _animComponent;
  _resourceLoader;
  _overrideLayer = null;
  _canBeInterrupted = !1;
  _exitOnAnimationEnd = !1;
  _currentCustomAnimation = null;
  _legLength = 0;
  constructor(t) {
    const { entity: e, animResources: i, pcApp: n, legLength: s, multiplier: r } = t, o = e.vrmHelper;
    if (!o || !o.humanoid)
      throw new Error("VRM plugin helper and humanoid are not initialized on the entity.");
    const l = o.humanoid.animatedEntity;
    l.anim || l.addComponent("anim"), this._animComponent = l.anim, this._legLength = s, this._resourceLoader = new Rn(o, n), this._setupStateGraph(i, r);
  }
  get overrideAnimationStates() {
    return this._overrideLayer ? this._overrideLayer.states : [];
  }
  get currentCustomAnimation() {
    return this._currentCustomAnimation;
  }
  _setupStateGraph(t, e) {
    const i = this._getSpeedByLegLength(this._legLength, e?.walk ?? 1), n = this._getSpeedByLegLength(this._legLength, e?.run ?? 1), s = Xn(i, n);
    this._animComponent.loadStateGraph(s), this._resourceLoader.createVrmAnimResources(t).forEach((o) => {
      this._animComponent.baseLayer?.assignAnimation(o.name, o.resource);
    });
  }
  setHorizontalDirection(t) {
    const e = X[t];
    this._animComponent.getParameterValue(
      "horizontalDir",
      pc.ANIM_PARAMETER_INTEGER
    ) !== e && (this._animComponent.setTrigger("horizontalDirChanged"), this._canBeInterrupted && this.exitOverrideAnimation()), this._animComponent.setInteger("horizontalDir", e);
  }
  setVerticalState(t) {
    const e = Lt[t];
    this._animComponent.getParameterValue(
      "verticalState",
      pc.ANIM_PARAMETER_INTEGER
    ) !== e && (this._animComponent.setTrigger("verticalStateChanged"), this._canBeInterrupted && this.exitOverrideAnimation()), this._animComponent.setInteger("verticalState", e);
  }
  setBoolean(t, e) {
    this._animComponent.setBoolean(t, e), this._canBeInterrupted && this.exitOverrideAnimation();
  }
  setTrigger(t, e = !1) {
    this._animComponent.setTrigger(t, e), this._canBeInterrupted && this.exitOverrideAnimation();
  }
  async setSitting() {
    if (this._currentCustomAnimation === "sitting") return;
    if (!(this.overrideAnimationStates || []).includes("sitting")) {
      const e = await this._resourceLoader.getSittingAsset();
      await this.loadOverrideAnimation("sitting", e);
    }
    this.playOverrideAnimation("sitting", {
      canBeInterrupted: !1,
      exitOnAnimationEnd: !1,
      duration: 0
    });
  }
  async setStandUp() {
    this.exitOverrideAnimation();
  }
  async loadOverrideAnimation(t, e, i) {
    try {
      const n = this._overrideLayer ?? this._createOverrideLayer();
      if (n.states.find((o) => o === t)) {
        E.warn(`Animation state "${t}" already exists in override layer.`);
        return;
      }
      const r = await this._resourceLoader.loadAnimation(t, e);
      r ? (n.assignAnimation(t, r.resource, i?.speed, i?.loop), this._animComponent.rebind()) : E.error(`Failed to load animation resource for "${t}"`);
    } catch (n) {
      E.error(`Error loading animation "${t}":`, n);
    }
  }
  _createOverrideLayer() {
    const t = this._animComponent.addLayer("override", 0);
    return this._overrideLayer = t, t;
  }
  _setLayerWeights(t, e) {
    Object.entries(t).forEach(([i, n]) => {
      const s = this._animComponent.findAnimationLayer(i);
      s && (e === 0 && (s.weight = n), s.blendToWeight(n, e));
    });
  }
  playOverrideAnimation(t, e) {
    if (!this._overrideLayer) {
      E.warn("Override layer is not created. Please load animation first.");
      return;
    }
    if (this._currentCustomAnimation === t) {
      E.warn(`Animation state "${t}" is already playing.`);
      return;
    }
    const { duration: i = 0.2, canBeInterrupted: n = !1, exitOnAnimationEnd: s = !1 } = e || {};
    if (this._canBeInterrupted = n, this._exitOnAnimationEnd = s, this._currentCustomAnimation = t, this._overrideLayer.states.some((o) => o === t)) {
      const o = { base: 0, override: 1 };
      this._setLayerWeights(o, i);
      const c = this._overrideLayer.weight > 0 ? i : 0;
      this._overrideLayer.transition(t, c);
    } else
      E.warn(`Animation state "${t}" not found. Please use load first.`);
  }
  exitOverrideAnimation(t = 0.2) {
    const e = { base: 1, override: 0 };
    this._setLayerWeights(e, t), this._canBeInterrupted = !1, this._currentCustomAnimation = null;
  }
  _getSpeedByLegLength(t, e) {
    let r = 1 + 0.73 * Math.log(0.83 / t);
    r = Number(r.toFixed(2)), r = Math.max(r, 0.1);
    const o = r * 5;
    return pc.math.clamp(r * e, 0.1, o);
  }
  _setStateSpeed(t, e, i) {
    i.forEach((n) => {
      t._controller?._states[n]?.animations.forEach((r) => r._speed = e);
    });
  }
  _updateSpeedMultiplier(t, e) {
    const i = this._animComponent.baseLayer;
    if (!i) return;
    const n = this._getSpeedByLegLength(this._legLength, e);
    this._setStateSpeed(i, n, t);
  }
  setSpeedMultipliers(t) {
    t.walk !== void 0 && this._updateSpeedMultiplier(
      [
        S.Forward,
        S.Backward,
        S.StrafeLeft,
        S.StrafeRight
      ],
      t.walk
    ), t.run !== void 0 && this._updateSpeedMultiplier([S.Sprint], t.run);
  }
  update() {
    this._overrideLayer && this._exitOnAnimationEnd && this._overrideLayer.activeStateProgress >= 1 && (this.exitOverrideAnimation(), this._exitOnAnimationEnd = !1);
  }
}
class $n {
  getHeadHeight(t) {
    const e = t.vrmHelper;
    if (!e || !e.humanoid)
      return E.warn("Humanoid not found in VRM model."), 0;
    const i = e.humanoid.getRawBoneNode("head");
    return i ? i.getPosition().y : (E.warn("Head bone not found in VRM model."), 0);
  }
  getUpperLegLength(t) {
    const e = t.vrmHelper;
    if (!e || !e.humanoid)
      return E.warn("Humanoid not found in VRM model."), 0;
    if (!e.humanoid.getRawBoneNode("hips"))
      return E.warn("Hips bone not found in VRM model."), 0;
    let n = 0, s = 0;
    const r = e.humanoid.getRawBoneNode("leftUpperLeg"), o = e.humanoid.getRawBoneNode("leftLowerLeg");
    if (r && o) {
      const h = r.getPosition(), u = o.getPosition();
      n = h.distance(u);
    }
    const l = e.humanoid.getRawBoneNode("rightUpperLeg"), c = e.humanoid.getRawBoneNode("rightLowerLeg");
    if (l && c) {
      const h = l.getPosition(), u = c.getPosition();
      s = h.distance(u);
    }
    return Math.max(n, s);
  }
  getThighRadius(t) {
    const e = t.vrmHelper;
    if (!e || !e.humanoid)
      return E.warn("Humanoid not found in VRM model."), 0;
    const i = e.humanoid.getRawBoneNode("leftUpperLeg"), n = e.humanoid.getRawBoneNode("rightUpperLeg");
    if (!i || !n)
      return E.warn("Upper leg bones not found in VRM model."), 0;
    const s = i.getPosition(), r = n.getPosition();
    return s.distance(r) * 0.7;
  }
  getLegLength(t) {
    const e = t.vrmHelper;
    if (!e || !e.humanoid)
      return E.warn("Humanoid not found in VRM model."), 0;
    const i = e.humanoid.getRawBoneNode("leftUpperLeg"), n = e.humanoid.getRawBoneNode("leftLowerLeg"), s = e.humanoid.getRawBoneNode("leftFoot");
    if (!(i && n && s))
      return E.warn(`${t} miss bones for left leg.`), 0;
    const r = i.getPosition(), o = n.getPosition(), l = s.getPosition(), c = r.distance(o), h = o.distance(l);
    return c + h;
  }
}
const qn = {
  [S.Idle]: "/animations/idle.vrma",
  [S.Forward]: "/animations/forward.vrma",
  [S.Backward]: "/animations/backward.glb",
  [S.StrafeLeft]: "/animations/strafe-left.glb",
  [S.StrafeRight]: "/animations/strafe-right.glb",
  [S.JumpingUp]: "/animations/jumping-up.vrma",
  [S.JumpingLoop]: "/animations/jumping-loop.vrma",
  [S.JumpingDown]: "/animations/jumping-down.vrma",
  [S.Sprint]: "/animations/sprint.vrma",
  [S.FlyFloat]: "/animations/fly-float.vrma",
  [S.FlyForward]: "/animations/fly-forward.vrma",
  [S.FlyBackward]: "/animations/fly-backward.vrma",
  [S.FlyStrafeLeft]: "/animations/fly-strafe-left.vrma",
  [S.FlyStrafeRight]: "/animations/fly-strafe-right.vrma",
  [S.FlyUp]: "/animations/fly-up.vrma",
  [S.FlyUpForward]: "/animations/fly-up-forward.vrma",
  [S.FlyDown]: "/animations/fly-down.vrma",
  [S.FlyDownForward]: "/animations/fly-down-forward.vrma",
  [S.FlyForwardSprint]: "/animations/fly-forward-sprint.vrma",
  [S.FlyUpForwardSprint]: "/animations/fly-up-forward-sprint.vrma",
  [S.FlyDownForwardSprint]: "/animations/fly-down-forward-sprint.vrma"
};
class Y {
  static assetUsageMap = /* @__PURE__ */ new Map();
  static avatarType = "vrm";
  type = Y.avatarType;
  isVrmAvatar = !0;
  name = crypto.randomUUID();
  config;
  _pcApp = null;
  _avatarUrl = "";
  _mtoonEnabled = !0;
  _vrmHelper = null;
  _animator = null;
  _bodyMeasurer = new $n();
  _walkSpeedMultiplier = 1;
  _runSpeedMultiplier = 1;
  entity = null;
  headHeight = 0;
  upperLegLength = 0;
  legLength = 0;
  boundingBox = new pc.BoundingBox();
  asset = null;
  _sitAnchorPosition = new pc.Vec3();
  _animationPaths = { ...qn };
  constructor(t) {
    const { avatarUrl: e, name: i } = t;
    this._avatarUrl = e, this.name = i ?? this.name, this.config = { avatarUrl: this._avatarUrl, name: this.name };
  }
  get customAnimationStates() {
    return this._animator ? this._animator.overrideAnimationStates : [];
  }
  get currentCustomAnimation() {
    return this._animator ? this._animator.currentCustomAnimation : null;
  }
  get sitAnchorPosition() {
    const t = this.getBoneEntity("leftUpperLeg"), e = this.getBoneEntity("rightUpperLeg");
    if (t && e && this.entity) {
      const i = t.getPosition(), n = e.getPosition();
      this._sitAnchorPosition.copy(i).add(n).mulScalar(0.5);
      const s = this.entity.up, r = this._getThighRadius(this.entity), o = s.clone().mulScalar(-r);
      this._sitAnchorPosition.add(o);
    }
    return this._sitAnchorPosition;
  }
  _registryScripts() {
    if (!this._pcApp)
      throw new Error("PlayCanvas application is not initialized.");
    this._pcApp.scripts.has("vrmSpringBone") || Re.importScript(pc), this._pcApp.scripts.has("vrmExpression") || Pe.importScript(pc), this._pcApp.scripts.has("vrmMtoon") || Ne.importScript(pc);
  }
  async _load() {
    if (!this._pcApp)
      throw new Error("PlayCanvas application is not initialized.");
    try {
      const { vrmAsset: t, animationAssets: e } = await this._loadDependencies(), i = this._instantiateVrmEntity(t), n = i, s = new Ln(n, t, {
        mtoonShading: this._mtoonEnabled
      });
      return i.vrmHelper = s, this._vrmHelper = s, this._initializeAvatarProperties(i, t), await this._setupAnimator(n, e), s.version === "v1" && i.rotateLocal(0, 180, 0), i;
    } catch (t) {
      throw new Error(
        `Failed to load VRM avatar: ${t instanceof Error ? t.message : "Unknown error"}`
      );
    }
  }
  async _loadDependencies() {
    if (!this._pcApp)
      throw new Error("PlayCanvas application is not initialized.");
    if (!this._avatarUrl)
      throw new Error("Avatar URL is not provided.");
    const t = await this._loadAsset(this._avatarUrl, `VRM_AVATAR_${this.name}`, "container"), e = await Bi(this._pcApp, this._animationPaths);
    return Fe(t), { vrmAsset: t, animationAssets: e };
  }
  _instantiateVrmEntity(t) {
    const e = t.resource.instantiateRenderEntity(), i = new pc.Entity(`VrmAvatarRoot_${this.name}`);
    return i.addChild(e), i;
  }
  _loadAsset(t, e, i) {
    if (!this._pcApp)
      throw new Error("PlayCanvas application is not initialized.");
    const n = this._pcApp, s = new pc.Asset(e, i, { url: t });
    return n.assets.add(s), this._registerAssetUsage(s), new Promise((r, o) => {
      s.once("load", () => r(s)), s.once("error", (l) => o(new Error(l))), n.assets.load(s);
    });
  }
  _getAssetId(t) {
    const e = t.getFileUrl();
    return `${t.type}_${e}`;
  }
  _registerAssetUsage(t) {
    const e = this._getAssetId(t);
    Y.assetUsageMap.has(e) || Y.assetUsageMap.set(e, /* @__PURE__ */ new Set()), Y.assetUsageMap.get(e).add(this.name);
  }
  _unregisterAssetUsage(t) {
    const e = this._getAssetId(t), i = Y.assetUsageMap.get(e);
    return i ? (i.delete(this.name), i.size === 0 ? (Y.assetUsageMap.delete(e), !0) : !1) : !1;
  }
  _getThighRadius(t) {
    return this._bodyMeasurer.getThighRadius(t);
  }
  _initializeAvatarProperties(t, e) {
    this.entity = t, this.asset = e, this.headHeight = this._bodyMeasurer.getHeadHeight(t), this.upperLegLength = this._bodyMeasurer.getUpperLegLength(t), this.legLength = this._bodyMeasurer.getLegLength(t), this._updateBoundingBox();
  }
  async _setupAnimator(t, e) {
    if (!this._pcApp)
      throw new Error("PlayCanvas application is not initialized.");
    this._animator = new Zn({
      entity: t,
      animResources: e,
      pcApp: this._pcApp,
      legLength: this.legLength,
      multiplier: { walk: this._walkSpeedMultiplier, run: this._runSpeedMultiplier }
    }), t.animator = this._animator;
  }
  _updateBoundingBox() {
    if (!this.entity)
      throw new Error("Avatar entity is not set.");
    const t = this.entity.clone();
    t.anim && t.anim.removeStateGraph(), t.setPosition(0, 0, 0), t.setRotation(0, 0, 0, 1), Ee(t, this.boundingBox);
  }
  async create(t) {
    return this._pcApp = t, this._registryScripts(), await this._load();
  }
  activate(t) {
    t && (this.setHorizontalDirection(t.horizontalDirection), this.setVerticalState(t.verticalState), this.setGrounded(t.isGrounded), this.setFalling(t.isFalling), this.setFlying(t.isFlying), this.setSprinting(t.isSprinting));
  }
  deactivate() {
    this.exitCustomAnimation();
  }
  setHorizontalDirection(t) {
    this._animator?.setHorizontalDirection(t);
  }
  setVerticalState(t) {
    this._animator?.setVerticalState(t);
  }
  jump() {
    document.hidden || this._animator?.setTrigger("jump");
  }
  async sit() {
    await this._animator?.setSitting();
  }
  async standUp() {
    await this._animator?.setStandUp();
  }
  setGrounded(t) {
    this._animator?.setBoolean("isGrounded", t);
  }
  setSprinting(t) {
    this._animator?.setBoolean("isSprinting", t);
  }
  setFalling(t) {
    this._animator?.setBoolean("isFalling", t);
  }
  setFlying(t) {
    this._animator?.setBoolean("isFlying", t);
  }
  /** @hidden */
  setTalking(t) {
    this.entity && this.entity.fire("vrm-expression:talking-state-changed", t);
  }
  setMtoonShading(t) {
    this._mtoonEnabled !== t && (this._mtoonEnabled = t, this.entity && this.entity.fire("vrm-mtoon:set-enabled", t));
  }
  async loadCustomAnimation(t, e, i) {
    if (!this._animator) {
      E.warn("VrmAvatar is not loaded");
      return;
    }
    await this._animator.loadOverrideAnimation(t, e, i);
  }
  playCustomAnimation(t, e) {
    if (!this._animator) {
      E.warn("VrmAvatar is not loaded");
      return;
    }
    this._animator.playOverrideAnimation(t, e);
  }
  exitCustomAnimation() {
    if (!this._animator) {
      E.warn("VrmAvatar is not loaded");
      return;
    }
    this._animator.exitOverrideAnimation();
  }
  _updateSpringBoneStrength(t = !1) {
    this.entity && this.entity.fire("vrm-spring-bone:set-strength-limit", !t);
  }
  getBoneEntity(t) {
    if (!this.entity)
      return E.warn("VrmAvatar entity is not ready. Cannot get bone entity."), null;
    const e = this.entity.vrmHelper?.humanoid;
    if (!e)
      return E.warn("Humanoid not found in VRM model. Cannot get bone entity."), null;
    const i = e.getBoneEntity(t);
    return i || null;
  }
  setSpeedMultipliers(t) {
    t.walk !== void 0 && (this._walkSpeedMultiplier = t.walk), t.run !== void 0 && (this._runSpeedMultiplier = t.run), this._animator?.setSpeedMultipliers(t);
  }
  destroy() {
    this._animator && (this._animator = null), this.entity && (this.entity.destroy(), this.entity = null), this.asset && (this._unregisterAssetUsage(this.asset) && (this.asset.unload(), this._pcApp && this._pcApp.assets.remove(this.asset)), this.asset = null);
  }
  update(t, e) {
    this._updateSpringBoneStrength(e), this._animator && this._animator.update(t), this._vrmHelper?.humanoid && this._vrmHelper.humanoid.update();
  }
}
class Ht extends Y {
  static avatarType = "default-avatar";
  type = Ht.avatarType;
  _textureAsset = null;
  constructor() {
    super({
      name: "defaultAvatar",
      avatarUrl: Vt("local-player", "/avatars/default-male-avatar.vrm")
    });
  }
  async create(t) {
    const e = await super.create(t), i = await this._loadTextureAsset();
    return e.findComponents("render").forEach((s) => {
      if (s.material) {
        const r = this._createMaterial(s.material, i);
        s.material = r;
      }
      s.meshInstances.forEach((r) => {
        if (r.material) {
          const o = this._createMaterial(r.material, i);
          r.material = o;
        }
      });
    }), this.entity && (this.entity.script || this.entity.addComponent("script"), this.entity.script && this.entity.script.create(_i, {
      properties: {
        speed: new pc.Vec2(0, 0.25)
      }
    })), e;
  }
  _loadTextureAsset() {
    return new Promise((t, e) => {
      if (!this._pcApp)
        throw new Error("PlayCanvas application is not initialized.");
      const i = "default-scroll-texture";
      if (!this._textureAsset) {
        const s = this._pcApp.assets.find(i);
        if (s)
          this._textureAsset = s;
        else {
          const r = Vt(
            "local-player",
            "/textures/default-scroll-texture.png"
          );
          this._textureAsset = new pc.Asset(i, "texture", {
            url: r
          }), this._pcApp.assets.add(this._textureAsset);
        }
      }
      const n = this._textureAsset;
      n.ready(() => t(n)), n.on("error", () => e("Failed to load default avatar texture asset.")), this._pcApp.assets.load(n);
    });
  }
  _createMaterial(t, e) {
    const i = e.resource, n = t.clone();
    return n.blendType = pc.BLEND_PREMULTIPLIED, n.depthWrite = !1, n instanceof pc.StandardMaterial && (n.opacityMapChannel = "a", n.opacityMap = i, n.emissiveMap = i, n.diffuseMap = i), n;
  }
}
class Jn extends Y {
  constructor(t) {
    const e = t.avatarUrl, i = crypto.randomUUID();
    super({ name: `viverse-${e}-${i}`, avatarUrl: e });
  }
}
const Qn = {
  canCameraSeeAvatar: !0
};
class Kn extends mi {
  _avatarEntity = null;
  _nameTag = null;
  constructor() {
    super(Qn);
  }
  setAvatarEntity(t) {
    this._avatarEntity = t, this.onConditionsUpdated(this.isPassed());
  }
  setNameTag(t) {
    this._nameTag = t, this.onConditionsUpdated(this.isPassed());
  }
  onConditionsUpdated(t) {
    this._setRenderComponentsEnabled(t);
  }
  _setRenderComponentsEnabled(t) {
    const e = this._avatarEntity;
    e && e.forEach((i) => {
      const n = i;
      n.render && (n.render.enabled = t);
    }), this._nameTag && this._nameTag.updateDisplayCondition("isAvatarVisible", t);
  }
}
class ts extends Ct {
  _verifier;
  constructor(t, e) {
    super(t, e), this._verifier = new Kn();
  }
  _setupStoreSubscriptions() {
    this._addSubscription(
      (t) => t.canCameraSeeAvatar,
      (t) => {
        this._verifier.updateCondition("canCameraSeeAvatar", t);
      }
    );
  }
  setNameTag(t) {
    this._verifier.setNameTag(t);
  }
  updateCondition(t, e) {
    this._verifier.updateCondition(t, e);
  }
  _onAvatarChanged(t) {
    this._verifier.setAvatarEntity(t?.entity || null), this._verifier.triggerConditionsCheck();
  }
}
const es = (a, t = 4) => {
  let i = Math.atan2(a.x, a.z) * 180 / Math.PI;
  for (; i < 0; ) i += 360;
  for (; i >= 360; ) i -= 360;
  return t === 4 ? i >= 292.5 || i < 67.5 ? b.Forward : i >= 67.5 && i < 112.5 ? b.StrafeRight : i >= 112.5 && i < 247.5 ? b.Backward : b.StrafeLeft : i >= 337.5 || i < 22.5 ? b.Forward : i >= 22.5 && i < 67.5 ? b.ForwardDiagonalRight : i >= 67.5 && i < 112.5 ? b.StrafeRight : i >= 112.5 && i < 157.5 ? b.BackwardDiagonalRight : i >= 157.5 && i < 202.5 ? b.Backward : i >= 202.5 && i < 247.5 ? b.BackwardDiagonalLeft : i >= 247.5 && i < 292.5 ? b.StrafeLeft : b.ForwardDiagonalLeft;
};
class is extends Ct {
  _horizontalDirection = b.Stop;
  _verticalState = F.Neutral;
  _isGrounded = !0;
  _isFalling = !1;
  _isFlying = !1;
  _isSprinting = !1;
  _triggerJump = !1;
  get horizontalDirection() {
    return this._horizontalDirection;
  }
  get verticalState() {
    return this._verticalState;
  }
  get isGrounded() {
    return this._isGrounded;
  }
  get isFalling() {
    return this._isFalling;
  }
  get isFlying() {
    return this._isFlying;
  }
  get isSprinting() {
    return this._isSprinting;
  }
  get triggerJump() {
    return this._triggerJump;
  }
  consumeJumpTrigger() {
    const t = this._triggerJump;
    return this._triggerJump = !1, t;
  }
  setActiveAvatar(t) {
    super.setActiveAvatar(t), this._setInitialPosture();
  }
  _setupStoreSubscriptions() {
    this._addSubscription(
      (t) => t.locomotionState,
      (t) => this._handleLocomotionStateChange(t)
    ), this._addSubscription(
      (t) => ({
        canSprint: t.canSprint,
        sprint: t.inputStates.sprint
      }),
      ({ canSprint: t, sprint: e }) => this._handleSprintStateChange(t, e),
      { equalityFn: Pt }
    );
  }
  _handleLocomotionStateChange(t) {
    this._avatar && (this._isGrounded = t === x.Grounded, this._avatar.setGrounded?.(this._isGrounded), this._isFalling = t === x.Falling, this._avatar.setFalling?.(this._isFalling), this._isFlying = t === x.Flying, this._avatar.setFlying?.(this._isFlying), t === x.Jumping && (this._triggerJump = !0, this._avatar.jump?.()));
  }
  _handleSprintStateChange(t, e) {
    this._avatar && (this._isSprinting = t && e, this._avatar.setSprinting?.(this._isSprinting));
  }
  _setInitialPosture() {
    if (!this._store) return;
    const t = this._store.getState();
    this._handleSprintStateChange(t.canSprint, t.inputStates.sprint), this._handleLocomotionStateChange(t.locomotionState);
  }
  _getHorizontalDirection(t) {
    const e = t.moveIntent;
    return e.x === 0 && e.z === 0 ? b.Stop : t.avatarFacingMode === K.Movement ? b.Forward : es(e);
  }
  _getVerticalState(t) {
    const e = t.moveIntent.y;
    return e === 0 ? F.Neutral : e > 0 ? F.Up : F.Down;
  }
  _updateMovementState() {
    if (!this._store || !this._avatar) return;
    const t = this._store.getState(), e = this._getHorizontalDirection(t);
    e !== this._horizontalDirection && (this._avatar.setHorizontalDirection?.(e), this._horizontalDirection = e);
    const i = this._getVerticalState(t);
    i !== this._verticalState && (this._avatar.setVerticalState?.(i), this._verticalState = i);
  }
  update() {
    this._updateMovementState();
  }
}
const pe = 0.2;
class ns extends Ct {
  _rotationDamping = 10;
  // Damping for rotation, higher is faster
  _targetQuat = new pc.Quat();
  _finalQuat = new pc.Quat();
  _currentYaw = 0;
  constructor(t, e, i = 10) {
    super(t, e), this._rotationDamping = i;
  }
  calculateTargetYaw(t) {
    const { yaw: e, moveIntent: i, avatarFacingMode: n, overriddenForward: s } = t;
    if (i.x === 0 && i.z === 0 && n === K.Movement)
      return this._currentYaw;
    let r = e;
    if (s) {
      const { x: h, z: u } = s;
      r = Math.atan2(h, u) * (180 / Math.PI) - 180;
    }
    if (n !== K.Movement) return r;
    const { x: o, z: l } = i;
    if (o * o + l * l < pe * pe)
      return r;
    const c = -Math.atan2(o, l) * (180 / Math.PI);
    return r + c;
  }
  applyRotation(t, e) {
    const i = this._module.avatarContainerEntity;
    i && (this._targetQuat.setFromAxisAngle(pc.Vec3.UP, t), this._finalQuat.slerp(
      i.getLocalRotation(),
      this._targetQuat,
      Math.min(this._rotationDamping * e, 1)
    ), i.setLocalRotation(this._finalQuat));
  }
  update(t) {
    if (!this._store) return;
    const { moveIntent: e, yaw: i, avatarFacingMode: n, overriddenForward: s, avatarFacingModeEnabled: r } = this._store.getState();
    if (!r) return;
    const o = {
      moveIntent: { x: e.x, z: e.z },
      yaw: i,
      avatarFacingMode: n,
      overriddenForward: s
    }, l = this.calculateTargetYaw(o);
    this.applyRotation(l, t), this._currentYaw = l;
  }
}
class ss extends ki {
  static moduleName = q.LocalAvatar;
  _defaultAvatar;
  _viverseAvatar;
  _loadedCustomAnimations = /* @__PURE__ */ new Map();
  _playingCustomAnimation = null;
  _unsubscribes = [];
  constructor(t, e) {
    super(t, e), this._defaultAvatar = new Ht(), this.addAvatar(this._defaultAvatar), this._viverseAvatar = this._defaultAvatar, this._setupSubscriptions();
  }
  get viverseAvatar() {
    return this._viverseAvatar;
  }
  get _viewPosition() {
    return this.system.store.getState().viewPosition;
  }
  get _playerBoundingBox() {
    return this.system.store.getState().boundingBox;
  }
  get _orientationHandler() {
    return this._handlers.getHandler("orientation");
  }
  get _visibilityHandler() {
    return this._handlers.getHandler("visibility");
  }
  get _postureHandler() {
    return this._handlers.getHandler("posture");
  }
  _registerHandlers() {
    super._registerHandlers();
    const t = this.system.store;
    this._handlers.registerHandler("orientation", new ns(this, t)), this._handlers.registerHandler("visibility", new ts(this, t)), this._handlers.registerHandler("posture", new is(this, t));
  }
  _setupSubscriptions() {
    this._subscribeAccount(), this._subscribePreferences(), this._subscribeStore();
  }
  _subscribeAccount() {
    const t = this.viverseApp.context.profile;
    this._unsubscribes.push(
      t.subscribe(
        (e) => e.avatarUrl,
        (e) => this._updateAvatarUrl(e)
      )
    );
  }
  _subscribePreferences() {
    const t = this.viverseApp.context.preference;
    this._unsubscribes.push(
      t.subscribe(
        (e) => e.vrmMtoonShading,
        () => this._updateVrmMtoonShading()
      )
    );
  }
  _subscribeStore() {
    const t = this.system.store;
    this._unsubscribes.push(
      t.subscribe(
        (e) => ({
          walk: e.walkSpeedMultiplier,
          run: e.runSpeedMultiplier
        }),
        () => this._updateSpeedMultipliers(),
        { equalityFn: Pt }
      )
    );
  }
  addAvatar(t) {
    const e = super.addAvatar(t);
    return e && (this._setMtoonShading(t), e);
  }
  _setMtoonShading(t) {
    if (!(t instanceof Y)) return;
    const { vrmMtoonShading: e } = this.viverseApp.context.preference.getState();
    t.setMtoonShading(e);
  }
  _updateAvatarUrl = (t) => {
    t && (this._viverseAvatar = new Jn({ avatarUrl: t }), this.addAvatar(this._viverseAvatar), this._autoSwitchViverseAvatar());
  };
  _autoSwitchViverseAvatar() {
    const t = this.viverseAvatar !== this._defaultAvatar, e = this._activeAvatar === this._defaultAvatar, i = this._switchController !== null;
    t && e && !i && this.setActiveAvatarByName(this.viverseAvatar.name);
  }
  async setupAvatars(t) {
    await super.setupAvatars(t), this._autoSwitchViverseAvatar(), this._listenToNameTagSetup();
  }
  _listenToNameTagSetup() {
    if (!this.system.nameTag) return;
    const e = (n) => {
      this._visibilityHandler.setNameTag(n);
    }, i = this.system.nameTag?.instance;
    i ? e(i) : this.system.once("name-tag:ready", e);
  }
  _activateAvatar(t) {
    super._activateAvatar(t), this._initHeadHeight(t.headHeight), this.system.updateCapsuleCollider(), this._updateSpeedMultipliers();
  }
  _initHeadHeight(t) {
    this.system.store.getState().setHeadHeight(t);
  }
  _updateSpeedMultipliers() {
    if (!this._activeAvatar) return;
    const { walkSpeedMultiplier: t, runSpeedMultiplier: e } = this.system.store.getState();
    this._activeAvatar.setSpeedMultipliers?.({
      walk: t,
      run: e
    });
  }
  _updateVrmMtoonShading() {
    this._avatars.forEach((t) => {
      this._setMtoonShading(t);
    });
  }
  _isIntenseMoving(t = 5) {
    const { playerEntity: e } = this.system.store.getState();
    return !e || !e.rigidbody ? !1 : e.rigidbody.linearVelocity.length() > t;
  }
  removeAvatarByName(t) {
    if (t === this._defaultAvatar.name) {
      E.warn("Cannot remove the VIVERSE default avatar.");
      return;
    }
    t === this._viverseAvatar.name && (this._viverseAvatar = this._defaultAvatar), super.removeAvatarByName(t);
  }
  playCustomAnimation(t, e) {
    if (!this._activeAvatar) {
      E.warn("No avatar is active.");
      return;
    }
    if (!this._activeAvatar.playCustomAnimation) {
      E.warn("The active avatar does not support playAnimation method.");
      return;
    }
    this._activeAvatar.playCustomAnimation(t, e);
    const i = this._loadedCustomAnimations.get(t);
    i && (this._playingCustomAnimation = {
      stateName: t,
      assetUrl: i.assetUrl,
      loadOptions: i.loadOptions,
      playOptions: e
    });
  }
  exitCustomAnimation() {
    if (!this._activeAvatar) {
      E.warn("No avatar is active.");
      return;
    }
    if (!this._activeAvatar.exitCustomAnimation) {
      E.warn("The active avatar does not support exitCustomAnimation method.");
      return;
    }
    this._activeAvatar.exitCustomAnimation();
  }
  async loadCustomAnimation(t, e, i) {
    if (!this._activeAvatar) {
      E.warn("No avatar is active.");
      return;
    }
    if (!this._activeAvatar.loadCustomAnimation) {
      E.warn("The active avatar does not support loadCustomAnimation method.");
      return;
    }
    await this._activeAvatar.loadCustomAnimation(t, e, i);
    const n = e.getFileUrl() || "", s = n.startsWith("/api/") ? n.slice(5) : n;
    s && this._loadedCustomAnimations.set(t, {
      assetUrl: s,
      loadOptions: i
    });
  }
  getAvatarStates() {
    const e = this.system.modules.interaction?.isSitting ?? !1;
    return {
      horizontalDirection: this._postureHandler.horizontalDirection,
      verticalState: this._postureHandler.verticalState,
      isGrounded: this._postureHandler.isGrounded,
      isFalling: this._postureHandler.isFalling,
      isFlying: this._postureHandler.isFlying,
      isSprinting: this._postureHandler.isSprinting,
      isSitting: e,
      triggerJump: this._postureHandler.triggerJump,
      customAnim: this._playingCustomAnimation
    };
  }
  consumeTriggers() {
    this._postureHandler.consumeJumpTrigger();
  }
  _clearCustomAnimState() {
    !this._activeAvatar?.currentCustomAnimation && this._playingCustomAnimation && (this._playingCustomAnimation = null);
  }
  update(t) {
    super.update(t), this._orientationHandler.update(t), this._postureHandler.update(), this._clearCustomAnimState();
  }
  destroy() {
    super.destroy(), this._unsubscribes.forEach((t) => t()), this._unsubscribes = [];
  }
}
class zt {
  name;
  canSeeAvatar;
  canSwitchToNext;
  rotationDamping;
  zoomDamping;
  zoomStep;
  zoomLimit;
  _module = null;
  _entity;
  _playerEntity = null;
  _store = null;
  _active = !1;
  _destroyed = !1;
  _quatX = new pc.Quat();
  _quatY = new pc.Quat();
  _targetQuat = new pc.Quat();
  _finalQuat = new pc.Quat();
  _zoomValue;
  _postEffectMap = /* @__PURE__ */ new Map();
  constructor(t, e, i = {}) {
    this.name = t;
    const { entity: n } = i;
    if (this._entity = n ?? new pc.Entity(e), !this._entity.camera) {
      if (n)
        throw new Error(`Camera entity "${e}" must have a camera component.`);
      this._entity.addComponent("camera");
    }
  }
  get entity() {
    return this._entity;
  }
  get module() {
    return this._module;
  }
  get zoomValue() {
    return this._zoomValue;
  }
  setup(t) {
    this._module = t, this._store = t.system.store;
    const e = t.system.viverseApp;
    _t(e).then((i) => {
      this._destroyed || this._bindPlayerEntity(i);
    }), this._syncPostEffectsFromModule(), this.updateRotation();
  }
  _bindPlayerEntity(t) {
    this._playerEntity = t;
  }
  /**
   * Sync post effects from module to this camera.
   * This is called during setup and when module's post effects change.
   * @internal
   */
  _syncPostEffectsFromModule() {
    if (!this._module) return;
    const t = this._module.getPostEffects(), e = new Set(t.map((i) => i.name));
    for (const [i, n] of this._postEffectMap.entries())
      e.has(i) || (this._removePostEffectFromEntity(n), this._postEffectMap.delete(i));
    t.forEach((i) => {
      if (!this._postEffectMap.get(i.name)) {
        const s = i.clone();
        s.name === te.SSAOEffect && s.applyConfig && s.applyConfig({ cameraEntity: this.entity }), this._postEffectMap.set(i.name, s), this.entity.enabled && this._addPostEffectToEntity(s);
      }
    });
  }
  activate() {
    this._active = !0, this.entity.enabled = !0, this.updateRotation(), this._postEffectMap.forEach((t) => {
      this._addPostEffectToEntity(t);
    });
  }
  deactivate() {
    this._active = !1, this._postEffectMap.forEach((t) => {
      this._removePostEffectFromEntity(t);
    }), this.entity.enabled = !1;
  }
  updateRotation() {
    !this.entity.enabled || !this._store || (this._quatY.setFromAxisAngle(pc.Vec3.UP, this._store.getState().yaw), this._quatX.setFromAxisAngle(pc.Vec3.RIGHT, this._store.getState().pitch), this._targetQuat.copy(this._quatY).mul(this._quatX));
  }
  updateZoom(t) {
    this._zoomValue === void 0 || this.zoomStep === void 0 || this.zoomLimit === void 0 || (this._zoomValue = pc.math.clamp(
      this._zoomValue + t * this.zoomStep,
      this.zoomLimit.min,
      this.zoomLimit.max
    ));
  }
  /**
   * Replace the camera entity with a new one while preserving all camera state.
   * This is useful when updating to use an entity from the Editor hierarchy.
   * Subclasses should override this to handle their specific hierarchy structure.
   *
   * @param newEntity - The new camera entity to use. Must have a camera component.
   */
  replaceEntity(t) {
    if (!t || !t.camera)
      throw new Error("New entity must have a camera component.");
    t.enabled = !1;
    const e = this._active;
    e && this.deactivate(), this._replaceEntityInternal(t);
    const i = this._entity;
    this._entity = t, e && this.activate(), this._module?.system && this._module.system.emit("camera:entity-replaced", {
      previousEntity: i,
      camera: this
    });
  }
  /**
   * Internal method to handle entity replacement in the hierarchy.
   * Subclasses should override this to handle their specific structure
   * (e.g., rigOrigin for ThirdPersonCamera/XrCamera, direct parent for FirstPersonCamera).
   *
   * @protected
   */
  _replaceEntityInternal(t) {
    const e = this._entity.parent, i = this._entity.getLocalPosition(), n = this._entity.getLocalRotation(), s = this._entity.getLocalScale();
    e && e.removeChild(this._entity), e && (e.addChild(t), t.setLocalPosition(i), t.setLocalRotation(n), t.setLocalScale(s));
  }
  destroy() {
    this._destroyed = !0, this.entity && (this.entity.destroy(), this._module = null);
  }
  addPostEffect(t, e = !1) {
    this.entity.camera && (t.name === te.SSAOEffect && t.applyConfig && t.applyConfig({ cameraEntity: this.entity }), this._postEffectMap.set(t.name, t), (this.entity.enabled || e) && this._addPostEffectToEntity(t));
  }
  /**
   * Remove a post effect from this camera.
   * This method is typically called by CameraModule to sync post effects.
   * @internal
   */
  removePostEffect(t) {
    if (!this.entity.camera) return;
    let e;
    t instanceof pc.PostEffect ? (e = this._postEffectMap.get(t.name), e && (this._removePostEffectFromEntity(e), this._postEffectMap.delete(t.name))) : this._postEffectMap.has(t) && (e = this._postEffectMap.get(t), e !== void 0 && (this._removePostEffectFromEntity(e), this._postEffectMap.delete(t)));
  }
  /**
   * Apply configuration to a post effect.
   * This method is typically called by CameraModule to sync post effect configs.
   * @internal
   */
  applyPostEffectConfig(t, e) {
    const i = this._postEffectMap.get(t);
    i?.applyConfig && i.applyConfig(e);
  }
  /**
   * Internal helper to add post effect to entity's camera component.
   * Only adds if camera is enabled.
   */
  _addPostEffectToEntity(t) {
    if (!this.entity.camera) return;
    const e = this.entity.camera.postEffects;
    e.removeEffect(t), e.addEffect(t);
  }
  /**
   * Internal helper to remove post effect from entity's camera component.
   */
  _removePostEffectFromEntity(t) {
    this.entity.camera && this.entity.camera.postEffects.removeEffect(t);
  }
}
const ke = {
  farClip: 1e3,
  nearClip: 0.1,
  fov: 60
}, rt = 5, rs = 5, os = 20, as = 5, wt = 0.2, Q = 1, _e = 0.02, me = 0.1, ls = 0.5, fe = Array.from({ length: 19 }, (a, t) => Number((0.05 * (t + 1)).toFixed(2)));
class cs extends zt {
  name = "third-person";
  canSeeAvatar = !0;
  canSwitchToNext = !0;
  rotationDamping = 8;
  // Damping for rotation
  zoomDamping = rs;
  // Damping for zoom
  zoomStep = 1;
  // Step size for zooming
  zoomLimit = {
    min: 0.5,
    max: 15
  };
  _rigOrigin;
  _zoomValue = rt;
  _zoomValueInput = rt;
  _hasCameraZoomingInput = !1;
  _canZoomIn = !0;
  _canZoomOut = !0;
  _currentZoomValue = rt;
  _timerZoomOut = 0;
  _currentPlayerPosition = new pc.Vec3();
  _tempCameraPositionA = new pc.Vec3();
  _tempCameraPositionB = new pc.Vec3();
  _tempRigOriginPositionA = new pc.Vec3();
  _tempOffset = new pc.Vec3();
  _tempForward = new pc.Vec3();
  _tempBack = new pc.Vec3();
  _tempRight = new pc.Vec3();
  _tempLeft = new pc.Vec3();
  _tempUp = new pc.Vec3();
  _tempDown = new pc.Vec3();
  _tempForwardRight = new pc.Vec3();
  _tempForwardLeft = new pc.Vec3();
  _tempBackRight = new pc.Vec3();
  _tempBackLeft = new pc.Vec3();
  constructor(t) {
    super("third-person", "ThirdPersonCamera", t), !t?.entity && this.entity.camera && Object.assign(this.entity.camera, ke), this._rigOrigin = new pc.Entity("ThirdPersonCameraRigOrigin"), this._rigOrigin.addChild(this._entity);
  }
  _replaceEntityInternal(t) {
    const e = this._entity.getLocalPosition(), i = this._entity.getLocalRotation(), n = this._entity.getLocalScale();
    this._rigOrigin.removeChild(this._entity), this._rigOrigin.addChild(t), t.setLocalPosition(e), t.setLocalRotation(i), t.setLocalScale(n);
  }
  _bindPlayerEntity(t) {
    super._bindPlayerEntity(t), t.addChild(this._rigOrigin), this.entity.setLocalPosition(0, 0, this._zoomValue);
    const e = this._store?.getState().headHeight ?? 1.6;
    this.updateHeadHeight(e);
  }
  activate() {
    if (super.activate(), !this._store) return;
    const { setAvatarFacingMode: t, headHeight: e } = this._store.getState();
    t(K.Movement), this._rigOrigin.setLocalRotation(this._targetQuat), this.updateHeadHeight(e);
  }
  update(t) {
    const e = this._rigOrigin.getLocalRotation(), i = this._zoomValue;
    this._applyAutoZoom(t), this._finalQuat.slerp(e, this._targetQuat, Math.min(this.rotationDamping * t, 1)), this._rigOrigin.setLocalRotation(this._finalQuat);
    const n = this._zoomValue;
    this._applyZoom(n, i, t);
  }
  updateHeadHeight(t) {
    this._store && this._rigOrigin.setLocalPosition(0, t, 0);
  }
  updateZoom(t) {
    (t > 0 ? this._canZoomOut : this._canZoomIn) && (this._hasCameraZoomingInput = !0, super.updateZoom(t), this._zoomValueInput = this._zoomValue);
  }
  _applyZoom(t, e, i) {
    const n = this.entity.getLocalPosition().z, r = this._zoomValueInput !== this._zoomValue ? (
      // check if auto zoom out
      t > e ? os : as
    ) : this.zoomDamping, o = Math.min(r * i, 1), l = pc.math.lerp(n, t, o);
    Math.abs(l - n) > 0 && (this._currentZoomValue = l, this.entity.setLocalPosition(0, 0, l));
  }
  _getZoomValueByPosition(t) {
    return this._rigOrigin.getPosition().distance(t);
  }
  _getPositionByZoomValue(t) {
    const e = this.entity.getPosition(), i = this._rigOrigin.getPosition();
    return this._tempCameraPositionA.copy(e).sub(i).normalize().mulScalar(t).add(i);
  }
  _filterRaycastResult(t) {
    return t !== this._playerEntity && !!t.collision && !!t.rigidbody;
  }
  // Use raycasting to identify potential target positions for camera auto-zoom
  _raycastAutoZoomPositionFromOrigin(t, e) {
    if (!pc?.app?.systems?.rigidbody)
      return {
        type: "CENTER",
        point: null
      };
    const i = pc.app?.systems.rigidbody.raycastFirst(t, e, {
      filterCallback: this._filterRaycastResult.bind(this)
    });
    return i ? {
      type: "CENTER",
      point: i.point
    } : {
      type: "CENTER",
      point: null
    };
  }
  // Use raycasting to identify potential target positions for camera auto-zoom
  _raycastAutoZoomPosition(t, e) {
    if (!pc?.app?.systems?.rigidbody)
      return {
        type: "CENTER",
        point: null
      };
    const i = pc.app?.systems.rigidbody.raycastFirst(
      this._tempCameraPositionA.copy(e).sub(t),
      this._tempCameraPositionB.copy(e).add(t),
      {
        filterCallback: this._filterRaycastResult.bind(this)
      }
    );
    if (i) {
      const n = this._tempCameraPositionA.copy(e).add(t).sub(i.point), s = this._tempRigOriginPositionA.copy(this._rigOrigin.getPosition()).sub(e), r = n.length() / s.project(this._tempOffset.copy(n).normalize()).length();
      return {
        type: "CENTER",
        point: s.mulScalar(r).add(e)
      };
    }
    return {
      type: "CENTER",
      point: null
    };
  }
  _raycastAutoZoomPositionAllXy(t, e = !0) {
    const i = {
      type: "CENTER",
      point: null
    };
    if (!pc?.app?.systems?.rigidbody) return [i];
    if (e && this._rigOrigin) {
      const n = pc.app?.systems.rigidbody.raycastFirst(
        this._rigOrigin.getPosition(),
        t,
        {
          filterCallback: this._filterRaycastResult.bind(this)
        }
      );
      i.point = n ? n?.point : null;
    }
    return [
      // up
      {
        type: "UP",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempUp.set(0, 1, 0).mulScalar(wt),
          t
        )
      },
      // down
      {
        type: "DOWN",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempDown.set(0, 1, 0).mulScalar(-wt),
          t
        )
      },
      // right
      {
        type: "RIGHT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempRight.copy(this.entity.right).mulScalar(wt),
          t
        )
      },
      // left
      {
        type: "LEFT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempLeft.copy(this.entity.right).mulScalar(-wt),
          t
        )
      },
      // center
      ...e ? [i] : []
    ];
  }
  _raycastAutoZoomPositionAllXz(t) {
    const e = [
      // forward
      {
        type: "FORWARD",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempForward.copy(this.entity.forward).mulScalar(Q * 3),
          t
        )
      },
      // back
      {
        type: "BACK",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempBack.copy(this.entity.forward).mulScalar(-Q * 3),
          t
        )
      },
      // right
      {
        type: "RIGHT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempRight.copy(this.entity.right).mulScalar(Q),
          t
        )
      },
      // left
      {
        type: "LEFT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempLeft.copy(this.entity.right).mulScalar(-Q),
          t
        )
      }
    ];
    return pc?.app?.systems?.rigidbody && fe.forEach((i) => {
      e.push({
        type: "FORWARD_RIGHT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempForwardRight.lerp(this.entity.forward, this.entity.right, i).normalize().mulScalar(Q * 2),
          t
        )
      }), e.push({
        type: "FORWARD_LEFT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempForwardLeft.lerp(this.entity.forward, this._tempLeft.copy(this.entity.right).mulScalar(-1), i).normalize().mulScalar(Q * 2),
          t
        )
      }), e.push({
        type: "BACK_RIGHT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempBackRight.lerp(this._tempBack.copy(this.entity.forward).mulScalar(-1), this.entity.right, i).normalize().mulScalar(Q * 2),
          t
        )
      }), e.push({
        type: "BACK_LEFT",
        point: null,
        ...this._raycastAutoZoomPosition(
          this._tempBackLeft.lerp(
            this._tempBack.copy(this.entity.forward).mulScalar(-1),
            this._tempLeft.copy(this.entity.right).mulScalar(-1),
            i
          ).normalize().mulScalar(Q * 2),
          t
        )
      });
    }), e;
  }
  _applyAutoZoom(t) {
    const e = this._rigOrigin.getLocalRotation();
    if (this._playerEntity) {
      const i = this._hasCameraZoomingInput;
      i && (this._hasCameraZoomingInput = !1);
      const n = !e.equalsApprox(this._targetQuat), s = this._playerEntity.getPosition(), r = this._currentPlayerPosition.distance(s) > 0.01;
      r && this._currentPlayerPosition.copy(s);
      const o = this.entity.getPosition(), l = this._raycastAutoZoomPositionFromOrigin(
        this._rigOrigin.getPosition(),
        o
      ).point, c = !i && !r && !n, h = this._raycastAutoZoomPositionAllXy(o).filter((u) => u.point !== null).map(
        ({ point: u = null }) => u !== null ? this._getZoomValueByPosition(u) : rt
      ).sort((u, d) => u - d);
      if (h.length > 0) {
        this._timerZoomOut = 0;
        const u = h[0];
        (!c || l) && u < this._currentZoomValue && Math.abs(u - this._currentZoomValue) / rt >= _e && (this._zoomValue = u), [
          ...this._raycastAutoZoomPositionAllXy(
            this._getPositionByZoomValue(
              this._currentZoomValue + me
            )
          )
        ].some((d) => d.point !== null) ? this._canZoomOut = !1 : this._canZoomOut = !0;
      } else if (this._timerZoomOut >= ls) {
        this._timerZoomOut = 0, this._raycastAutoZoomPositionAllXy(
          this._getPositionByZoomValue(
            this._currentZoomValue + me
          )
        ).every((d) => d.point === null) && (this._canZoomOut = !0);
        const u = [
          ...this._raycastAutoZoomPositionAllXy(this._getPositionByZoomValue(this._zoomValueInput)),
          ...fe.reduce((d, p) => (d.push(
            ...this._raycastAutoZoomPositionAllXz(
              this._getPositionByZoomValue(
                this._currentZoomValue + (this._zoomValueInput - this._currentZoomValue) * p
              )
            )
          ), d), [])
        ].filter(
          ({ point: d }) => d && this._raycastAutoZoomPositionAllXy(d).every((p) => p.point === null)
        ).map(({ point: d }) => d !== null ? this._getZoomValueByPosition(d) : 1).sort((d, p) => p - d);
        if (u.length > 0) {
          const d = u.length % 2 !== 0, p = Math.floor(u.length / 2), f = ((d ? u[p] : (u[p] + u[p - 1]) / 2) + this._currentZoomValue) / 2;
          (!c || l) && Math.abs(f - this._currentZoomValue) / rt >= _e && (this._zoomValue = f);
        } else !i && Math.abs(this._zoomValueInput - this._currentZoomValue) > 1e-3 && this._zoomValueInput > this._currentZoomValue && (this._zoomValue = this._zoomValueInput);
      } else
        this._timerZoomOut += t;
    }
  }
}
const hs = 60;
class us extends zt {
  name = "first-person";
  canSeeAvatar = !1;
  canSwitchToNext = !0;
  rotationDamping = 20;
  // Damping for rotation
  zoomDamping = 5;
  // Damping for zoom
  _zoomValue = hs;
  zoomStep = 10;
  // Step size for zooming
  zoomLimit = {
    min: 15,
    max: 120
  };
  constructor(t) {
    super("first-person", "FirstPersonCamera", t), !t?.entity && this.entity.camera && Object.assign(this.entity.camera, ke);
  }
  _bindPlayerEntity(t) {
    super._bindPlayerEntity(t), t.addChild(this._entity), this._zoomValue = this._entity.camera?.fov || this._zoomValue;
    const e = this._store?.getState().headHeight ?? 1.6;
    this.updateHeadHeight(e);
  }
  activate() {
    if (super.activate(), !this._store) return;
    this._store.getState().setAvatarFacingMode(K.View), this.entity.setLocalRotation(this._targetQuat);
    const t = this._store.getState().headHeight;
    this.updateHeadHeight(t);
  }
  updateHeadHeight(t) {
    this.entity.setLocalPosition(0, t, 0);
  }
  update(t) {
    if (this._finalQuat.slerp(
      this.entity.getLocalRotation(),
      this._targetQuat,
      Math.min(this.rotationDamping * t, 1)
    ), this.entity.setLocalRotation(this._finalQuat), this.entity.camera) {
      const e = pc.math.lerp(
        this.entity.camera.fov,
        this._zoomValue,
        Math.min(this.zoomDamping * t, 1)
      );
      this.entity.camera.fov = e;
    }
  }
}
class ge extends zt {
  canSeeAvatar = !1;
  canSwitchToNext = !1;
  rotationDamping = 8;
  _rigOrigin;
  constructor(t) {
    super("xr", "XrCamera", t), this._rigOrigin = new pc.Entity("XrCameraRigOrigin"), this._rigOrigin.addChild(this._entity);
  }
  _replaceEntityInternal(t) {
    const e = this._entity.getLocalPosition(), i = this._entity.getLocalRotation(), n = this._entity.getLocalScale();
    this._rigOrigin.removeChild(this._entity), this._rigOrigin.addChild(t), t.setLocalPosition(e), t.setLocalRotation(i), t.setLocalScale(n);
  }
  _bindPlayerEntity(t) {
    super._bindPlayerEntity(t), t.addChild(this._rigOrigin);
    const e = this._store?.getState().headHeight ?? 1.6;
    this.updateHeadHeight(e);
  }
  activate() {
    if (super.activate(), this._rigOrigin.setLocalRotation(this._targetQuat), !this._store) return;
    const t = this._store.getState().headHeight;
    this.updateHeadHeight(t);
  }
  updateHeadHeight(t) {
    this._rigOrigin.setLocalPosition(0, t, 0);
  }
  updateRotation() {
    this._store && (this._quatY.setFromAxisAngle(pc.Vec3.UP, this._store.getState().yaw), this._targetQuat.copy(this._quatY));
  }
  update(t) {
    this._finalQuat.slerp(
      this._rigOrigin.getLocalRotation(),
      this._targetQuat,
      Math.min(this.rotationDamping * t, 1)
    ), this._rigOrigin.setLocalRotation(this._finalQuat);
  }
  destroy() {
    super.destroy(), this._rigOrigin.destroy();
  }
}
class ds extends pc.PostEffect {
  color;
  texture;
  shader;
  _colorData;
  constructor(t, e) {
    super(t);
    const { thickness: i, color: n } = e, s = [
      `#define THICKNESS ${i ? i.toFixed(0) : 1}`,
      "uniform float uWidth;",
      "uniform float uHeight;",
      "uniform vec4 uOutlineCol;",
      "uniform sampler2D uColorBuffer;",
      "uniform sampler2D uOutlineTex;",
      "",
      "varying vec2 vUv0;",
      "",
      "void main(void)",
      "{",
      "    vec4 texel1 = texture2D(uColorBuffer, vUv0);",
      "    float sample0 = texture2D(uOutlineTex, vUv0).a;",
      "    float outline = 0.0;",
      "    if (sample0==0.0)",
      "    {",
      "        for (int x=-THICKNESS;x<=THICKNESS;x++)",
      "        {",
      "            for (int y=-THICKNESS;y<=THICKNESS;y++)",
      "            {    ",
      "                float tex=texture2DLod(uOutlineTex, vUv0 + vec2(float(x)/uWidth, float(y)/uHeight), 0.0).a;",
      "                if (tex>0.0)",
      "                {",
      "                    outline=1.0;",
      "                }",
      "            }",
      "        } ",
      "    }",
      "    gl_FragColor = mix(texel1, uOutlineCol, outline * uOutlineCol.a);",
      "}"
    ].join(`
`);
    this.shader = pc.ShaderUtils.createShader(t, {
      uniqueName: "OutlineShader",
      attributes: { aPosition: pc.SEMANTIC_POSITION },
      vertexGLSL: pc.PostEffect.quadVertexShader,
      fragmentGLSL: s
    }), this.color = n || new pc.Color(1, 1, 1, 1), this.texture = new pc.Texture(t), this.texture.name = "pe-outline", this._colorData = new Float32Array(4);
  }
  render(t, e, i) {
    const s = this.device.scope;
    this._colorData[0] = this.color.r, this._colorData[1] = this.color.g, this._colorData[2] = this.color.b, this._colorData[3] = this.color.a, s.resolve("uWidth").setValue(t.width), s.resolve("uHeight").setValue(t.height), s.resolve("uOutlineCol").setValue(this._colorData), s.resolve("uColorBuffer").setValue(t.colorBuffer), s.resolve("uOutlineTex").setValue(this.texture), this.drawQuad(e, this.shader, i);
  }
}
class ps {
  _layer;
  _camera;
  _renderTarget = null;
  _effect;
  _config;
  _app;
  constructor(t, e) {
    this._app = t, this._config = e, this._layer = Ae(t, `OutlineLayer_${e.name}`), this._camera = this._createCamera(), this._effect = new ds(t.graphicsDevice, {
      thickness: e.outlineWidth,
      color: e.color
    });
  }
  get layer() {
    return this._layer;
  }
  get effect() {
    return this._effect;
  }
  _createCamera() {
    const t = new pc.Entity(`OutlineCamera_${this._config.name}`);
    return t.addComponent("camera", {
      clearColor: new pc.Color(0, 0, 0, 0),
      layers: [this._layer.id],
      priority: -1,
      fov: 45,
      nearClip: 0.1,
      farClip: 1e3
    }), t.enabled = !1, this._app.root.addChild(t), t;
  }
  _createRenderTarget() {
    this._renderTarget || (this._renderTarget = new pc.RenderTarget({
      colorBuffer: new pc.Texture(this._app.graphicsDevice, {
        name: `OutlineRT${this._config.name}`,
        width: this._app.graphicsDevice.width,
        height: this._app.graphicsDevice.height,
        format: pc.PIXELFORMAT_RGBA8,
        mipmaps: !1,
        minFilter: pc.FILTER_LINEAR,
        magFilter: pc.FILTER_LINEAR
      }),
      depth: !0
    }));
  }
  _destroyRenderTarget() {
    this._renderTarget && (this._renderTarget.colorBuffer.destroy(), this._renderTarget.destroy(), this._renderTarget = null);
  }
  _setupCameraRenderTarget() {
    if (!this._renderTarget) return;
    !this._camera.camera && (this._camera = this._createCamera()), this._camera.camera.renderTarget = this._renderTarget, this._effect.texture = this._renderTarget.colorBuffer;
  }
  _clearCameraRenderTarget() {
    this._camera.camera && (this._camera.camera.renderTarget = null), this._effect.texture = null;
  }
  enable() {
    this._createRenderTarget(), this._setupCameraRenderTarget(), this._camera.enabled = !0;
  }
  disable() {
    this._camera.enabled = !1, this._clearCameraRenderTarget(), this._destroyRenderTarget();
  }
  updateCamera(t) {
    this._camera.setPosition(t.getPosition()), this._camera.setRotation(t.getRotation()), t.camera && this._camera.camera && (this._camera.camera.fov = t.camera.fov, this._camera.camera.nearClip = t.camera.nearClip, this._camera.camera.farClip = t.camera.farClip);
  }
  destroy() {
    this.disable(), this._camera && this._camera.destroy(), this._layer && this._app.scene.layers.remove(this._layer);
  }
}
class _s {
  _viverseApp;
  _system;
  _mainCamera = null;
  _isSystemEnabled = !1;
  _outlineChannels = /* @__PURE__ */ new Map();
  _entityChannelMap = /* @__PURE__ */ new Map();
  constructor(t) {
    this._viverseApp = t.viverseApp, this._system = t;
    const e = this._system.modules.camera?.currentCamera;
    this._mainCamera = e?.entity || null, this._bindEvents();
  }
  _bindEvents() {
    this._system.on("camera:before-change", this._cameraBeforeChange, this);
  }
  _unbindEvents() {
    this._system.off("camera:before-change", this._cameraBeforeChange, this);
  }
  _cameraBeforeChange({
    previousCamera: t,
    newCamera: e
  }) {
    this._mainCamera = e.entity, this._isSystemEnabled && this._outlineChannels.forEach((i) => {
      t && this._removeEffectFromCamera(t.entity, i.effect), this._addEffectToCamera(e.entity, i.effect);
    });
  }
  _removeEffectFromCamera(t, e) {
    t.camera && t.camera.postEffects.removeEffect(e);
  }
  _addEffectToCamera(t, e) {
    if (t.camera) {
      const i = t.camera.postEffects;
      i.effects.some((s) => s.effect === e) || i.addEffect(e);
    }
  }
  createChannel(t) {
    const e = new ps(this._viverseApp.pcApp, t);
    this._outlineChannels.set(t.name, e);
  }
  addEntity(t, e) {
    const i = this._outlineChannels.get(t);
    if (!i) {
      E.warn(`OutlineHandler Channel with name "${t}" does not exist.`);
      return;
    }
    const n = e.findComponents("render");
    n.length === 0 || this._entityChannelMap.get(e) === t || (this._removeEntityFromChannel(e), this._entityChannelMap.set(e, t), n.forEach((r) => {
      r.layers = [...r.layers, i.layer.id];
    }), this._entityChannelMap.size > 0 && !this._isSystemEnabled && this._enableOutlineSystem());
  }
  removeEntity(t) {
    this._entityChannelMap.has(t) && (this._removeEntityFromChannel(t), this._entityChannelMap.delete(t), this._entityChannelMap.size === 0 && this._disableOutlineSystem());
  }
  _removeEntityFromChannel(t) {
    if (!this._entityChannelMap.has(t)) return;
    const e = this._entityChannelMap.get(t);
    if (e) {
      const i = this._outlineChannels.get(e);
      i && t.findComponents("render").forEach((s) => {
        s.layers = s.layers.filter(
          (r) => r !== i.layer.id
        );
      });
    }
  }
  _enableOutlineSystem() {
    this._isSystemEnabled || (this._isSystemEnabled = !0, this._outlineChannels.forEach((t) => {
      this._mainCamera && (t.enable(), this._addEffectToCamera(this._mainCamera, t.effect));
    }));
  }
  _disableOutlineSystem() {
    this._isSystemEnabled && (this._isSystemEnabled = !1, this._outlineChannels.forEach((t) => {
      this._mainCamera && this._removeEffectFromCamera(this._mainCamera, t.effect), t.disable();
    }));
  }
  destroy() {
    this._unbindEvents(), this._outlineChannels.forEach((t) => t.destroy()), this._outlineChannels.clear(), this._entityChannelMap.clear(), this._disableOutlineSystem();
  }
  update() {
    this._outlineChannels.forEach((t) => {
      this._mainCamera && t.updateCamera(this._mainCamera);
    });
  }
}
class ms {
  clear;
  toggle;
  enabled = !1;
  mode = 1;
  constructor(t = {}) {
    if (!window.Ammo) {
      E.error(
        "Warning! Trying to initialize Ammo Debug Drawer without Ammo lib in the project. Aborting."
      );
      return;
    }
    if (!window.Ammo.DebugDrawer) {
      E.error(
        "Warning! Your Ammo does'nt have Debug Drawer. The version of it might be the lite one. Aborting."
      );
      return;
    }
    const e = pc.Application.getApplication();
    if (!e) {
      E.error(
        "Warning! Trying to initialize Ammo Debug Drawer without PlayCanvas Application instance. Aborting."
      );
      return;
    }
    const n = e.scene.layers, s = t.layer || n.getLayerById(pc.LAYERID_UI) || void 0, { entity: r, distance: o = 1 / 0, ignorePartials: l } = t.limit || {}, c = new fs(), h = new pc.Vec3(), u = new pc.Vec3();
    let d = 1, p = !1;
    const m = window.Ammo, f = new m.DebugDrawer();
    f.drawLine = T.bind(this), f.drawContactPoint = y.bind(this), f.reportErrorWarning = g.bind(this), f.draw3dText = v.bind(this), f.setDebugMode = w.bind(this), f.getDebugMode = M.bind(this), f.enable = P.bind(this), f.disable = C.bind(this), f.update = k.bind(this);
    const _ = e.systems.rigidbody?.dynamicsWorld;
    if (!_) {
      E.error("Warning! Rigidbody system or dynamics world not found. Aborting.");
      return;
    }
    _.setDebugDrawer(f), this.clear = A, this.toggle = L;
    function g(I) {
    }
    function v(I, G) {
    }
    function y(I, G, et, W, N) {
      const R = m.wrapPointer(I, m.btVector3), U = m.wrapPointer(G, m.btVector3), B = m.wrapPointer(N, m.btVector3), j = R.x(), it = R.y(), Z = R.z();
      c.pushPos(j, it, Z, j + U.x() * 0.5, it + U.y() * 0.5, Z + U.z() * 0.5), c.pushColor(B.x(), B.y(), B.z(), 1, B.x(), B.y(), B.z(), 1);
    }
    function T(I, G, et) {
      const W = m.wrapPointer(I, m.btVector3), N = m.wrapPointer(G, m.btVector3), R = m.wrapPointer(et, m.btVector3);
      if (r && o !== 1 / 0) {
        h.set(W.x(), W.y(), W.z()), u.set(N.x(), N.y(), N.z());
        const U = r.getPosition(), B = U.distance(h), j = U.distance(u);
        (B < o && j < o || r && !l && (B < o || j < o)) && (c.pushPos(h.x, h.y, h.z, u.x, u.y, u.z), c.pushColor(R.x(), R.y(), R.z(), 1, R.x(), R.y(), R.z(), 1));
      } else
        c.pushPos(W.x(), W.y(), W.z(), N.x(), N.y(), N.z()), c.pushColor(R.x(), R.y(), R.z(), 1, R.x(), R.y(), R.z(), 1);
    }
    function A() {
      c.clear();
    }
    function w(I) {
      d = I;
    }
    function M() {
      return d;
    }
    function P() {
      p = !0;
    }
    function C() {
      p = !1;
    }
    function L() {
      p = !p;
    }
    function z() {
      try {
        c.entries.forEach((I) => {
          s && e.drawLineArrays(I.positions, I.colors, !1, s);
        });
      } catch (I) {
        E.warn("Error drawing debug lines", I), C();
      }
    }
    function k() {
      p && _.debugDrawWorld();
    }
    function D() {
      p && (z(), A());
    }
    Object.defineProperties(this, {
      enabled: {
        get: () => p,
        set: (I) => {
          p = I, p ? (e.systems.on("update", k, this), e.systems.on("postUpdate", D, this)) : (e.systems.off("update", k, this), e.systems.off("postUpdate", D, this), A());
        }
      },
      // 0: Disable
      // 1: Wireframe
      // 2: Bounding Boxes
      // 3: Wireframe + AABB
      // 8: Contact Points
      mode: {
        get: () => d,
        set: (I) => {
          d = I;
        }
      }
    });
  }
}
class fs {
  entries;
  clear;
  pushColor;
  pushPos;
  constructor() {
    const t = /* @__PURE__ */ new Map(), e = 64e3;
    let i = 0;
    t.set(i, { positions: [], colors: [] }), this.entries = t, this.clear = n, this.pushColor = s, this.pushPos = r, o(i);
    function n() {
      t.clear(), i = 0, o(i);
    }
    function s(c, h, u, d, p, m, f, _) {
      l("colors", 8).colors.push(c, h, u, d, p, m, f, _);
    }
    function r(c, h, u, d, p, m) {
      l("positions", 6).positions.push(c, h, u, d, p, m);
    }
    function o(c) {
      const h = { positions: [], colors: [] };
      return t.set(c, h), h;
    }
    function l(c, h) {
      let u = t.get(i);
      return (!u || u[c].length + h > e) && (u = o(++i)), u;
    }
  }
}
class gs {
  _drawer = null;
  _layer;
  _cameraEntity = null;
  constructor(t, e) {
    this._layer = Ae(t, "PhysicsDebugLayer", {
      clearDepthBuffer: !0
    }), e && this._createDrawer(e);
  }
  _removeLayer(t) {
    if (!t.camera) return;
    const e = t.camera.layers;
    t.camera.layers = e.filter((i) => i !== this._layer.id);
  }
  _addLayer(t) {
    if (!t.camera) return;
    const e = t.camera.layers;
    t.camera.layers = [...e, this._layer.id];
  }
  _createDrawer(t) {
    this._drawer = new ms({
      layer: this._layer,
      limit: {
        entity: t,
        distance: 50
      }
    }), this._addLayer(t), this._cameraEntity = t, this._drawer.enabled = !0;
  }
  updateCamera(t) {
    this._drawer && (this._drawer.clear(), this._drawer.enabled = !1, this._drawer = null), this._cameraEntity && (this._removeLayer(this._cameraEntity), this._cameraEntity = null), this._createDrawer(t);
  }
}
class ys extends pt {
  static moduleName = q.Camera;
  cameras = {};
  outline;
  _physicsDrawer = null;
  _cameraOrders = [];
  _currentCamera;
  _previousCamera;
  _xrCamera = new ge();
  _viewAxes = new pc.Mat3();
  _canRotate = !0;
  _canZoom = !0;
  _canSwitchToNext = !0;
  _postEffectMap = /* @__PURE__ */ new Map();
  constructor(t, e) {
    super(t), this.outline = new _s(t);
    const i = {
      ...this._getDefaultOptions(),
      ...e
    };
    if (this.canRotate = i.canRotate, this.canZoom = i.canZoom, this._initCameras(i.cameras), i.usePhysicsDebug) {
      const s = this._currentCamera?.entity;
      this._physicsDrawer = new gs(t.pcApp, s);
    }
    i.postEffects && i.postEffects.forEach((s) => {
      this.addPostEffect(s);
    });
    const n = this.system.store;
    n.subscribe(
      (s) => ({
        yaw: s.yaw,
        pitch: s.pitch
      }),
      () => this._updateRotation(),
      { equalityFn: Pt }
    ), n.subscribe(
      (s) => s.headHeight,
      (s) => this._updateHeadHeight(s)
    ), this.system.on("input:switch-camera", this.switchToNextCamera, this), this.system.on("input:zoom", this._updateZoom, this);
  }
  get currentCamera() {
    return this._currentCamera;
  }
  get previousCamera() {
    return this._previousCamera;
  }
  get xrCamera() {
    return this._xrCamera;
  }
  get cameraOrders() {
    return this._cameraOrders;
  }
  set cameraOrders(t) {
    fi(t, this._cameraOrders) ? this._cameraOrders = t : E.error("Order array does not match the original order.");
  }
  get canRotate() {
    return this._canRotate;
  }
  set canRotate(t) {
    this._canRotate = t, this.system.store.getState().setCanInputRotateYawPitch(t);
  }
  get canZoom() {
    return this._canZoom;
  }
  set canZoom(t) {
    this._canZoom = t;
  }
  get canSwitchToNext() {
    return this._canSwitchToNext;
  }
  set canSwitchToNext(t) {
    this._canSwitchToNext = t;
  }
  setCurrentCamera(t) {
    if (!this.cameras[t.name]) {
      E.error(`Camera "${t.name}" does not exist in the module.`);
      return;
    }
    if (this._currentCamera === t) {
      E.warn(`Camera "${t.name}" is already the current camera.`);
      return;
    }
    this.system.emit("camera:before-change", {
      previousCamera: this._currentCamera,
      newCamera: t
    }), this._deactivateCurrentCamera(), this._previousCamera = this._currentCamera, this._currentCamera = t, this._activateCurrentCamera(), this._physicsDrawer && this._physicsDrawer.updateCamera(t.entity), this._syncCameraActivation(), this.system.emit("camera:changed", {
      previousCamera: this._previousCamera,
      newCamera: t
    });
  }
  setCurrentCameraByName(t) {
    const e = this.cameras[t];
    if (!e) {
      E.error(`Camera with name "${t}" does not exist in the module.`);
      return;
    }
    this.setCurrentCamera(e);
  }
  getCameraByName(t) {
    return this.cameras[t] || null;
  }
  addCamera(t) {
    if (this.cameras[t.name]) {
      E.error(`Camera with name ${t.name} already exists.`);
      return;
    }
    return this.cameras[t.name] = t, this._cameraOrders.push(t.name), t.name;
  }
  removeCamera(t) {
    if (!this.cameras[t.name]) {
      E.error(`Camera with name ${t.name} does not exist.`);
      return;
    }
    if (this._currentCamera === t) {
      E.error(
        `Cannot remove the current active camera "${t.name}". Please switch to another camera first.`
      );
      return;
    }
    delete this.cameras[t.name], this._cameraOrders = this._cameraOrders.filter((e) => e !== t.name);
  }
  removeCameraByName(t) {
    const e = this.getCameraByName(t);
    if (!e) {
      E.error(`Camera with name ${t} does not exist.`);
      return;
    }
    this.removeCamera(e);
  }
  restorePreviousCamera() {
    this._previousCamera && this.setCurrentCamera(this._previousCamera);
  }
  switchToNextCamera() {
    if (!this.canSwitchToNext)
      return;
    if (!this._currentCamera) {
      E.warn("No current camera to switch from.");
      return;
    }
    if (this.system.store.getState().isXrActive) {
      E.warn("Cannot switch camera while XR is active.");
      return;
    }
    if (this._currentCamera.canSwitchToNext === !1) return;
    const t = this._cameraOrders.filter((s) => this.cameras[s].canSwitchToNext ?? !0), e = t.indexOf(this._currentCamera.name), i = (e + 1) % t.length, n = t[i];
    e !== i && this.setCurrentCameraByName(n);
  }
  prepareXrCamera(t) {
    return t && !this.cameras[t.name] && (this.addCamera(t), t.setup(this)), this._xrCamera = t || this._xrCamera, this.setCurrentCamera(this._xrCamera), this._xrCamera;
  }
  update(t) {
    this._currentCamera && this._currentCamera.update && this._currentCamera.update(t), this._setViewAxes(), this._setViewPosition(), this.outline.update();
  }
  _syncCameraActivation() {
    const t = Object.values(this.cameras).filter((e) => e.entity.enabled);
    if (t.length > 1) {
      const e = t.map((i) => i.name).join(", ");
      E.warn(`Multiple cameras are active: ${e}`);
    }
    Object.values(this.cameras).forEach((e) => {
      e === this._currentCamera ? e.activate() : e.deactivate();
    });
  }
  updateCameraEntities(t = {}) {
    if (this.system.store.getState().isXrActive) {
      E.error("Can't update camera entities while XR is active.");
      return;
    }
    [nt.FirstPerson, nt.ThirdPerson, nt.Xr].forEach(
      (i) => {
        const n = t[i];
        n && this._replaceCameraEntity(i, n);
      }
    ), this._syncCameraActivation();
  }
  _replaceCameraEntity(t, e) {
    const i = this.cameras[t];
    if (i)
      i.replaceEntity(e);
    else {
      const n = this._createCameraForKey(t, e);
      if (!n)
        return;
      this._cameraOrders.includes(n.name) || this._cameraOrders.push(n.name), this.cameras[n.name] = n, t === nt.Xr && (this._xrCamera = n), n.setup(this);
    }
  }
  _createCameraForKey(t, e) {
    switch (t) {
      case nt.ThirdPerson:
        return new cs({ entity: e });
      case nt.FirstPerson:
        return new us({ entity: e });
      case nt.Xr:
        return new ge({ entity: e });
      default:
        return null;
    }
  }
  getPostEffects() {
    return Array.from(this._postEffectMap.values());
  }
  _getDefaultOptions() {
    return {
      cameras: [],
      canRotate: !0,
      canZoom: !0,
      usePhysicsDebug: !1,
      postEffects: []
    };
  }
  _initCameras(t) {
    if (t.length !== 0) {
      t.forEach((e) => this.addCamera(e)), this.addCamera(this._xrCamera);
      for (const e of this._cameraOrders)
        this.cameras[e].setup(this);
      this._cameraOrders.length > 0 && this.setCurrentCameraByName(this._cameraOrders[0]);
    }
  }
  _activateCurrentCamera() {
    if (this._currentCamera) {
      this._currentCamera.activate();
      const { setCanCameraSeeAvatar: t } = this.system.store.getState();
      t(this._currentCamera.canSeeAvatar ?? !0);
    }
  }
  _deactivateCurrentCamera() {
    this._currentCamera && this._currentCamera.deactivate();
  }
  _updateZoom(t) {
    this.canZoom && this._currentCamera && this._currentCamera.updateZoom && this._currentCamera.updateZoom(t);
  }
  _updateRotation() {
    this._currentCamera && this._currentCamera.updateRotation && this._currentCamera.updateRotation();
  }
  _updateHeadHeight(t) {
    this._currentCamera && this._currentCamera.updateHeadHeight && this._currentCamera.updateHeadHeight(t);
  }
  _setViewAxes() {
    this._currentCamera && this._viewAxes.set([
      this._currentCamera.entity.right.x,
      this._currentCamera.entity.right.y,
      this._currentCamera.entity.right.z,
      this._currentCamera.entity.up.x,
      this._currentCamera.entity.up.y,
      this._currentCamera.entity.up.z,
      this._currentCamera.entity.forward.x,
      this._currentCamera.entity.forward.y,
      this._currentCamera.entity.forward.z
    ]), this.system.store.getState().setViewAxes(this._viewAxes);
  }
  _setViewPosition() {
    if (this._currentCamera) {
      const t = this._currentCamera.entity.getPosition();
      this.system.store.getState().setViewPosition(t);
    }
  }
  addPostEffect(t) {
    this._postEffectMap.set(t.name, t), Object.values(this.cameras).forEach((e) => {
      e.addPostEffect && e.addPostEffect(t.clone(), e === this._currentCamera);
    });
  }
  removePostEffect(t) {
    t instanceof pc.PostEffect ? this._postEffectMap.delete(t.name) : this._postEffectMap.has(t) && this._postEffectMap.delete(t), Object.values(this.cameras).forEach((e) => {
      e.removePostEffect && e.removePostEffect(t);
    });
  }
  applyPostEffectConfig(t, e) {
    if (this._postEffectMap.has(t)) {
      const i = this._postEffectMap.get(t);
      i !== void 0 && i.applyConfig && i.applyConfig(e);
    }
    Object.values(this.cameras).forEach((i) => {
      i.applyPostEffectConfig && i.applyPostEffectConfig(t, e);
    });
  }
}
class ot {
  name;
  _module;
  _store;
  _hasEntered = !1;
  _moveIntent = new pc.Vec3();
  _direction = new pc.Vec3();
  _axesMat3 = new pc.Mat3();
  _baseSpeed = 1.65;
  _sprintScale = 3;
  _defaultSpeed;
  _sprintSpeed;
  _velocity = new pc.Vec3();
  _shouldBlockInput = !1;
  _sharedRaycastStartPoint = new pc.Vec3();
  _sharedRaycastEndPoint = new pc.Vec3();
  _tempRight = new pc.Vec3().copy(pc.Vec3.RIGHT);
  _tempUp = new pc.Vec3().copy(pc.Vec3.UP);
  _tempForward = new pc.Vec3().copy(pc.Vec3.FORWARD);
  _blockedInputStates = {
    forward: !1,
    back: !1,
    left: !1,
    right: !1,
    up: !1,
    down: !1,
    jump: !1,
    sprint: !1,
    joystick: new pc.Vec2(0, 0)
  };
  constructor(t, e) {
    this.name = t, this._module = e, this._store = e.system.store, this._axesMat3.set([1, 0, 0, 0, 1, 0, 0, 0, -1]), this._defaultSpeed = this._baseSpeed, this._sprintSpeed = this._baseSpeed * this._sprintScale;
  }
  get _validInputStates() {
    return this._module.canMove && !this._shouldBlockInput ? this._store.getState().inputStates : this._blockedInputStates;
  }
  onEnter() {
    this._store.getState().setLocomotionState(this.name), this._hasEntered = !0;
  }
  onExit() {
    this._hasEntered = !1;
  }
  update(t) {
    this._hasEntered && (this._updateMoveIntent(), this._updateStateTransitions(), this._updateStateSpecificLogic(t), this._updateDirection(), this._applySpeedMultiplier(), this._updateVelocity(this._shouldIgnoreGravity()), this._syncStore());
  }
  _updateMoveIntent() {
    this._mapDirectionalInputsToMoveIntent(), this._mapOverriddenDirectionToMoveIntent();
  }
  _mapDirectionalInputsToMoveIntent() {
    const t = this._validInputStates;
    this._moveIntent.set(0, 0, 0), t.left && (this._moveIntent.x -= 1), t.right && (this._moveIntent.x += 1), t.forward && (this._moveIntent.z += 1), t.back && (this._moveIntent.z -= 1), t.up && (this._moveIntent.y += 1), t.down && (this._moveIntent.y -= 1), t.joystick.length() > 0 && (this._moveIntent.x = t.joystick.x, this._moveIntent.z = t.joystick.y), this._moveIntent.normalize();
  }
  _mapOverriddenDirectionToMoveIntent() {
    if (!this._module.overriddenDirection) return;
    this._moveIntent.copy(this._module.overriddenDirection).normalize();
    const t = this._store.getState().yaw * -1 * pc.math.DEG_TO_RAD, e = this._moveIntent.x, i = this._moveIntent.z * -1;
    this._moveIntent.set(
      e * Math.cos(t) - i * Math.sin(t),
      this._moveIntent.y,
      e * Math.sin(t) + i * Math.cos(t)
    );
  }
  _syncStore() {
    this._moveIntent.lengthSq() > 0 && this._moveIntent.normalize(), this._store.getState().setMoveIntent(this._moveIntent);
  }
  _getHorizontalizedMat3Data() {
    return this._tempUp.copy(pc.Vec3.UP), this._tempForward.copy(
      this._module.overriddenForward ?? this._store.getState().viewAxes.getZ()
    ), this._tempForward.y = 0, this._tempForward.lengthSq() === 0 && this._tempForward.copy(pc.Vec3.FORWARD), this._tempForward.normalize(), this._tempRight.cross(this._tempForward, this._tempUp).normalize(), this._tempUp.cross(this._tempRight, this._tempForward).normalize(), [
      this._tempRight.x,
      this._tempRight.y,
      this._tempRight.z,
      this._tempUp.x,
      this._tempUp.y,
      this._tempUp.z,
      this._tempForward.x,
      this._tempForward.y,
      this._tempForward.z
    ];
  }
  _setAxes() {
    this._axesMat3.set(this._getHorizontalizedMat3Data());
  }
  _updateDirection() {
    this._setAxes(), this._applyMoveIntentToDirection();
  }
  _updateVelocity(t = !1) {
    const e = this._store.getState().playerEntity;
    if (!e || !e.rigidbody) {
      E.warn("Player entity or Rigidbody is not set.");
      return;
    }
    const i = this._validInputStates.sprint, s = this._store.getState().canSprint && i ? this._sprintSpeed : this._defaultSpeed, r = t ? this._direction.y * s : e.rigidbody.linearVelocity.y;
    this._velocity.set(this._direction.x * s, r, this._direction.z * s), e.rigidbody.linearVelocity = this._velocity;
  }
  /**
   * Performs a raycast from the player position downward to check for ground.
   * Useful for both Grounded and Falling states avoiding duplicated raycast code.
   * @param offset The positional offset from the player origin.
   * @param yLift Extra height added to the start point to avoid penetrating the floor.
   * @param distance The downward raycast distance length.
   * @returns boolean true if hit a valid non-actor ground.
   */
  _raycastGround(t, e, i) {
    const n = this._store.getState().playerEntity;
    if (!n) return !1;
    this._sharedRaycastStartPoint.copy(n.getPosition()).add(t), this._sharedRaycastStartPoint.y += e, this._sharedRaycastEndPoint.copy(this._sharedRaycastStartPoint), this._sharedRaycastEndPoint.y -= i;
    const s = this._module.system.pcApp.systems?.rigidbody?.raycastFirst(
      this._sharedRaycastStartPoint,
      this._sharedRaycastEndPoint,
      {
        filterCollisionMask: pc.BODYGROUP_STATIC | pc.BODYGROUP_KINEMATIC
      }
    );
    return s != null && s.entity.name !== "ACTOR_RIGIDBODY";
  }
}
class vs extends ot {
  _raycastDistance = 0.5;
  _raycastOffsets = [
    new pc.Vec3(0, 0, 0),
    new pc.Vec3(0.3, 0, 0),
    new pc.Vec3(-0.3, 0, 0),
    new pc.Vec3(0, 0, 0.3),
    new pc.Vec3(0, 0, -0.3)
  ];
  constructor(t) {
    super(x.Grounded, t);
  }
  _updateStateTransitions() {
    this._tryFallingTransition(), this._tryFlyingTransition(), this._tryJumpingTransition();
  }
  _updateStateSpecificLogic(t) {
  }
  _applyMoveIntentToDirection() {
    this._axesMat3.transformVector(this._moveIntent, this._direction), this._direction.y = 0;
  }
  _applySpeedMultiplier() {
    this._defaultSpeed = this._baseSpeed * this._module.walkSpeedMultiplier, this._sprintSpeed = this._baseSpeed * this._sprintScale * this._module.runSpeedMultiplier;
  }
  _shouldIgnoreGravity() {
    return !1;
  }
  _checkGrounded() {
    return this._module.isCollidingWithGround ? !0 : this._store.getState().playerEntity ? this._raycastOffsets.some(
      (e) => this._raycastGround(e, 0.01, this._raycastDistance)
    ) : !1;
  }
  _tryFallingTransition() {
    this._checkGrounded() || this._module.setStateByName(x.Falling);
  }
  _tryFlyingTransition() {
    this._module.canFly && this._validInputStates.up && this._module.setStateByName(x.Flying);
  }
  _tryJumpingTransition() {
    this._module.canJump && this._validInputStates.jump && this._module.setStateByName(x.Jumping);
  }
}
class Ss extends ot {
  _jumpToFlyDuration = 0.2;
  _jumpStartTime = 0;
  constructor(t) {
    super(x.Jumping, t);
  }
  /** @hidden */
  onEnter() {
    super.onEnter(), this._jumpStartTime = Date.now() / 1e3;
    const t = this._store.getState().playerEntity, e = t?.rigidbody;
    t && e && e.applyImpulse(0, e.mass * 5 * this._module.jumpImpulseMultiplier, 0);
  }
  _updateStateTransitions() {
    this._tryFlyingTransition(), this._tryFallingTransition();
  }
  _updateStateSpecificLogic(t) {
  }
  _applyMoveIntentToDirection() {
    if (!this._module.canMoveDuringJumpFall) {
      this._direction.set(0, 0, 0);
      return;
    }
    this._axesMat3.transformVector(this._moveIntent, this._direction), this._direction.y = 0;
  }
  _applySpeedMultiplier() {
    this._defaultSpeed = this._baseSpeed * this._module.walkSpeedMultiplier, this._sprintSpeed = this._baseSpeed * this._sprintScale * this._module.runSpeedMultiplier;
  }
  _shouldIgnoreGravity() {
    return !1;
  }
  _tryFallingTransition() {
    const e = this._store.getState().playerEntity?.rigidbody;
    e && e.linearVelocity.y <= 0 && this._module.setStateByName(x.Falling);
  }
  _tryFlyingTransition() {
    this._module.canFly && this._validInputStates.jump && Date.now() / 1e3 - this._jumpStartTime > this._jumpToFlyDuration && this._module.setStateByName(x.Flying);
  }
}
class Es extends ot {
  _fallDuration = 0;
  _fallToDeathDuration = 3;
  _previousState = null;
  constructor(t) {
    super(x.Falling, t);
  }
  /** @hidden */
  onEnter() {
    super.onEnter(), this._previousState = this._store.getState().locomotionState, this._fallDuration = 0;
    const t = this._store.getState().playerEntity;
    if (t && t.rigidbody) {
      const i = this._module.gravity.clone().mulScalar(t.rigidbody.mass * 0.35 * this._module.fallImpulseMultiplier);
      t.rigidbody.applyImpulse(i);
    }
  }
  _updateStateTransitions() {
    this._tryFlyingTransition(), this._tryGroundedTransition(), this._tryDeathTransition();
  }
  _updateStateSpecificLogic(t) {
    this._updateFallDuration(t);
    const e = this._store.getState().playerEntity;
    e && e.rigidbody && e.collision && (e.rigidbody.body.setCcdMotionThreshold(1e-4), e.rigidbody.body.setCcdSweptSphereRadius(e.collision.height / 2));
  }
  _applyMoveIntentToDirection() {
    if (!this._module.canMoveDuringJumpFall) {
      this._direction.set(0, 0, 0);
      return;
    }
    this._axesMat3.transformVector(this._moveIntent, this._direction), this._direction.y = 0;
  }
  _applySpeedMultiplier() {
    this._previousState === x.Flying ? (this._defaultSpeed = this._baseSpeed * this._module.flySpeedMultiplier, this._sprintSpeed = this._baseSpeed * this._sprintScale * this._module.flySprintSpeedMultiplier) : (this._defaultSpeed = this._baseSpeed * this._module.walkSpeedMultiplier, this._sprintSpeed = this._baseSpeed * this._sprintScale * this._module.runSpeedMultiplier);
  }
  _shouldIgnoreGravity() {
    return !1;
  }
  _updateFallDuration(t) {
    this._fallDuration += t;
  }
  _checkGroundExistence() {
    return this._raycastGround(pc.Vec3.ZERO, 0, 1e3);
  }
  _checkGroundedByShortRaycast() {
    return this._raycastGround(pc.Vec3.ZERO, 0.01, 0.01);
  }
  _checkGrounded() {
    return this._module.isCollidingWithGround || this._checkGroundedByShortRaycast();
  }
  _tryFlyingTransition() {
    this._module.canFly && this._moveIntent.y > 0 && this._module.setStateByName(x.Flying);
  }
  _tryDeathTransition() {
    this._fallDuration > this._fallToDeathDuration && !this._checkGroundExistence() && this._module.setStateByName(x.Dead);
  }
  _tryGroundedTransition() {
    this._checkGrounded() && this._module.setStateByName(x.Grounded);
  }
}
class As extends ot {
  _prevJumpInput = !1;
  _jumpInputDuration = 0;
  _fallTimeout = null;
  _previousFacingMode = K.Movement;
  _unsubscribeStore = null;
  constructor(t) {
    super(x.Flying, t);
  }
  /** @hidden */
  onEnter() {
    super.onEnter(), this._prevJumpInput = this._validInputStates.jump, this._prevJumpInput && (this._jumpInputDuration = this._module.jumpReleaseTimeoutMs / 1e3), this._previousFacingMode = this._store.getState().avatarFacingMode, this._store.getState().setAvatarFacingMode(K.View), this._unsubscribeStore = this._store.subscribe(
      (t) => t.canFly,
      (t) => {
        t || this._module.setStateByName(x.Falling);
      }
    );
  }
  /** @hidden */
  onExit() {
    super.onExit(), this._fallTimeout && (clearTimeout(this._fallTimeout), this._fallTimeout = null), this._store.getState().setAvatarFacingMode(this._previousFacingMode), this._unsubscribeStore && (this._unsubscribeStore(), this._unsubscribeStore = null);
  }
  _updateStateTransitions() {
    this._tryFallingTransition();
  }
  _updateMoveIntent() {
    super._updateMoveIntent(), this._mapJumpInputToMoveIntent();
  }
  _updateStateSpecificLogic(t) {
    this._updateAntiGravityForce(), this._updateJumpInputDuration(t);
  }
  _applyMoveIntentToDirection() {
    this._axesMat3.transformVector(this._moveIntent, this._direction);
  }
  _applySpeedMultiplier() {
    this._defaultSpeed = this._baseSpeed * this._module.flySpeedMultiplier, this._sprintSpeed = this._baseSpeed * this._sprintScale * this._module.flySprintSpeedMultiplier;
  }
  _shouldIgnoreGravity() {
    return !0;
  }
  _updateAntiGravityForce() {
    const t = this._store.getState().playerEntity;
    if (!t) return;
    const e = t.rigidbody;
    if (!e) return;
    const n = this._module.gravity.clone().mulScalar(-e.mass);
    e.applyForce(n);
  }
  _updateJumpInputDuration(t) {
    this._prevJumpInput ? this._jumpInputDuration += t : this._jumpInputDuration = 0, this._prevJumpInput = this._validInputStates.jump;
  }
  _mapJumpInputToMoveIntent() {
    const e = this._validInputStates.jump && this._prevJumpInput, i = this._jumpInputDuration >= this._module.jumpReleaseTimeoutMs / 1e3;
    e && i && (this._moveIntent.y += 1);
  }
  _tryFallingTransition() {
    this._validInputStates.jump && !this._prevJumpInput && (this._fallTimeout && clearTimeout(this._fallTimeout), this._fallTimeout = setTimeout(() => {
      this._validInputStates.jump || this._module.setStateByName(x.Falling);
    }, this._module.jumpReleaseTimeoutMs));
  }
}
class Ts extends ot {
  _deathDuration = 0;
  _respawnDuration = 0.5;
  _respawnPosition;
  constructor(t) {
    super(x.Dead, t), this._respawnPosition = this._module.system.getSpawnPoint();
  }
  /** @hidden */
  onEnter() {
    super.onEnter(), this._deathDuration = 0, this._stopMovement();
  }
  _updateStateTransitions() {
    this._tryRespawn();
  }
  _updateStateSpecificLogic(t) {
    this._updateDeathDuration(t);
  }
  _applyMoveIntentToDirection() {
    this._direction.set(0, 0, 0);
  }
  _applySpeedMultiplier() {
  }
  _shouldIgnoreGravity() {
    return !1;
  }
  _stopMovement() {
    const t = this._store.getState().playerEntity;
    t?.rigidbody && (t.rigidbody.linearVelocity = new pc.Vec3(0, 0, 0), t.rigidbody.angularVelocity = new pc.Vec3(0, 0, 0)), this._shouldBlockInput = !0;
  }
  _updateDeathDuration(t) {
    this._deathDuration += t;
  }
  _respawnPlayer() {
    const t = this._store.getState().playerEntity;
    if (!t) {
      E.warn("Cannot respawn: Player entity not found");
      return;
    }
    this._respawnPosition = this._module.system.getSpawnPoint(), t.rigidbody ? (t.rigidbody.teleport(
      this._respawnPosition.x,
      this._respawnPosition.y + 1,
      this._respawnPosition.z
    ), t.rigidbody.linearVelocity = new pc.Vec3(0, 0, 0), t.rigidbody.angularVelocity = new pc.Vec3(0, 0, 0)) : t.setPosition(this._respawnPosition);
  }
  _tryRespawn() {
    this._deathDuration > this._respawnDuration && (this._respawnPlayer(), this._module.setStateByName(x.Falling));
  }
}
class ws extends ot {
  constructor(t) {
    super(x.Sitting, t);
  }
  _updateStateTransitions() {
  }
  _updateStateSpecificLogic() {
  }
  _applyMoveIntentToDirection() {
    this._direction.set(0, 0, 0);
  }
  _applySpeedMultiplier() {
  }
  _shouldIgnoreGravity() {
    return !1;
  }
}
class xs extends pt {
  static moduleName = q.Locomotion;
  gravity = new pc.Vec3(0, -9.8, 0);
  jumpReleaseTimeoutMs = 150;
  canMoveDuringJumpFall = !0;
  canMove = !0;
  jumpImpulseMultiplier = 1;
  fallImpulseMultiplier = 1;
  flySpeedMultiplier = 1;
  flySprintSpeedMultiplier = 1;
  _currentState;
  _states;
  _isSpawnFlying = !1;
  _groundedBodies = /* @__PURE__ */ new Set();
  _overriddenDirection = null;
  _overriddenForward = null;
  _sprintBlocked = /* @__PURE__ */ new Set();
  constructor(t, e) {
    super(t);
    const i = this.system.pcApp?.systems?.rigidbody?.gravity;
    i && (this.gravity = i), this.viverseApp.once("player:ready", this._onPlayerReady, this);
    const n = {
      ...this._getDefaultOptions(),
      ...e
    };
    this.canFly = n.canFly, this.isSpawnFlying = n.isSpawnFlying, this.canJump = n.canJump, this.canMove = n.canMove, this.canRun = n.canRun, this.canFlySprint = n.canFlySprint, this.canMoveDuringJumpFall = n.canMoveDuringJumpFall, this._states = {
      [x.Grounded]: new vs(this),
      [x.Jumping]: new Ss(this),
      [x.Falling]: new Es(this),
      [x.Flying]: new As(this),
      [x.Dead]: new Ts(this),
      [x.Sitting]: new ws(this)
    }, this._currentState = this.isSpawnFlying ? this._states[x.Flying] : this._states[x.Grounded], this._updateCanSprint();
  }
  get currentState() {
    return this._currentState;
  }
  get isGrounded() {
    return this._groundedBodies.size > 0 || this._currentState.name === x.Grounded;
  }
  get isCollidingWithGround() {
    return this._groundedBodies.size > 0;
  }
  get canFly() {
    return this.system.store.getState().canFly;
  }
  set canFly(t) {
    this.system.store.getState().setCanFly(t);
  }
  get canJump() {
    return this.system.store.getState().canJump;
  }
  set canJump(t) {
    this.system.store.getState().setCanJump(t);
  }
  get canRun() {
    return !this._sprintBlocked.has(x.Grounded);
  }
  set canRun(t) {
    this._updateSprintBlock(x.Grounded, !t);
  }
  get canFlySprint() {
    return !this._sprintBlocked.has(x.Flying);
  }
  set canFlySprint(t) {
    this._updateSprintBlock(x.Flying, !t);
  }
  set isSpawnFlying(t) {
    t && !this.canFly && (E.warn("Cannot spawn flying if canFly is false."), this._isSpawnFlying = !1), this._isSpawnFlying = t;
  }
  get isSpawnFlying() {
    return this._isSpawnFlying;
  }
  get overriddenDirection() {
    return this._overriddenDirection;
  }
  get overriddenForward() {
    return this._overriddenForward;
  }
  get walkSpeedMultiplier() {
    return this.system.store.getState().walkSpeedMultiplier;
  }
  set walkSpeedMultiplier(t) {
    this.system.store.getState().setWalkSpeedMultiplier(t);
  }
  get runSpeedMultiplier() {
    return this.system.store.getState().runSpeedMultiplier;
  }
  set runSpeedMultiplier(t) {
    this.system.store.getState().setRunSpeedMultiplier(t);
  }
  overrideDirection(t, e, i) {
    if (this._overriddenForward && E.warn("Override direction when forward is overridden may cause unexpected behavior."), typeof t == "number") {
      if (typeof e != "number" || typeof i != "number") {
        E.warn("Override direction requires x, y, and z values.");
        return;
      }
      this._overriddenDirection = new pc.Vec3(t, e, i);
    } else
      this._overriddenDirection = t.clone();
    this._overriddenDirection?.normalize();
  }
  overrideForward(t, e, i) {
    this._overriddenDirection && E.warn("Override forward when direction is overridden may cause unexpected behavior.");
    let n;
    if (typeof t == "number") {
      if (typeof e != "number" || typeof i != "number") {
        E.warn("Override forward requires x, y, and z values.");
        return;
      }
      n = new pc.Vec3(t, e, i);
    } else
      n = t.clone();
    if (n.equals(pc.Vec3.ZERO) || n.equals(pc.Vec3.UP) || n.equals(pc.Vec3.DOWN)) {
      E.warn("Override forward vector cannot be zero, up, or down.");
      return;
    }
    this._overriddenForward = n.normalize(), this.system.store.getState().setOverriddenForward(this._overriddenForward);
  }
  clearOverriddenDirection() {
    this._overriddenDirection = null;
  }
  clearOverriddenForward() {
    this._overriddenForward = null, this.system.store.getState().setOverriddenForward(null);
  }
  setStateByName(t) {
    const e = this._states[t];
    e ? (this._currentState.onExit(), this._currentState = e, this._currentState.onEnter(), this._updateCanSprint()) : E.warn(`Locomotion state ${t} not found.`);
  }
  jump() {
    this._currentState.name === x.Grounded && (this.canJump ? this.setStateByName(x.Jumping) : E.warn("Cannot jump because canJump is false."));
  }
  update(t) {
    this._currentState.update(t);
  }
  _getDefaultOptions() {
    return Ms;
  }
  _onPlayerReady() {
    const t = this.system.store.getState().playerEntity.rigidbody;
    t && (t.on("collisionstart", this._onCollisionStart, this), t.on("collisionend", this._onCollisionEnd, this)), this._currentState.onEnter();
  }
  _onCollisionStart(t) {
    const { other: e, contacts: i } = t;
    if (e.name === "ACTOR_RIGIDBODY") return;
    i.some((s) => {
      const r = s.normal.dot(pc.Vec3.UP), o = Math.acos(pc.math.clamp(r, -1, 1)) * pc.math.RAD_TO_DEG;
      return o < 70 || o > 110;
    }) && this._groundedBodies.add(e);
  }
  _onCollisionEnd(t) {
    this._groundedBodies.delete(t);
  }
  _updateSprintBlock(t, e) {
    e ? this._sprintBlocked.add(t) : this._sprintBlocked.delete(t), this._updateCanSprint();
  }
  _updateCanSprint() {
    if (!this._currentState) return;
    const t = !this._sprintBlocked.has(this._currentState.name), { setCanSprint: e, canSprint: i } = this.system.store.getState();
    i !== t && e(t);
  }
}
const bs = {
  spawnPoints: [new pc.Vec3(0, 0, 0)],
  useNameTag: !0,
  modules: [
    {
      name: q.LocalAvatar,
      Module: ss
    },
    {
      name: q.Camera,
      Module: ys
    },
    {
      name: q.Locomotion,
      Module: xs
    }
  ]
}, Ms = {
  canFly: !1,
  isSpawnFlying: !1,
  canJump: !0,
  canMove: !0,
  canRun: !0,
  canFlySprint: !0,
  canMoveDuringJumpFall: !0
}, Is = {
  avatars: []
}, Ps = {
  locomotionType: {
    left: tt.Teleport,
    right: tt.Teleport
  }
}, Cs = {
  forward: [pc.KEY_W],
  back: [pc.KEY_S],
  left: [pc.KEY_A],
  right: [pc.KEY_D],
  up: [pc.KEY_E],
  down: [pc.KEY_Q]
};
class Ls {
  _keyboard;
  _context;
  _moveXzKeys = Cs;
  _jumpKey = pc.KEY_SPACE;
  _sprintKey = pc.KEY_SHIFT;
  _switchCameraKey = pc.KEY_V;
  _interactionActionKeyA = pc.KEY_F;
  _interactionActionKeyB = pc.KEY_G;
  _interactionPickKey = pc.KEY_R;
  _doubleTapInterval = 500;
  _doubleTapTimes = /* @__PURE__ */ new Map();
  _sprintStates = /* @__PURE__ */ new Map();
  _lastCleanupTime = 0;
  constructor(t, e) {
    this._keyboard = t, this._context = e, this._keyboard.on(pc.EVENT_KEYDOWN, this._onKeyDown, this);
  }
  update() {
    this._updateInputStates(), this._cleanupDoubleTapTimes(), this._cleanupSprintStates();
  }
  destroy() {
    this._keyboard.off(pc.EVENT_KEYDOWN, this._onKeyDown, this), this._doubleTapTimes.clear(), this._sprintStates.clear();
  }
  _updateInputStates() {
    const t = (e) => this._keyboard.isPressed(e);
    this._context.setInputStates(this, {
      forward: this._moveXzKeys.forward.some(t),
      back: this._moveXzKeys.back.some(t),
      left: this._moveXzKeys.left.some(t),
      right: this._moveXzKeys.right.some(t),
      up: this._moveXzKeys.up.some(t),
      down: this._moveXzKeys.down.some(t),
      jump: this._keyboard.isPressed(this._jumpKey),
      sprint: this._checkShouldSprint()
    });
  }
  _onKeyDown(t) {
    t.key === this._switchCameraKey && this._onSwitchCameraKeyDown(), t.key === this._interactionPickKey && this._onPickKeyDown(), t.key === this._interactionActionKeyA && this._onActionAKeyDown(), t.key === this._interactionActionKeyB && this._onActionBKeyDown();
  }
  _checkShouldSprint() {
    return this._keyboard.isPressed(this._sprintKey) ? !0 : Object.values(this._moveXzKeys).flat().some((t) => (this._checkDoubleTapToSprint(t), this._sprintStates.get(t) && this._keyboard.isPressed(t)));
  }
  _checkDoubleTapToSprint(t) {
    const e = this._keyboard.isPressed(t);
    if (this._keyboard.wasPressed(t) && e) {
      const n = Date.now(), s = this._doubleTapTimes.get(t);
      s && n - s < this._doubleTapInterval ? (this._sprintStates.set(t, !0), this._doubleTapTimes.delete(t)) : (this._doubleTapTimes.set(t, n), this._sprintStates.set(t, !1));
    }
    e || this._sprintStates.set(t, !1);
  }
  _onSwitchCameraKeyDown() {
    this._context.emit("input:switch-camera");
  }
  _onPickKeyDown() {
    this._context.emit("input:pick-nearest-item");
  }
  _onActionAKeyDown() {
    this._context.emit("input:action-a");
  }
  _onActionBKeyDown() {
    this._context.emit("input:action-b");
  }
  /**
   * Cleanup old double-tap times that have exceeded the interval
   */
  _cleanupDoubleTapTimes() {
    const t = Date.now();
    for (const [e, i] of this._doubleTapTimes.entries())
      t - i > this._doubleTapInterval && this._doubleTapTimes.delete(e);
  }
  /**
   * Remove sprint states for keys that are no longer tracked movement keys
   * Only runs occasionally (every 5 seconds) to avoid performance impact
   */
  _cleanupSprintStates() {
    const t = Date.now();
    if (t - this._lastCleanupTime < 5e3) return;
    this._lastCleanupTime = t;
    const e = Object.values(this._moveXzKeys).flat();
    for (const i of this._sprintStates.keys())
      e.includes(i) || this._sprintStates.delete(i);
  }
}
class Be {
  _context;
  _rootEntity;
  _textureAssets;
  _orientation;
  _offset = {
    landscape: new pc.Vec2(),
    portrait: new pc.Vec2()
  };
  constructor(t, e) {
    this._context = t, this._textureAssets = e, this._orientation = t.system.viverseApp.deviceInfo.screenOrientation, this._context.system.viverseApp.on(
      "device-info:orientation-changed",
      this._onOrientationChange,
      this
    );
  }
  get enabled() {
    return this._rootEntity.enabled;
  }
  set enabled(t) {
    this._rootEntity.enabled = t;
  }
  _loadTextureAssets(t, e, i) {
    return Promise.all(
      e.map((n) => this._loadTextureAsset(t, n, `${n}.png`, i))
    );
  }
  _onOrientationChange(t) {
    this._orientation = t, this._rootEntity.setLocalPosition(this._offset[t].x, this._offset[t].y, 0);
  }
  async _loadTextureAsset(t, e, i, n) {
    if (n.has(e)) {
      const r = n.get(e);
      if (r.resource)
        return r;
    }
    const s = await H(t, i, "/touch-input/", "local-player", "texture");
    return n.set(e, s), s;
  }
}
class Gt extends Be {
  _statesNames = ["default", "move", "sprint"];
  _currentState = "default";
  _uiEntities = {
    default: null,
    move: null,
    sprint: null
  };
  _radius = 84;
  _sprintThreshold = 0.7;
  _touchStartCoords = new pc.Vec2(0, 0);
  _joystickDirection = new pc.Vec2(0, 0);
  static async create(t, e, i) {
    const n = /* @__PURE__ */ new Map(), s = new Gt(i, n), r = s._getTextureNames();
    try {
      await s._loadTextureAssets(t, r, n);
    } catch (l) {
      throw console.error("JoystickTouchUi: Error loading texture assets", l), l;
    }
    const o = i.system.viverseApp.deviceInfo.screenOrientation;
    return s._setupOffset(), s._rootEntity = s._createRootEntity(e, o), s._createUiEntities(), s._bindElementEvents(), s;
  }
  update(t) {
    !this._uiEntities.default || !this._uiEntities.move || !this._uiEntities.sprint || (this._updateUiEntities(), this._updateInputStates());
  }
  destroy() {
    this._rootEntity.element?.off(pc.EVENT_TOUCHSTART, this._onTouchStart), this._rootEntity.element?.off(pc.EVENT_TOUCHEND, this._onTouchEnd), this._rootEntity.element?.off(pc.EVENT_TOUCHMOVE, this._onTouchMove), this._context.system.viverseApp.off(
      "device-info:orientation-changed",
      this._onOrientationChange
    ), this._rootEntity.destroy();
  }
  _getTextureNames() {
    return this._statesNames.map((t) => `joystick-${t}`);
  }
  _setupOffset() {
    this._offset.landscape.set(36 + this._radius, 8 + this._radius), this._offset.portrait.set(8 + this._radius, 24 + this._radius);
  }
  _createRootEntity(t, e) {
    const i = new pc.Entity("JoystickRoot");
    return i.addComponent("element", {
      anchor: [0, 0, 0, 0],
      pivot: [0.5, 0.5],
      width: this._radius * 2,
      height: this._radius * 2,
      type: pc.ELEMENTTYPE_GROUP,
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), i.setLocalPosition(this._offset[e].x, this._offset[e].y, 0), t.addChild(i), i;
  }
  _createUiEntities() {
    this._statesNames.forEach((t) => {
      this._uiEntities[t] = this._createUiEntity(
        `Joystick_${t}`,
        this._textureAssets.get(`joystick-${t}`)
      );
    });
  }
  _createUiEntity(t, e) {
    const i = new pc.Entity(t);
    return i.addComponent("element", {
      anchor: [0, 0, 1, 1],
      pivot: [0.5, 0.5],
      type: pc.ELEMENTTYPE_IMAGE,
      opacity: 1,
      color: new pc.Color(1, 1, 1, 1),
      textureAsset: e,
      useInput: !1,
      layers: [pc.LAYERID_UI]
    }), this._rootEntity.addChild(i), i;
  }
  _setCurrentState(t) {
    this._currentState = t;
  }
  _updateUiEntities() {
    this._uiEntities.default.enabled = this._currentState === "default", this._uiEntities.move.enabled = this._currentState === "move", this._uiEntities.sprint.enabled = this._currentState === "sprint";
  }
  _bindElementEvents() {
    this._rootEntity.element?.on(pc.EVENT_TOUCHSTART, this._onTouchStart, this), this._rootEntity.element?.on(pc.EVENT_TOUCHEND, this._onTouchEnd, this);
  }
  _onTouchStart(t) {
    const e = t.touch;
    this._context.addTouchIds(e.identifier), this._touchStartCoords = new pc.Vec2(t.x, t.y), this._rootEntity.element?.on(pc.EVENT_TOUCHMOVE, this._onTouchMove, this);
  }
  _onTouchEnd(t) {
    this._rootEntity.element?.off(pc.EVENT_TOUCHMOVE, this._onTouchMove), this._uiEntities.move.setLocalEulerAngles(0, 0, 0), this._uiEntities.sprint.setLocalEulerAngles(0, 0, 0), this._joystickDirection.set(0, 0), this._setCurrentState("default");
    const e = t.touch;
    this._context.removeTouchIds(e.identifier);
  }
  _onTouchMove(t) {
    this._joystickDirection.set(
      t.x - this._touchStartCoords.x,
      (t.y - this._touchStartCoords.y) * -1
    );
    const e = this._joystickDirection.angle() * -1;
    this._uiEntities.move.setLocalEulerAngles(0, 0, e), this._uiEntities.sprint.setLocalEulerAngles(0, 0, e), this._joystickDirection.length() < this._radius * this._sprintThreshold ? this._setCurrentState("move") : this._setCurrentState("sprint");
  }
  _updateInputStates() {
    this._context.setInputStates(this, {
      joystick: this._joystickDirection.normalize(),
      sprint: this._currentState === "sprint"
    });
  }
}
class Wt extends Be {
  _width = 112;
  _height = 128;
  _jumpButton = null;
  _jumpButtonIcon = null;
  _greetButton = null;
  _arrowUpButton = null;
  _arrowDownButton = null;
  _pickButton = null;
  _actionAButton = null;
  _actionBButton = null;
  _canFly = !1;
  _canJump = !1;
  _isHolding = !1;
  _unsubscribeStore = null;
  _inputStates = {
    jump: !1,
    greet: !1,
    up: !1,
    down: !1
  };
  static async create(t, e, i) {
    const n = /* @__PURE__ */ new Map(), s = new Wt(i, n), r = s._getTextureNames();
    try {
      await s._loadTextureAssets(t, r, n);
    } catch (l) {
      throw console.error("ButtonsTouchUi: Error loading texture assets", l), l;
    }
    const o = i.system.viverseApp.deviceInfo.screenOrientation;
    return s._setupOffset(), s._canFly = i.getState().canFly, s._canJump = i.getState().canJump, s._rootEntity = s._createRootEntity(e, o), s._createUiEntities(), s._bindElementEvents(), s;
  }
  get _jumpButtonEnabled() {
    return this._canJump || this._canFly;
  }
  update(t) {
    this._updateInputStates();
  }
  destroy() {
    this._unbindElementEvents(), this._context.system.viverseApp.off(
      "device-info:orientation-changed",
      this._onOrientationChange
    ), this._rootEntity.destroy();
  }
  _getTextureNames() {
    return [
      "button-base",
      "button-jump",
      "button-greet",
      "button-arrow",
      "button-pick",
      "button-actionA",
      "button-actionB"
    ];
  }
  _setupOffset() {
    this._offset.landscape.set(-this._width / 2 - 48, this._height / 2 + 28), this._offset.portrait.set(-this._width / 2 - 16, this._height / 2 + 64);
  }
  _createRootEntity(t, e) {
    const i = new pc.Entity("ActionButtonsRoot");
    return i.addComponent("element", {
      anchor: [1, 0, 1, 0],
      pivot: [0.5, 0.5],
      width: this._width,
      height: this._height,
      type: pc.ELEMENTTYPE_GROUP,
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), i.setLocalPosition(this._offset[e].x, this._offset[e].y, 0), t.addChild(i), i;
  }
  _createUiEntities() {
    this._jumpButton = this._createJumpButton(), this._pickButton = this._createPickButton(), this._actionAButton = this._createActionAButton(), this._actionBButton = this._createActionBButton(), this._updateButtonVisibility();
  }
  _createIcon(t, e) {
    const i = new pc.Entity(`ButtonIcon_${t}`);
    return i.addComponent("element", {
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      type: pc.ELEMENTTYPE_IMAGE,
      width: e,
      height: e,
      opacity: 1,
      textureAsset: this._textureAssets.get(`button-${t}`),
      useInput: !1,
      layers: [pc.LAYERID_UI]
    }), i;
  }
  _createJumpButton() {
    const t = new pc.Entity("ButtonJump");
    return t.addComponent("element", {
      anchor: [0, 0.5, 0, 0.5],
      pivot: [0, 0.5],
      type: pc.ELEMENTTYPE_IMAGE,
      width: 58,
      height: 58,
      opacity: 1,
      textureAsset: this._textureAssets.get("button-base"),
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), this._jumpButtonIcon = this._createIcon("jump", 33), t.addChild(this._jumpButtonIcon), this._rootEntity.addChild(t), t.enabled = this._jumpButtonEnabled, t;
  }
  // private _createGreetButton(): pc.Entity {
  //   const greetButton = new pc.Entity('ButtonGreet');
  //   greetButton.addComponent('element', {
  //     anchor: [1, 0.5, 1, 0.5],
  //     pivot: [1, 0.5],
  //     type: pc.ELEMENTTYPE_IMAGE,
  //     width: 36,
  //     height: 36,
  //     opacity: 1,
  //     textureAsset: this._textureAssets.get('button-base')!,
  //     useInput: true,
  //     layers: [pc.LAYERID_UI],
  //   });
  //   greetButton.addChild(this._createIcon('greet', 24));
  //   this._rootEntity.addChild(greetButton);
  //   return greetButton;
  // }
  // private _createArrowButton(isUp: boolean): pc.Entity {
  //   const name = isUp ? 'ButtonArrowUp' : 'ButtonArrowDown';
  //   const verticalAnchorPivot = isUp ? 1 : 0;
  //   const arrowButton = new pc.Entity(name);
  //   arrowButton.addComponent('element', {
  //     anchor: [0.5, verticalAnchorPivot, 0.5, verticalAnchorPivot],
  //     pivot: [0.5, verticalAnchorPivot],
  //     type: pc.ELEMENTTYPE_IMAGE,
  //     width: 28,
  //     height: 28,
  //     opacity: 1,
  //     textureAsset: this._textureAssets.get('button-base')!,
  //     useInput: true,
  //   });
  //   const icon = this._createIcon('arrow', 16);
  //   if (!isUp) icon.setLocalEulerAngles(0, 0, 180);
  //   arrowButton.addChild(icon);
  //   arrowButton.setLocalPosition(11, 0, 0);
  //   this._rootEntity.addChild(arrowButton);
  //   arrowButton.enabled = this._canFly;
  //   return arrowButton;
  // }
  _createPickButton() {
    const t = new pc.Entity("ButtonPick");
    return t.addComponent("element", {
      anchor: [0, 0, 0, 0],
      pivot: [1, 0],
      type: pc.ELEMENTTYPE_IMAGE,
      width: 36,
      height: 36,
      opacity: 1,
      textureAsset: this._textureAssets.get("button-base"),
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), t.addChild(this._createIcon("pick", 24)), t.setLocalPosition(0, -11, 0), this._rootEntity.addChild(t), t;
  }
  _createActionBButton() {
    const t = new pc.Entity("ButtonActionB");
    return t.addComponent("element", {
      anchor: [0.5, 0, 0.5, 0],
      pivot: [0, 0],
      type: pc.ELEMENTTYPE_IMAGE,
      width: 36,
      height: 36,
      opacity: 1,
      textureAsset: this._textureAssets.get("button-base"),
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), t.addChild(this._createIcon("actionB", 24)), this._rootEntity.addChild(t), t;
  }
  _createActionAButton() {
    const t = new pc.Entity("ButtonActionA");
    return t.addComponent("element", {
      anchor: [0, 0.5, 0, 0.5],
      pivot: [0, 0.5],
      type: pc.ELEMENTTYPE_IMAGE,
      width: 58,
      height: 58,
      opacity: 1,
      textureAsset: this._textureAssets.get("button-base"),
      useInput: !0,
      layers: [pc.LAYERID_UI]
    }), t.addChild(this._createIcon("actionA", 33)), this._rootEntity.addChild(t), t;
  }
  _bindElementEvents() {
    this._jumpButton?.element?.on(pc.EVENT_TOUCHSTART, this._onJumpTriggered, this), this._greetButton?.element?.on(pc.EVENT_TOUCHSTART, this._onGreetTriggered, this), this._arrowUpButton?.element?.on(pc.EVENT_TOUCHSTART, this._onArrowUpTriggered, this), this._arrowDownButton?.element?.on(pc.EVENT_TOUCHSTART, this._onArrowDownTriggered, this), this._jumpButton?.element?.on(pc.EVENT_TOUCHEND, this._onJumpReleased, this), this._greetButton?.element?.on(pc.EVENT_TOUCHEND, this._onGreetReleased, this), this._arrowUpButton?.element?.on(pc.EVENT_TOUCHEND, this._onArrowUpReleased, this), this._arrowDownButton?.element?.on(pc.EVENT_TOUCHEND, this._onArrowDownReleased, this), this._pickButton?.element?.on(pc.EVENT_TOUCHSTART, this._onPickTriggered, this), this._actionAButton?.element?.on(pc.EVENT_TOUCHSTART, this._onActionATriggered, this), this._actionBButton?.element?.on(pc.EVENT_TOUCHSTART, this._onActionBTriggered, this), this._rootEntity.element?.on(pc.EVENT_TOUCHSTART, this._onTouchStart, this), this._rootEntity.element?.on(pc.EVENT_TOUCHEND, this._onTouchEnd, this), this._context.system.viverseApp.on("interaction:holding", this._onHoldingStateChanged, this);
    const t = this._context.system.store;
    this._unsubscribeStore = t.subscribe(
      (e) => ({ canFly: e.canFly, canJump: e.canJump }),
      ({ canFly: e, canJump: i }) => {
        this._canFly = e, this._canJump = i, this._arrowUpButton && this._arrowDownButton && (this._arrowUpButton.enabled = this._canFly, this._arrowDownButton.enabled = this._canFly), this._jumpButton && (this._jumpButton.enabled = this._jumpButtonEnabled);
      },
      { equalityFn: Pt }
    );
  }
  _unbindElementEvents() {
    this._jumpButton?.element?.off(pc.EVENT_TOUCHSTART, this._onJumpTriggered), this._greetButton?.element?.off(pc.EVENT_TOUCHSTART, this._onGreetTriggered), this._arrowUpButton?.element?.off(pc.EVENT_TOUCHSTART, this._onArrowUpTriggered), this._arrowDownButton?.element?.off(pc.EVENT_TOUCHSTART, this._onArrowDownTriggered), this._jumpButton?.element?.off(pc.EVENT_TOUCHEND, this._onJumpReleased), this._greetButton?.element?.off(pc.EVENT_TOUCHEND, this._onGreetReleased), this._arrowUpButton?.element?.off(pc.EVENT_TOUCHEND, this._onArrowUpReleased), this._arrowDownButton?.element?.off(pc.EVENT_TOUCHEND, this._onArrowDownReleased), this._rootEntity.element?.off(pc.EVENT_TOUCHSTART, this._onTouchStart), this._rootEntity.element?.off(pc.EVENT_TOUCHEND, this._onTouchEnd), this._context.system.viverseApp.off("interaction:holding", this._onHoldingStateChanged), this._unsubscribeStore?.();
  }
  _onTouchStart(t) {
    const e = t.touch;
    this._context.addTouchIds(e.identifier);
  }
  _onTouchEnd(t) {
    const e = t.touch;
    this._context.removeTouchIds(e.identifier);
  }
  _onHoldingStateChanged = (t) => {
    this._isHolding = t, this._updateButtonVisibility();
  };
  _updateButtonVisibility() {
    this._actionAButton && (this._actionAButton.enabled = this._isHolding), this._actionBButton && (this._actionBButton.enabled = this._isHolding), this._pickButton && (this._pickButton.enabled = this._isHolding), this._jumpButton && this._jumpButtonIcon && (this._jumpButton.element.width = this._isHolding ? 36 : 58, this._jumpButton.element.height = this._isHolding ? 36 : 58, this._jumpButtonIcon.element.width = this._isHolding ? 24 : 33, this._jumpButtonIcon.element.height = this._isHolding ? 24 : 33, this._jumpButton.element.pivot = this._isHolding ? [0, 0.5] : [0, 0.5], this._jumpButton.element.anchor = this._isHolding ? [0.5, 1, 0.5, 1] : [0, 0.5, 0, 0.5]);
  }
  _onJumpTriggered() {
    this._inputStates.jump = !0;
  }
  _onGreetTriggered() {
    this._inputStates.greet = !0;
  }
  _onArrowUpTriggered() {
    this._inputStates.up = !0;
  }
  _onArrowDownTriggered() {
    this._inputStates.down = !0;
  }
  _onJumpReleased() {
    this._inputStates.jump = !1;
  }
  _onGreetReleased() {
    this._inputStates.greet = !1;
  }
  _onArrowUpReleased() {
    this._inputStates.up = !1;
  }
  _onArrowDownReleased() {
    this._inputStates.down = !1;
  }
  _onPickTriggered() {
    this._context.system.emit("input:pick-nearest-item");
  }
  _onActionATriggered() {
    this._context.system.emit("input:action-a");
  }
  _onActionBTriggered() {
    this._context.system.emit("input:action-b");
  }
  _updateInputStates() {
    this._context.setInputStates(this, {
      up: this._inputStates.up,
      down: this._inputStates.down,
      jump: this._inputStates.jump
    });
  }
}
class Rs {
  _context;
  _touchDevice;
  _touches = [];
  _previousRotationCoords = new pc.Vec2();
  _previousZoomCoords = [new pc.Vec2(), new pc.Vec2()];
  constructor(t, e) {
    this._context = e, this._touchDevice = t, this._touchDevice.on("touchstart", this._onTouchStart, this), this._touchDevice.on("touchmove", this._onTouchMove, this), this._touchDevice.on("touchend", this._onTouchEnd, this);
  }
  destroy() {
    this._touchDevice.off("touchstart", this._onTouchStart, this), this._touchDevice.off("touchmove", this._onTouchMove, this);
  }
  _onTouchStart(t) {
    this._updateValidTouches(t), this._updatePreviousCoords();
  }
  _onTouchMove(t) {
    this._updateValidTouches(t), this._touches.length === 1 ? this._updateViewRotation(this._touches[0]) : this._touches.length === 2 && this._updateViewZoom(this._touches);
  }
  _onTouchEnd(t) {
    this._updateValidTouches(t), this._updatePreviousCoords();
  }
  _updatePreviousCoords() {
    this._touches.length === 1 ? this._previousRotationCoords.set(this._touches[0].x, this._touches[0].y) : this._touches.length === 2 && (this._previousZoomCoords[0].set(this._touches[0].x, this._touches[0].y), this._previousZoomCoords[1].set(this._touches[1].x, this._touches[1].y));
  }
  _updateValidTouches(t) {
    this._touches = Array.from(t.touches), this._touches.forEach((e) => {
      this._context.touchIds.includes(e.id) && this._touches.splice(this._touches.indexOf(e), 1);
    });
  }
  _updateViewZoom(t) {
    const e = this._previousZoomCoords[0].distance(this._previousZoomCoords[1]), n = Math.sqrt(
      (t[0].x - t[1].x) ** 2 + (t[0].y - t[1].y) ** 2
    ) - e;
    n !== 0 && this._context.emit("input:zoom", n * this._context.getZoomSensitivity()), this._previousZoomCoords[0].set(t[0].x, t[0].y), this._previousZoomCoords[1].set(t[1].x, t[1].y);
  }
  _updateViewRotation(t) {
    const e = this._context.getRotationSensitivity(), i = -(t.x - this._previousRotationCoords.x) * e, n = -(t.y - this._previousRotationCoords.y) * e;
    this._context.setYaw(this._context.getState().yaw + i), this._context.setPitch(pc.math.clamp(this._context.getState().pitch + n, -80, 80)), this._previousRotationCoords.set(t.x, t.y);
  }
}
class Ds {
  rotationSensitivity = 0.5;
  zoomSensitivity = 0.1;
  _pcApp;
  _context;
  _viewControl;
  _touchIds = [];
  _uiArray = [];
  _screen;
  _joystick = null;
  _actionButtons = null;
  constructor(t, e) {
    this._pcApp = t.pcApp, this._context = {
      ...e,
      system: t,
      touchIds: this._touchIds,
      addTouchIds: this._addTouchIds.bind(this),
      removeTouchIds: this._removeTouchIds.bind(this),
      getRotationSensitivity: this._getRotationSensitivity.bind(this),
      getZoomSensitivity: this._getZoomSensitivity.bind(this)
    }, this._viewControl = new Rs(this._pcApp.touch, this._context), this._screen = this._createScreen(), Gt.create(this._pcApp, this._screen, this._context).then(
      (i) => {
        this._joystick = i, this._joystick && this._uiArray.push(this._joystick);
      }
    ), Wt.create(this._pcApp, this._screen, this._context).then(
      (i) => {
        this._actionButtons = i, this._actionButtons && this._uiArray.push(this._actionButtons);
      }
    );
  }
  update(t) {
    this._uiArray.forEach((e) => {
      e.update(t);
    });
  }
  destroy() {
    this._uiArray.forEach((t) => {
      t.destroy();
    }), this._viewControl.destroy(), this._screen.destroy();
  }
  _createScreen() {
    const t = new pc.Entity("TouchInputScreen");
    return t.addComponent("screen", {
      referenceResolution: new pc.Vec2(844, 390),
      scaleBlend: 0.5,
      scaleMode: pc.SCALEMODE_BLEND,
      screenSpace: !0
    }), this._pcApp.root.addChild(t), t;
  }
  _addTouchIds(t) {
    this._touchIds.push(t);
  }
  _removeTouchIds(t) {
    this._touchIds.splice(this._touchIds.indexOf(t), 1);
  }
  _getRotationSensitivity() {
    return this.rotationSensitivity;
  }
  _getZoomSensitivity() {
    return this.zoomSensitivity;
  }
}
class Ns {
  rotationSensitivity = 0.2;
  zoomSensitivity = 0.2;
  _mouse;
  _context;
  _dragButton = pc.MOUSEBUTTON_LEFT;
  constructor(t, e) {
    this._mouse = t, this._context = e, this._mouse.on(pc.EVENT_MOUSEDOWN, this._onMouseDown, this), this._mouse.on(pc.EVENT_MOUSEMOVE, this._onMouseMove, this), this._mouse.on(pc.EVENT_MOUSEWHEEL, this._onMouseScroll, this);
  }
  destroy() {
    this._mouse.off(pc.EVENT_MOUSEDOWN, this._onMouseDown, this), this._mouse.off(pc.EVENT_MOUSEMOVE, this._onMouseMove, this), this._mouse.off(pc.EVENT_MOUSEWHEEL, this._onMouseScroll, this);
  }
  _onMouseDown(t) {
    this._context.pointerLock.shouldUse && !this._context.pointerLock.isLocked && (t.button === this._dragButton || t.buttons[0]) && (this._context.pointerLock.isLocked = !0, this._context.emit("input:pointer-lock", !0));
  }
  _onMouseMove(t) {
    if (!this._context.pointerLock.isLocked && !(this._mouse.isPressed(this._dragButton) || t.buttons[0]))
      return;
    const e = -t.dx * this.rotationSensitivity, i = -t.dy * this.rotationSensitivity;
    this._context.setYaw(this._context.getState().yaw + e), this._context.setPitch(pc.math.clamp(this._context.getState().pitch + i, -80, 80));
  }
  _onMouseScroll(t) {
    const e = t.wheelDelta;
    e !== 0 && this._context.emit("input:zoom", e * this.zoomSensitivity);
  }
}
class Os {
  system;
  inputs = [];
  _inputStatesMap = /* @__PURE__ */ new Map();
  _keyboardInput = null;
  _mouseInput = null;
  _touchInput = null;
  _pointerLock = {
    shouldUse: !1,
    isLocked: !1
  };
  constructor(t) {
    this.system = t;
    const e = {
      getState: () => t.store.getState(),
      setInputStates: this._resolveInputStates.bind(this),
      setYaw: this._setYawInput.bind(this),
      setPitch: this._setPitchInput.bind(this),
      pointerLock: this._pointerLock,
      emit: (o, ...l) => {
        t.emit(o, ...l);
      }
    }, i = t.pcApp.keyboard, n = t.pcApp.mouse, s = t.pcApp.touch;
    this._initializeInputs(e, i, n, s);
    const r = () => {
      document.pointerLockElement !== t.pcApp.graphicsDevice.canvas && t.emit("input:pointer-lock", !1);
    };
    n && i && (t.on("input:pointer-lock", this._onIsPointerLockedChange.bind(this)), document.addEventListener("pointerlockchange", r, !1), document.addEventListener("mozpointerlockchange", r, !1), document.addEventListener("webkitpointerlockchange", r, !1), document.addEventListener("mspointerlockchange", r, !1));
  }
  set pointerLock(t) {
    this._pointerLock.shouldUse = t, this._pointerLock.isLocked = !1;
  }
  get pointerLock() {
    return this._pointerLock.shouldUse;
  }
  update(t) {
    for (const e of this.inputs)
      e.update && e.update(t);
  }
  destroy() {
    for (const t of this.inputs)
      t.destroy && t.destroy();
    this.inputs.length = 0, this._keyboardInput = null, this._mouseInput = null, this._touchInput = null;
  }
  _initializeInputs(t, e, i, n) {
    e && (this._keyboardInput = new Ls(e, t), this.inputs.push(this._keyboardInput)), i && (this._mouseInput = new Ns(i, t), this.inputs.push(this._mouseInput)), n && this.system.viverseApp.deviceInfo.hardware === bi.Mobile && (this._touchInput = new Ds(this.system, t), this.inputs.push(this._touchInput));
  }
  _setYawInput(t) {
    const { canInputRotateYawPitch: e, setYaw: i } = this.system.store.getState();
    e && i(t);
  }
  _setPitchInput(t) {
    const { canInputRotateYawPitch: e, setPitch: i } = this.system.store.getState();
    e && i(t);
  }
  _onIsPointerLockedChange(t) {
    this._pointerLock.isLocked = t;
    const e = this.system.pcApp.graphicsDevice.canvas;
    if (e)
      if (t)
        e.requestPointerLock = e.requestPointerLock || e.webkitRequestPointerLock || e.mozRequestPointerLock || e.msRequestPointerLock || function() {
        }, e.requestPointerLock();
      else {
        const i = e.ownerDocument;
        i.exitPointerLock = i.exitPointerLock || i.mozExitPointerLock || i.webkitExitPointerLock || i.msExitPointerLock || function() {
        }, i.exitPointerLock(), alert("Pointer lock exited. Click the canvas to re-enter.");
      }
  }
  _resolveInputStates(t, e) {
    this._inputStatesMap.set(t, e);
    const i = {}, n = (r, o) => {
      i[r] = o;
    };
    this._inputStatesMap.forEach((r) => {
      for (const o of Object.keys(r)) {
        const l = o, c = r[l];
        c !== void 0 && (l in i || n(l, c), c && n(l, c));
      }
    }), this.system.store.getState().setInputStates(i);
  }
}
class Vs {
  _store;
  _entity;
  _unsubscribes = [];
  constructor(t) {
    this._store = t.store, this._entity = new pc.Entity("PlayerAudioListener"), this._entity.addComponent("audiolistener"), this._bindStoreEvents();
  }
  _bindStoreEvents() {
    this._unsubscribes.push(
      this._store.subscribe((t) => t.headHeight, this._updateHeadHeight.bind(this))
    );
  }
  _updateHeadHeight() {
    const { headHeight: t } = this._store.getState();
    this._entity.setLocalPosition(0, t, 0);
  }
  setup(t) {
    t.addChild(this._entity), this._updateHeadHeight();
  }
  destroy() {
    this._entity.destroy(), this._unsubscribes.forEach((t) => t());
  }
}
class Fs {
  _module = null;
  _prevLocalRotation = new pc.Quat();
  _prevStates = null;
  constructor(t) {
    this._module = t.modules.localAvatar ?? null;
  }
  _getLocalRotation() {
    const t = this._module?.avatarContainerEntity;
    if (!t) return [0, 0, 0, 1];
    const e = t.getLocalRotation();
    return [e.x, e.y, e.z, e.w];
  }
  _isLocalRotationChanged() {
    const t = this._module?.avatarContainerEntity;
    if (!t) return !1;
    const e = t.getLocalRotation(), n = !this._prevLocalRotation.equalsApprox(e, 0.01);
    return n && this._prevLocalRotation.copy(e), n;
  }
  _isAvatarStatesChanged() {
    if (!this._module) return !1;
    const t = this._module.getAvatarStates();
    if (!t) return !1;
    if (!this._prevStates)
      return this._prevStates = { ...t }, !0;
    const e = this._prevStates, i = e.customAnim?.stateName !== t.customAnim?.stateName, n = e.horizontalDirection !== t.horizontalDirection || e.verticalState !== t.verticalState || e.isGrounded !== t.isGrounded || e.isFalling !== t.isFalling || e.isFlying !== t.isFlying || e.isSprinting !== t.isSprinting || e.isSitting !== t.isSitting || t.triggerJump || i;
    return n && (this._prevStates = { ...t }), n;
  }
  gatherPayload() {
    if (!this._module) return null;
    const t = this._module.activeAvatar;
    if (!t) return null;
    const e = this._getLocalRotation(), i = this._module.getAvatarStates(), { name: n, type: s, config: r } = t;
    return {
      type: s,
      name: n,
      localRotation: e,
      ...r && { config: r },
      ...i && { states: i }
    };
  }
  hasChanged() {
    const t = this._isLocalRotationChanged(), e = this._isAvatarStatesChanged();
    return t || e;
  }
  consumeTriggers() {
    this._module?.consumeTriggers();
  }
}
class ks {
  _system;
  _prevPosition = new pc.Vec3();
  _prevRotation = new pc.Quat();
  constructor(t) {
    this._system = t;
  }
  _isPositionChanged() {
    const t = this._system.playerEntity?.getPosition();
    if (!t) return !1;
    const i = this._prevPosition.distance(t) >= 0.01;
    return i && this._prevPosition.copy(t), i;
  }
  _isRotationChanged() {
    const t = this._system.playerEntity?.getRotation();
    if (!t) return !1;
    const i = !this._prevRotation.equalsApprox(t, 0.01);
    return i && this._prevRotation.copy(t), i;
  }
  _gatherPayload() {
    const t = this._system.playerEntity;
    if (!t) return null;
    const e = t.getPosition(), i = t.getRotation();
    return {
      position: [e.x, e.y, e.z],
      rotation: [i.x, i.y, i.z, i.w]
    };
  }
  gatherPayload() {
    return this._gatherPayload();
  }
  hasChanged() {
    if (!this._system.playerEntity) return !1;
    const e = this._isPositionChanged(), i = this._isRotationChanged();
    return e || i;
  }
}
class Bs {
  _viverseApp;
  _messageType = "player";
  _syncInterval = 3e3;
  _lastSyncTime = 0;
  _changeCheckInterval = 100;
  _changeCheckTimer = 0;
  _avatarBuilder;
  _transformBuilder;
  constructor(t) {
    this._viverseApp = t.viverseApp, this._avatarBuilder = new Fs(t), this._transformBuilder = new ks(t);
  }
  _isEmptyObject(t) {
    for (const e in t) return !1;
    return !0;
  }
  _sendPeriodicPayload() {
    const t = this._avatarBuilder.gatherPayload(), e = this._transformBuilder.gatherPayload(), i = {
      ...t && { avatar: t },
      ...e && { transform: e }
    };
    this._send(i);
  }
  _handleChanges() {
    const t = this._avatarBuilder.hasChanged(), e = this._transformBuilder.hasChanged();
    if (t || e) {
      const i = this._avatarBuilder.gatherPayload(), n = this._transformBuilder.gatherPayload(), s = {
        ...i && { avatar: i },
        ...n && { transform: n }
      };
      this._send(s);
    }
  }
  _send(t) {
    if (this._isEmptyObject(t)) return;
    const e = {
      type: this._messageType,
      data: t
    };
    this._avatarBuilder.consumeTriggers(), this._viverseApp.emit("multiplayer:send-system-message", e);
  }
  update(t) {
    this._changeCheckTimer += t * 1e3, this._changeCheckTimer >= this._changeCheckInterval && (this._changeCheckTimer = 0, this._handleChanges()), this._lastSyncTime += t * 1e3, this._lastSyncTime >= this._syncInterval && (this._lastSyncTime = 0, this._sendPeriodicPayload());
  }
}
class Us {
  _nameTag = null;
  _system;
  _offset = { x: 0, y: 0.25, z: 0 };
  _customOffset = null;
  _customScale = null;
  _isSceneHierarchyEnabled = !0;
  _unsubscribes = [];
  _customHeight = null;
  _onClickName;
  constructor(t, e) {
    this._system = t, this._onClickName = e, this._bindEvents();
  }
  get instance() {
    return this._nameTag;
  }
  get customHeight() {
    return this._customHeight;
  }
  get customOffset() {
    return this._customOffset;
  }
  get customScale() {
    return this._customScale;
  }
  get isSceneHierarchyEnabled() {
    return this._isSceneHierarchyEnabled;
  }
  _bindEvents() {
    const t = this._system.viverseApp.context.profile;
    this._unsubscribes.push(
      t.subscribe(
        (e) => e.displayName,
        () => this._updateDisplayName()
      )
    ), this._system.on("local-avatar:changed", this._handleAvatarChanged, this);
  }
  _unbindEvents() {
    this._system.off("local-avatar:changed", this._handleAvatarChanged, this), this._unsubscribes.forEach((t) => t()), this._unsubscribes = [];
  }
  async setup(t) {
    this._nameTag || (this._nameTag = await gi.create(this._system.pcApp, {
      onNameTagClick: this._onNameTagClick.bind(this)
    }), this._nameTag.setup(t), this._updatePosition(), this._updateDisplayName(), this._updateScale(), this._applySceneHierarchyDisplayCondition(this._isSceneHierarchyEnabled), this._system.emit("name-tag:ready", this._nameTag));
  }
  _onNameTagClick() {
    this._onClickName ? this._onClickName() : this._system.viverseApp.emit("ui:open-my-profile");
  }
  setText(t) {
    this._nameTag && this._nameTag.setText(t);
  }
  _updateViewPosition() {
    if (this._nameTag) {
      const t = this._system.store.getState().viewPosition;
      this._nameTag.updateViewPosition(t);
    }
  }
  _applySceneHierarchyDisplayCondition(t) {
    this._nameTag && this._nameTag.updateDisplayCondition("isSceneHierarchyEntityEnabled", t);
  }
  setCustomHeight(t) {
    this._customHeight = t, this._updatePosition();
  }
  recoverDefaultHeight() {
    this._customHeight = null, this._updatePosition();
  }
  setCustomOffset(t) {
    this._customOffset = t, this._updatePosition(), this._system.emit("name-tag:custom-offset-changed", t);
  }
  recoverDefaultOffset() {
    this._customOffset = null, this._updatePosition(), this._system.emit("name-tag:custom-offset-changed", null);
  }
  setCustomScale(t) {
    this._customScale = t, this._updateScale(), this._system.emit("name-tag:custom-scale-changed", t);
  }
  recoverDefaultScale() {
    this._customScale = null, this._updateScale(), this._system.emit("name-tag:custom-scale-changed", null);
  }
  setSceneHierarchyEnabled(t) {
    this._isSceneHierarchyEnabled = t, this._applySceneHierarchyDisplayCondition(t), this._system.emit("name-tag:scene-hierarchy-enabled-changed", t);
  }
  _updateScale() {
    this._nameTag && (this._customScale ? this._nameTag.updateLocalScale(this._customScale.x, this._customScale.y, this._customScale.z) : this._nameTag.updateLocalScale(1, 1, 1));
  }
  _updatePosition() {
    if (!this._nameTag) return;
    const t = this._customHeight ?? this._getAvatarHeight(), e = this._customOffset ?? this._offset;
    this._nameTag.updateLocalPosition(e.x, t + e.y, e.z);
  }
  _getAvatarHeight() {
    const t = this._system.modules.localAvatar;
    if (!t) return 1;
    const e = t.activeAvatar;
    if (!e) return 1;
    const i = e.boundingBox;
    return i.center.y + i.halfExtents.y;
  }
  _handleAvatarChanged() {
    this._updatePosition();
  }
  _updateDisplayName() {
    const t = this._system.viverseApp.context.profile, { displayName: e } = t.getState();
    e && this._nameTag && this._nameTag.setText(e);
  }
  update() {
    this._updateViewPosition();
  }
  destroy() {
    this._nameTag && (this._nameTag = null), this._unbindEvents();
  }
  setSpeaking(t) {
    this._nameTag && this._nameTag.setSpeaking(t);
  }
}
class Tr extends yi {
  static systemName = Mi.LocalPlayer;
  _options;
  _audioListener;
  _audioProcessor;
  _sender;
  _nameTag = null;
  modules = {};
  store = Di();
  input;
  spawnPoints = [];
  constructor(t, e) {
    super(t), this._checkAmmoDependency(), this.input = new Os(this), this._audioListener = new Vs(this), this._audioProcessor = new vi(this), this._options = { ...this._getDefaultOptions(), ...e };
    const { modules: i, spawnPoints: n, useNameTag: s, onNameTagClick: r } = this._options;
    i && this._setupModules(i), n && (this.spawnPoints = n), this._sender = new Bs(this), s && (this._nameTag = new Us(this, r)), this._bindListeners();
  }
  get playerEntity() {
    return this.store.getState().playerEntity;
  }
  get nameTag() {
    return this._nameTag;
  }
  get activeAvatar() {
    return this.modules.localAvatar?.activeAvatar || null;
  }
  onTalkingStateChanged(t) {
    this.emit("local-player:audio-talking", t), this.nameTag?.setSpeaking(t), this.activeAvatar?.setTalking?.(t);
  }
  _getDefaultOptions() {
    return bs;
  }
  _setupModules(t) {
    t.forEach((e) => {
      const { Module: i, name: n, options: s } = e;
      if (!i || typeof i != "function")
        throw new Error("Module class is not specified or is not a valid constructor.");
      if (i.moduleName !== n)
        throw new Error(`Module class mismatch: expected ${n}, got ${i.moduleName}`);
      const r = new i(this, s);
      Si(this.modules, r.name, r);
    });
  }
  _checkAmmoDependency() {
    if (!window.Ammo)
      throw Error("LocalPlayerSystem depends on Ammo.js. Ensure it is loaded first.");
  }
  async addPlayer() {
    if (this.playerEntity) {
      E.warn("Local player entity already exists.");
      return;
    }
    const t = new pc.Entity("Player");
    this.store.setState({ playerEntity: t });
    const e = this.modules.localAvatar;
    if (e)
      try {
        await e.setupAvatars(t);
      } catch (r) {
        E.error("Failed to set avatar:", r);
        return;
      }
    const n = e?.avatarContainerEntity || t;
    this._audioListener.setup(n), await this._nameTag?.setup(t), this._setupPhysic(t);
    const s = this.getSpawnPoint();
    t.setPosition(s), this.pcApp.root.addChild(t), this.viverseApp.emit("player:ready", t);
  }
  _setupPhysic(t) {
    t.addComponent("rigidbody", Ni), this.updateCapsuleCollider();
  }
  updateCapsuleCollider(t) {
    if (!this.playerEntity) {
      E.error("Player entity is not added yet.");
      return;
    }
    const e = t || this.store.getState().boundingBox;
    Ei(this.playerEntity, e);
  }
  getSpawnPoint() {
    if (this.spawnPoints.length === 0)
      return new pc.Vec3(0, 0, 0);
    const t = Math.floor(Math.random() * this.spawnPoints.length);
    return this.spawnPoints[t];
  }
  setSpawnPoint(t) {
    t && (this.spawnPoints = t instanceof pc.Vec3 ? [t] : t);
  }
  start() {
  }
  _onStartVr() {
    this.modules.xr ? this.modules.xr.start() : E.warn(
      "XR module not registered. Register XR module or handle event for custom initialization."
    );
  }
  _handleLocalAudioStream(t) {
    this._audioProcessor.setStream(t);
  }
  _bindListeners() {
    this.viverseApp.on("xr:start-vr", this._onStartVr, this), this.pcApp.on("update", this.update, this), this.viverseApp.on("multiplayer:local-stream-updated", this._handleLocalAudioStream, this);
  }
  _unbindListeners() {
    this.viverseApp.off("xr:start-vr", this._onStartVr, this), this.pcApp.off("update", this.update, this), this.viverseApp.off("multiplayer:local-stream-updated", this._handleLocalAudioStream, this);
  }
  destroy() {
    super.destroy(), this._unbindListeners(), this._nameTag && (this._nameTag.destroy(), this._nameTag = null), this._audioProcessor && this._audioProcessor.destroy(), Object.values(this.modules).forEach((t) => {
      t.destroy && t.destroy(), delete this.modules[t.name];
    });
  }
  update(t) {
    this.input.update(t), this._sender.update(t), this._nameTag?.update(), this._audioProcessor.update();
    for (const e in this.modules) {
      const i = e, n = this.modules[i];
      n && n.update && n.update(t);
    }
  }
  teleport(t, e) {
    const i = this.playerEntity?.rigidbody;
    if (!i) return;
    const { x: n, y: s, z: r } = t;
    if (e) {
      const { y: o } = e.getEulerAngles();
      i.teleport(n, s, r, 0, o, 0);
    } else
      i.teleport(n, s, r);
    i.linearVelocity = pc.Vec3.ZERO;
  }
}
class Ue {
  type = $.Controller;
  node;
  enabled = !0;
  _pcApp;
  _isActive = !1;
  _inputSource = null;
  _modelAsset = null;
  _entity = null;
  constructor(t, e) {
    this.node = t, this.type = e, this._pcApp = t.module.system.pcApp, this._setup();
  }
  get entity() {
    return this._entity;
  }
  set entity(t) {
    this._entity && this.node.entity.removeChild(this._entity), this._entity = t, this.node.entity.addChild(this._entity), this._entity.enabled = this._isActive;
  }
  addInputSource(t) {
    this._inputSource = t, this.activate();
  }
  removeInputSource() {
    this._inputSource = null, this.deactivate();
  }
  async _loadModel() {
    try {
      this._modelAsset = await H(
        this._pcApp,
        `xr-${this.type}-${this.node.handedness}.glb`,
        "/models/xr/",
        "local-player",
        "container"
      );
    } catch (t) {
      throw console.error(`Xr ${this.type}: Failed to load assets`, t), t;
    }
  }
}
class Hs extends Ue {
  _customAsset = null;
  constructor(t) {
    super(t, $.Controller);
  }
  get customAsset() {
    return this._customAsset;
  }
  activate() {
    this.enabled && (this._isActive = !0, this._entity && (this._entity.enabled = !0));
  }
  deactivate() {
    this._isActive = !1, this._entity && (this._entity.enabled = !1);
  }
  update(t) {
    !this.enabled || !this._isActive || (this._updateTransform(), this._updateJoystickVec2());
  }
  destroy() {
    this._entity && (this._entity.destroy(), this._entity = null), this._inputSource = null;
  }
  async setCustomAsset(t) {
    await this._loadCutsomModel(t), this._createControllerEntity();
  }
  async _setup() {
    await this._loadModel(), this._entity || this._createControllerEntity();
  }
  async _loadCutsomModel(t) {
    try {
      const e = t.file;
      this._customAsset = await Ai(this._pcApp, e.fileName, e.url, "container");
    } catch (e) {
      throw console.error(`Xr ${this.type}: Failed to load assets`, e), e;
    }
  }
  _createControllerEntity() {
    if (!this._pcApp) return;
    const t = this._customAsset || this._modelAsset;
    if (t && t.type === "container") {
      this._entity && (this.node.entity.removeChild(this._entity), this._entity.destroy(), this._entity = null);
      const e = t.resource;
      this._entity = e.instantiateRenderEntity({
        castShadows: !1,
        receiveShadows: !1
      }), this._entity.name = `controller-model-${this.node.handedness}`, this._entity.setLocalPosition(0, 0, -0.05);
      const i = this._entity.getLocalEulerAngles();
      this._entity.setLocalEulerAngles(i.x - 30, i.y, i.z), this.node.entity.addChild(this._entity), this._entity.enabled = this._isActive;
    }
  }
  _updateTransform() {
    if (!this._inputSource) return;
    const t = this._inputSource.getPosition(), e = this._inputSource.getRotation();
    t && this.node.entity.setPosition(t), e && this.node.entity.setRotation(e);
  }
  // private _determineJoystickPressed(): boolean {
  //   if (!this._inputSource?.gamepad) return false;
  //   const { buttons } = this._inputSource.gamepad;
  //   // Note: XR gamepads don't have profiles property, use a different approach
  //   // For now, use standard WebXR gamepad button mapping
  //   // Different controllers have thumbstick button at different indices
  //   // Try button index 3 first (most common), then 2
  //   if (buttons.length > 3) {
  //     return buttons[3].pressed;
  //   } else if (buttons.length > 2) {
  //     return buttons[2].pressed;
  //   }
  //   return false;
  // }
  _updateJoystickVec2() {
    if (!this._inputSource?.gamepad || this._inputSource.gamepad.axes.length < 4) {
      this.node.setInputVec2(0, 0);
      return;
    }
    this.node.setInputVec2(
      this._inputSource.gamepad.axes[2],
      // X axis
      this._inputSource.gamepad.axes[3]
      // Y axis
    );
  }
}
const He = (
  /* glsl */
  `
void getBoneMatrix(const in int width, const in int index, out vec4 v1, out vec4 v2, out vec4 v3) {
    int v = index / width;
    int u = index % width;

    v1 = texelFetch(texture_poseMap, ivec2(u + 0, v), 0);
    v2 = texelFetch(texture_poseMap, ivec2(u + 1, v), 0);
    v3 = texelFetch(texture_poseMap, ivec2(u + 2, v), 0);
}

mat4 getSkinMatrix(const in vec4 indicesFloat, const in vec4 weights) {
    int width = textureSize(texture_poseMap, 0).x;
    ivec4 indices = ivec4(indicesFloat + 0.5) * 3;

    vec4 a1, a2, a3;
    getBoneMatrix(width, indices.x, a1, a2, a3);
    vec4 b1, b2, b3;
    getBoneMatrix(width, indices.y, b1, b2, b3);
    vec4 c1, c2, c3;
    getBoneMatrix(width, indices.z, c1, c2, c3);
    vec4 d1, d2, d3;
    getBoneMatrix(width, indices.w, d1, d2, d3);

    vec4 v1 = a1 * weights.x + b1 * weights.y + c1 * weights.z + d1 * weights.w;
    vec4 v2 = a2 * weights.x + b2 * weights.y + c2 * weights.z + d2 * weights.w;
    vec4 v3 = a3 * weights.x + b3 * weights.y + c3 * weights.z + d3 * weights.w;

    float one = dot(weights, vec4(1.0));

    return mat4(
        v1.x, v2.x, v3.x, 0,
        v1.y, v2.y, v3.y, 0,
        v1.z, v2.z, v3.z, 0,
        v1.w, v2.w, v3.w, one
    );
}
`
), zs = (
  /* glsl */
  `
uniform mat4 matrix_model;
uniform mat4 matrix_view;
uniform mat4 matrix_projection;
uniform vec3 view_position;
uniform sampler2D texture_poseMap;

attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec4 vertex_boneIndices;
attribute vec4 vertex_boneWeights;

varying vec3 vNormal;
varying vec3 vViewDir;
varying vec3 vPosition;

${He}

void main(void) {
    mat4 skinMat = getSkinMatrix(vertex_boneIndices, vertex_boneWeights);
    vec4 worldPosition = matrix_model * skinMat * vec4(aPosition, 1.0);

    vNormal = mat3(matrix_model * skinMat) * aNormal; 
    vViewDir = normalize(view_position - worldPosition.xyz);
    vPosition = aPosition.xyz;

    gl_Position = matrix_projection * matrix_view  * worldPosition;
}
`
), Gs = (
  /* glsl */
  `
precision mediump float;

varying vec3 vNormal;
varying vec3 vViewDir;
varying vec3 vPosition;

void main(void) {
    vec3 normal = normalize(vNormal);
    vec3 viewDir = normalize(vViewDir);
    float rim = 1.0 - pow(max(dot(normal, viewDir), 0.0), 5.0);
    float alpha = max((-vPosition.y+0.07) * rim * 10.0, pow((-vPosition.y+0.07), 1.5) * 29.0);

    gl_FragColor = vec4(vec3(1.0), alpha);
}
`
), Ws = (
  /* glsl */
  `
uniform mat4 matrix_model;
uniform mat4 matrix_view;
uniform mat4 matrix_projection;
uniform sampler2D texture_poseMap;

attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec4 vertex_boneIndices;
attribute vec4 vertex_boneWeights;

varying vec3 vPosition;

${He}

void main(void) {
    mat4 skinMat = getSkinMatrix(vertex_boneIndices, vertex_boneWeights);
    vec4 worldPosition = matrix_model * skinMat * vec4(aPosition + aNormal * 0.002, 1.0);
    vPosition = aPosition.xyz;
    gl_Position = matrix_projection * matrix_view * worldPosition;
}
`
), js = (
  /* glsl */
  `
varying vec3 vPosition;

void main(void) {
    float alpha = pow(max((-vPosition.y+0.07) * 5.0, 0.0), 1.5);
    gl_FragColor = vec4(vec3(0.1), alpha);
}
`
);
class Ys extends Ue {
  _components = {
    main: { entity: null, material: null, jointToEntity: /* @__PURE__ */ new Map() },
    outline: { entity: null, material: null, jointToEntity: /* @__PURE__ */ new Map() }
  };
  constructor(t) {
    super(t, $.Hand);
  }
  activate() {
    this.enabled && (this._isActive = !0, Object.entries(this._components).forEach(([t, e]) => {
      e.entity && (e.entity.enabled = !0, this._inputSource && this._mapHandJoints(this._inputSource, t));
    }));
  }
  deactivate() {
    this._isActive = !1, Object.values(this._components).forEach((t) => {
      t.entity && (t.entity.enabled = !1);
    });
  }
  update(t) {
    !this.enabled || !this._isActive || this._updateJointsTransform();
  }
  destroy() {
    Object.values(this._components).forEach((t) => {
      t.entity && (t.entity.destroy(), t.entity = null), t.material && (t.material.destroy(), t.material = null), t.jointToEntity.clear();
    }), this._inputSource = null;
  }
  async _setup() {
    await this._loadModel(), this._createHandEntities();
  }
  _createHandEntities() {
    if (!(!this._modelAsset || !this._pcApp || this._entity) && (this._entity = new pc.Entity(`hand-root-${this.node.handedness}`), this.node.entity.addChild(this._entity), this._modelAsset.type === "container")) {
      const t = this._modelAsset.resource;
      Object.entries(this._components).forEach(([e, i]) => {
        i.entity = t.instantiateRenderEntity({
          castShadows: !1,
          receiveShadows: !1
        }), i.entity && (i.entity.name = `hand-${e}-${this.node.handedness}`, this._entity.addChild(i.entity), this._setupEntityMaterial(i.entity, e), this._setupEntityTransform(i.entity), i.entity.enabled = this._isActive);
      });
    }
  }
  _setupEntityMaterial(t, e) {
    const i = t.findComponents("render"), n = this._createMaterial(e);
    this._components[e].material = n, e === "main" ? this._writeStencil(n) : this._testStencil(n);
    for (let s = 0; s < i.length; ++s) {
      const r = i[s].meshInstances;
      for (let o = 0; o < r.length; o++)
        r[o].material = n;
    }
  }
  _createMaterial(t) {
    const e = new pc.ShaderMaterial({
      uniqueName: `hand-${t}`,
      vertexGLSL: t === "main" ? zs : Ws,
      fragmentGLSL: t === "main" ? Gs : js,
      attributes: {
        aPosition: pc.SEMANTIC_POSITION,
        aNormal: pc.SEMANTIC_NORMAL
      }
    });
    return e.blendType = pc.BLEND_NORMAL, e.depthWrite = !0, e.depthTest = !0, e;
  }
  _writeStencil(t) {
    const e = Math.pow(2, 2), i = new pc.StencilParameters({
      readMask: e,
      writeMask: e,
      ref: e,
      zpass: pc.STENCILOP_REPLACE
    });
    t.stencilFront = i, t.stencilBack = t.stencilFront, t.update();
  }
  _testStencil(t) {
    const e = Math.pow(2, 2), i = new pc.StencilParameters({
      readMask: e,
      writeMask: e,
      ref: e,
      func: pc.FUNC_NOTEQUAL
    });
    t.stencilFront = i, t.stencilBack = i, t.update();
  }
  _setupEntityTransform(t) {
    t.setLocalPosition(0, 0, -0.05);
    const e = t.getLocalEulerAngles();
    t.setLocalEulerAngles(e.x - 30, e.y, e.z);
  }
  _mapHandJoints(t, e) {
    const i = this._components[e].entity;
    if (!i || !this._inputSource || !this._inputSource.hand) return;
    const n = [
      "wrist",
      "thumb-metacarpal",
      "thumb-phalanx-proximal",
      "thumb-phalanx-distal",
      "thumb-tip",
      "index-finger-metacarpal",
      "index-finger-phalanx-proximal",
      "index-finger-phalanx-intermediate",
      "index-finger-phalanx-distal",
      "index-finger-tip",
      "middle-finger-metacarpal",
      "middle-finger-phalanx-proximal",
      "middle-finger-phalanx-intermediate",
      "middle-finger-phalanx-distal",
      "middle-finger-tip",
      "ring-finger-metacarpal",
      "ring-finger-phalanx-proximal",
      "ring-finger-phalanx-intermediate",
      "ring-finger-phalanx-distal",
      "ring-finger-tip",
      "pinky-finger-metacarpal",
      "pinky-finger-phalanx-proximal",
      "pinky-finger-phalanx-intermediate",
      "pinky-finger-phalanx-distal",
      "pinky-finger-tip"
    ];
    this._components[e].jointToEntity.clear(), n.forEach((s) => {
      const r = i.findByName(s), o = t.hand?.getJointById(s);
      o && r && this._components[e].jointToEntity.set(o, r);
    });
  }
  _updateJointsTransform() {
    !this._inputSource || !this._inputSource.hand || Object.values(this._components).forEach((t) => {
      t.jointToEntity.forEach((e, i) => {
        e.setPosition(i.getPosition()), e.setRotation(i.getRotation());
      });
    });
  }
}
const Xs = (
  /* glsl */
  `
uniform mat4 matrix_model;
uniform mat4 matrix_view;
uniform mat4 matrix_projection;

attribute vec3 aPosition;
varying float vPosY;

void main() {
  gl_Position = matrix_projection * matrix_view * matrix_model * vec4(aPosition, 1.0);
  vPosY = 0.5 - aPosition.y;
}
`
), Zs = (
  /* glsl */
  `
uniform int uIsBlue;
varying float vPosY;

void main(){
  float alpha = smoothstep(0.5, 0.875, vPosY);
  vec3 color = uIsBlue > 0 ? vec3(0.0, 0.61569, 0.90589) : vec3(1.0);
  color = mix(vec3(1.0), color, alpha - 0.2);

  if (alpha < 0.01) discard;
  gl_FragColor = vec4(color, alpha);
}
`
), $s = 0.15;
class qs {
  node;
  enabled = !0;
  _pcApp;
  _isActive = !1;
  _inputSource = null;
  _cone = new pc.Entity();
  _coneMaterial = null;
  _cursor = new pc.Entity();
  _hoverImage = new pc.Entity();
  _pinchImage = new pc.Entity();
  _cursorScaler = 0.055;
  _cursorPosition = new pc.Vec3();
  _coneLookAt = new pc.Vec3();
  _shouldShowCursor = !1;
  _hoverAsset = null;
  _pinchAsset = null;
  constructor(t) {
    this.node = t, this._pcApp = t.module.system.pcApp, this._setup();
  }
  activate() {
    this.enabled && (this._isActive = !0, this._shouldShowCursor = !0, this._cone.enabled = !0);
  }
  deactivate() {
    this._isActive = !1, this._shouldShowCursor = !1, this._cone.enabled = !1, this._cursor.enabled = !1;
  }
  addInputSource(t) {
    this._inputSource = t, this.activate();
  }
  removeInputSource() {
    this._inputSource = null, this.deactivate();
  }
  update(t) {
    if (!this.enabled || !this._isActive || !this._inputSource || !this._inputSource.elementInput)
      return;
    if (this._updateConeTransform(this._inputSource), this._performUiRaycast(this._inputSource), !this._shouldShowCursor) {
      this._cursor.enabled = !1, this._hoverImage.enabled = !1, this._pinchImage.enabled = !1;
      return;
    }
    const e = this._inputSource.elementEntity?.entity;
    this._cursor.setRotation(e.getRotation()), this._cursor.setPosition(this._cursorPosition), this._updateCursorScale(this._inputSource), this._cursor.setLocalScale(this._cursorScaler, this._cursorScaler, this._cursorScaler), this._cursor.enabled = !0, this._hoverImage.enabled = !this._inputSource.selecting, this._pinchImage.enabled = this._inputSource.selecting, this._updateConeMaterialColor(this._inputSource.selecting);
  }
  destroy() {
    this._cone.destroy(), this._cursor.destroy(), this._hoverImage.destroy(), this._pinchImage.destroy(), this._hoverAsset = null, this._pinchAsset = null;
  }
  async _setup() {
    this._setupConeEntity(), this._setupCursorEntity(), await this._loadTextureAssets(), this._setupImageEntities();
  }
  async _loadTextureAssets() {
    const t = [], e = "/textures/xr/", i = this._pcApp;
    t.push(H(i, "xr-cursor-hover.png", e, "local-player", "texture")), t.push(H(i, "xr-cursor-pinch.png", e, "local-player", "texture"));
    try {
      const [n, s] = await Promise.all(t);
      this._hoverAsset = n, this._pinchAsset = s;
    } catch (n) {
      throw console.error("XrCursor: Failed to load assets", n), n;
    }
  }
  _createConeMaterial(t = !1) {
    const e = new pc.ShaderMaterial({
      uniqueName: "vrCursor",
      vertexGLSL: Xs,
      fragmentGLSL: Zs,
      attributes: {
        aPosition: pc.SEMANTIC_POSITION
      }
    });
    return e.blendType = pc.BLEND_NORMAL, e.depthTest = !0, e.setParameter("uIsBlue", t ? 1 : 0), e.update(), e;
  }
  _setupConeEntity() {
    this._cone.name = `cursor-cone-${this.node.handedness}`, this._coneMaterial = this._createConeMaterial();
    const t = new pc.Entity();
    t.addComponent("render", {
      type: "cone",
      material: this._coneMaterial
    }), t.setLocalScale(6e-3, 0.6, 6e-3), t.setLocalPosition(0, 0, -0.3), t.setLocalEulerAngles(-90, 0, 0), this._cone.addChild(t), this.node.entity.addChild(this._cone), this._cone.enabled = !1;
  }
  _setupCursorEntity() {
    this._cursor.name = `cursor-screen-${this.node.handedness}`, this._cursor.addComponent("screen", {
      screenSpace: !1,
      resolution: new pc.Vec2(1, 1),
      priority: 100
    }), this.node.entity.addChild(this._cursor), this._cursor.setLocalScale(this._cursorScaler, this._cursorScaler, this._cursorScaler), this._cursor.enabled = !1;
  }
  _setupImageEntities() {
    this._hoverAsset && (this._setupImageEntity(this._hoverImage, "hover", this._hoverAsset), this._cursor.addChild(this._hoverImage)), this._pinchAsset && (this._setupImageEntity(this._pinchImage, "pinch", this._pinchAsset), this._cursor.addChild(this._pinchImage));
  }
  _setupImageEntity(t, e, i) {
    t.name = `cursor-image-${e}-${this.node.handedness}`, t.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      anchor: [0.5, 0.5, 0.5, 0.5],
      margin: [-1, -1, -1, -1],
      width: 1,
      height: 1,
      pivot: [0.5, 0.5],
      useInput: !1,
      textureAsset: i,
      layers: [pc.LAYERID_WORLD]
    }), t.enabled = !1;
  }
  _performUiRaycast(t) {
    if (!t.elementEntity) {
      this._shouldShowCursor = !1;
      return;
    }
    const e = new pc.Ray(t.getOrigin(), t.getDirection()), i = [], n = t.elementEntity?.entity, s = n.element?.aabb ? (
      // Element has aabb -> test aabb
      n.element.aabb.intersectsRay(e, this._cursorPosition)
    ) : (
      // Element doesn't have aabb -> test children with element component & aabb
      n.findComponents("element").some((r) => {
        const o = new pc.Vec3(), l = r.aabb && r.aabb.intersectsRay(e, o);
        return l && i.push(o), l;
      })
    );
    i.length > 0 && (i.sort(
      (r, o) => r.distance(t.getOrigin()) - o.distance(t.getOrigin())
    ), this._cursorPosition = i[0]), this._shouldShowCursor = s;
  }
  _updateConeTransform(t) {
    this._coneLookAt.copy(t.getDirection()), this._coneLookAt.add(t.getOrigin()), this._cone.lookAt(this._coneLookAt), this._cone.setPosition(t.getOrigin());
  }
  _updateConeMaterialColor(t) {
    this._coneMaterial && (this._coneMaterial.setParameter("uIsBlue", t ? 1 : 0), this._coneMaterial.update());
  }
  _updateCursorScale(t) {
    const e = t.getOrigin().distance(this._cursorPosition);
    this._cursorScaler = $s * Math.pow(e, 0.6);
  }
}
class ze {
  type;
  node;
  _inputSource = null;
  _system;
  _pcApp;
  _enabled = !0;
  constructor(t, e) {
    this.node = t, this.type = e, this._system = t.module.system, this._pcApp = this._system.pcApp;
  }
  get enabled() {
    return this._enabled;
  }
  set enabled(t) {
    this._enabled = t, this.node.isLocomotionEnabled = t;
  }
  addInputSource(t) {
    this._inputSource = t;
  }
  removeInputSource() {
    this._inputSource = null;
  }
}
const Js = (
  /* glsl */
  `
uniform mat4 matrix_model;
uniform mat4 matrix_view;
uniform mat4 matrix_projection;
uniform vec3 uInitVelocity;
uniform float uGravity;
uniform float uFlightTime;

varying float vUvY;
varying float vDistToOrigin;

const int SIDED = 5;
const int SEGMENTS = 50;
const int RING_COUNT = SEGMENTS + 1;
const int VERTICES = RING_COUNT * SIDED;
const float RADIUS = 0.01;


mat3 getRotationMatrix(vec3 tangent) {
    tangent = normalize(tangent);
    vec3 binormal = normalize(cross(vec3(0.0, 1.0, 0.0), tangent));
    if (length(binormal) < 0.001) binormal = normalize(cross(vec3(1.0, 0.0, 0.0), tangent));
    vec3 normal = cross(tangent, binormal);
    return mat3(binormal, normal, tangent);
}

float getSegmentOffset(int index) {
    float base = 1.07;
    float percentage = (pow(base, float(index)) - 1.0) / (pow(base, float(SEGMENTS)) - 1.0);
    return percentage * float(SEGMENTS);
}


void main() {
    int RING_INDEX = int(floor(float(gl_VertexID / SIDED)));
    int SIDED_INDEX = gl_VertexID - (RING_INDEX * SIDED);

    float angle = floor(float(SIDED_INDEX) * (2.0 * 3.14159 / float(SIDED)) * 10000.0) / 10000.0;
    float x = round(cos(angle) * 1000.0) / 1000.0 * RADIUS;
    float y = round(sin(angle) * 1000.0) / 1000.0 * RADIUS;
    vec3 pos = vec3(x, y, 0.0);

    float offset0 = getSegmentOffset(RING_INDEX);
    float offset1 = getSegmentOffset(RING_INDEX + 1);
    float t0 = offset0 * uFlightTime;
    float t1 = offset1 * uFlightTime;

    vec3 center = vec3(0.0) + uInitVelocity * t0 + 0.5 * vec3(0.0, uGravity, 0.0) * t0 * t0;
    vec3 nextCenter = vec3(0.0) + uInitVelocity * t1 + 0.5 * vec3(0.0, uGravity, 0.0) * t1 * t1;

    vec3 tangent = normalize(nextCenter - center);
    mat3 rotateMat = getRotationMatrix(tangent);

    pos = rotateMat * pos;
    pos += center;

    gl_Position = matrix_projection * matrix_view * matrix_model * vec4(pos, 1.0);
    vUvY = offset0 / float(RING_COUNT);
    vDistToOrigin = length(pos);
}
`
), Qs = (
  /* glsl */
  `
uniform bool uIsRed;
varying float vUvY;
varying float vDistToOrigin;

float remap(float value, float inMin, float inMax, float outMin, float outMax) {
    return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
}

vec3 linearToSRGB(vec3 color) {
    return pow(color, vec3(1.0 / 2.2));
}

void main(){
    vec3 color = uIsRed ? vec3(0.96078, 0.196078, 0.196078) : vec3(0.0, 0.61569, 0.90589);
    color = mix(color, vec3(1.0), vUvY);
    color = linearToSRGB(color);

    float alpha = smoothstep(1.0, 0.5, vUvY) * smoothstep(0.005, 0.06, vDistToOrigin);
    // alpha = remap(alpha, 0.0, 1.0, 0.333, 1.0);

    gl_FragColor = vec4(color, alpha);
}
`
);
class Ks extends ze {
  _initialVelocity = 10;
  _gravity = 4.9;
  _stepLength = 0.12;
  _parabola = new pc.Entity("TeleportParabola");
  _locator = new pc.Entity("TeleportLocator");
  _locatorAsset = null;
  _parabolaMaterial = null;
  _teleportResult = null;
  _wasParabolaShown = !1;
  _yawValue = 0;
  _yawSpeed = 15;
  _isValidDebounce = 0;
  constructor(t) {
    super(t, tt.Teleport), this._setupLocator(), this._setupParabola();
  }
  update(t) {
    this.enabled && (this._locator.enabled = !1, this._executeRotation(t), !(!this._parabola || !this._parabola.enabled) && (this._performParabolaRaycast(), this._updateLocator(), this._updateParabola()));
  }
  destroy() {
    this._locator.destroy(), this._parabola.destroy();
  }
  onInputVec2Updated(t) {
    this.enabled && (t.x < -0.9 ? this._yawValue = 1 : t.x > 0.9 ? this._yawValue = -1 : this._yawValue = 0, t.y < -0.9 ? (this._parabola.enabled = !0, this._wasParabolaShown = !0) : (this._parabola.enabled = !1, this._wasParabolaShown && this._executeTeleport(), this._wasParabolaShown = !1));
  }
  async _setupLocator() {
    await this._loadTextureAsset();
    const t = new pc.Entity("TeleportLocatorImage");
    t.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      anchor: [0.5, 0.5, 0.5, 0.5],
      margin: [-1, -1, -1, -1],
      width: 1,
      height: 1,
      pivot: [0.5, 0.5],
      useInput: !1,
      layers: [pc.LAYERID_WORLD],
      textureAsset: this._locatorAsset
    }), t.setLocalScale(0.8, 0.8, 0.8), t.setLocalEulerAngles(-90, 0, 0), this._locator.addChild(t), this._system.pcApp.root.addChild(this._locator), this._locator.enabled = this._teleportResult?.isValid ?? !1;
  }
  async _loadTextureAsset() {
    try {
      this._locatorAsset = await H(
        this._pcApp,
        "xr-teleport-locator.png",
        "/textures/xr/",
        "local-player",
        "texture"
      );
    } catch (t) {
      throw console.error("HandXrInputDevice: Failed to load assets", t), t;
    }
  }
  _setupParabola() {
    const t = this._createParabolaMesh(5, 50);
    this._parabolaMaterial = this._createParabolaMaterial(this._gravity);
    const e = new pc.MeshInstance(t, this._parabolaMaterial);
    e.castShadow = !1, this._parabola.addComponent("render", {
      material: this._parabolaMaterial,
      meshInstances: [e],
      castShadows: !1
    }), this._system.pcApp.root.addChild(this._parabola), this._parabola.enabled = !1;
  }
  _createParabolaMaterial(t, e = !1) {
    const i = new pc.ShaderMaterial({
      uniqueName: "teleport",
      vertexGLSL: Js,
      fragmentGLSL: Qs,
      attributes: {
        aPosition: pc.SEMANTIC_POSITION
      }
    });
    return i.blendType = pc.BLEND_NORMAL, i.setParameter("uIsRed", e ? 1 : 0), i.setParameter("uInitVelocity", [0, 0, -this._initialVelocity]), i.setParameter("uGravity", t * -1), i.setParameter("uFlightTime", 0.3), i.cull = pc.CULLFACE_FRONT, i.update(), i;
  }
  _createParabolaMesh(t, e) {
    const i = e + 1, s = t * i, r = new Float32Array(s * 3), o = [];
    for (let c = 0; c < i; c++)
      for (let h = 0; h < t; h++) {
        const d = (c * t + h) * 3;
        r[d + 0] = 0, r[d + 1] = 0, r[d + 2] = 0;
      }
    for (let c = 0; c < e; c++)
      for (let h = 0; h < t; h++) {
        const u = c * t + h, d = (c + 1) * t + h;
        let p = c * t + (h + 1), m = (c + 1) * t + (h + 1);
        (h + 1) % t === 0 && (p = c * t, m = (c + 1) * t), o.push(u, d, m), o.push(p, u, m);
      }
    const l = new pc.Mesh(this._system.pcApp.graphicsDevice);
    return l.clear(!0, !1), l.setPositions(r), l.setIndices(o), l.update(pc.PRIMITIVE_TRIANGLES), l.aabb.halfExtents.set(2, 2, 2), l;
  }
  _performParabolaRaycast() {
    if (!this._inputSource || !this._pcApp) {
      this._teleportResult = null;
      return;
    }
    const t = this._inputSource?.getOrigin(), e = this._inputSource?.getDirection();
    let i = null, n = new pc.Vec3().copy(t), s = 1;
    for (let r = 1; r <= this._calcMaxSteps(); r++) {
      s++;
      const o = n.clone();
      if (n = this._calcRaycastEndPosition(r, t, e), i = this._pcApp?.systems?.rigidbody?.raycastFirst(o, n) || null, i) break;
    }
    if (!i) {
      this._teleportResult = {
        isValid: !1,
        steps: s,
        position: null,
        normal: null
      };
      return;
    }
    this._teleportResult = {
      isValid: this._determineIsValidGround(i),
      steps: s,
      position: i?.point ?? null,
      normal: i.normal
    };
  }
  _calcMaxSteps() {
    const t = this._pcApp?.xr?.camera?.camera?.farClip;
    return t ? Math.floor(t / this._stepLength) + 1 : 0;
  }
  _calcRaycastEndPosition(t, e, i) {
    const n = t * this._stepLength, s = new pc.Vec3(), r = new pc.Vec3().copy(i), o = new pc.Vec3().copy(pc.Vec3.DOWN).mulScalar(this._gravity);
    return s.copy(e), s.add(r.mulScalar(this._initialVelocity * n)), s.add(o.mulScalar(0.5 * n * n)), s;
  }
  _determineIsValidGround(t) {
    let e = !!t.normal;
    return e = Math.acos(pc.math.clamp(pc.Vec3.UP.dot(t.normal), -1, 1)) * pc.math.RAD_TO_DEG < 45, e ? (this._isValidDebounce++, this._isValidDebounce > 6 && (this._isValidDebounce = 6)) : (this._isValidDebounce--, this._isValidDebounce < 0 && (this._isValidDebounce = 0)), this._isValidDebounce > 0;
  }
  _updateLocator() {
    !this._teleportResult || !this._teleportResult.isValid || !this._teleportResult.position || (this._locator.setPosition(
      this._teleportResult.position.x,
      this._teleportResult.position.y + 0.01,
      this._teleportResult.position.z
    ), this._locator.enabled = !0);
  }
  _updateParabola() {
    this._updateParabolaTransform(), this._updateParabolaMaterial(1);
  }
  _updateParabolaMaterial(t) {
    if (!this._teleportResult || !this._parabolaMaterial || !this._inputSource) return;
    const { steps: e, isValid: i } = this._teleportResult, n = (e > 45 ? 45 : e - 1 + (t < 1 ? t : 1)) * this._stepLength / 50;
    this._parabolaMaterial.setParameter("uFlightTime", n), this._parabolaMaterial.setParameter("uIsRed", i ? 0 : 1);
    const s = this._inputSource.getDirection();
    this._parabolaMaterial.setParameter("uInitVelocity", [
      s.x * this._initialVelocity,
      s.y * this._initialVelocity,
      s.z * this._initialVelocity
    ]), this._parabolaMaterial.update();
  }
  _updateParabolaTransform() {
    !this._parabola || !this._inputSource?.getOrigin() || this._parabola.setPosition(this._inputSource.getOrigin());
  }
  _executeTeleport() {
    !this._teleportResult || !this._teleportResult.isValid || !this._teleportResult.position || this._system.teleport(this._teleportResult.position);
  }
  _executeRotation(t) {
    if (this._yawValue === 0) return;
    const e = this._system.store.getState().yaw + this._yawValue * this._yawSpeed * t;
    this._system.store.getState().setYaw(e);
  }
}
class tr extends ze {
  _invertInputVec2 = new pc.Vec2();
  _currentState = "default";
  _sprintThreshold = 0.7;
  constructor(t) {
    super(t, tt.Smooth);
  }
  onInputVec2Updated(t) {
    this.enabled && (t.length() <= 0.05 ? this._currentState = "default" : t.length() > this._sprintThreshold ? this._currentState = "sprint" : this._currentState = "move", !(this._invertInputVec2.x === t.x && this._invertInputVec2.y === -t.y) && (this._invertInputVec2.set(t.x, -t.y), this._system.store.getState().setInputStates({
      joystick: this._invertInputVec2.normalize(),
      sprint: this._currentState === "sprint"
    })));
  }
  update(t) {
  }
  destroy() {
  }
}
class ye {
  module;
  entity;
  handedness;
  locomotions = {};
  cursor;
  controller;
  hand;
  _pcApp;
  _inputSource = null;
  _locomotionType;
  _isLocomotionEnabled = !0;
  _currentLocomotion = null;
  _inputType = $.Controller;
  _currentDevice = null;
  _vec2Input = new pc.Vec2();
  // TODO: hide cursor when teleporting
  constructor(t, e, i) {
    this.module = t, this.handedness = e, this._locomotionType = i, this._pcApp = t.system.pcApp, this.entity = new pc.Entity(`XrInput_${e}`), this._pcApp.root.addChild(this.entity), this.cursor = new qs(this), this.controller = new Hs(this), this.hand = new Ys(this), this.controller.deactivate(), this.hand.deactivate(), this._setLocomotionByType(this.locomotionType);
  }
  set locomotionType(t) {
    this._locomotionType = t, this._setLocomotionByType(t);
  }
  get locomotionType() {
    return this._locomotionType;
  }
  set isLocomotionEnabled(t) {
    this._isLocomotionEnabled !== t && (this._isLocomotionEnabled = t, Object.values(this.locomotions).forEach((e) => {
      e.enabled = t;
    }));
  }
  get isLocomotionEnabled() {
    return this._isLocomotionEnabled;
  }
  get inputSource() {
    return this._inputSource;
  }
  activate() {
    this.entity.enabled = !0;
  }
  deactivate() {
    this.entity.enabled = !1;
  }
  destroy() {
    this.entity.destroy(), this.controller.destroy(), this.hand.destroy(), this.cursor.destroy(), this._currentDevice = null, this._inputSource = null;
  }
  update(t) {
    this._inputSource && (this._currentDevice?.update(t), this.cursor?.update(t), this._currentLocomotion?.update(t));
  }
  addInputSource(t) {
    this._inputSource = t, this._inputType = this._determineInputType(t), this._switchInputDeviceByType(this._inputType), this._currentDevice?.addInputSource(t), this.cursor?.addInputSource(t), this._currentLocomotion?.addInputSource(t);
  }
  removeInputSource() {
    this._currentDevice && this._currentDevice.removeInputSource(), this.cursor && this.cursor.removeInputSource(), this._inputSource = null;
  }
  setInputVec2(t, e) {
    this._vec2Input.set(t, e), this._currentLocomotion?.onInputVec2Updated(this._vec2Input);
  }
  _setLocomotionByType(t) {
    if (this.locomotions[t]) {
      this._currentLocomotion = this.locomotions[t], this._inputSource && this._currentLocomotion.addInputSource(this._inputSource);
      return;
    }
    let e = null;
    t === tt.Teleport ? e = new Ks(this) : t === tt.Smooth && (e = new tr(this)), e && (this.locomotions[t] = e, this._currentLocomotion = e, this._inputSource && this._currentLocomotion.addInputSource(this._inputSource));
  }
  _determineInputType(t) {
    const e = !!t.grip, i = !!t.hand;
    return e && i ? $.Controller : e ? $.Controller : i ? $.Hand : $.Controller;
  }
  _switchInputDeviceByType(t) {
    const e = t === $.Controller ? this.controller : this.hand;
    this._currentDevice !== e && (this._currentDevice && (this._currentDevice.deactivate(), this._inputSource && this._currentDevice.removeInputSource()), this._currentDevice = e, this._currentDevice && (this._currentDevice.activate(), this._inputSource && this._currentDevice.addInputSource(this._inputSource)));
  }
}
class er {
  type = Ii.Head;
  handler;
  entity;
  _pcApp;
  _cameraEntity;
  _cameraYawForward = new pc.Vec3();
  _cameraYawRotation = new pc.Quat();
  targetPosition = new pc.Vec3();
  targetRotation = new pc.Quat();
  currentPos = new pc.Vec3();
  currentRot = new pc.Quat();
  positionThreshold = 0.7;
  rotationThreshold = 0.5;
  lerpAlpha = 0.1;
  constructor(t) {
    this.handler = t, this.entity = new pc.Entity("HeadXrUiAnchor"), this._pcApp = t.module.pcApp, this._cameraEntity = t.module.cameraEntity, this._pcApp.root.addChild(this.entity);
  }
  activate() {
    if (this._cameraEntity = this.handler.module.cameraEntity, !this._cameraEntity) {
      console.warn("Camera entity not found, HeadXrUiAnchor cannot activate");
      return;
    }
    this.currentPos.copy(this._cameraEntity.getPosition()), this.currentRot.copy(this._cameraEntity.getRotation());
  }
  deactivate() {
    this._cameraEntity = null;
  }
  update(t) {
    this.handler.module.isXrActive && (this._updatePosition(), this._updateRotation());
  }
  destroy() {
    this.entity.destroy(), this._cameraEntity = null;
  }
  _updatePosition() {
    if (!this._cameraEntity) return;
    const t = this._cameraEntity.getPosition();
    !this.targetPosition.equalsApprox(t, this.positionThreshold) && this.targetPosition.copy(t), this.currentPos.lerp(this.currentPos, this.targetPosition, this.lerpAlpha), this.entity.setPosition(this.currentPos);
  }
  _updateRotation() {
    if (!this._cameraEntity) return;
    this._updateCameraYawRotation(), !this.targetRotation.equalsApprox(
      this._cameraYawRotation,
      this.rotationThreshold
    ) && this.targetRotation.copy(this._cameraYawRotation), this.currentRot.slerp(this.currentRot, this.targetRotation, this.lerpAlpha), this.entity.setRotation(this.currentRot);
  }
  _updateCameraYawRotation() {
    this._cameraEntity && (this._cameraYawForward.copy(this._cameraEntity.forward), this._cameraYawForward.y = 0, this._cameraYawForward.normalize(), this._cameraYawRotation.setFromDirections(pc.Vec3.FORWARD, this._cameraYawForward));
  }
}
class ir {
  name = "overhead-bar";
  handler;
  entity;
  anchorEntity;
  _pcApp;
  _endButton = null;
  _endButtonAsset = null;
  _fontAsset = null;
  _iconSize = 36;
  _fontSize = 12;
  _blueTint = new pc.Color().fromString("#009DE7");
  _fontColor = new pc.Color().fromString("#D5E2F2");
  constructor(t, e) {
    this.handler = t, this._pcApp = t.module.pcApp, this.entity = new pc.Entity("OverheadXrUi"), this.anchorEntity = e, this._setupScreen(), this._setupEndButton();
  }
  activate() {
    this.entity.enabled = !0;
  }
  deactivate() {
    this.entity.enabled = !1;
  }
  destroy() {
    this.entity.destroy(), this._endButtonAsset = null;
  }
  _setupScreen() {
    this.entity.addComponent("screen", {
      referenceResolution: new pc.Vec2(1, 1),
      screenSpace: !1
    }), this.entity.setLocalScale(0.01, 0.01, 0.01);
    const t = 2.5;
    this.entity.setLocalPosition(0, t * Math.sqrt(3), -t), this.entity.setLocalEulerAngles(60, 0, 0), this.anchorEntity.addChild(this.entity);
  }
  async _setupEndButton() {
    await this._loadAssets(), !(!this._endButtonAsset || !this._fontAsset) && (this._endButton = this._createButton(
      "End",
      "EXIT",
      this._endButtonAsset,
      this._onEndButtonClick
    ), this.entity.addChild(this._endButton), this.entity.enabled = !!this.handler.module.isXrActive);
  }
  async _loadAssets() {
    try {
      await Promise.all([this._loadTextureAsset(), this._loadFontsAsset()]);
    } catch (t) {
      throw console.error("OverheadXrUi: Failed to load assets", t), t;
    }
  }
  async _loadTextureAsset() {
    this._endButtonAsset = await H(
      this._pcApp,
      "xr-end-button.png",
      "/textures/xr/",
      "local-player",
      "texture"
    );
  }
  async _loadFontsAsset() {
    this._fontAsset = await Ti(this._pcApp, "roboto-medium", "/fonts/", "local-player");
  }
  _createButton(t, e, i, n) {
    const s = new pc.Entity(`Xr${t}Button`), r = new pc.Entity(`Xr${t}ButtonText`);
    return s.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      textureAsset: i,
      width: this._iconSize,
      height: this._iconSize,
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      useInput: !0,
      layers: [pc.LAYERID_WORLD]
    }), s.addComponent("button", {
      hoverTint: this._blueTint,
      inactiveTint: this._blueTint,
      pressedTint: this._blueTint,
      transitionMode: pc.BUTTON_TRANSITION_MODE_TINT,
      imageEntity: s
    }), r.addComponent("element", {
      type: pc.ELEMENTTYPE_TEXT,
      text: e,
      fontSize: this._fontSize,
      fontAsset: this._fontAsset,
      color: this._fontColor,
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      alignment: [0.5, 0.5],
      autoWidth: !0,
      autoHeight: !0,
      useInput: !0,
      layers: [pc.LAYERID_WORLD]
    }), s.addChild(r), r.setLocalPosition(0, -(this._iconSize / 2 + this._fontSize), 0), s.button.on("click", n, this), s;
  }
  _onEndButtonClick() {
    this.handler.module.end();
  }
}
class nr {
  module;
  // TODO: Add more anchors and components as needed as the UI expands
  // readonly anchors: { [key: string]: IXrUiAnchor } = {}; --- IGNORE ---
  // readonly components: { [key: string]: IXrUiComponent } = {}; --- IGNORE ---
  _headAnchor;
  _overheadBar;
  constructor(t) {
    this.module = t, this._headAnchor = new er(this), this._overheadBar = new ir(this, this._headAnchor.entity);
  }
  activate() {
    this._overheadBar.activate(), this._headAnchor.activate();
  }
  deactivate() {
    this._overheadBar.deactivate(), this._headAnchor.deactivate();
  }
  update(t) {
    this._headAnchor.update(t);
  }
  destroy() {
    this._overheadBar.destroy(), this._headAnchor.destroy();
  }
}
class wr extends pt {
  static moduleName = q.Xr;
  _handedNodes = null;
  _cameraEntity = null;
  _isXrActive = !1;
  _uiHandler = null;
  _isInitialized = !1;
  _options;
  _unsubscribeVrSupport;
  constructor(t, e) {
    super(t), this._options = {
      ...this._getDefaultOptions(),
      ...e
    };
    const i = this.viverseApp.context.capability;
    this._unsubscribeVrSupport = i.subscribe(
      (n) => n.isVrSupported,
      (n) => {
        n && !this._isInitialized && this._initializeXrComponents();
      }
    );
  }
  get handedNodes() {
    return this._handedNodes;
  }
  _initializeXrComponents() {
    if (this._isInitialized) return;
    const { locomotionType: t } = this._options, e = t?.left || tt.Teleport, i = t?.right || tt.Teleport;
    this._handedNodes = {
      left: new ye(this, pc.XRHAND_LEFT, e),
      right: new ye(this, pc.XRHAND_RIGHT, i)
    }, this._uiHandler = new nr(this), this._setupEventListeners(), this._isInitialized = !0, this.system.emit("xr:initialized");
  }
  get cameraEntity() {
    return this._cameraEntity;
  }
  get isXrActive() {
    return this._isXrActive;
  }
  start(t) {
    const e = this.system.modules.camera;
    if (!e) {
      E.error(
        "Camera module is not available, please use startWithEntity() method instead."
      );
      return;
    }
    const i = e.prepareXrCamera(t);
    i && this._startXrSession(i.entity);
  }
  startWithCameraEntity(t) {
    if (this.system.modules.camera) {
      E.error("Camera module is available, please use start() method instead.");
      return;
    }
    if (!t) {
      E.error("Camera entity is not provided.");
      return;
    }
    this._startXrSession(t);
  }
  end() {
    this.system.pcApp.xr?.end();
  }
  update(t) {
    this._isXrActive && (this.handedNodes?.left?.update(t), this.handedNodes?.right?.update(t), this._uiHandler?.update(t));
  }
  destroy() {
    this._unsubscribeVrSupport(), this.system.pcApp && (this.pcApp.xr?.off("start", this._onXrStart, this), this.pcApp.xr?.off("end", this._onXrEnd, this), this.pcApp.xr?.input.off("add", this._addInputSource, this), this.pcApp.xr?.input.off("remove", this._removeInputSource, this)), this.handedNodes?.left?.destroy(), this.handedNodes?.right?.destroy(), this._uiHandler?.destroy();
  }
  enableHandLocomotion(t) {
    this._toggleHandLocomotion(t, !0);
  }
  disableHandLocomotion(t) {
    this._toggleHandLocomotion(t, !1);
  }
  _getDefaultOptions() {
    return Ps;
  }
  _setupEventListeners() {
    !this.pcApp || !this.pcApp.xr || (this.pcApp.xr.active && this._onXrStart(), this.pcApp.xr.on("start", this._onXrStart, this), this.pcApp.xr.on("end", this._onXrEnd, this), this.pcApp.xr.input.on("add", this._addInputSource, this), this.pcApp.xr.input.on("remove", this._removeInputSource, this));
  }
  _startXrSession(t) {
    const e = "immersive-vr";
    if (!this.system.pcApp || !this.system.pcApp.xr || !this.system.pcApp.xr.isAvailable(e)) {
      E.warn("XR is not available.");
      return;
    }
    this._cameraEntity = t;
    const i = this._cameraEntity.camera;
    i ? this.system.pcApp.xr.start(i, e, "local") : E.error("The XR camera entity does not have a camera component. XR start aborted.");
  }
  _onXrStart() {
    !this.pcApp || !this.pcApp.xr || (this._isXrActive = !0, this.system.store.getState().setIsXrActive(!0), this.handedNodes?.left?.activate(), this.handedNodes?.right?.activate(), this._uiHandler?.activate());
  }
  _onXrEnd() {
    this._isXrActive = !1, this.system.store.getState().setIsXrActive(!1), this.handedNodes?.left?.deactivate(), this.handedNodes?.right?.deactivate(), this._uiHandler?.deactivate();
    const t = this.system.modules.camera;
    t && t.restorePreviousCamera(), this._cameraEntity = null;
  }
  _addInputSource(t) {
    const e = () => {
      t.handedness === pc.XRHAND_LEFT ? this.handedNodes?.left?.addInputSource(t) : t.handedness === pc.XRHAND_RIGHT && this.handedNodes?.right?.addInputSource(t);
    };
    t.handedness ? e() : setTimeout(e, 50);
  }
  _removeInputSource(t) {
    t.handedness === pc.XRHAND_LEFT ? this.handedNodes?.left?.removeInputSource() : t.handedness === pc.XRHAND_RIGHT && this.handedNodes?.right?.removeInputSource();
  }
  _toggleHandLocomotion(t, e) {
    const i = this.handedNodes?.[t];
    i && (i.isLocomotionEnabled = e);
  }
}
class sr {
  _viverseApp;
  _isShown = !1;
  _isEnabled = !1;
  _triggerEntity = null;
  _triggerIconEntity = null;
  _onClick;
  _cameraEntity = null;
  constructor(t, e) {
    this._viverseApp = t, this._onClick = e, this._createButton();
  }
  setEnable(t) {
    this._isEnabled = t, this._updateVisibility();
  }
  setShown(t) {
    this._isShown = t, this._updateVisibility();
  }
  restore() {
    this._triggerEntity?.script || this._createButton();
  }
  _updateVisibility() {
    const t = this._isEnabled && this._isShown;
    this._triggerIconEntity && (this._triggerIconEntity.enabled = t);
  }
  updatePosition(t) {
    if (!this._triggerEntity) return;
    this._triggerEntity.getPosition().equalsApprox(t) || this._triggerEntity.setPosition(t);
  }
  async _createButton() {
    const t = await H(
      this._viverseApp.pcApp,
      "pick.png",
      "/textures/interaction/",
      "local-player",
      "texture"
    );
    if (this._triggerEntity = new pc.Entity("TriggerEntity"), this._triggerEntity.setLocalScale(0.5, 0.5, 0.5), this._triggerIconEntity = new pc.Entity("TriggerIconEntity"), this._triggerIconEntity.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      pivot: [0.5, 0.5],
      anchor: [0.5, 0.5, 0.5, 0.5],
      width: 0.5,
      height: 0.5,
      layers: [pc.LAYERID_WORLD],
      textureAsset: t,
      useInput: !0
    }), this._triggerIconEntity.addComponent("button", {
      active: !0,
      useInput: !0,
      imageEntity: this._triggerIconEntity,
      hitPadding: new pc.Vec4(0, 0, 0, 0)
    }), this._triggerIconEntity.setLocalPosition(0, 1, 0), this._triggerEntity.addChild(this._triggerIconEntity), this._viverseApp.deviceInfo.hardware === "desktop") {
      const s = await this._createTriggerText();
      this._triggerIconEntity.addChild(s);
    }
    const n = this._viverseApp.systems.localPlayer?.modules.camera?.currentCamera;
    n && (this._cameraEntity = n.entity), this._triggerEntity.addComponent("script"), this._triggerEntity.script && this._triggerEntity.script.create(Ot, {
      properties: {
        ...n && { targetEntity: n.entity },
        rotateLocal: new pc.Vec3(0, 180, 0)
      }
    }), this._bindIconEvents(), this._updateVisibility(), this._viverseApp.pcApp.root.addChild(this._triggerEntity);
  }
  async _createTriggerText() {
    const t = await H(
      this._viverseApp.pcApp,
      "pick-hotkey.png",
      "/textures/interaction/",
      "local-player",
      "texture"
    ), e = new pc.Entity("TriggerTextEntity");
    return e.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      color: new pc.Color(1, 1, 1, 1),
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      width: 1,
      height: 0.5,
      layers: [pc.LAYERID_WORLD],
      useInput: !1,
      textureAsset: t
    }), e.setLocalPosition(0, -0.5, 0), e.setLocalScale(0.5, 0.5, 0.5), e;
  }
  _bindIconEvents() {
    this._triggerIconEntity?.button && this._triggerIconEntity.button.on("click", this._onClick, this);
    const t = this._viverseApp.systems.localPlayer;
    t && (t.on("camera:changed", this._cameraChanged, this), t.on("camera:entity-replaced", this._cameraReplaced, this));
  }
  _unbindIconEvents() {
    this._triggerIconEntity?.button && this._triggerIconEntity.button.off("click", this._onClick, this);
    const t = this._viverseApp.systems.localPlayer;
    t && (t.off("camera:changed", this._cameraChanged, this), t.off("camera:entity-replaced", this._cameraReplaced, this));
  }
  _cameraChanged = ({ newCamera: t }) => {
    this._cameraEntity = t?.entity, this._triggerEntity?.fire("billboard:set-target", t?.entity);
  };
  _cameraReplaced({
    previousEntity: t,
    camera: e
  }) {
    t === this._cameraEntity && (this._cameraEntity = e.entity, this._triggerEntity?.fire("billboard:set-target", e.entity));
  }
  destroy() {
    this._unbindIconEvents(), this._triggerIconEntity && (this._triggerIconEntity.destroy(), this._triggerIconEntity = null), this._triggerEntity && (this._triggerEntity.destroy(), this._triggerEntity = null);
  }
}
class rr {
  _viverseApp;
  _collisionEntity = null;
  _rangeHalfExtents;
  _onTriggerEnter;
  _onTriggerLeave;
  constructor(t, e, i, n) {
    this._viverseApp = t, this._rangeHalfExtents = e, this._onTriggerEnter = i, this._onTriggerLeave = n, this._createCollisionEntity();
  }
  setEnable(t) {
    this._collisionEntity && (this._collisionEntity.enabled = t);
  }
  updatePosition(t) {
    if (!this._collisionEntity) return;
    const e = t;
    this._collisionEntity.getPosition().equalsApprox(e) || this._collisionEntity.setPosition(e);
  }
  restore() {
    this._collisionEntity?.collision || this._createCollisionEntity();
  }
  _createCollisionEntity() {
    this._collisionEntity = new pc.Entity("PickCollisionDetector"), this._collisionEntity.addComponent("collision", {
      type: "box",
      halfExtents: this._rangeHalfExtents,
      trigger: !0
    }), this._viverseApp.pcApp.root.addChild(this._collisionEntity), this._collisionEntity.collision?.on("triggerenter", this._onTriggerEnter), this._collisionEntity.collision?.on("triggerleave", this._onTriggerLeave);
  }
  destroy() {
    this._collisionEntity && (this._collisionEntity.collision?.off("triggerenter", this._onTriggerEnter), this._collisionEntity.collision?.off("triggerleave", this._onTriggerLeave), this._collisionEntity.destroy(), this._collisionEntity = null);
  }
}
class Ge {
  _viverseApp;
  _isActionExecuting = !1;
  _duration = 500;
  // in milliseconds
  _stateName;
  _animationFileName;
  constructor(t, e, i) {
    this._viverseApp = t, this._stateName = e, this._animationFileName = i;
  }
  get duration() {
    return this._duration;
  }
  set duration(t) {
    this._duration = t;
  }
  execute() {
    this._isActionExecuting || (this._isActionExecuting = !0, this._loadAnimationAsset().then((t) => this._playSwingAnimation(t)), this._viverseApp.emit("interaction:pick-action-executing", this, !0), setTimeout(() => {
      this._isActionExecuting = !1, this._viverseApp.emit("interaction:pick-action-executing", this, !1);
    }, this._duration));
  }
  async _playSwingAnimation(t) {
    const i = this._viverseApp.systems.localPlayer?.modules.localAvatar, n = i?.activeAvatar;
    if (!n) return;
    (n.customAnimationStates || []).includes(this._stateName) || await i.loadCustomAnimation(this._stateName, t, { loop: !1, isVrma: !0 }), i.playCustomAnimation(this._stateName, {
      canBeInterrupted: !0,
      exitOnAnimationEnd: !0
    });
  }
  async _loadAnimationAsset() {
    return H(
      this._viverseApp.pcApp,
      this._animationFileName,
      "/animations/",
      "local-player",
      "container"
    );
  }
}
class or extends Ge {
  constructor(t) {
    super(t, "swing-a", "action-a.vrma");
  }
}
class ar extends Ge {
  constructor(t) {
    super(t, "swing-b", "action-b.vrma");
  }
}
var Nt = { exports: {} }, ve;
function lr() {
  return ve || (ve = 1, (function(a) {
    var t = Object.prototype.hasOwnProperty, e = "~";
    function i() {
    }
    Object.create && (i.prototype = /* @__PURE__ */ Object.create(null), new i().__proto__ || (e = !1));
    function n(l, c, h) {
      this.fn = l, this.context = c, this.once = h || !1;
    }
    function s(l, c, h, u, d) {
      if (typeof h != "function")
        throw new TypeError("The listener must be a function");
      var p = new n(h, u || l, d), m = e ? e + c : c;
      return l._events[m] ? l._events[m].fn ? l._events[m] = [l._events[m], p] : l._events[m].push(p) : (l._events[m] = p, l._eventsCount++), l;
    }
    function r(l, c) {
      --l._eventsCount === 0 ? l._events = new i() : delete l._events[c];
    }
    function o() {
      this._events = new i(), this._eventsCount = 0;
    }
    o.prototype.eventNames = function() {
      var c = [], h, u;
      if (this._eventsCount === 0) return c;
      for (u in h = this._events)
        t.call(h, u) && c.push(e ? u.slice(1) : u);
      return Object.getOwnPropertySymbols ? c.concat(Object.getOwnPropertySymbols(h)) : c;
    }, o.prototype.listeners = function(c) {
      var h = e ? e + c : c, u = this._events[h];
      if (!u) return [];
      if (u.fn) return [u.fn];
      for (var d = 0, p = u.length, m = new Array(p); d < p; d++)
        m[d] = u[d].fn;
      return m;
    }, o.prototype.listenerCount = function(c) {
      var h = e ? e + c : c, u = this._events[h];
      return u ? u.fn ? 1 : u.length : 0;
    }, o.prototype.emit = function(c, h, u, d, p, m) {
      var f = e ? e + c : c;
      if (!this._events[f]) return !1;
      var _ = this._events[f], g = arguments.length, v, y;
      if (_.fn) {
        switch (_.once && this.removeListener(c, _.fn, void 0, !0), g) {
          case 1:
            return _.fn.call(_.context), !0;
          case 2:
            return _.fn.call(_.context, h), !0;
          case 3:
            return _.fn.call(_.context, h, u), !0;
          case 4:
            return _.fn.call(_.context, h, u, d), !0;
          case 5:
            return _.fn.call(_.context, h, u, d, p), !0;
          case 6:
            return _.fn.call(_.context, h, u, d, p, m), !0;
        }
        for (y = 1, v = new Array(g - 1); y < g; y++)
          v[y - 1] = arguments[y];
        _.fn.apply(_.context, v);
      } else {
        var T = _.length, A;
        for (y = 0; y < T; y++)
          switch (_[y].once && this.removeListener(c, _[y].fn, void 0, !0), g) {
            case 1:
              _[y].fn.call(_[y].context);
              break;
            case 2:
              _[y].fn.call(_[y].context, h);
              break;
            case 3:
              _[y].fn.call(_[y].context, h, u);
              break;
            case 4:
              _[y].fn.call(_[y].context, h, u, d);
              break;
            default:
              if (!v) for (A = 1, v = new Array(g - 1); A < g; A++)
                v[A - 1] = arguments[A];
              _[y].fn.apply(_[y].context, v);
          }
      }
      return !0;
    }, o.prototype.on = function(c, h, u) {
      return s(this, c, h, u, !1);
    }, o.prototype.once = function(c, h, u) {
      return s(this, c, h, u, !0);
    }, o.prototype.removeListener = function(c, h, u, d) {
      var p = e ? e + c : c;
      if (!this._events[p]) return this;
      if (!h)
        return r(this, p), this;
      var m = this._events[p];
      if (m.fn)
        m.fn === h && (!d || m.once) && (!u || m.context === u) && r(this, p);
      else {
        for (var f = 0, _ = [], g = m.length; f < g; f++)
          (m[f].fn !== h || d && !m[f].once || u && m[f].context !== u) && _.push(m[f]);
        _.length ? this._events[p] = _.length === 1 ? _[0] : _ : r(this, p);
      }
      return this;
    }, o.prototype.removeAllListeners = function(c) {
      var h;
      return c ? (h = e ? e + c : c, this._events[h] && r(this, h)) : (this._events = new i(), this._eventsCount = 0), this;
    }, o.prototype.off = o.prototype.removeListener, o.prototype.addListener = o.prototype.on, o.prefixed = e, o.EventEmitter = o, a.exports = o;
  })(Nt)), Nt.exports;
}
var cr = lr();
const hr = /* @__PURE__ */ Ci(cr);
class We extends hr {
  entity;
  name;
  constructor(t, e) {
    super(), this.name = t, this.entity = e;
  }
  // Called after subclass construction is complete.
  // This ensures all subclass properties are initialized before binding events.
  _initializeEventBindings() {
    this._bindEntityEvents();
  }
  _bindEntityEvents() {
    this._updateEnabledState(), this.entity.on("state:changed", this._updateEnabledState, this), this.entity.on("insert", this._updateEnabledState, this), this.entity.on("inserthierarchy", this._updateEnabledState, this), this.entity.on("remove", this._updateEnabledState, this), this.entity.on("removehierarchy", this._updateEnabledState, this), this.entity.on("destroy", this._onDestroyed, this), this.entity.script || this.entity.addComponent("script"), this.entity.script.create(Kt);
  }
  _unbindEntityEvents() {
    this.entity.script && this.entity.script.destroy(Kt.scriptName), this.entity.off("state:changed", this._updateEnabledState, this), this.entity.off("insert", this._updateEnabledState, this), this.entity.off("inserthierarchy", this._updateEnabledState, this), this.entity.off("remove", this._updateEnabledState, this), this.entity.off("removehierarchy", this._updateEnabledState, this), this.entity.off("destroy", this._onDestroyed, this);
  }
  destroy() {
    this._unbindEntityEvents(), this.removeAllListeners();
  }
}
class ur extends We {
  _viverseApp;
  _system;
  _outline = null;
  _playerEntity = null;
  _gripPointEntity;
  _button;
  _collisionDetector;
  _rangeHalfExtents;
  _originalRotation;
  _rigidBodyEnabledStates = /* @__PURE__ */ new Map();
  _isPicked = !1;
  _isPlayerInRange = !1;
  _isNearest = !1;
  _actionA;
  _actionB;
  constructor(t, e, i, n) {
    super(e, i), this._system = t;
    const s = this._viverseApp = t.viverseApp;
    this._button = new sr(s, this._onPickClick.bind(this)), this._rangeHalfExtents = n?.rangeHalfExtents || new pc.Vec3(1, 1, 1), this._gripPointEntity = n?.gripPoint || this._setupGripPoint(), this._actionA = n?.actionA ?? new or(s), this._actionB = n?.actionB ?? new ar(s), this._originalRotation = i.getRotation().clone();
    const r = this._system.modules.camera;
    this._outline = r?.outline || null, this._collisionDetector = new rr(
      s,
      this._rangeHalfExtents,
      this._onTriggerEnter.bind(this),
      this._onTriggerLeave.bind(this)
    ), this._initializeEventBindings(), _t(s).then((o) => this._setup(o));
  }
  get isPicked() {
    return this._isPicked;
  }
  get isPlayerInRange() {
    return this._isPlayerInRange;
  }
  get isNearest() {
    return this._isNearest;
  }
  set isNearest(t) {
    this._isNearest = t;
  }
  _updateEnabledState() {
    const t = this.entity.enabled && !this._isPicked;
    this._collisionDetector.setEnable(t), this._button.setEnable(t);
  }
  _onDestroyed() {
    this.emit("pickable-item:destroyed", this);
  }
  _onTriggerEnter = (t) => {
    !this._playerEntity || this._isPicked || t === this._playerEntity && (this._isPlayerInRange = !0, this.emit("pickable-item:enter-range", this));
  };
  _onTriggerLeave = (t) => {
    !this._playerEntity || this._isPicked || t === this._playerEntity && (this._isPlayerInRange = !1, this.emit("pickable-item:leave-range", this));
  };
  _setupGripPoint() {
    const t = new pc.Entity("GripPoint");
    return this.entity.addChild(t), t;
  }
  _setup(t) {
    this._playerEntity = t;
  }
  updateDisplay() {
    const e = [
      { condition: this._isPicked, outline: "none", buttonShown: !1 },
      { condition: this._isNearest, outline: "orange", buttonShown: !0 },
      { condition: this._isPlayerInRange, outline: "white", buttonShown: !1 }
    ].find((i) => i.condition) ?? { outline: "none", buttonShown: !1 };
    this._setOutline(e.outline), this._button.setShown(e.buttonShown);
  }
  _setOutline(t) {
    this._outline && (t === "white" ? this._outline.addEntity("white", this.entity) : t === "orange" ? this._outline.addEntity("orange", this.entity) : this._outline.removeEntity(this.entity));
  }
  pick(t) {
    this._isPicked || (this._isPicked = !0, this._updateEnabledState(), this.updateDisplay(), this._reparentToHand(t));
  }
  drop(t) {
    this._isPicked && (this._isPicked = !1, this._updateEnabledState(), this.updateDisplay(), this._restoreResource(), this._placeInFront(t));
  }
  reattach(t) {
    this._reparentToHand(t);
  }
  reparentToHand(t) {
    this._reparentToHand(t);
  }
  placeInFront(t) {
    this._placeInFront(t);
  }
  executeActionA() {
    this._actionA.execute();
  }
  executeActionB() {
    this._actionB.execute();
  }
  _restoreResource() {
    this._button.restore(), this._collisionDetector.restore();
  }
  _onPickClick() {
    this.emit("pickable-item:attempt-pick", this);
  }
  _reparentToHand(t) {
    const e = this.entity;
    e.reparent(t);
    const i = this._gripPointEntity.getLocalRotation();
    e.setLocalRotation(i);
    const n = t.getPosition().clone(), s = this._gripPointEntity.getPosition().clone(), r = n.clone().sub(s), o = e.getPosition().clone().add(r), l = new pc.Mat4().copy(t.getWorldTransform()).invert(), c = new pc.Vec3();
    l.transformPoint(o, c), e.setLocalPosition(c.x + 0.1, c.y, c.z), this.entity.findComponents("rigidbody").forEach((u) => {
      this._rigidBodyEnabledStates.set(u, u.enabled), u.enabled = !1;
    });
  }
  _placeInFront(t) {
    const e = this.entity, i = t.getPosition(), n = t.forward, s = 1, r = new pc.Vec3(
      i.x + n.x * s,
      i.y + 0.5,
      i.z + n.z * s
    );
    e.reparent(this._viverseApp.pcApp.root), e.setPosition(r), e.setRotation(this._originalRotation), this._rigidBodyEnabledStates.forEach((o, l) => {
      l.enabled = o, l.linearVelocity = pc.Vec3.ZERO, l.angularVelocity = pc.Vec3.ZERO;
    }), this._rigidBodyEnabledStates.clear();
  }
  update() {
    const t = this.entity.getPosition();
    this._button.updatePosition(t), this._collisionDetector.updatePosition(t);
  }
  destroy() {
    this._setOutline("none"), this._button.destroy(), this._collisionDetector.destroy(), this._unbindEntityEvents();
  }
}
const dr = [
  { name: "white", color: new pc.Color(1, 1, 1, 0.8), outlineWidth: 3 },
  { name: "orange", color: new pc.Color(1, 0.5, 0, 0.8), outlineWidth: 3 }
];
class pr {
  _viverseApp;
  _system;
  _playerEntity = null;
  _fallbackGripBone = null;
  _isActionExecuting = !1;
  _isSitting = !1;
  _pickableItems = /* @__PURE__ */ new Map();
  _inRangeItems = /* @__PURE__ */ new Set();
  _currentNearestItem = null;
  _currentPickedItem = null;
  constructor(t) {
    this._viverseApp = t.viverseApp, this._system = t, _t(t.viverseApp).then((e) => this._playerEntity = e), this._bindEvents(), this._initializeOutlines();
  }
  get isActionExecuting() {
    return this._isActionExecuting;
  }
  get currentPickedItem() {
    return this._currentPickedItem;
  }
  get _canInteract() {
    return !this._isActionExecuting && !this._isSitting;
  }
  addItem(t, e, i) {
    this._validateItemName(t), this._validateGripPoint(e, i?.gripPoint);
    const { itemEntity: n, gripPoint: s } = this._preparePickableEntity(e, i?.gripPoint), r = { ...i, gripPoint: s }, o = new ur(this._system, t, n, r);
    return this._pickableItems.set(o.name, o), this._registerItemEvents(o), o;
  }
  removeItem(t) {
    const e = Array.from(this._pickableItems).find(
      ([n, s]) => s.entity === t || n === t
    ), [, i] = e || [];
    i && (i === this._currentPickedItem && this._dropItem(), this._unregisterItemEvents(i), this._pickableItems.delete(i.name), this._inRangeItems.delete(i), this._updateAllItemsState(), i.destroy());
  }
  getItem(t) {
    return this._pickableItems.get(t);
  }
  _bindEvents() {
    this._system.on("input:pick-nearest-item", this._onItemAttemptPick, this), this._system.on("input:action-a", this._onActionA, this), this._system.on("input:action-b", this._onActionB, this), this._system.on("local-avatar:before-change", this._beforeAvatarChange, this), this._system.on("local-avatar:changed", this._onAvatarChanged, this), this._viverseApp.on("interaction:pick-action-executing", this._onPickActionExecuting, this), this._viverseApp.on("interaction:sitting", this._onSitting, this), this._viverseApp.on("interaction-network:pickable-item-acquired", this._handleAcquired, this), this._viverseApp.on("interaction-network:pickable-item-released", this._handleReleased, this);
  }
  _unbindEvents() {
    this._system.off("input:pick-nearest-item", this._onItemAttemptPick, this), this._system.off("input:action-a", this._onActionA, this), this._system.off("input:action-b", this._onActionB, this), this._system.off("local-avatar:before-change", this._beforeAvatarChange, this), this._system.off("local-avatar:changed", this._onAvatarChanged, this), this._viverseApp.off("interaction:pick-action-executing", this._onPickActionExecuting, this), this._viverseApp.off("interaction:sitting", this._onSitting, this), this._viverseApp.off("interaction-network:pickable-item-acquired", this._handleAcquired, this), this._viverseApp.off("interaction-network:pickable-item-released", this._handleReleased, this);
  }
  _beforeAvatarChange() {
    const t = this._currentPickedItem?.entity;
    t && t.remove();
  }
  _onAvatarChanged() {
    if (!this._currentPickedItem) return;
    const t = this._getLocalGripBone();
    t && this._currentPickedItem.reattach(t);
  }
  _validateItemName(t) {
    if (this._pickableItems.has(t))
      throw new Error(`Pickable item with name "${t}" already exists.`);
  }
  _validateGripPoint(t, e) {
    if (!e) return;
    if (!t.findByGuid(e.getGuid()))
      throw new Error("Grip point entity is not a child of the picked item entity.");
  }
  _registerItemEvents(t) {
    t.on("pickable-item:enter-range", this._onItemEnterRange, this), t.on("pickable-item:leave-range", this._onItemLeaveRange, this), t.on("pickable-item:attempt-pick", this._onItemAttemptPick, this), t.on("pickable-item:destroyed", this._onItemDestroyed, this);
  }
  _unregisterItemEvents(t) {
    t.off("pickable-item:enter-range", this._onItemEnterRange, this), t.off("pickable-item:leave-range", this._onItemLeaveRange, this), t.off("pickable-item:attempt-pick", this._onItemAttemptPick, this), t.off("pickable-item:destroyed", this._onItemDestroyed, this);
  }
  cloneEntityFromScene(t, e, i) {
    const n = "pickable-grip-point";
    e && e.tags.add(n);
    const s = t.clone(), r = s.findByTag(n)[0];
    return r && r.tags.remove(n), i && i(s), (t.parent || this._viverseApp.pcApp.scene.root).addChild(s), t.enabled = !1, { itemEntity: s, gripPoint: r };
  }
  _needCloneEntityFromScene(t) {
    const e = this._viverseApp.pcApp, n = !!e.scene.root?.findByGuid(t.getGuid());
    return e.scenes.list().length > 1 && n;
  }
  _preparePickableEntity(t, e) {
    return this._needCloneEntityFromScene(t) ? this.cloneEntityFromScene(t, e) : { itemEntity: t, gripPoint: e };
  }
  _initializeOutlines() {
    const t = this._system.modules.camera;
    dr.forEach((e) => {
      t && t.outline.createChannel(e);
    });
  }
  _onItemEnterRange(t) {
    this._inRangeItems.add(t), this._updateAllItemsState();
  }
  _onItemLeaveRange(t) {
    this._inRangeItems.delete(t), this._updateAllItemsState();
  }
  _onItemAttemptPick(t) {
    if (!this._canInteract) return;
    this._dropItem();
    const e = t || this._currentNearestItem;
    e && this._pickItem(e), this._updateAllItemsState();
  }
  _onItemDestroyed(t) {
    this.removeItem(t.entity);
  }
  _onPickActionExecuting(t, e) {
    this._isActionExecuting = e;
  }
  _onSitting(t) {
    this._isSitting = t;
  }
  _onActionA() {
    this._canInteract && this._currentPickedItem?.executeActionA();
  }
  _onActionB() {
    this._canInteract && this._currentPickedItem?.executeActionB();
  }
  _createFallbackGripBone() {
    const t = this._system.modules?.localAvatar, e = t?.avatarContainerEntity || this._playerEntity;
    if (!e) return null;
    const { boundingBox: i } = t?.activeAvatar ?? this._system.store.getState();
    return this._fallbackGripBone ? (this._fallbackGripBone.reparent(e), xi(this._fallbackGripBone, i)) : this._fallbackGripBone = wi(e, i, "PlayerGripBone"), this._fallbackGripBone;
  }
  _getLocalGripBone() {
    const t = this._system.modules?.localAvatar;
    return t?.getBoneEntity?.("rightHand") || t?.getBoneEntity?.("leftHand") || this._createFallbackGripBone();
  }
  _getLocalReleaseTarget() {
    return this._system.modules?.localAvatar?.avatarContainerEntity || this._playerEntity || this._viverseApp.pcApp.root;
  }
  _pickItem(t) {
    this._currentPickedItem = t;
    const e = this._getLocalGripBone();
    e && (t.pick(e), this._viverseApp.emit("interaction:holding", !0), this._viverseApp.emit("interaction-network:request-pickable-item", t.name));
  }
  _dropItem() {
    if (!this._currentPickedItem) return;
    const t = this._currentPickedItem, e = this._getLocalReleaseTarget();
    e && (this._currentPickedItem.drop(e), this._currentPickedItem = null, this._viverseApp.emit("interaction:holding", !1), this._viverseApp.emit("interaction-network:drop-pickable-item", t.name));
  }
  _handleAcquired(t) {
    const { itemName: e, isLocal: i, gripBone: n } = t, s = this._pickableItems.get(e);
    if (!s) return;
    !i && n && (s === this._currentPickedItem && this._dropItem(), s.isPicked ? s.reattach(n) : s.pick(n));
  }
  _handleReleased(t) {
    const { itemName: e, isLocal: i, targetEntity: n } = t, s = this._pickableItems.get(e);
    s && (i ? s === this._currentPickedItem && this._dropItem() : s.drop(n || this._viverseApp.pcApp.root));
  }
  _findNearestItem() {
    if (!this._playerEntity) return null;
    const t = this._playerEntity.getPosition();
    let e = null, i = 1 / 0;
    return this._inRangeItems.forEach((n) => {
      if (n.isPicked) return;
      const s = n.entity.getPosition(), r = t.distance(s);
      r < i && (i = r, e = n);
    }), e;
  }
  _updateNearestItem() {
    const t = this._findNearestItem();
    if (t === this._currentNearestItem) return;
    const e = this._currentNearestItem;
    e && (e.isNearest = !1, e.updateDisplay()), this._currentNearestItem = t, t && (t.isNearest = !0, t.updateDisplay());
  }
  _updateAllItemsState() {
    this._updateNearestItem(), this._pickableItems.forEach((t) => t.updateDisplay());
  }
  update(t) {
    this._inRangeItems.size >= 2 && this._updateNearestItem(), this._pickableItems.forEach((i) => i.update());
  }
  destroy() {
    this._unbindEvents(), this._pickableItems.forEach((t) => {
      this._unregisterItemEvents(t), t.destroy();
    }), this._pickableItems.clear(), this._inRangeItems.clear(), this._currentNearestItem = null, this._currentPickedItem = null;
  }
}
class _r {
  _viverseApp;
  _system;
  _playerEntity = null;
  _sitFrameEndHandle = null;
  _pivotEntity = null;
  _sittingOffset = new pc.Vec3();
  _currentPivotPosition = new pc.Vec3();
  _currentPivotRotation = new pc.Quat();
  _nextPlayerPosition = new pc.Vec3();
  constructor(t) {
    this._system = t, this._viverseApp = t.viverseApp, _t(this._viverseApp).then((e) => this._playerEntity = e);
  }
  get _avatarModule() {
    return this._system.modules.localAvatar || null;
  }
  get _avatar() {
    return this._avatarModule?.activeAvatar || null;
  }
  async sit(t) {
    this._cleanupFrameEndHandle(), await this._playSitAnim(), await new Promise((e) => {
      this._sitFrameEndHandle = this._viverseApp.pcApp.once("frameend", () => {
        this._teleportToSeat(t), e();
      });
    });
  }
  async standUp(t) {
    this._pivotEntity = null, this._cleanupFrameEndHandle(), await this._standInFrontOfSeat(t);
  }
  _cleanupFrameEndHandle() {
    this._sitFrameEndHandle && (this._sitFrameEndHandle.off(), this._sitFrameEndHandle = null);
  }
  async _playSitAnim() {
    const t = this._avatar;
    t && t.sit && await t.sit();
  }
  _getSitPosition(t) {
    const e = t.entity, i = e.getPosition().clone(), n = t.seatRadius, s = Math.max(0, (this._avatar?.upperLegLength ?? n) - 0.1), r = Math.max(0, n - s), o = e.forward.clone().mulScalar(-1);
    return i.add(o.mulScalar(r)), i;
  }
  _calculateAvatarSitPosition(t, e) {
    this._setAvatarFacingDirection(t.entity);
    const i = this._avatar?.sitAnchorPosition, n = this._avatarModule?.avatarContainerEntity?.getPosition();
    if (!(i && n)) return e;
    const s = new pc.Vec3(), r = t.entity.up, o = s.sub2(n, i), l = o.dot(r);
    return o.copy(r).mulScalar(l), e.add(o), e;
  }
  _adjustAvatarForSitting(t, e, i) {
    const { setAvatarFacingModeEnabled: n } = this._system.store.getState();
    n(!1);
    const s = this._calculateAvatarSitPosition(e, t);
    i.rigidbody && i.rigidbody.teleport(s), this._applyPostSitAvatarAdjustments(e);
  }
  _getSittingHeadHeight(t) {
    const e = this._avatarModule?.getBoneEntity("head"), i = this._avatarModule?.avatarContainerEntity;
    if (!(e && i)) return null;
    const n = t.entity.up, s = e.getPosition(), r = i.getPosition();
    return new pc.Vec3().sub2(s, r).dot(n);
  }
  _applyPostSitAvatarAdjustments(t) {
    if (!t) return;
    const e = this._playerEntity;
    if (!e) return;
    const i = this._getSittingHeadHeight(t);
    if (i !== null) {
      const { setHeadHeight: s } = this._system.store.getState();
      s(i);
    }
    const n = this._avatar?.entity;
    if (this._avatarModule && n) {
      const s = Ee(n);
      this._system.updateCapsuleCollider(s), this._setAvatarFacingDirection(t.entity);
      const { capsuleHeight: r } = Se(s, e.getPosition());
      this._system.nameTag?.setCustomHeight(r);
    }
  }
  _setAvatarFacingDirection(t) {
    const e = this._avatarModule?.avatarContainerEntity;
    if (!e) return;
    const i = t.getRotation();
    e.setRotation(i), e.rotateLocal(0, 180, 0);
  }
  _teleportToSeat(t) {
    const e = this._playerEntity;
    if (!(e && e.rigidbody))
      throw new Error("Local player entity is not available.");
    this._pivotEntity = t.entity, this._currentPivotPosition.copy(t.entity.getPosition()), this._currentPivotRotation.copy(t.entity.getRotation());
    const i = this._getSitPosition(t);
    e.rigidbody.linearVelocity = pc.Vec3.ZERO, e.rigidbody.angularVelocity = pc.Vec3.ZERO, e.rigidbody.type = pc.BODYTYPE_KINEMATIC, e.rigidbody.teleport(i), this._adjustAvatarForSitting(i, t, e), this._pivotEntity && (this._sittingOffset.copy(e.getPosition()), this._sittingOffset.sub(this._pivotEntity.getPosition()));
    const n = this._system.modules.locomotion;
    n && n.setStateByName(x.Sitting);
  }
  async _playStandUpAnim() {
    const t = this._avatar;
    t && t.standUp && await t.standUp();
  }
  _getStandPosition(t) {
    const e = new pc.Vec3();
    if (!t) return e;
    if (t.exitPosition)
      return e.copy(t.exitPosition), e;
    e.copy(t.entity.getPosition());
    const i = t.entity.forward.clone().mulScalar(-1), n = t.seatRadius;
    e.add(i.mulScalar(n + 0.5));
    const r = this._viverseApp.pcApp.systems.rigidbody;
    if (!r) return e;
    const o = e.clone().add(new pc.Vec3(0, -10, 0)), l = r.raycastFirst(e, o);
    return l && (e.y = l.point.y), e;
  }
  async _adjustAvatarForStandUp(t) {
    await this._playStandUpAnim(), this._system.modules.localAvatar?.update(0);
    const { setHeadHeight: e, setAvatarFacingModeEnabled: i } = this._system.store.getState();
    i(!0), e(t.headHeight), this._system.nameTag?.recoverDefaultHeight(), this._system.updateCapsuleCollider();
  }
  async _standInFrontOfSeat(t) {
    const e = this._playerEntity;
    if (!(e && e.rigidbody)) return;
    const i = this._getStandPosition(t);
    e.rigidbody.teleport(i), e.rigidbody.type = pc.BODYTYPE_DYNAMIC;
    const n = this._avatar;
    n && await this._adjustAvatarForStandUp(n);
    const s = this._system.modules.locomotion;
    s && s.setStateByName(x.Grounded);
  }
  _syncPivot() {
    if (!this._pivotEntity || !this._playerEntity) return;
    const t = this._pivotEntity.getPosition();
    t.equalsApprox(this._currentPivotPosition) || (this._currentPivotPosition.copy(t), this._nextPlayerPosition.copy(t).add(this._sittingOffset), this._playerEntity.rigidbody?.teleport(this._nextPlayerPosition));
    const e = this._pivotEntity.getRotation();
    e.equalsApprox(this._currentPivotRotation) || (this._currentPivotRotation.copy(e), this._setAvatarFacingDirection(this._pivotEntity));
  }
  update() {
    this._syncPivot();
  }
  destroy() {
    this._cleanupFrameEndHandle();
  }
}
class mr {
  _viverseApp;
  _isShown = !0;
  _state = "out";
  _hintEntity = null;
  _innerHintEntity = null;
  _outerHintEntity = null;
  _onClick;
  _cameraEntity = null;
  outerTexture = null;
  innerTexture = null;
  hoverTexture = null;
  // for inner hint hover state
  constructor(t, e) {
    this._viverseApp = t, this._onClick = e, this._createHintEntity();
  }
  setVisible(t) {
    this._isShown = t, this._hintEntity && (this._hintEntity.enabled = t);
  }
  updateState(t) {
    this._state !== t && (this._state = t, this._updateHintVisibility());
  }
  updateTransform(t, e) {
    if (!this._hintEntity) return;
    this._hintEntity.getPosition().equalsApprox(t) || this._hintEntity.setPosition(t), this._hintEntity.getRotation().equals(e) || this._hintEntity.setRotation(e);
  }
  _updateHintVisibility() {
    if (!(!this._innerHintEntity || !this._outerHintEntity))
      switch (this._state) {
        case "inner":
          this._innerHintEntity.enabled = !0, this._outerHintEntity.enabled = !1;
          break;
        case "outer":
          this._innerHintEntity.enabled = !1, this._outerHintEntity.enabled = !0;
          break;
        case "out":
          this._innerHintEntity.enabled = !1, this._outerHintEntity.enabled = !1;
          break;
      }
  }
  _loadAssets() {
    const t = "/textures/interaction/";
    return Promise.all([
      H(this._viverseApp.pcApp, "seat-outer-hint.png", t, "local-player", "texture"),
      H(this._viverseApp.pcApp, "seat-hint.png", t, "local-player", "texture"),
      H(this._viverseApp.pcApp, "seat-hint-hover.png", t, "local-player", "texture")
    ]);
  }
  _createInnerHintElement(t) {
    this.innerTexture && (t.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      texture: this.innerTexture,
      useInput: !0,
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      width: 0.3,
      height: 0.3,
      layers: [pc.LAYERID_WORLD]
    }), t.addComponent("button"));
  }
  _createOuterHintElement(t) {
    this.outerTexture && (t.addComponent("element", {
      type: pc.ELEMENTTYPE_IMAGE,
      texture: this.outerTexture,
      useInput: !0,
      anchor: [0.5, 0.5, 0.5, 0.5],
      pivot: [0.5, 0.5],
      width: 0.3,
      height: 0.3,
      layers: [pc.LAYERID_WORLD]
    }), t.addComponent("button"));
  }
  async _createHintEntity() {
    this._hintEntity = new pc.Entity("SeatHintContainer"), this._innerHintEntity = new pc.Entity("SeatInnerHint"), this._outerHintEntity = new pc.Entity("SeatOuterHint"), this._hintEntity.addChild(this._innerHintEntity), this._hintEntity.addChild(this._outerHintEntity), this._innerHintEntity.setLocalPosition(0, 0.5, 0), this._outerHintEntity.setLocalPosition(0, 0.5, 0);
    const [t, e, i] = await this._loadAssets();
    this.outerTexture = t.resource, this.innerTexture = e.resource, this.hoverTexture = i.resource, this._createOuterHintElement(this._outerHintEntity), this._createInnerHintElement(this._innerHintEntity);
    const s = this._viverseApp.systems.localPlayer?.modules.camera?.currentCamera;
    s && (this._cameraEntity = s.entity), this._innerHintEntity.addComponent("script"), this._innerHintEntity.script && this._innerHintEntity.script.create(Ot, {
      properties: {
        ...s && { targetEntity: s.entity },
        rotateLocal: new pc.Vec3(0, 180, 0)
      }
    }), this._outerHintEntity.addComponent("script"), this._outerHintEntity.script && this._outerHintEntity.script.create(Ot, {
      properties: {
        ...s && { targetEntity: s.entity },
        rotateLocal: new pc.Vec3(0, 180, 0)
      }
    }), this._bindIconEvents(), this._updateHintVisibility(), this._hintEntity.enabled = this._isShown, this._viverseApp.pcApp.root.addChild(this._hintEntity);
  }
  _showInnerHintHover() {
    const t = this._innerHintEntity?.element;
    !t || !this.hoverTexture || (t.texture = this.hoverTexture);
  }
  _hideInnerHintHover() {
    const t = this._innerHintEntity?.element;
    !t || !this.innerTexture || (t.texture = this.innerTexture);
  }
  _bindIconEvents() {
    const t = this._innerHintEntity?.button;
    t && (t.on("click", this._onClick, this), t.on("hoverstart", this._showInnerHintHover, this), t.on("hoverend", this._hideInnerHintHover, this), t.on("pressedstart", this._showInnerHintHover, this), t.on("pressedend", this._hideInnerHintHover, this));
    const e = this._viverseApp.systems.localPlayer;
    e && (e.on("camera:changed", this._cameraChanged, this), e.on("camera:entity-replaced", this._cameraReplaced, this));
  }
  _unbindIconEvents() {
    const t = this._innerHintEntity?.button;
    t && (t.off("click", this._onClick, this), t.off("hoverstart", this._showInnerHintHover, this), t.off("hoverend", this._hideInnerHintHover, this), t.off("pressedstart", this._showInnerHintHover, this), t.off("pressedend", this._hideInnerHintHover, this));
    const e = this._viverseApp.systems.localPlayer;
    e && (e.off("camera:changed", this._cameraChanged, this), e.off("camera:entity-replaced", this._cameraReplaced, this));
  }
  _cameraChanged({ newCamera: t }) {
    this._cameraEntity = t?.entity, this._innerHintEntity?.fire("billboard:set-target", t?.entity), this._outerHintEntity?.fire("billboard:set-target", t?.entity);
  }
  _cameraReplaced({
    previousEntity: t,
    camera: e
  }) {
    t === this._cameraEntity && (this._cameraEntity = e.entity, this._innerHintEntity?.fire("billboard:set-target", e.entity), this._outerHintEntity?.fire("billboard:set-target", e.entity));
  }
  destroy() {
    this._unbindIconEvents(), this._hintEntity && (this._hintEntity.destroy(), this._hintEntity = null), this._innerHintEntity && (this._innerHintEntity.destroy(), this._innerHintEntity = null), this._outerHintEntity && (this._outerHintEntity.destroy(), this._outerHintEntity = null);
  }
}
class fr {
  _viverseApp;
  _containerEntity = null;
  _innerZone = null;
  _outerZone = null;
  _playerEntity = null;
  _onStateChange;
  _isPlayerInInnerRange = !1;
  _isPlayerInOuterRange = !1;
  constructor(t, e, i, n, s) {
    this._viverseApp = t, this._onStateChange = s, this._createCollisionEntities(e, i, n), _t(this._viverseApp).then((r) => {
      this._playerEntity = r;
    });
  }
  setEnabled(t) {
    this._outerZone?.collision && (this._outerZone.collision.enabled = t), this._innerZone?.collision && (this._innerZone.collision.enabled = t);
  }
  updatePosition(t) {
    this._containerEntity && this._containerEntity.setPosition(t);
  }
  _createCollisionEntities(t, e, i) {
    this._containerEntity = new pc.Entity("SeatCollisionContainer"), this._outerZone = new pc.Entity("SeatOuterCollisionDetector"), this._outerZone.addComponent("collision", {
      type: "cylinder",
      height: e,
      linearOffset: i,
      radius: t.outer
    }), this._innerZone = new pc.Entity("SeatInnerCollisionDetector"), this._innerZone.addComponent("collision", {
      type: "cylinder",
      height: e,
      linearOffset: i,
      radius: t.inner
    }), this._outerZone.collision?.on("triggerenter", this._onOuterTriggerEnter, this), this._outerZone.collision?.on("triggerleave", this._onOuterTriggerLeave, this), this._innerZone.collision?.on("triggerenter", this._onInnerTriggerEnter, this), this._innerZone.collision?.on("triggerleave", this._onInnerTriggerLeave, this), this._containerEntity.addChild(this._outerZone), this._containerEntity.addChild(this._innerZone), this._viverseApp.pcApp.root.addChild(this._containerEntity);
  }
  _onOuterTriggerEnter(t) {
    t === this._playerEntity && (this._isPlayerInOuterRange = !0, this._updateState());
  }
  _onOuterTriggerLeave(t) {
    t === this._playerEntity && (this._isPlayerInOuterRange = !1, this._isPlayerInInnerRange = !1, this._updateState());
  }
  _onInnerTriggerEnter = (t) => {
    t === this._playerEntity && (this._isPlayerInInnerRange = !0, this._updateState());
  };
  _onInnerTriggerLeave(t) {
    t === this._playerEntity && (this._isPlayerInInnerRange = !1, this._updateState());
  }
  _updateState() {
    let t;
    this._isPlayerInInnerRange ? t = "inner" : this._isPlayerInOuterRange ? t = "outer" : t = "out", this._onStateChange(t);
  }
  destroy() {
    this._containerEntity && (this._containerEntity.destroy(), this._containerEntity = null), this._outerZone && (this._outerZone.collision?.off("triggerenter", this._onOuterTriggerEnter, this), this._outerZone.collision?.off("triggerleave", this._onOuterTriggerLeave, this), this._outerZone.destroy(), this._outerZone = null), this._innerZone && (this._innerZone.collision?.off("triggerenter", this._onInnerTriggerEnter, this), this._innerZone.collision?.off("triggerleave", this._onInnerTriggerLeave, this), this._innerZone.destroy(), this._innerZone = null);
  }
}
class gr extends We {
  seatRadius;
  exitPosition;
  standUpOnMoveInput = !0;
  _hint = null;
  _rangeDetector = null;
  _isOccupied = !1;
  constructor(t, e, i, n = {}) {
    super(e, i), this.exitPosition = n.exitPosition || null, this.seatRadius = n.seatRadius || 0.5, this.standUpOnMoveInput = n.standUpOnMoveInput ?? !0;
    const s = n.useHintIcon ?? !0, r = this._handleHintClicked.bind(this);
    this._hint = s ? new mr(t.viverseApp, r) : null;
    const o = n.rangeRadius || { inner: 1, outer: 2 }, l = n.rangeHeight || 0.1, c = n.rangeOffset || [0, 0, 0], h = this._handleRangeChanged.bind(this);
    this._rangeDetector = new fr(
      t.viverseApp,
      o,
      l,
      c,
      h
    ), this._initializeEventBindings();
  }
  get isOccupied() {
    return this._isOccupied;
  }
  _updateEnabledState() {
    const t = this.entity.enabled && !this._isOccupied;
    this._rangeDetector?.setEnabled(t), this._hint?.setVisible(t);
  }
  _onDestroyed() {
    this.emit("seat:destroyed", this);
  }
  _handleHintClicked() {
    this.emit("seat:attempt-sit", this);
  }
  _handleRangeChanged(t) {
    this._hint && this._hint.updateState(t);
  }
  async occupy() {
    this._isOccupied || (this._isOccupied = !0, this._updateEnabledState(), this._hint && this._hint.setVisible(!1));
  }
  async leave() {
    this._isOccupied && (this._isOccupied = !1, this._updateEnabledState(), this._hint && this._hint.setVisible(!0));
  }
  update() {
    const t = this.entity.getPosition(), e = this.entity.getRotation();
    this._hint && this._hint.updateTransform(t, e), this._rangeDetector && this._rangeDetector.updatePosition(t);
  }
  destroy() {
    super.destroy(), this._hint && (this._hint.destroy(), this._hint = null), this._rangeDetector && (this._rangeDetector.destroy(), this._rangeDetector = null);
  }
}
class yr {
  _viverseApp;
  _system;
  _playerAction;
  _seats = /* @__PURE__ */ new Map();
  _currentSeat = null;
  _isTransitioning = !1;
  constructor(t) {
    this._system = t, this._viverseApp = t.viverseApp, this._playerAction = new _r(t), this._bindEvents();
  }
  get seats() {
    return this._seats;
  }
  get currentSeat() {
    return this._currentSeat;
  }
  get isSitting() {
    return this._currentSeat !== null;
  }
  get isTransitioning() {
    return this._isTransitioning;
  }
  addSeat(t, e, i) {
    this._validateSeatName(t);
    const n = new gr(this._system, t, e, i);
    return this._seats.set(t, n), this._registerSeatEvents(n), n;
  }
  async removeSeat(t) {
    const i = [...this._seats.values()].find((n) => n.entity === t || n.name === t);
    if (!i) return Promise.resolve();
    this._currentSeat === i && await this.standUp(), this._unregisterSeatEvents(i), this._seats.delete(i.name), i.destroy();
  }
  getSeat(t) {
    let e = null;
    return t instanceof pc.Entity ? e = [...this._seats.values()].find((i) => i.entity === t) || null : typeof t == "string" && (e = this._seats.get(t) || null), e || E.warn(`Seat not found for ${t}`), e;
  }
  _bindEvents() {
    this._system.on("local-avatar:changed", this._handleAvatarChanged, this), this._viverseApp.on("interaction-network:seat-acquired", this._handleAcquired, this), this._viverseApp.on("interaction-network:seat-released", this._handleReleased, this);
  }
  _unbindEvents() {
    this._system.off("local-avatar:changed", this._handleAvatarChanged, this), this._viverseApp.off("interaction-network:seat-acquired", this._handleAcquired, this), this._viverseApp.off("interaction-network:seat-released", this._handleReleased, this);
  }
  _validateSeatName(t) {
    if (this._seats.has(t))
      throw new Error(`Seat with name "${t}" already exists.`);
  }
  _registerSeatEvents(t) {
    t.on("seat:attempt-sit", this._handleAttemptSit, this), t.on("seat:destroyed", this._handleDestroySeat, this);
  }
  _unregisterSeatEvents(t) {
    t.off("seat:attempt-sit", this._handleAttemptSit, this), t.off("seat:destroyed", this._handleDestroySeat, this);
  }
  _handleAvatarChanged() {
    this._currentSeat && this._playerAction.sit(this._currentSeat);
  }
  _handleAttemptSit(t) {
    this.sit(t.name);
  }
  _handleDestroySeat(t) {
    this.removeSeat(t.name);
  }
  async _handleAcquired(t) {
    const { itemName: e, isLocal: i } = t, n = this.getSeat(e);
    if (!n) return;
    !i && (n === this._currentSeat && await this.standUp(), n.occupy());
  }
  async _handleReleased(t) {
    const { itemName: e, isLocal: i } = t, n = this.getSeat(e);
    n && (i ? n === this._currentSeat && await this.standUp() : n.leave());
  }
  async _sit(t) {
    if (t.isOccupied) {
      E.warn(`Seat ${t.name} is already occupied.`);
      return;
    }
    await this._leaveCurrentSeat(), await this._playerAction.sit(t), this._currentSeat = t, t.occupy(), this._viverseApp.emit("interaction:sitting", !0, t);
  }
  async sit(t) {
    if (this._isTransitioning) {
      E.warn("Already transitioning, please wait for the current action to complete");
      return;
    }
    const e = this.getSeat(t);
    if (e) {
      this._isTransitioning = !0;
      try {
        await this._sit(e), this._viverseApp.emit("interaction-network:request-seat", e.name);
      } catch (i) {
        E.error(`Failed to sit on seat ${e.name}:`, i);
      } finally {
        this._isTransitioning = !1;
      }
    }
  }
  async _leaveCurrentSeat() {
    if (this._currentSeat) {
      const t = this._currentSeat;
      await t.leave(), this._currentSeat = null, this._viverseApp.emit("interaction-network:leave-seat", t.name);
    }
  }
  async standUp() {
    if (this._isTransitioning) {
      E.warn("Already transitioning, please wait for the current action to complete");
      return;
    }
    if (this._currentSeat)
      try {
        this._isTransitioning = !0;
        const t = this._currentSeat;
        await this._playerAction.standUp(this._currentSeat), await this._leaveCurrentSeat(), this._viverseApp.emit("interaction:sitting", !1, t);
      } catch (t) {
        E.error("Failed to stand up:", t);
      } finally {
        this._isTransitioning = !1;
      }
  }
  _handleStandUpInput() {
    if (!this._isTransitioning && this._currentSeat && this._currentSeat.standUpOnMoveInput) {
      const t = this._system.store.getState(), e = t.moveIntent && t.moveIntent.lengthSq() > 0, i = t.inputStates.jump;
      (e || i) && this.standUp();
    }
  }
  update(t) {
    this._handleStandUpInput(), this._playerAction.update(), this._seats.forEach((e) => e.update());
  }
  destroy() {
    this._seats.forEach((t) => {
      this._unregisterSeatEvents(t), t.destroy();
    }), this._currentSeat = null, this._seats.clear(), this._playerAction.destroy(), this._unbindEvents();
  }
}
class xr extends pt {
  static moduleName = q.Interaction;
  pickHandler;
  sitHandler;
  constructor(t, e) {
    super(t);
    const { usePickInteraction: i = !0, useSitInteraction: n = !0 } = e ?? {};
    this.pickHandler = i ? new pr(t) : null, this.sitHandler = n ? new yr(t) : null;
  }
  get isActionExecuting() {
    return this.pickHandler?.isActionExecuting ?? !1;
  }
  get isSitting() {
    return this.sitHandler?.isSitting ?? !1;
  }
  addPickableItem(t, e, i) {
    if (!this.pickHandler)
      throw new Error("Pick interaction is not enabled. Please check the module options.");
    return this.pickHandler.addItem(t, e, i);
  }
  removePickableItem(t) {
    if (!this.pickHandler)
      throw new Error("Pick interaction is not enabled. Please check the module options.");
    this.pickHandler.removeItem(t);
  }
  addSeat(t, e, i) {
    if (!this.sitHandler)
      throw new Error("Sit interaction is not enabled. Please check the module options.");
    this.sitHandler.addSeat(t, e, i);
  }
  removeSeat(t) {
    if (!this.sitHandler)
      throw new Error("Sit interaction is not enabled. Please check the module options.");
    this.sitHandler.removeSeat(t);
  }
  update(t) {
    this.pickHandler?.update(t), this.sitHandler?.update(t);
  }
  destroy() {
    this.pickHandler?.destroy(), this.sitHandler?.destroy();
  }
}
export {
  ki as AvatarModule,
  zt as Camera,
  ys as CameraModule,
  Hs as ControllerXrInputDevice,
  ke as DEFAULT_CAMERA_COMPONENT_SETTINGS,
  Ts as DeadState,
  Ht as DefaultAvatar,
  Es as FallingState,
  us as FirstPersonCamera,
  As as FlyingState,
  vs as GroundedState,
  Ys as HandXrInputDevice,
  er as HeadXrUiAnchor,
  Os as InputHandler,
  xr as InteractionModule,
  Ss as JumpingState,
  Ls as KeyboardInput,
  ss as LocalAvatarModule,
  Tr as LocalPlayerSystem,
  xs as LocomotionModule,
  ot as LocomotionState,
  Ns as MouseInput,
  ir as OverheadXrUi,
  tr as SmoothXrLocomotion,
  Ks as TeleportXrLocomotion,
  cs as ThirdPersonCamera,
  Ds as TouchInput,
  Jn as ViverseAvatar,
  Y as VrmAvatar,
  ge as XrCamera,
  qs as XrCursor,
  ye as XrHandedNode,
  Ue as XrInputDevice,
  ze as XrLocomotion,
  wr as XrModule,
  nr as XrUiHandler
};
