// "script" file for definition of ClusterScript 

/**
 * The `$` object is an instance of a handle that can be used to manipulate individual scriptable items.
 * @item
 */
declare const $: ClusterScript;

/**
 * The handle to manipulate the item itself. This exists for each individual item, and can be accessed from the `$` object.
 * @item
 */
interface ClusterScript {
  /**
   * Performs a `toString` on the content of `v`, then outputs it to the log.
   * 
   * @param v
   */
  log(v: any): void;

  /**
   * Calculates the data size in bytes when the data is sent with {@link ItemHandle.send}.
   *
   * If the data is not a {@link Sendable}, a {@link TypeError} will occur.
   */
  computeSendableSize(arg: Sendable): number;

  /**
   * Specify a position to move the item to, using the global coordinates of the world the item is in.
   * 
   * The item must have a `MovableItem` Component attached.
   * As the positions are interpolated and synced across the network, please be aware they may not be reflected immediately.
   * 
   * @param v
   */
  setPosition(v: Vector3): void;

  /**
   * Obtains the current position of the item. Values will be returned in the global coordinates of the world the item is in. 
   * 
   * If you call this immediately after calling `setPosition`, please be aware it will return the item's current position, not the value passed to `setPosition`.
   */
  getPosition(): Vector3;

  /**
   * Specify a rotation to rotate the item to, using the global coordinates of the world the item is in.
   * 
   * The item must have a `MovableItem` Component attached.
   * As the rotations are interpolated and synced across the network, please be aware they may not be reflected immediately.
   * 
   * @example
   * ```ts
   * $.setRotation(new Quaternion().setFromEulerAngles(new Vector3(90, 0, 0)));
   * ```
   * 
   * @param v 
   */
  setRotation(v: Quaternion): void;

  /**
   * Obtains the current rotation of the item. Values will be returned in the global coordinates of the world the item is in. 
   * 
   * If you call this immediately after calling `setRotation`, please be aware it will return the item's current rotation, not the value passed to `setRotation`.
   */
  getRotation(): Quaternion;

  /**
   * Locates an object named `subNodeName` within the item's children and descendants, and returns a `SubNode` object that refers to it.
   * 
   * This method does not support the object with [Player Local UI](https://docs.cluster.mu/creatorkit/en/world-components/player-local-ui/) or the children of such object.
   * This is because the hierarchy of those GameObjects is subject to the change. 
   * 
   * @param subNodeName 
   */
  subNode(subNodeName: string): SubNode;

  /**
   * Locates an audio entry with the ID `itemAudioSetId` within the item's `ItemAudioSetList`, and returns an `ApiAudio` object referring to it.
   * 
   * For details on `ItemAudioSetList`, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/item-components/item-audio-set-list/). 
   * 
   * @param itemAudioSetId 
   */
  audio(itemAudioSetId: string): ApiAudio;

  /**
   * Returns the {@link AudioLinkHandle} object for the item.  
   * The item must have an AudioLink component attached.  
   * If the target is a craft item or an item that does not have an AudioLink component,  
   * calls to AudioLinkHandle methods are ignored.
   */
  audioLink(): AudioLinkHandle;

  /**
   * Locates an animation entry with the ID `humanoidAnimationId` within the item's `HumanoidAnimationList`, and returns a {@link HumanoidAnimation} object referring to it.
   * 
   * For details on `HumanoidAnimationList`, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/item-components/humanoid-animation-list/).
   *
   * @param humanoidAnimationId
   */
  humanoidAnimation(humanoidAnimationId: string): HumanoidAnimation;

  /**
   * Returns a {@link MaterialHandle} object that references the material with the id specified in `materialId` in the item's `ItemMaterialSetList`.
   *
   * For details on `ItemMaterialSetList`, see [documentation](https://docs.cluster.mu/creatorkit/en/item-components/item-material-set-list/).
   *
   * @example
   * ```ts
   * // Items that change the color of the material when interacted
   * $.onInteract(() => {
   *   const mh = $.material("materialId");
   *   mh.setBaseColor(Math.random(), Math.random(), Math.random(), 1);
   * });
   * ```
   *
   * @param materialId
   */
  material(materialId: string): MaterialHandle;

  /**
   * Returns an {@link ItemHandle} object that references the Item specified by `worldItemReferenceId` in the item's WorldItemReferenceList.
   *
   * For details on `WorldItmeReferenceList`, see [documentation](https://docs.cluster.mu/creatorkit/en/item-components/world-item-reference-list/).
   *
   * Supported when called at the top level of the script or from callbacks.
   *
   * @example
   * ```ts
   * // Item that sends message "click" to the specified item when interacted
   * const target = $.worldItemReference("target");
   *
   * $.onInteract(() => {
   *   target.send("click", null);
   * });
   * ```
   *
   * @param worldItemReferenceId
   */
  worldItemReference(worldItemReferenceId: string): ItemHandle;

  /**
   * The string representation of the ID that uniquely identifies an item within the space.
   * This is the same as the {@link ItemHandle.id | ItemHandle.id} of the ItemHandle for this item.
   */
  readonly id: string;

  /**
   * Returns the {@link ItemHandle} that represents this item.
   */
  readonly itemHandle: ItemHandle;

  /**
   * The ID of item template that this Craft Item is based on.
   * if the item executing this script is World Item, this function returns `null`.
   * This value can be used by {@link ClusterScript.createItem}.
   */
  readonly itemTemplateId: ItemTemplateId | null;

  /**
   * Registers a callback to be called once, before the first execution of `onUpdate`, when this item first appears in the space.
   * If `onReceive` callback also registered, it is ensured to be called after `onStart` is called.
   * 
   * The item appearing in the space refers to any of the following situations:
   * - When an item is created with `createItem` or `createItemGimmick`
   * - In Creator Kit based worlds, when the space starts anew
   * - In World Craft, when an item is newly created by placing or copying
   * 
   * Only the last registered callback at script load time will be active.
   *
   *
   * For more details, see [When onStart is called](/script/en/#When%20onStart%20is%20called)
   * @param callback 
   */
  onStart(callback: () => void): void;

  /**
   * Registers a callback to be called on each update loop.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * // Output to log every 10 seconds
   * $.onUpdate(deltaTime => {
   *     let t = $.state.time ?? 0;
   *     t += deltaTime;
   *     if (t > 10) {
   *         $.log("10 seconds elapsed.");
   *         t -= 10;
   *     }
   *     $.state.time = t;
   * });
   * ```
   * 
   * @param callback 
   */
  onUpdate(callback: (deltaTime: number) => void): void;

  /**
   * Registers a callback to be called when grabbing or releasing an object. The item must have a `GrabbableItem` Component attached.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * $.onGrab((isGrab, isLeftHand) => {
   *   if (isGrab) {
   *     if (isLeftHand) {
   *       $.log("Grabbed by left hand.");
   *     } else {
   *       $.log("Grabbed by right hand.");
   *     }
   *   }
   * });
   * ```
   * The player handle can also be obtained.
   * ```ts
   * // Increase the movement speed while grabbing
   * $.onGrab((isGrab, isLeftHand, player) => {
   *   if (isGrab) {
   *     player.setMoveSpeedRate(2);
   *   } else {
   *     player.setMoveSpeedRate(1);
   *   }
   * });
   * ```
   *
   * @param callback
   * isGrab = `true` when grabbing, `false` when releasing.
   * 
   * isLeftHand = `true` when grabbed/released with the left hand, `false` when with the right hand.
   * 
   * player = The handle of the player who grabbed/released the item.
   */
  onGrab(callback: (isGrab: boolean, isLeftHand: boolean, player: PlayerHandle) => void): void;

  /**
   * Registers a callback to be called when a "Use" action is performed on a non-grabbable item. The item must have 1 or more `Collider` Components attached.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * $.onInteract(() => {
   *   $.log("Interacted.");
   * });
   * ```
   * The player handle can also be obtained.
   * ```ts
   * // Respawn the player who interacted with it
   * $.onInteract(player => {
   *   player.respawn();
   * });
   * ```
   * 
   * @param callback 
   * player = The handle of the player who interacted with the item.
   */
  onInteract(callback: (player: PlayerHandle) => void): void;

  /**
   * Registers a callback to be called when a "Use" action is performed on a item being grabbed. 
   * The item must have a `GrabbableItem` Component attached.
   * If `UseItemTrigger` Component is attached to the item, the callback is not be called and instead `UseItemTrigger` will be triggered.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * @example
   * ```ts
   * $.onUse(isDown => {
   *   $.log(`isDown: ${isDown}.`);
   * });
   * ```
   * 
   * The player handle can also be obtained.
   * ```ts
   * // Apply upwards velocity to the player who used this
   * $.onUse((isDown, player) => {
   *   if (isDown) {
   *     player.addVelocity(new Vector3(0, 5, 0));
   *   }
   * });
   * ```
   * 
   * @param callback
   * isDown = `true` when beginning the "Use" action, `false` when ending.
   * 
   * player = The handle of the player who used the item.
   */
  onUse(callback: (isDown: boolean, player: PlayerHandle) => void): void;

  /**
   * Registers a callback to be called when mounting or dismounting a ridable item. The item must have a `RidableItem` Component attached.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * // Rotates only while the players is riding.
   * $.onRide(isGetOn => {
   *   $.state.isRiding = isGetOn;
   * });
   *
   * $.onUpdate(deltaTime => {
   *   if (!$.state.isRiding) return;
   *   let t = $.state.time ?? 0;
   *   t += deltaTime;
   *   $.state.time = t % 360;
   *   $.setRotation(new Quaternion().setFromEulerAngles(0, t, 0));
   * });
   * ```
   * The player handle can also be obtained.
   * ```ts
   * $.onRide((isGetOn, player) => {
   *   $.state.isRiding = isGetOn;
   *   $.state.player = isGetOn ? player : null;
   * });
   * ```
   * @param callback
   * isGetOn = `true` when mounting, `false` when dismounting.
   * 
   * player = The handle of the player mounted/dismounted the item.
   */
  onRide(callback: (isGetOn: boolean, player: PlayerHandle) => void): void;

  /**
   * Retrieves the {@link PlayerHandle} of the player who is grabbing an item with the Grabbable Item component.
   * Returns null if no player is grabbing the item.
   *
   * If called within the {@link onGrab} callback, it returns the {@link PlayerHandle} grabbing the item if `isGrab` is true, and null if `isGrab` is false.
   */
  getGrabbingPlayer(): PlayerHandle | null;

  /**
   * Retrieves the {@link PlayerHandle} of the player who is riding an item with the Ridable Item component.
   * Returns null if no player is riding the item.
   *
   * If called within the {@link onRide} callback, it returns the {@link PlayerHandle} riding the item if `isGetOn` is true, and null if `isGetOn` is false.
   */
  getRidingPlayer(): PlayerHandle | null;

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Creating and Destroying
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * Creates the specified item in the current space.
   * 
   * If {@link ItemTemplateId} is passed as `itemTemplateId`, a craft item will be created.
   * If {@link WorldItemTemplateId} is passed as `itemTemplateId`, a world item will be created.
   * However, if WorldItemTemplateId is passed to `itemTemplateId` in a call from a craft item, an error will occur.
   * 
   * In principle, the owner of the item that executes the `createItem` method will become the owner of the newly created item.
   * 
   * An item can create other items by `createItem` up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and `createItem` will fail.
   * 
   * #### Behavior when creating a craft item
   * 
   * There may be a delay before the craft item is actually created.
   * 
   * The author of the craft item template to be created must meet one of the following criteria:
   * - If the item executing this script is a Craft Item, it must have the same author as that craft item's template.
   * - If the item executing this script is a World Item, it must have the same author as the current Venue.
   *
   * If a beta item is to be created, the item executing this script must either be a beta Craft Item or a World Item in a beta world.
   *
   * The creation of craft items may fail due to the following reasons:
   * - Attempting to create a craft item that does not meet the criteria.
   * - The creation of a craft item would cause the Craft Item Capacity Usage to exceed 500%.
   * - The owner of the original item exits during the creation of a craft item.
   * 
   * If craft item creation fails, the returned ItemHandle will be in a state where it does not point to anything, and {@link ItemHandle.exists | ItemHandle.exists} will return `false`.
   *
   * #### Behavior when creating a world item
   *
   * Creates a world item by referring to the [World Item Template List](https://docs.cluster.mu/creatorkit/en/item-components/world-item-template-list/) registered [World Item Template](https://docs.cluster.mu/creatorkit/en/world/item/#item-templates-and-dynamic-item-generation).
   *
   * It is not possible to create any world items from craft items.
   *
   * If an unregistered Id in the World Item Template List or an Id without a World Item Template is specified, {@link ClusterScriptError} will occur and `createItem` will fail.
   *
   * If the owner of the original item exits during the creation of a world item, the creation may fail.
   *
   * If world item creation fails, the returned ItemHandle will be in a state where it does not point to anything, and {@link ItemHandle.exists | ItemHandle.exists} will return `false`.
   *
   * @example
   * In the example below, when the item is used, a world item "marker" is created above the player, and the PlayerHandle of the player who used the item is sent.
   * ```ts
   * $.onUse((isDown, player) => {
   *   if (!isDown) return;
   *
   *   const markerPosition = player.getPosition();
   *   markerPosition.y += 2.5;
   *
   *   const markerRotation = player.getRotation();
   *
   *   const worldItemTemplateId = new WorldItemTemplateId("marker");
   *   const itemHandle = $.createItem(worldItemTemplateId, markerPosition, markerRotation);
   *
   *   itemHandle.send("createdPlayer", player);
   * });
   * ```
   *
   * @param itemTemplateId `TemplateId` of the item to be created
   * @param position Initial position (global coordinates)
   * @param rotation Initial rotation (global coordinates)
   */
  createItem(itemTemplateId: ItemTemplateId | WorldItemTemplateId, position: Vector3, rotation: Quaternion): ItemHandle;

  /**
   * @beta
   * Generates an item with specified options.
   * 
   * @example
   * ```ts
   * let itemHandle = $.createItem(templateId, position, rotation, { asMember: true });
   * ```
   * 
   * @param itemTemplateId The TemplateId of the item to be generated
   * @param position The position where the item will be generated (global coordinates)
   * @param rotation The orientation of the item (global coordinates)
   * @param option Option values
   */
  createItem(itemTemplateId: ItemTemplateId | WorldItemTemplateId, position: Vector3, rotation: Quaternion, option: CreateItemOption): ItemHandle;

  /**
   * Destroys this item. There may be a delay before the item is actually destroyed.
   * 
   * Items to destroy must meet one of the following criteria:
   * - The item is a Craft Item.
   * - If the item is not a Craft Item, it should be dynamically created using Create Item Gimmick or ClusterScript.createItem of Scriptable Item.
   *
   * If called on an item that cannot be destroyed, a {@link ClusterScriptError} (`executionNotAllowed`) error will occur and `destroy` will fail.
   * Currently, it is not possible to destroy [World Placed Items](https://docs.cluster.mu/creatorkit/en/world/item/#item-templates-and-dynamic-item-generation).
  */
  destroy(): void;

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Proximity and Collision Detection
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * Returns an array of handles for items (excluding itself) that have detectable colliders within a specified spherical space.
   * Detectable colliders are: colliders with a `PhysicalShape`, colliders with an `OverlapSourceShape`, and colliders without a `Shape` that can cause physics collisions.
   * Detectable layers are: `Default`, `RidingItem`, `InteractableItem`, and `GrabbingItem`.
   *
   * When a large number of colliders are included in the range, it may not be possible to retrieve all ItemHandles that meet the condition.
   * In this case, a warning message will be output to the console.
   * 
   * @param position Center position (global coordinates)
   * @param radius Radius of sphere
   * 
   * @returns An array of handles for the detected items (order is undefined)
   */
  getItemsNear(position: Vector3, radius: number): ItemHandle[];

  /**
   * Returns an array of handles for players whose colliders exist within a specified spherical space.
   * 
   * @param position Center position (global coordinates)
   * @param radius Radius of sphere
   * 
   * @returns An array of handles for the detected players (order is undefined)
   */
  getPlayersNear(position: Vector3, radius: number): PlayerHandle[];

  /**
   * Casts a ray, and returns the first object it collided with.
   *
   * @example
   * ```ts
   * // Casts a ray toward Z axis positive direction in item local coordinates, and logs the nearest object hit.
   * let direction = new Vector3(0, 0, 1).applyQuaternion($.getRotation());
   * let result = $.raycast($.getPosition(), direction, 10);
   * if (result === null) {
   *   $.log("ray hits nothing");
   * } else if (result.handle === null) {
   *   $.log("ray hits something other than player or item");
   * } else if (result.handle.type === "player") {
   *   $.log("ray hits player " + result.handle.userDisplayName);
   * } else if (result.handle.type === "item") {
   *   $.log("ray hits item " + result.handle.id);
   * }
   * ```
   * 
   * @param position Origin of the ray (global coordinates)
   * @param direction Direction of the ray (global coordinates)
   * @param maxDistance Maximum distance for performing collision detection
   * 
   * @returns The collided object (`null` if no collision)
   */
  raycast(position: Vector3, direction: Vector3, maxDistance: number): RaycastResult | null;

  /**
   * Casts a ray, and returns all the objects it collided with.
   *
   * When a large number of colliders are included in the range, it may not be possible to retrieve all ItemHandles that meet the condition.
   * In this case, a warning message will be output to the console.
   *
   * @example
   * ```ts
   * // Casts a ray downwards, and move the item itself to the nearest hit position which target is not item or player.
   * let raycastResults = $.raycastAll($.getPosition(), new Vector3(0, -1, 0), 10);
   * let result = null;
   * let minDistance = Infinity;
   * for (let raycastResult of raycastResults) {
   *   if (raycastResult.handle !== null) continue;
   *   var distance = raycastResult.hit.point.clone().sub(pos).length();
   *   if (distance >= minDistance) continue;
   *   result = raycastResult;
   *   minDistance = distance;
   * }
   * if (result != null) {
   *   $.setPosition(result.hit.point);
   * }
   * ```
   * 
   * @param position Origin of the ray (global coordinates)
   * @param direction Direction of the ray (global coordinates)
   * @param maxDistance Maximum distance for performing collision detection
   * 
   * @returns An array of the collided objects (order is undefined)
   */
  raycastAll(position: Vector3, direction: Vector3, maxDistance: number): RaycastResult[];

  /**
   * Registers a callback to be called when this item collides with another object. The item must have physics behaviors enabled.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * $.onCollide(collision => {
   *   if (collision.handle?.type === "player") {
   *     $.log("collide with a player.");
   *   }
   * });
   * ```
   */
  onCollide(callback: (collision: Collision) => void): void;

  /**
   * Returns an array of detectable objects that overlap with this item's `OverlapDetectorShape`.
   * Detectable objects are: colliders with a `PhysicalShape`, colliders with an `OverlapSourceShape`, and colliders without a `Shape` that can cause physics collisions.
   * Overlaps with this item itself are excluded.
   * 
   * Either this item or the detectable object must fulfill one of the following: be a `MovableItem`, have a `Rigidbody`, have a `CharacterController`, or be a player.
   * Detectable layers are those that perform collision detection on this item's `OverlapDetectorShape`.
   * In some cases, this method may exclude objects that do overlap in space, eg. if the item had already been overlapping when it was created or enabled.
   * @example
   * ```ts
   * // Count players who overlap with me
   * let set = new Set();
   * let overlaps = $.getOverlaps();
   * for (let overlap of overlaps) {
   *   if (overlap.handle?.type === "player") {
   *     let player = overlap.handle;
   *     set.add(player.id);
   *   }
   * }
   * $.log(`player count: ${set.size}`);
   * ```
   */
  getOverlaps(): Overlap[];

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Physics
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * Registers a callback to be called when this item's physics state gets updated.
   * (Corresponds to `FixedUpdate` in Unity)
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * // Rise for 1 second, then fall for 2 seconds.
   * // The Rigidbody's Mass here is assumed to be 1.
   * $.onPhysicsUpdate(deltaTime => {
   *   let t = $.state.time ?? 0;
   *   t += deltaTime;
   *   if (t < 1) {
   *     $.addForce(new Vector3(0, 12, 0));
   *   } else if (t > 3) {
   *     t = 0;
   *   }
   *   $.state.time = t;
   * });
   * ```
   */
  onPhysicsUpdate(callback: (deltaTime: number) => void): void;

  /**
   * Gets or sets whether this item is affected by gravity under normal conditions.
   * This property cannot be accessed at the top level of the script.
   * Items are not affected by gravity while being grabbed, but this does not affect `useGravity`.
   * 
   * If this item is not a physics-enabled `MovableItem`, the value will be `false`.
   * If this item is not a physics-enabled `MovableItem`, attempting to modify it will result in an exception.
   */
  useGravity: boolean;

  /**
   * Gets or sets this item's velocity (global coordinates).
   * This property cannot be accessed at the top level of the script.
   * 
   * If this item is not a `MovableItem`, the value will be a Zero Vector.
   * If this item is not a physics-enabled `MovableItem`, attempting to modify it will result in an exception.
   * Changes made during grabbing, etc. will be ignored.
   */
  velocity: Vector3;

  /**
   * Gets or sets this item's angular velocity (global coordinates).
   * This property cannot be accessed at the top level of the script.
   * 
   * If this item is not a `MovableItem`, the value will be a Zero Vector.
   * If this item is not a physics-enabled `MovableItem`, attempting to modify it will result in an exception.
   * Changes made during grabbing, etc. will be ignored.
   */
  angularVelocity: Vector3;

  /**
   * Adds a force, valid during the current `PhysicsUpdate`, to the item's center of gravity.
   * This can only be used inside the callback of {@link ClusterScript.onPhysicsUpdate}. Calling it elsewhere will result in an exception.
   * 
   * @param force Force (global coordinates)
   */
  addForce(force: Vector3): void;

  /**
   * Adds a torque, valid during the current `PhysicsUpdate`, to the item's center of gravity.
   * This can only be used inside the callback of {@link ClusterScript.onPhysicsUpdate}. Calling it elsewhere will result in an exception.
   * 
   * @param torque Torque (global coordinates)
   */
  addTorque(torque: Vector3): void;

  /**
   * Adds a force (in global coordinates), valid during the current `PhysicsUpdate`, to a specified point on the item.
   * This can only be used inside the callback of {@link ClusterScript.onPhysicsUpdate}. Calling it elsewhere will result in an exception.
   * 
   * @param force Force (global coordinates)
   * @param position Point to apply force (global coordinates)
   */
  addForceAt(force: Vector3, position: Vector3): void;

  /**
   * Adds an impulsive force to the item's center of gravity.
   * To apply impulsive force to points other than the center of gravity, use {@link ClusterScript.addImpulsiveForceAt}.
   * 
   * @param impulsiveForce Impulsive force (global coordinates)
   */
  addImpulsiveForce(impulsiveForce: Vector3): void;

  /**
   * Adds an impulsive torque to the item's center of gravity.
   * 
   * @param impulsiveTorque Impulsive torque (global coordinates)
   */
  addImpulsiveTorque(impulsiveTorque: Vector3): void;

  /**
   * Adds an impulsive force to a specified point on the item.
   * 
   * @param impulsiveForce Impulsive force (global coordinates)
   * @param position Point to apply impulsive force (global coordinates)
   */
  addImpulsiveForceAt(impulsiveForce: Vector3, position: Vector3): void;


  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // States
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * Registers a callback to be called when this item receives a message sent from {@link ItemHandle.send | ItemHandle.send} or sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} to {@link ItemId | ItemId}.
   *
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * By specifying `option`, it can receive messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo}.
   * To receive messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo}, set the argument `option`.
   *
   * If `option` is unset, it will only receive messages from {@link ItemHandle.send | ItemHandle.send}.
   *
   * - If `option.item` is `true`, then messages sent from {@link ItemHandle.send | ItemHandle.send} will be received.
   * - If `option.item` is `false`, then messages sent from {@link ItemHandle.send | ItemHandle.send} will be ignored.
   * - If `option.item` is unset, then messages sent from {@link ItemHandle.send | ItemHandle.send} will be received.
   * - If `option.player` is `true`, the messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be received.
   * - If `option.player` is `false`, then messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be ignored.
   * - If `option.player` is unset, then messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be ignored.
   *
   * The handling of the case where `option.player` is unset is different from that of {@link PlayerScript.onReceive | PlayerScript.onReceive}.
   * With `ClusterScript.onReceive`, it will not receive any messages from PlayerScript if the option is unset in order not to break compatibility of existing scripts.
   *
   * The `sender` value passed to the callback is either ItemHandle or PlayerHandle.
   * Refer [Handles](/script/en/#Handles) in the top page of Script Reference to know how to handle this value.
   * 
   * @example
   * ```ts
   * // Log to output if the message type received is either "damage" or "heal".
   * $.onReceive((messageType, arg, sender) => {
   *   switch (messageType) {
   *     case "damage":
   *       $.log(`damage: ${arg}`);
   *       break;
   *     case "heal":
   *       $.log(`heal: ${arg}`);
   *       break;
   *   }
   * });
   * ```
   *
   * @example
   * ```ts
   * // Receive "attack" messages from PlayerScript and output logs.
   * $.onReceive((messageType, arg, sender) => {
   *   if (messageType === "attack") {
   *     if (sender instanceof ItemHandle) {
   *       $.log(`attack: ${arg}`);
   *     }
   *   }
   * }, { player: true });
   * ```
   *
   * @param callback sender represents the item or player from which it is sent.
   * @param option Option to register callbacks. You can specify the type of messages to receive.
   */
  onReceive(callback: (messageType: string, arg: Sendable, sender: ItemHandle | PlayerHandle) => void, option?: { player: boolean, item: boolean }): void;

  /**
   * Registers a callback to be called when this item receives a text input from the player, requested with {@link PlayerHandle.requestTextInput | PlayerHandle.requestTextInput}.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * @example
   * ```ts
   * $.onTextInput((text, meta, status) => {
   *   switch(status) {
   *     case TextInputStatus.Success:
   *       $.log(text);
   *       break;
   *     case TextInputStatus.Busy:
   *       // Retry in 5 seconds
   *       $.state.should_retry = true;
   *       $.state.retry_timer = 5;
   *       break;
   *     case TextInputStatus.Refused:
   *       // Give up if refused
   *       $.state.should_retry = false;
   *       break;
   *   }
   * });
   * ```
   * @param callback 
   * text = Text entered by the player.
   * 
   * meta = The meta string as specified in {@link PlayerHandle.requestTextInput | PlayerHandle.requestTextInput}.
   * 
   * status = Status signifying the outcome of the text input request.
   */
  onTextInput(callback: (text: string, meta: string, status: TextInputStatus) => void): void;

  /**
   * Registers a callback to be called when this item receives the result of the purchasable item purchase, requested with {@link PlayerHandle.requestPurchase | PlayerHandle.requestPurchase}.
   *
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * @param callback
   * meta = The meta string as specified in {@link PlayerHandle.requestPurchase | PlayerHandle.requestPurchase}.
   *
   * status = Status signifying the outcome of the purchasable item purchase.
   *
   * errorReason = The reason for the failure is provided if the status is {@link PurchaseRequestStatus.Unknown | PurchaseRequestStatus.Unknown }, {@link PurchaseRequestStatus.NotAvailable | PurchaseRequestStatus.NotAvailable }, or {@link PurchaseRequestStatus.Failed | PurchaseRequestStatus.Failed }.
   * If the status is anything else, it is null.
   *
   * player = The player who was requested to purchase the purchasable item.
   */
  onRequestPurchaseStatus(callback: (meta: string, status: PurchaseRequestStatus, errorReason: string | null, player: PlayerHandle) => void): void;

  /**
   * Registers a callback that is called when the status of owned purchasable items changes for players within the space.
   * Simply registering this callback will not trigger any actions.
   * Registering the product ID with {@link ClusterScript.subscribePurchase | ClusterScript.subscribePurchase}, the callback will be invoked for the specified product ID.
   *
   * {@link ClusterScript.getOwnProducts | ClusterScript.getOwnProducts}  can be used to retrieve the details of changes in status of owned purchasable items.
   *
   * In some situations, the callback may not be called even though the status of owned purchasable items has changed.
   * Script should be implemented so that the status of owned purchasable items is reflected in the world by using methods like `getOwnProduct`, even in cases where the callback was not called or when a player who has already purchased the item enters the space.
   *
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * @param callback
   * player = The player whose status of owned purchasable items has changed.
   * productId = The product ID of the target purchasable item.
   */
  onPurchaseUpdated(callback: (player: PlayerHandle, productId: string) => void): void;

  /**
   * Registers a purchasable item in {@link ClusterScript.onPurchaseUpdated | ClusterScript.onPurchaseUpdated} for detecting changes in status of owned purchasable items.
   * This API cannot be called at the top level of the script.
   *
   * @param productId The product ID for detecting changes in status of owned purchasable items.
   */
  subscribePurchase(productId: string): void;

  /**
   * Unregisters a purchasable item in {@link ClusterScript.onPurchaseUpdated | ClusterScript.onPurchaseUpdated} for detecting changes in status of owned purchasable items.
   * This API cannot be called at the top level of the script.
   *
   * @param productId The product ID for detecting changes in status of owned purchasable items.
   */
  unsubscribePurchase(productId: string): void;

  /**
   * Registers a callback that is called when retrieving the status of owned purchasable items requested in {@link ClusterScript.getOwnProducts | ClusterScript.getOwnProducts}.
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * The status of owned purchasable items will be provided in the `ownProducts` of the callback if the player has purchased the specified item.
   * The `OwnProduct` will not be included in the array if the player has not purchased the specified item.
   *
   * #### Differences in behavior based on room type
   *
   * When called in a test space, the 'ownProducts' in the callback will only include the status of owned purchasable items resulting from item purchases made within that test space.
   * Status of owned purchasable items in the test space is managed separately from other space, and item purchases in the test space do not affect status of owned purchasable items in other space.
   *
   * Called in an event, the `ownProducts` in the callback will always be an empty array.
   *
   * @param callback response: The status of owned purchasable items of the successfully retrieved item. It is null in case of failure. meta: The same string passed during getOwnProducts. errorReason: The reason for failure if response is null.
   */
  onGetOwnProducts(callback: (ownProducts: OwnProduct[] | null, meta: string, errorReason: string | null) => void): void;

  /**
   * Provides access to the `state` of individual items.
   * Arbitrary property names can be used as keys for reading/writing data in the `state`.
   * 
   * @example
   * Reading from a not yet defined property will default to returning `undefined`.
   * ```ts
   * let v = $.state.exampleKey; // Read the value of the key "exampleKey". If it has never been written to before, it will return undefined.
   * if (v == null) { v = 0.0; }
   * $.state.exampleKey = v + 1;
   * ```
   * 
   * Values of the {@link Sendable} type can also be written and saved to states.
   * 
   * Specifically, you can use numbers, strings, booleans, {@link Vector2}, {@link Vector3}, {@link Quaternion}, {@link PlayerHandle}, {@link ItemHandle}, arrays of the aforementioned types, and objects having keys assigned with strings.
   * 
   * If you try to write a non-Sendable value, such as `undefined`, it will be ignored.
   * This behavior may change in future releases.
   *    
   * @example
   * ```ts
   * $.state.exampleKey1 = 1; // Write a number
   * $.state.exampleKey2 = "hello"; // Write a string
   * $.state.exampleKey3 = true; // Write a boolean
   * $.state.exampleKey4 = { foo: "bar" }; // Write an object
   * $.state.exampleKey5 = [1, 2, 3]; // Write an array
   * $.state.exampleKey6 = { // Write a complex object
   *   array: [1, 2, 3],
   *   object: { foo: "bar" },
   * };
   * ```
   * 
   * @example
   * To make changes on arrays and objects reflect on a `state`, they need to be reassigned.
   * ```ts
   * $.state.exampleKey = [1, 2, 3];
   * // $.state.exampleKey.push(4); // This will NOT make the changes reflect on the state
   * 
   * // This will make the changes reflect on the state
   * const v = $.state.exampleKey;
   * v.push(4);
   * $.state.exampleKey = v;
   * ```
   */
  state: StateProxy;

  /**
   * @beta
   * Provides access to the group state.
   * Similar to {@link state}, it allows read/write access, but the value is shared across all items belonging to the item group.
   * 
   * If the item does not belong to an item group, a {@link ClusterScriptError} will be thrown.
   * 
   * For more details on item groups, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world/item/item-group/).
   */
  groupState: StateProxy;

  /**
   * In Worlds made using the Creator Kit, obtains a message from the target. If used outside of items in Creator Kit-developed worlds, a runtime error will occur.
   * 
   * @example
   * ```ts
   * // Obtain a message to this item, with the identifer "foo", in the boolean type.
   * $.getStateCompat("this", "foo", "boolean");
   * ```
   * 
   * @param target The target from which to obtain messages
   *
   * `"this"`: Obtain a message for this item.
   *
   * `"owner"`: Obtain a message for this item's owner.
   *
   * `"global"`: Obtain a global message.
   *
   * @param key Message identifier
   * @param parameterType Message type
   *
   * Can be one of the following: `"signal"`, `"boolean"`, `"float"`, `"double"`, `"integer"`, `"vector2"`, and `"vector3"`.
   *
   * @returns
   * If `"signal"` is specified for `parameterType`, returns the date when the signal was notified as a `Date`.\
   * For other parameterTypes, returns the message value, if exists, which may be one of the following: numbers, booleans, {@link Vector2}, and {@link Vector3}.
   */
  getStateCompat(target: CompatGimmickTarget, key: string, parameterType: CompatParamType): CompatSendable | Date | undefined;

  /**
   * In Worlds made using the Creator Kit, sends a message to the target. If used outside of items in Creator Kit-developed worlds, a runtime error will occur.
   * 
   * @example
   * ```ts
   * // Send a message to this item, with the identifier "foo", in the boolean type.
   * $.setStateCompat("this", "foo", true);
   * ```
   * 
   * @param target The target to send the message
   *
   * `"this"`: Send a message to this item.
   *
   * `"owner"`: Send a message to this item's owner.
   *
   * @param key Message identifier
   * @param value Message value
   *
   * Can be one of the following: numbers, booleans, {@link Vector2}, and {@link Vector3}.
   */
  setStateCompat(target: CompatStateTarget, key: string, value: CompatSendable): void;

  /**
   * In Worlds made using the Creator Kit, sends a signal to the target. If used outside of items in Creator Kit-developed worlds, a runtime error will occur.
   * 
   * @param target The target to send the message
   *
   * `"this"`: Send a message to this item.
   *
   * `"owner"`: Send a message to this item's owner.
   * 
   * @param key Message identifier
   */
  sendSignalCompat(target: CompatStateTarget, key: string): void;

  /**
   * Gets the owner of the item.
   * For more details about ownership, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world/item/owner/).
   * @beta
   */
  getOwner(): PlayerHandle;

  /**
   * Request to change the owner of the item.
   * For more details about ownership, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world/item/owner/).
   * 
   * Changing the owner may take some time.
   * If the player is grabbing, riding, manipulating the item in craft mode, or editing the script of it, the change of owner will fail.
   * It can fail due to factors like the network status of the target player or interactions from other players.
   * 
   * #### Rate limitations
   * 
   * An item can request owner changes up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * @param player The player to assign as the new owner
   * @beta
   */
  requestOwner(player: PlayerHandle): void;

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // External Call
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  
  /**
   * Registers a callback to be called upon the completion of {@link ClusterScript.callExternal}.
   * The callback is called once upon success or failure of callExternal.
   *
   * Only supported for calls at the script's top level.
   * If called multiple times at the top level, only the last registration is effective.
   *
   * @param callback response: The response obtained from external. It is null in case of failure. meta: The same string passed during callExternal. errorReason: The reason for failure if response is null.
   */
  onExternalCallEnd(callback: (response: string | null, meta: string, errorReason: string | null) => void): void;
  
  /**
   * Sends a request outside of the space.
   * The response is received through {@link ClusterScript.onExternalCallEnd}.
   * To use this call, the developer themselves must prepare an external server.
   *
   * Also refer the documentation for [External communication](https://docs.cluster.mu/creatorkit/en/world/manage-data/call-external/) for more information on the external communication feature. 
   * 
   * #### Frequency Limit
   * 
   * There are no frequency limitations on calling `callExternal` itself, but the external server must be able to respond at an appropriate frequency.  
   * If it appears that the server is under heavy load and unable to respond, restrictions may be applied, or we may contact you for further inquiries.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * #### Limitations from Flow Control
   * 
   * The `callExternal` operation will only succeed if Flow Control Delay is 30 seconds or less.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   *
   * #### Size Limit
   * If the request or meta exceeds the size limit, {@link ClusterScriptError} (`requestSizeLimitExceeded`) will occur.
   *
   * #### Setup
   * Endpoint and Verify Token are required to use `callExternal`.
   * Endpoint and Verify Token can be registered/created through `external communication (callExternal) connection URL` of Creator Kit.
   *
   * Endpoints are used to specify the endpoint URL for the external server to receive requests.
   * A maximum of 100 endpoints can be registered per account.
   * 
   * Verify Tokens are used to confirm the developer themselves manages the endpoint.
   * A maximum of two tokens can be registered per account.
   *
   * #### How to Use
   * Requests are sent to the endpoint tied to the account that uploaded the item/world, and specified by endpointId. 
   *
   * Each time `callExternal` is called from Cluster Script, an HTTP POST call is made from Cluster's server to the endpoint.
   * The data included in the response to the POST is passed to `onExternalCallEnd`.
   * If the endpoint does not respond within 5 seconds timeout or returns an error, it is considered a failure.
   * There are no retries from Cluster to the endpoint.
   *
   * #### Endpoint Specifications
   * Must respond to HTTP POST in the following format.
   * Only HTTP/1.1 and HTTP/2 are supported, calls via HTTP/3 are not supported.
   * Both HTTP and HTTPS are supported, but HTTPS is recommended for security reasons upon publication.
   *
   * **Request**
   * ```json
   * {
   *   "request": "...string (100kB or less)..."
   * }
   * ```
   *
   * **Response**
   * ```json
   * {
   *   "verify": "...verify_token (can be obtained in Creator Kit)...",
   *   "response": "...string (100kB or less)..."
   * }
   * ```
   *
   * One of the Verify Tokens tied to the account should be provided in the verify field.
   *
   * In cases below, it is considered an invalid response and `callExternal` is treated as a failure.
   *
   * - If the response field exceeds 100kB
   * - If any valid verification token is not provided in the verify field
   * 
   * If the ownership of the endpoint cannot be confirmed due to an invalid response, etc., the use of the callExternal API may be restricted.
   * Similarly, restrictions or inquiries may be made in cases where it is thought that responses are not being made due to high load.
   *
   * #### Privacy
   * Sending information that corresponds to personal information of players without their consent is prohibited.
   * If such use is suspected, there may be restrictions on the use of the callExternal API or inquiries regarding the purpose of use.
   * Also, if deemed inappropriate by us, we may restrict its use without notice.
   *
   * @param endpointId The Endpoint ID to specify the target external server.
   * @param request A string less than 100kB. It is sent to an external server.
   * @param meta A string less than 100 bytes. It can be used to identify multiple `callExternal` calls. It is fine to specify an empty string or the same string multiple times.
   */
  callExternal(endpointId: ExternalEndpointId, request: string, meta: string): void;

  /**
   * Sends a request to outside the space instance without specifying the target endpoint.
   * The request is sent to the endpoint registered with `external communication (callExternal) connection URL` of legacy Creator Kit version.
   *
   * @deprecated
   * This API is deprecated by Creator Kit v2.32.0 or later.\
   * Instead, please use {@link ClusterScript.callExternal} overload that passes {@link ExternalEndpointId}.
   *
   * @param request A string less than 100kB. It is sent to an external server.
   * @param meta A string less than 100 bytes. It can be used to identify multiple `callExternal` calls. It is fine to specify an empty string or the same string multiple times.
   */
  callExternal(request: string, meta: string): void;

  /**
   * Registers the scripts held by the item's Player Script component to the player.
   * If the item does not have a PlayerScript component attached, an Error is thrown.
   *
   * For more information on PlayerScript components, please refer to [Documentation](https://docs.cluster.mu/creatorkit/en/item-components/player-script/).
   *
   * When this item is deleted, the script is unregistered.
   * If the `setPlayerScript` method is called multiple times for the same player, the previously registered scripts are deleted and only the last registered script is executed.
   *
   * In the registered script, you can use {@link PlayerScript.sourceItemId | PlayerScript.sourceItemId} to obtain a reference to the item which registered the script.
   *
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * #### PlayerScript of craft items
   *
   * `setPlayerScript` is beta feature for craft items.
   */
  setPlayerScript(playerHandle: PlayerHandle): void;

  /**
   * Asynchronously retrieves the status of owned purchasable items purchased by the player in this world.
   * The retrieved status of owned purchasable items is passed to the callback set in {@link ClusterScript.onGetOwnProducts | ClusterScript.onGetOwnProducts}.
   *
   * If the player has purchased the specified item, the status of owned purchasable items will be included in the `ownProducts` of the callback.
   * If the player has not purchased the specified item, the corresponding `OwnProduct` for the player will not be included in the array.
   *
   * #### Frequency Limit
   * There is a limit on how often getOwnProducts can be called.
   * - If the item running this script is a craft item, 5 times per minute per item
   * - If the item running this script is a world item, a total of 100 times per minute per space for all world items
   *
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls stays below this limit.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   * @param productId The product ID for the targe purchasable item.
   * @param players A list of players whose status of owned purchasable items is to be retrieved.
   * @param meta A string less than 100 bytes. It can be used to identify multiple getOwnProducts calls. It is fine to specify an empty string or the same string multiple times.
   */
  getOwnProducts(productId: string, players: PlayerHandle | PlayerHandle[], meta: string): void;

  /**
   * Sets the players who can see this item.
   *
   * Before calling this method, the Item is set to be visible to everyone.
   *
   * If this method is called, the settings for which players can see the item set with this method will be overwritten.
   *
   * The only things that change are whether or not the item is visible and whether or not it can be interacted with.
   * The physical behavior and collision detection are not changed.
   *
   * `setVisiblePlayers` and `clearVisiblePlayers` change the enabled property of the Renderer contained in the item.
   * Therefore, if you are using an Animator or other method to change the enabled state of a Renderer contained in an item in a world uploaded from Creator Kit, this function may not work properly if used in conjunction with it.
   *
   * To cancel this setting, use {@link ClusterScript.clearVisiblePlayers | ClusterScript.clearVisiblePlayers}.
   *
   * If the players argument is null, an exception will be thrown.
   * The maximum number of elements in the array of players that can be passed as an argument is 64.
   *
   * @param players List of players who will be able to see the item
   */
  setVisiblePlayers(players: PlayerHandle[]): void;

  /**
   * Clear the settings of players who can see this Item.
   *
   * If cleared, the Item will be visible to all.
   */
  clearVisiblePlayers(): void;

  /**
   * Gets the handle of the Unity component attached to this object by type name.
   * The available type names are defined in {@link UnityComponent}.
   * 
   * If the object has multiple components, returns first component.
   * 
   * This API is only available for worlds uploaded from the Creator Kit. This API is not available from Craft Items.
   * 
   * @param type 
   * @returns The component specified by type name, or `null` if not found
   */
  getUnityComponent(type: string) : UnityComponent | null;

  /**
   * Returns whether the space in which this item is placed is an event.
   *
   * @returns `true` for events, `false` otherwise
   */
  isEvent(): boolean;

  /**
   * Registers a callback to be called when player's move input changed during riding the item.
   * The item must have a `RidableItem` Component attached.
   * If `SteerItemTrigger` Component is attached to the item, the callback is not called and `SteerItemTrigger` will be triggered instead.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * 
   * `input` value in `callback` indicates move input of the player by stick or keyboard.
   * Magnitude of `input` is between 0 and 1.
   * 
   * Left and right input is represented as `x`, and right direction is positive.
   * Forward and backward input is represented as `y`, and forward direction is positive.
   * 
   * @param callback 
   * 
   * input = The move input value of the player.
   * 
   * player = The handle of the player controlling the item.
   * 
   */
  onSteer(callback: (input: Vector2, player: PlayerHandle) => void): void;

  /**
   * Registers a callback to be called when player's additional axis input changed during riding the item.
   * The item must have a `RidableItem` Component attached.
   * If `SteerItemTrigger` Component is attached to the item, the callback is not called and `SteerItemTrigger` will be triggered instead.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * 
   * The input method differs depending on the device of the player.
   * Either way, the input value is between -1 and 1.
   * 
   * - In mobile devices, input is made using up/down button at the bottom right side in screen.
   * - In desktop devices, space key and left shift key is treated as up and down button, respectively.
   * - In VR devices, player input is made by right hand controller.
   * 
   * @param callback 
   * 
   * input = The input value of the player.
   * 
   * player = The handle of the player controlling the item.
   * 
   */
  onSteerAdditionalAxis(callback: (input: number, player: PlayerHandle) => void): void;

  /** 
   * Registers a callback to be called when the players have sent gifts in an event.
   * 
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   * 
   * When the current space is not an event, then callback can be registered but the callback is not called except using test-purpose functions referred below.
   * 
   * `gifts` can have different order from the order that the gifts actually has been sent.
   * It is possible that the callback is called with multiple gifts.
   * 
   * This method can be tested in world or craft space without using Cluster Coin.
   * Please see detail at [Slash Commands](https://docs.cluster.mu/creatorkit/en/world/testing/slash-command/).
   * 
   * @example 
   * ```ts
   * // Gets the players' display names who sent the gifts in an event.
   * $.onGiftSent((gifts) => {
   *   let names = gifts.map(g => g.senderDisplayName);
   * });
   * ```
   * 
   * @param callback
   * 
   * gifts: The data of the gift sent.
   * 
   */
  onGiftSent(callback: (gifts: GiftInfo[]) => void): void;

  /**
   * Get the most recent comments, up to the specified `count`.
   *
   * The `count` can be a natural number up to 100, and specifies the maximum number of comments to be obtained.
   * In some cases, it may not be possible to obtain enough of the past comments.
   * In this case, the array will contain fewer comments than the `count`.
   *
   * The `count` is clamped between 0 and 100.
   *
   * The comments are roughly ordered from the earliest time, but the order is not guaranteed to be stable.
   * The order of comments with similar posting times may change each time they are retrieved.
   *
   * This API is only available in the event and test spaces.
   * If you use this API other than in the event and test spaces, it will return an empty array.
   */
  getLatestComments(count: number): Comment[];

  /**
   * Register a callback to be called when a comment is submitted.
   *
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * Due to timing issues, there is a possibility that the callback will be called twice for the same comment, or that the callback will not be called at all.
   *
   * The callback may be called for two or more comments at once.
   *
   * This API is only available in the event and test spaces.
   * Other than in the event and test spaces, registering callbacks using this API will succeed, but the callbacks will not be called.
   */
  onCommentReceived(callback: (comments: Comment[]) => void): void;

  /**
   * Registers a callback to be called when this item receives the result of a product grant request performed using {@link PlayerHandle.requestGrantProduct | PlayerHandle.requestGrantProduct}.
   *
   * Supported only when called at the top level of the script.
   * If called multiple times at the top level, only the last registration will be valid.
   *
   * #### Behavior differences by room type
   *
   * When called in a test space, the callback argument {@link ProductGrantResult.status | result.status} will indicate `"Granted"` regardless of whether the target player is the seller or already owns the product. However, the product is not actually granted.
   *
   * @param callback result = Indicates the result of the product grant request.
   */
  onRequestGrantProductResult(callback: (result: ProductGrantResult) => void): void;
}

/** @internal @item */
type StateProxy = {
  [propName: string]: Sendable;
};

/** @internal @item */
type CompatGimmickTarget = "this" | "owner" | "global";

/** @internal @item */
type CompatStateTarget = "this" | "owner";

/** @internal @item */
type CompatParamType = "signal" | "boolean" | "float" | "double" | "integer" | "vector2" | "vector3";

/** @internal @item */
type CompatSendable = boolean | number | Vector2 | Vector3;

/**
 * Data types that can be saved to {@link ClusterScript.state | ClusterScript.state} or sent using {@link ItemHandle.send | ItemHandle.send}.
 * 
 * Specifically, values below are {@link Sendable}:
 *
 * - `null`
 * - numbers
 * - strings
 * - booleans
 * - {@link Vector2}
 * - {@link Vector3}
 * - {@link Quaternion}
 * - {@link PlayerHandle}
 * - {@link ItemHandle}
 * - arrays of {@link Sendable}
 * - objects having keys assigned with strings and {@link Sendable} as values
 * 
 * Notably, Sendable does not include `undefined`.
 * 
 * #### Conversion from non-Sendable to Sendable
 *
 * If a non-Sendable value, such as `undefined`, is passed to APIs that require a Sendable value, it will be handled according to the following rules.
 * 
 * - If a non-Sendable value such as `undefined` is passed directly, it will either throw an error or be ignored depending on the API.
 * - If an array containing non-Sendable values such as `undefined` is passed, it will be treated as Sendable by converting the non-Sendable values to `null`.
 * - If an object containing non-Sendable values such as `undefined` is passed, it will be treated as Sendable by deleting the corresponding key-values.
 * 
 * If these behaviors occur, a warning message will be logged to the script console.
 * These behaviours are planned to throw errors instead in future updates. 
 *
 * #### Conversion from Sendable to PlayerScriptSendable
 *
 * When {@link Sendable} is sent to PlayerScript, values that cannot be treated as {@link PlayerScriptSendable} are converted to {@link PlayerScriptSendable} based on the following rules.
 *
 * - {@link PlayerHandle} becomes {@link PlayerId} that represents the same player.
 * - {@link ItemHandle} becomes {@link ItemId} that represents the same item.
 * - Contents of arrays and objects are converted in the same manner.
 *
 * @example
 * ```ts
 * $.state.exampleKey1 = 1; // Write a number
 * $.state.exampleKey2 = "hello"; // Write a string
 * $.state.exampleKey3 = true; // Write a boolean
 * $.state.exampleKey4 = { foo: "bar" }; // Write an object
 * $.state.exampleKey5 = [1, 2, 3]; // Write an array
 * $.state.exampleKey6 = { // Write a complex object
 *   array: [1, 2, 3],
 *   object: { foo: "bar" },
 * };
 * ```
 * 
 * @example
 * ```ts
 * itemHandle.send("message1", 10); // Send a number
 * itemHandle.send("message2", "hello"); // Send a string
 * itemHandle.send("message3", true); // Send a boolean
 * itemHandle.send("message4", { foo: "bar" }); // Send an object
 * itemHandle.send("message5", [1, 2, 3]); // Send an array
 * itemHandle.send("message6", { // Send a complex object
 *   array: [1, 2, 3],
 *   object: { foo: "bar" },
 * });
 * ```
 * @item
 */
type Sendable = ExtJSON<SendablePrims>;

/**
 * Data types that can be sent with {@link Sendable} in addition to ordinary JSON.
 * @item
 */
type SendablePrims = Vector2 | Vector3 | Quaternion | PlayerHandle | ItemHandle;

/**
 * Data types that can be sent using {@link PlayerScript.sendTo | PlayerScript.sendTo}.
 *
 * Specifically, values below are {@link PlayerScriptSendable}:
 *
 * - `null` 
 * - numbers
 * - strings
 * - booleans
 * - {@link Vector2}
 * - {@link Vector3}
 * - {@link Quaternion}
 * - {@link PlayerId}
 * - {@link ItemId}
 * - arrays of {@link PlayerScriptSendable}
 * - objects having keys assigned with strings and {@link PlayerScriptSendable} as values
 * 
 * Notably, PlayerScriptSendable does not include `undefined`.
 * 
 * #### Conversion from non-PlayerScriptSendable to PlayerScriptSendable
 *
 * If a non-PlayerScriptSendable value, such as `undefined`, is passed to APIs that require a PlayerScriptSendable value, it will be handled according to the following rules.
 *
 * - If a non-PlayerScriptSendable value such as `undefined` is passed directly, it will either throw an error or be ignored depending on the API.
 * - If an array containing non-PlayerScriptSendable values such as `undefined` is passed, it will be treated as PlayerScriptSendable by converting the non-PlayerScriptSendable values to `null`.
 * - If an object containing non-PlayerScriptSendable values such as `undefined` is passed, it will be treated as PlayerScriptSendable by deleting the corresponding key-values.
 *
 * If these behaviors occur, a warning message will be logged to the script console.
 * These behaviours are planned to throw errors instead in future updates.
 * 
 * #### Conversion from Sendable to PlayerScriptSendable
 * 
 * When {@link PlayerScriptSendable} is sent to ItemScript, values that cannot be treated as {@link Sendable} are converted to {@link Sendable} based on the following rules.
 *
 * - {@link PlayerId} becomes {@link PlayerHandle} that represents the same player.
 * - {@link ItemId} becomes {@link ItemHandle} that represents the same item.
 * - Contents of arrays and objects are converted in the same manner. 
 *
 * @example
 * ```ts
 * _.sendTo(_.sourceItemId, "message1", 10); // Send a number
 * _.sendTo(_.sourceItemId, "message2", "hello"); // Send a string
 * _.sendTo(_.sourceItemId, "message3", true); // Send a boolean
 * _.sendTo(_.sourceItemId, "message4", { foo: "bar" }); // Send an object
 * _.sendTo(_.sourceItemId, "message5", [1, 2, 3]); // Send an array
 * _.sendTo(_.sourceItemId, "message6", { // Send a complex object
 *   array: [1, 2, 3],
 *   object: { foo: "bar" },
 * });
 * ```
 * @player 
 */
type PlayerScriptSendable = ExtJSON<PlayerScriptSendablePrims>;

/**
 * Data types that can be sent with {@link PlayerScriptSendable} in addition to ordinary JSON.
 * @player
 */
type PlayerScriptSendablePrims = Vector2 | Vector3 | Quaternion | PlayerId | ItemId;

/**
 * This type extends the primitives of data structures that are representable as JSON, by also including `T`.
 * 
 * Unlike ordinary JSON, this type can also handle `Infinity`, `-Infinity`, and `NaN` as numbers.  
 */
type ExtJSON<T> = { [key: string]: ExtJSON<T> } | ExtJSON<T>[] | number | string | boolean | null | T;

/**
 * Optional value used to incorporate pose data information from the humanoid model.
 * By passing it as an argument to PlayerHandle.setHumanoidPose, you can control how the pose data is configured for the target avatar.
 * @item
 */
type SetHumanoidPoseOption = {
 /**
  * The number of seconds for reflecting pose data overrides in HumanoidPose.
  * During the transition to the overridden pose data, the current pose data of the avatar and the overridden pose data are linearly interpolated based on time.
  *
  * Can be set to a value greater than or equal to 0.
  * If a value less than 0 or NaN is set, 0 will be applied.
  * If not set, it is treated as 0.
  */
 transitionSeconds: number;
 /**
  * The setting for the number of seconds required to cancel a configured HumanoidPose.
  * The override of the pose data by `setHumanoidPose` can be cancelled when the specified number of seconds has elapsed after the pose data is set.
  *
  * Can be set to a value greater than or equal to `transitionSeconds`.
  * If a value smaller than `transitionSeconds` is set, the value of `transitionSeconds` will be applied.
  * Setting NaN will result in Infinity being applied.
  * If not set, it is treated as Infinity.
  * If Infinity is set, the pose data will not be canceled over time.
  */
 timeoutSeconds: number;
 /**
  * The number of seconds for returning to the original pose data when the pose data override is cancelled using timeoutSeconds.
  * During the transition to the original pose data, the overridden pose data and the original pose data are linearly interpolated based on time.
  *
  * Can be set to a  value greater than or equal to 0.
  * If a value less than 0 or NaN is set, 0 will be applied.
  * If not set, it is treated as 0.
  */
 timeoutTransitionSeconds: number
}

/**
 * @item @beta
 * Option values used with {@link ClusterScript.createItem | ClusterScript.createItem}.
 */
type CreateItemOption = {
  /**
   * Generates the item as a member item of an item group.
   * 
   * If the calling item is not a host item, a {@link ClusterScriptError} will be thrown.
   * If the specified world item template has an [Item Group Host](https://docs.cluster.mu/creatorkit/en/item-components/item-group-host/) component, the item will be generated as a host item regardless of the value of `asMember`.
   * 
   * For more details on item groups, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world/item/item-group/).
   */
  asMember: boolean;
}

/**
 * A handle to manipulate child objects of this item.
 * @item
 */
interface SubNode {
  /**
   * The name of the SubNode object.
   * It is the same as the `subNodeName` specified in {@link ClusterScript.subNode | ClusterScript.subNode}.
   * @example
   * ```ts
   * let subNode = $.subNode("MySubNode");
   * $.log(subNode.name); // => MySubNode
   * ```
   */
  readonly name: string;

  /**
   * Specify a position to move the `SubNode` to.
   * As the positions are interpolated and synced across the network, please be aware they may not be reflected immediately.
   * 
   * @param pos Target position (local coordinates of the item)
   */
  setPosition(pos: Vector3): void;

  /**
   * Obtains the current position of the `SubNode`.
   * If you call this immediately after calling setPosition, please be aware it will return the `SubNode`'s current position, not the value passed to setPosition.
   *
   * If the value cannot be obtained, this method will return `undefined`.
   *
   * @returns Current position (local coordinates of the item)
   */
  getPosition(): Vector3 | undefined;

  /**
   * Specify a rotation to rotate the `SubNode` to.
   * As the rotations are interpolated and synced across the network, please be aware they may not be reflected immediately.
   * 
   * @param rot Target rotation (local coordinates of the item)
   */
  setRotation(rot: Quaternion): void;

  /**
   * Obtains the current rotation of the `SubNode`.
   * If you call this immediately after calling setRotation, please be aware it will return the `SubNode`'s current rotation, not the value passed to setRotation.
   *
   * If the value cannot be obtained, this method will return `undefined`.
   *
   * @returns Current rotation (local coordinates of the item)
   */
  getRotation(): Quaternion | undefined;

  /**
   * Obtains the current position.
   * If you call this immediately after calling setPosition, please be aware it will return the `SubNode`'s current position, not the value passed to setPosition.
   *
   * If the value cannot be obtained, this method will return `null`.
   *
   * @returns Current position (Global coordinates)
   */
  getGlobalPosition(): Vector3 | null;

  /**
   * Obtains the current rotation.
   * If you call this immediately after calling setRotation, please be aware it will return the `SubNode`'s current rotation, not the value passed to setRotation.
   *
   * If the value cannot be obtained, this method will return `null`.
   *
   * @returns Current rotation (Global coordinates)
   */
  getGlobalRotation(): Quaternion | null;

  /**
   * Modifies the Enabled state of the `SubNode`.
   * A disabled `SubNode` and all of its children will be treated as disabled in the space. It will not be displayed, and will be excluded from collision detection.
   * 
   * As the Enabled state is synced across the network, please be aware it may not be reflected immediately.
   * 
   * @param v `true` if Enabled
   */
  setEnabled(v: boolean): void;

  /**
   * Obtains the Enabled state of the `SubNode`.
   * 
   * If you call this immediately after calling setEnabled, please be aware it will return the `SubNode`'s current Enabled state, not the state passed to setEnabled.
   *
   * If the value cannot be obtained, this method will return `undefined`.
   *
   */
  getEnabled(): boolean | undefined;

  /**
   * Obtains whether the `SubNode` is treated as Enabled in the space.
   * A `SubNode` is treated as Enabled in the space only when the `SubNode`, and all of its parents, are Enabled.
   * 
   * If you call this immediately after calling setEnabled, please be aware it will return the `SubNode`'s current Enabled state, not the state passed to setEnabled.
   *
   * If the value cannot be obtained, this method will return `undefined`.
   *
   */
  getTotalEnabled(): boolean | undefined;

  /**
   * Specify a text string for the `SubNode`'s text display.
   * Line breaks can be used by entering `\n`.
   * The string must be 1 KB or less in size.
   * If the string exceeds 1 KB, this method will fail with a {@link ClusterScriptError} (`requestSizeLimitExceeded`) error.
   * If the `SubNode` does not have a `TextView` attached, nothing will happen.
   * 
   * For details on TextView, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world-components/text-view/).
   * 
   * @param text
   */
  setText(text: string): void;

  /**
   * Specify the font size for the `SubNode`'s text display.
   * The `size` is clamped between 0 and 5.
   * The final display size of the text depends on both the `size` value set here, and the global scale of the `SubNode`.
   * When the global scale of the `SubNode` is 1 and `size` is set to 1, the x-height of the text will be approximately 1 meter tall.
   * If the `SubNode` does not have a `TextView` attached, nothing will happen.
   * 
   * For details on TextView, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world-components/text-view/).
   * 
   * @param size
   */
  setTextSize(size: number): void;

  /**
   * Specify the horizontal text alignment (if the text contains line breaks) of the `SubNode`'s text display.
   * If the `SubNode` does not have a `TextView` attached, nothing will happen.
   * 
   * For details on TextView, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world-components/text-view/).
   * 
   * @example
   * ```ts
   * subNode.setTextAlignment(TextAlignment.Left);
   * ```
   * @param alignment
   */
  setTextAlignment(alignment: TextAlignment): void;

  /**
   * Specify the anchor position of the `SubNode`'s text display.
   * eg. When set to `UpperLeft`, the upper left corner of the text display will match the `SubNode`'s position.
   * If the `SubNode` does not have a `TextView` attached, nothing will happen.
   * 
   * For details on TextView, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world-components/text-view/).
   * 
   * @example
   * ```ts
   * subNode.setTextAnchor(TextAnchor.UpperLeft);
   * ```
   * @param alignment
   */
  setTextAnchor(anchor: TextAnchor): void;

  /**
   * Specify the font color of the `SubNode`'s text display.
   *
   * The value passed to this method is treated as a value in the sRGB color space.
   * Each specified RGBA value is clamped between 0 and 1.
   * If the `SubNode` does not have a `TextView` attached, nothing will happen.
   * 
   * For details on TextView, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/world-components/text-view/).
   * 
   * @param r Red value
   * @param g Green value
   * @param b Blue value
   * @param a Alpha value (will be transparent when 0)
   */
  setTextColor(r: number, g: number, b: number, a: number): void;

  /**
   * Gets the handle of the Unity component attached to this object by type name.
   * The available type names are defined in {@link UnityComponent}.
   * 
   * If the object has multiple components, returns first component.
   * 
   * This API is only available for worlds uploaded from the Creator Kit. This API is not available from Craft Items.
   * 
   * @param type 
   * @returns The component specified by type name, or `null` if not found
   */
  getUnityComponent(type: string) : UnityComponent | null;
}

/**
 * Describes the anchor positions of text.
 * @item
 */
declare enum TextAnchor {
  UpperLeft,
  UpperCenter,
  UpperRight,
  MiddleLeft,
  MiddleCenter,
  MiddleRight,
  LowerLeft,
  LowerCenter,
  LowerRight,
}

/**
 * Describes the horizontal text alignment positions of text that contains line breaks.
 * @item
 */
declare enum TextAlignment {
  Left,
  Center,
  Right,
}

/**
 * A read-only type describing the result of a raycast.
 * @item
 */
interface RaycastResult {
  /**
   * Describes a hit.
   */
  readonly hit: Hit;

  /**
   * Returns a handle that describes the object hit, or `null`.
   *
   * If the object hit is an item, returns {@link ItemHandle}.  
   * If the object hit is a player, returns {@link PlayerHandle}.  
   * If the object hit is not an item or a player, returns `null`.
   * 
   * Refer [Handles](/script/en/#Handles) in the top page of Script Reference to know how to handle this value.
   */
  readonly handle: ItemHandle | PlayerHandle | null;
}

/**
 * A read-only type describing where a raycast had hit.
 */
interface Hit {
  /**
   * Describes the point where the raycast hit. (global coordinates)
   */
  readonly point: Vector3;

  /**
   * Describes the normal of where the raycast hit. (global coordinates)
   */
  readonly normal: Vector3;
}

/**
 * Describes a collision event between an item and another object.
 * @item
 */
interface Collision {
  /**
   * Returns a handle that describes the collided object, or `null`.
   *
   * If the collided object is an item, returns {@link ItemHandle}.  
   * If the collided object is a player, returns {@link PlayerHandle}.  
   * If the collided object is not an item or a player, returns `null`.
   * 
   * Refer [Handles](/script/en/#Handles) in the top page of Script Reference to know how to handle this value.
   */
  readonly handle: ItemHandle | PlayerHandle | null;

  /**
   * Describes information of the collision point(s).
   * If the collided object is touching with its surface or edge, it will be represented as multiple collision points.
   */
  readonly collidePoints: CollidePoint[];

  /**
   * The total amount of impulse generated from the collision.
   */
  readonly impulse: Vector3;

  /**
   * The relative velocity of the collided object as seen from the item.
   */
  readonly relativeVelocity: Vector3;
}

/**
 * Describes a single collision point between an item and another object.
 * @item
 */
interface CollidePoint {
  /**
   * Describes which part of the collision source item is colliding.
   */
  readonly selfNode: ClusterScript | SubNode;

  /**
   * Describes a point on the collision target object.
   */
  readonly hit: Hit;
}

/**
 * Describes an overlap between an item and another object.
 * @item
 */
interface Overlap {
  /**
   * Returns a handle that describes the overlapping object, or `null`.
   *
   * If the overlapping object is an item, returns {@link ItemHandle}.  
   * If the overlapping object is a player, returns {@link PlayerHandle}.  
   * If the overlapping object is not an item or a player, returns `null`.
   * 
   * Refer [Handles](/script/en/#Handles) in the top page of Script Reference to know how to handle this value.
   */
  readonly handle: ItemHandle | PlayerHandle | null;

  /**
   * Describes which part of the item is overlapping.
   */
  readonly selfNode: ClusterScript | SubNode;
}

/**
 * Describes animation data for a humanoid model.
 * To add animation data to an item, register an `AnimationClip` to a `HumanoidAnimationList`.
 * This can be obtained using {@link ClusterScript.humanoidAnimation | ClusterScript.humanoidAnimation}.
 *
 * For details on `HumanoidAnimationList`, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/item-components/humanoid-animation-list/).
 */
interface HumanoidAnimation {

  /**
   * Obtains the pose data of a humanoid model at a given playback position.
   * The playback position value will be 0 for the beginning of the animation, and the value of `getLength()` for the end.
   *
   * For loop animations, if a playback position after the end of the animation is specified, returned pose data takes the loop into account.
   * Otherwise, the specified playback position will be clamped between the start and the end of the animation.
   *
   * If the animation does not exist, this method will return an empty `HumanoidPose`.
   * @param time Playback position within the animation (in seconds)
   */
  getSample(time: number): HumanoidPose;

  /**
   * Obtains the duration of the animation, in seconds.
   *
   * If the animation does not exist, this method will return 0.
   */
  getLength(): number;

  /**
   * Returns true if the animation is a loop animation.
   */
  getIsLoop(): boolean;
}

/**
 * Describes the pose data for a humanoid model.
 * The avatar's root position roughly corresponds to the bottom center of the avatar's feet.
 */
declare class HumanoidPose {
  /**
   * Generates a `HumanoidPose`.
   */
  constructor(centerPosition: Vector3 | null, centerRotation: Quaternion | null, muscles: Muscles | null);

  /**
   * The position of the avatar's center of gravity, represented in normalized local coordinates, relative to the avatar's root position.
   * As the scale is normalized by the avatar's size, it is not recommended to use this to specify positional changes in global coordinates.
   * ({@link PlayerHandle.setPosition | PlayerHandle.setPosition} may be used instead.)
   */
  centerPosition: Vector3 | null;

  /**
   * The rotation of the avatar's center of gravity, represented relative to the avatar's root.
   */
  centerRotation: Quaternion | null;

  muscles: Muscles | null;
}

/**
 * The muscle values for the humanoid model's pose.
 * Each muscle value describes the amount of bending, normalized to [-1, 1].
 */
declare class Muscles {
  /**
   * Generates a `Muscles` class where all elements are `undefined`.
   * A muscle where the value is `undefined` is considered as not defined.
   */
  constructor();
  spineFrontBack: number | undefined;
  spineLeftRight: number | undefined;
  spineTwistLeftRight: number | undefined;
  chestFrontBack: number | undefined;
  chestLeftRight: number | undefined;
  chestTwistLeftRight: number | undefined;
  upperChestFrontBack: number | undefined;
  upperChestLeftRight: number | undefined;
  upperChestTwistLeftRight: number | undefined;
  neckNodDownUp: number | undefined;
  neckTiltLeftRight: number | undefined;
  neckTurnLeftRight: number | undefined;
  headNodDownUp: number | undefined;
  headTiltLeftRight: number | undefined;
  headTurnLeftRight: number | undefined;
  leftEyeDownUp: number | undefined;
  leftEyeInOut: number | undefined;
  rightEyeDownUp: number | undefined;
  rightEyeInOut: number | undefined;
  jawClose: number | undefined;
  jawLeftRight: number | undefined;
  leftUpperLegFrontBack: number | undefined;
  leftUpperLegInOut: number | undefined;
  leftUpperLegTwistInOut: number | undefined;
  leftLowerLegStretch: number | undefined;
  leftLowerLegTwistInOut: number | undefined;
  leftFootUpDown: number | undefined;
  leftFootTwistInOut: number | undefined;
  leftToesUpDown: number | undefined;
  rightUpperLegFrontBack: number | undefined;
  rightUpperLegInOut: number | undefined;
  rightUpperLegTwistInOut: number | undefined;
  rightLowerLegStretch: number | undefined;
  rightLowerLegTwistInOut: number | undefined;
  rightFootUpDown: number | undefined;
  rightFootTwistInOut: number | undefined;
  rightToesUpDown: number | undefined;
  leftShoulderDownUp: number | undefined;
  leftShoulderFrontBack: number | undefined;
  leftArmDownUp: number | undefined;
  leftArmFrontBack: number | undefined;
  leftArmTwistInOut: number | undefined;
  leftForearmStretch: number | undefined;
  leftForearmTwistInOut: number | undefined;
  leftHandDownUp: number | undefined;
  leftHandInOut: number | undefined;
  rightShoulderDownUp: number | undefined;
  rightShoulderFrontBack: number | undefined;
  rightArmDownUp: number | undefined;
  rightArmFrontBack: number | undefined;
  rightArmTwistInOut: number | undefined;
  rightForearmStretch: number | undefined;
  rightForearmTwistInOut: number | undefined;
  rightHandDownUp: number | undefined;
  rightHandInOut: number | undefined;
  leftThumb1Stretched: number | undefined;
  leftThumbSpread: number | undefined;
  leftThumb2Stretched: number | undefined;
  leftThumb3Stretched: number | undefined;
  leftIndex1Stretched: number | undefined;
  leftIndexSpread: number | undefined;
  leftIndex2Stretched: number | undefined;
  leftIndex3Stretched: number | undefined;
  leftMiddle1Stretched: number | undefined;
  leftMiddleSpread: number | undefined;
  leftMiddle2Stretched: number | undefined;
  leftMiddle3Stretched: number | undefined;
  leftRing1Stretched: number | undefined;
  leftRingSpread: number | undefined;
  leftRing2Stretched: number | undefined;
  leftRing3Stretched: number | undefined;
  leftLittle1Stretched: number | undefined;
  leftLittleSpread: number | undefined;
  leftLittle2Stretched: number | undefined;
  leftLittle3Stretched: number | undefined;
  rightThumb1Stretched: number | undefined;
  rightThumbSpread: number | undefined;
  rightThumb2Stretched: number | undefined;
  rightThumb3Stretched: number | undefined;
  rightIndex1Stretched: number | undefined;
  rightIndexSpread: number | undefined;
  rightIndex2Stretched: number | undefined;
  rightIndex3Stretched: number | undefined;
  rightMiddle1Stretched: number | undefined;
  rightMiddleSpread: number | undefined;
  rightMiddle2Stretched: number | undefined;
  rightMiddle3Stretched: number | undefined;
  rightRing1Stretched: number | undefined;
  rightRingSpread: number | undefined;
  rightRing2Stretched: number | undefined;
  rightRing3Stretched: number | undefined;
  rightLittle1Stretched: number | undefined;
  rightLittleSpread: number | undefined;
  rightLittle2Stretched: number | undefined;
  rightLittle3Stretched: number | undefined;

}

/**
 * Describes the ID of an item template, which forms the basis of craft items.
 * By passing it to {@link ClusterScript.createItem | ClusterScript.createItem} you can create a craft item.
 * @item
 */
declare class ItemTemplateId {
  /**
   * Creates an instance representing the ID of a Craft Item's template uploaded to Cluster.
   * 
   * The ID for a Craft Item's template can be obtained with the "Retrieve Craft Item Information" functionality in the Creator Kit.
   * The Item's template ID is the string that follows `ItemTemplateId =` in the "Retrieve Craft Item Information" window.
   * For details, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/craft-item/upload/get-craft-item-informations/).
   * 
   * @example
   * ```ts
   * let itemTemplateId = new ItemTemplateId("12345678-abcd-1234-abcd-123456789abc");
   * ```
   * 
   * @param id UUID formatted string
   */
  constructor(id: string);
}

/**
 * This represents the ID used to refer to a [World Item Template](https://docs.cluster.mu/creatorkit/en/world/item/#item-templates-and-dynamic-item-generation) registered in the [World Item Template List](https://docs.cluster.mu/creatorkit/en/item-components/world-item-template-list/).
 * By passing it to {@link ClusterScript.createItem | ClusterScript.createItem}, you can create a world item from the world item template.
 *
 * @example
 * ```ts
 * const position = $.getPosition();
 * position.y += 1.0;
 * const rotation = $.getRotation();
 *
 * const worldItemTemplateId = new WorldItemTemplateId("marker");
 * $.createItem(worldItemTemplateId, position, rotation);
 * ```
 * @item
 */
declare class WorldItemTemplateId {
  /**
   * Generates an instance that represents an ID for referencing a world item template.
   *
   * @param id Id set in WorldItemTemplateList
   */
  constructor(id: string);
}

/**
 * Represents an ID to specify the target endpoint for the external communication feature.
 * Pass this instance to {@link ClusterScript.callExternal} to specify the target external server that the request should be sent. 
 *
 * @item
 */
declare class ExternalEndpointId {
  /**
   * Generates an instance that represents an ID for the destination endpoint of the external communication feature.
   *
   * @param id The Endpoint ID, which is displayed at the `external communication (callExternal) connection URL` window of Creator Kit
   */
  constructor(id: string);
}

/**
 * @item
 * This enum represents the type of player role in an event.
 */
declare enum EventRole {
  Staff = 1,
  Guest = 2,
  Audience = 3,
}

/**
 * A handle to externally manipulate items.
 * A handle may refer to itself, but it may also refer to others, or to nothing.
 * @item
 */
declare class ItemHandle {
  /** @internal */
  private constructor();

  /**
   * The string representation of the ID that uniquely identifies an item within the space.
   * `ItemHandle`s sharing an identical `id` will all refer to the same object.
   */
  readonly id: string;

  /**
   * Returns string "item".
   * This value can be used to distinguish {@link ItemHandle} and {@link PlayerHandle}.
   */
  readonly type: "item";

  /**
   * If the item exists, returns `true`.
   * Note that this may return `true` even if it is currently loading.
   */
  exists(): boolean;

  /**
   * Sends a message to an item.
   * An item can receive the sent message in a callback set in {@link ClusterScript.onReceive | ClusterScript.onReceive}.
   * 
   * Messages sent to destroyed items or invalid `ItemHandle`s will be ignored.
   *
   * For data types that can be used as the message's payload (the `arg` argument), refer to {@link Sendable}.
   *
   * If a non-Sendable value, such as `undefined`, is passed to `arg` argument as the message's payload, it will be ignored.
   * This behaviour may change in future releases.
   * 
   * @example
   * The below example sends a message that corresponds to the example code on {@link ClusterScript.onReceive | ClusterScript.onReceive}.
   * ```ts
   * itemHandle.send("damage", 20);
   * itemHandle.send("heal", 10);
   * ```
   *
   * The below example sends a message with the message type `chase`, containing the handle of the player who used the item, to all items within a 2 meter radius.
   * ```ts
   * $.onUse((isDown, player) => {
   *   if (!isDown) return;
   *   let items = $.getItemsNear($.getPosition(), 2);
   *   for (let item of items) {
   *     item.send("chase", player);
   *   }
   * });
   * ```
   *
   * The actions an item should do upon receiving a message should be written in that item's {@link ClusterScript.onReceive | ClusterScript.onReceive}.
   * In the below example, the item will chase the player for 5 seconds.
   * ```ts
   * $.onReceive((messageType, arg, sender) => {
   *   switch (messageType) {
   *     case "chase":
   *       $.state.target = arg;
   *       $.state.time = 0;
   *       break;
   *   }
   * });
   * 
   * $.onUpdate(deltaTime => {
   *   let target = $.state.target;
   *   if (!target) return;
   * 
   *   let time = $.state.time ?? 0;
   *   time += deltaTime;
   *   $.state.time = time;
   * 
   *   if (time > 5) {
   *     $.state.target = null;
   *     return;
   *   }
   * 
   *   $.setPosition($.getPosition().lerp(target.getPosition(), 0.02));
   * });
   * ```
   * #### Rate limitations
   * 
   * There is a limit on how often `send` can be called.
   * - If the item running this script is a craft item, it must not exceed 10 calls per second per item
   * - If the item running this script is a world item, the total number of calls to {@link ItemHandle.send}, {@link PlayerHandle.send}, and {@link PlayerScript.sendTo} from all world items in the space must not exceed 3000 calls per second
   *
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls stays below this limit.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * #### Limitations from Flow Control
   * 
   * If the item running this script is a world item, the `send` operation will only succeed if Flow Control Delay is 30 seconds or less.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   * 
   * #### Size limitations
   * 
   * Encoded size of `arg` must meet the following limits.
   * 
   * - When sending a message from a world item, 100kB or less.
   * - When sending a message from a craft item, 1000 bytes or less.
   *
   * If the data size exceeds the limit, either a warning will be displayed or {@link ClusterScriptError} (`requestSizeLimitExceeded`) will occur and the send will fail.
   * The data size can be calculated with {@link ClusterScript.computeSendableSize}.
   *
   * @param messageType A short string to describe the message type
   * @param arg The message payload
   */
  send(messageType: string, arg: Sendable): void;

  ////////////////////////////////////////////////////////////////////////////////////////////////////
  // Force
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  /**
   * Adds an impulsive force to the item's center of gravity. This is ignored if the item is immune to force.
   * To apply impulsive force to points other than the center of gravity, use {@link ItemHandle.addImpulsiveForceAt}.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param force Impulsive force (global coordinates)
   */
  addImpulsiveForce(force: Vector3): void;

  /**
   * Adds an impulsive torque to the item's center of gravity. This is ignored if the item is immune to force.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param torque Impulsive torque (global coordinates)
   */
  addImpulsiveTorque(torque: Vector3): void;

  /**
   * Adds an impulsive force to a specified position on the item. This is ignored if the item is immune to force.
   * There is no need for a `PhysicalShape` nor a mesh to be present on the point to apply the force.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param impulse Impulsive force (global coordinates)
   * @param position Point to apply impulsive force (global coordinates)
   */
  addImpulsiveForceAt(impulse: Vector3, position: Vector3): void;
}

/**
 * A handle to externally manipulate the player.
 * The `PlayerHandle` stays the same even if the player changes their avatar.
 * A user is treated as a different player every time they enter a room.
 * Therefore, a new `PlayerHandle` will need to be acquired again for users who left and joined back in.
 *
 * In events, ghosts and group viewing users cannot be retrieved from script.
 * For details, refer to [About ghost participants](https://docs.cluster.mu/creatorkit/en/event/#about-ghost-participants).
 * @item
 */
declare class PlayerHandle {
  /** @internal */
  private constructor();

  /**
   * The string representation of the ID that uniquely identifies a player within the space.
   * `PlayerHandle`s sharing an identical `id` will all refer to the same player.
   */
  readonly id: string;

  /**
   * Returns string "player".
   * This value can be used to distinguish {@link ItemHandle} and {@link PlayerHandle}.
   */
  readonly type: "player";

  /**
   * This is the player's [User ID](https://help.cluster.mu/hc/en-us/articles/115000821651-User-ID).
   * Users can change their own user ID, but
   * it is not possible for different users to have the same user ID at the same time.
   * If the player does not exist, `null` is returned. The existence of a player can be checked with {@link PlayerHandle.exists}.
   */
  readonly userId: string | null;

  /**
   * This is the player's [Display Name](https://help.cluster.mu/hc/en-us/articles/115000827152-Display-name).
   * Users can change their own display name, and different users can use the same display name.
   * If the player does not exist, `null` is returned. The existence of a player can be checked with {@link PlayerHandle.exists}.
   */
  readonly userDisplayName: string | null;

  /**
   * Get the value of [IDFC](https://docs.cluster.mu/creatorkit/en/world/manage-data/#idfc-identifier-for-creator).
   * The IDFC is a string that creators can use to uniquely identify a user.
   * This string is 32 characters long, using the characters `0123456789abcdef`.
   * This string is determined by the pair of the account that uploaded the item/world and the user's account.
   * It does not change depending on the device or space used by the user.
   * If the player does not exist, `null` is returned. The existence of a player can be checked with {@link PlayerHandle.exists}.
   *
   * This string can be used to improve the content experience. We may restrict its use without notice if we deem it inappropriate.
   */
  readonly idfc: string | null;

  /**
   * If the player is in the room, returns `true`.
   * This will still return `true` when a player is temporarily hidden for some reason, eg. connection issues.
   *
   * If the player does not exist, returns `false`.
   *
   */
  exists(): boolean;

  /**
   * Modifies the position of the player.
   *
   * Since the player's position is synchronized over the network, please be aware that changes may not take effect immediately.
   *
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param position The avatar's root position, corresponding to the bottom center of the avatar's feet. (global coordinates)
   */
  setPosition(position: Vector3): void;

  /**
   * Modifies the rotation of the player.
   * Note the body orientation will stay vertical. (the camera and neck directions will be affected by the pitch.)
   *
   * Since the player's position is synchronized over the network, please be aware that changes may not take effect immediately.
   *
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param rotation The player's rotation (global coordinates)
   */
  setRotation(rotation: Quaternion): void;

  /**
   * Overwrites the pose of the player's avatar model with the specified `HumanoidPose`.
   * The pose data override method can be specified with option; see {@link SetHumanoidPoseOption} for properties that can be specified by option.
   *
   * The argument option can be omitted. If it is omitted, the default setting is used.
   *
   * If the `rootPosition`, `rootRotation`, or `muscle` of the given `HumanoidPose` are not defined, they will not be overwritten.
   * Additionally, `option.timeoutSeconds` and `option.timeoutTransitionSeconds` won't affect behavior for unspecified elements and will not be overwritten.
   * Pose overwrites will persist until the next time `setHumanoidPose` is called or the pose data is cancelled at the timeout specified by option.
   *
   * To remove all previous overwrites made with `setHumanoidPose`, pass a `null` or an empty `HumanoidPose` as the argument.
   * If a null or empty HumanoidPose is passed with HumanoidPoseOption, it will transition to the remove all previous overwrites after `HumanoidPoseOption.transitionSeconds`.
   * 
   * Pose overwrites made through `setHumanoidPose` will take precedence over pose changes made from emotes or `RidableItem`s.
   *
   * In VR, items being grabbed by the player will follow the specified pose, but elements such as the first-person camera, UI controls, etc. will be unaffected.
   * @example
   * ```ts
   * // Register a HumanoidAnimation with the ID "MyAnimation"
   * const animation = $.humanoidAnimation("MyAnimation");
   * // Overwrite the pose
   * playerHandle.setHumanoidPose(animation.getSample(0));
   * // Remove the overwrite
   * playerHandle.setHumanoidPose(null);
   * ```
   *
   * ```ts
   * const animation = $.humanoidAnimation("MyAnimation");
   * const interval = 0.1;
   * const animationLength = animation.getLength();
   *
   * // Make the person you Interact with the target of the animation.
   * $.onInteract(player => {
   *     if ($.state.player) {
   *         // Deactivate when the target is already present.
   *         $.state.player.setHumanoidPose(null);
   *     }
   *     $.state.animationTime = 0;
   *     $.state.waitingTime = 0;
   *     $.state.player = player;
   * });
   *
   * $.onUpdate(deltaTime => {
   *     let player = $.state.player;
   *     if (!player || !player.exists()) return;
   *
   *     let animationTime = $.state.animationTime + deltaTime;
   *     if (animationTime > animationLength) {
   *         animationTime = animationTime % animationLength;
   *     }
   *     let waitingTime = $.state.waitingTime + deltaTime;
   *     if (waitingTime >= interval) {
   *         let pose = animation.getSample(animationTime);
   *         // Transition the pose data over the amount of time since the last transmission.
   *         player.setHumanoidPose(pose, {transitionSeconds: waitingTime});
   *         waitingTime = 0;
   *     }
   *     $.state.animationTime = animationTime;
   *     $.state.waitingTime = waitingTime;
   * });
   * ```
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   */
  setHumanoidPose(pose: HumanoidPose, option: SetHumanoidPoseOption): void;

  /**
   * Obtains the current position of the player synchronized in the space, in global coordinates.
   *
   * If failed, returns `null`.
   */
  getPosition(): Vector3 | null;

  /**
   * Obtains the current rotation of the player synchronized in the space, in global coordinates.
   *
   * If failed, returns `null`.
   */
  getRotation(): Quaternion | null;

  /**
   * Respawns the player.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   */
  respawn(): void;

  /**
   * Adds a velocity to the player.
   * The actual movement speed of the player is determined from both the added velocity and player input.
   * While the player is in contact with the ground, the added velocity will gradually decrease, similar to the effects of friction.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param velocity Velocity to add (global coordinates)
   */
  addVelocity(velocity: Vector3): void

  /**
   * Modifies the player's movement speed multiplier. The default is 1.
   * 
   * The setting is shared with {@link PlayerScript.setMoveSpeedRate | PlayerScript.setMoveSpeedRate}.
   * The value of the one called later will overwrite it.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param moveSpeedRate Movement speed multiplier
   */
  setMoveSpeedRate(moveSpeedRate: number): void

  /**
   * Modifies the player's jumping speed multiplier. The default is 1.
   * 
   * The setting is shared with {@link PlayerScript.setJumpSpeedRate | PlayerScript.setJumpSpeedRate}.
   * The value of the one called later will overwrite it.
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param jumpSpeedRate Jumping speed multiplier
   */
  setJumpSpeedRate(jumpSpeedRate: number): void

  /**
   * Modifies the gravitational acceleration applied to the player. (Units are in m/s^2.) The default is -9.81.
   * 
   * The setting is shared with {@link PlayerHandle.setGravity | PlayerHandle.setGravity}.
   * The value of the one called later will overwrite it.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param gravity Gravitational acceleration value
   */
  setGravity(gravity: number): void

  /**
   * Resets any movement velocity, jumping speed, and gravity applied to the player.
   * The movement speed, jump speed, and gravity specified by {@link PlayerScript} will also be reset.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   */
  resetPlayerEffects(): void

  /**
   * @beta Obtains the position of a player's `HumanoidBone`.
   * Values are in global coordinates.
   * If the avatar has not finished loading yet, or the specified bone does not exist on the avatar, returns `null`.
   * 
   * @param bone Humanoid bone
   */
  getHumanoidBonePosition(bone: HumanoidBone): Vector3 | null

  /**
   * @beta Obtains the rotation of a player's `HumanoidBone`.
   * Values are in global coordinates.
   * If the avatar has not finished loading yet, or the specified bone does not exist on the avatar, returns `null`.
   * 
   * @param bone Humanoid bone
   */
  getHumanoidBoneRotation(bone: HumanoidBone): Quaternion | null

  /**
   * Requests the player to input a text string.
   * 
   * The text string from the player can be received in a callback set in {@link ClusterScript.onTextInput | ClusterScript.onTextInput}.
   * If the player is unable to respond to the input request, the request is automatically refused.
   * An example of this is a situation where the player received a new input request, but was already in the middle of an earlier input request.
   * The player can also intentionally refuse input requests.
   * The outcome of the input request is represented in {@link TextInputStatus}.
   * @example
   * ```ts
   * $.onInteract(player => {
   *   player.requestTextInput("ask_name", "Hi, what is your name?");
   * });
   * ```
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @param meta A text string in 100 bytes or less. Useful for distinguishing between multiple `requestTextInput` calls. Empty or reused strings are allowed.
   * @param title A text string to display to the player who received the input request. Must be 200 bytes or less.
   */
  requestTextInput(meta: string, title: string): void

  /**
   * @beta Sets post-process effects for the player.
   *
   * Each time this method is called, the previously set PostProcessEffects are overwritten with the new PostProcessEffects.
   *
   * Setting null clears all effects.
   *
   * The settings are shared with {@link PlayerScript.setPostProcessEffects | PlayerScript.setPostProcessEffects}.
   * The value of the one called later will overwrite it.
   *
   * #### Frequency Limit
   *
   * A single item can act on other ItemHandle and PlayerHandle up to 10 times per second.
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls does not surpass it.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) occurs, and the operation will fail.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   *
   * @example
   * ```ts
   * // The screen becomes very bright when interacted with
   * $.onInteract((player) => {
   *     const effects = new PostProcessEffects();
   *     effects.bloom.active = true;
   *     effects.bloom.threshold.setValue(0.5);
   *     effects.bloom.intensity.setValue(10.0);
   *     player.setPostProcessEffects(effects);
   * });
   * ```
   *
   * @param effects An instance of PostProcessEffects.
   */
  setPostProcessEffects(effects: PostProcessEffects | null): void

  /**
   * Send a message to PlayerScript.
   * A player can receive the sent message in a callback set in {@link PlayerScript.onReceive | PlayerScript.onReceive}.
   *
   * Messages sent to players who have left the room or invalid `PlayerHandle`s will be ignored.
   *
   * For data types that can be used as the message's payload (the `arg` argument), refer to {@link Sendable}.
   *
   * {@link Sendable} sent for PlayerScript will be converted to {@link PlayerScriptSendable}.
   * Specifically, {@link ItemHandle} is converted to {@link ItemId} and {@link PlayerHandle} is converted to {@link PlayerId}.
   * 
   * If a non-Sendable value, such as `undefined`, is passed to `arg` argument as the message's payload, it will be ignored.
   * This behavior may change in future releases.
   * 
   * @example
   * The following is an example of sending an message.
   * ```ts
   * playerHandle.send("damage", 20);
   * ```
   *
   * In the following example, the item handle is sent to the player who Interacted to the item.
   * ```ts
   * $.onInteract(player => {
   *   player.send("item-handle", $.itemHandle);
   * });
   * ```
   *
   * How to handle the received message is described in {@link PlayerScript.onReceive | PlayerScript.onReceive} of the receiving PlayerScript.
   * In the following example, store the received ItemId in a variable.
   * For this ItemId, you can perform processing such as {@link PlayerScript.sendTo | PlayerScript.sendTo} of a message when necessary.
   * ```ts
   * let itemId = null;
   * _.onReceive((messageType, arg, sender) => {
   *   switch (messageType) {
   *     case "item-handle":
   *       itemId = arg;
   *       break;
   *   }
   * });
   * ```
   *
   * #### Frequency Limit
   *
   * There is a limit on how often `send` can be called.
   * - If the item running this script is a craft item, it must not exceed 10 calls per second per item
   * - If the item running this script is a world item, the total number of calls to {@link ItemHandle.send}, {@link PlayerHandle.send}, and {@link PlayerScript.sendTo} from all world items in the space must not exceed 3000 calls per second
   *
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls stays below this limit.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * #### Limitations from Flow Control
   * 
   * If the item running this script is a world item, the `send` operation will only succeed if Flow Control Delay is 30 seconds or less.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   * 
   * #### Capacity Limit
   *
   * Encoded size of `arg` must meet the following limits.
   *
   * - When sending a message from a world item, 100kB or less.
   * - When sending a message from a craft item, 1000 bytes or less.
   * 
   * If the data size exceeds the limit, either a warning will be displayed or {@link ClusterScriptError} (`requestSizeLimitExceeded`) will occur and the send will fail.
   * The data size can be calculated with {@link ClusterScript.computeSendableSize}.
   *
   * @param messageType Arbitrary string of 100 bytes or less indicating the message type
   * @param arg Message Payload
   */
  send(messageType: string, arg: Sendable): void;

  /**
   * Requests the player to purchase an purchasable item.
   *
   * The player who is requested to purchase the item will see a purchase dialog for the item.
   * The result of the purchase request is received through the callback of  {@link ClusterScript.onRequestPurchaseStatus | ClusterScript.onRequestPurchaseStatus} .
   *
   * If the player purchases the item, the callback of {@link ClusterScript.onPurchaseUpdated | ClusterScript.onPurchaseUpdated} will be called.
   *
   * If the player closes the dialog without purchasing the item, the purchase is canceled.
   *
   * If the player cannot display the purchase dialog, the request will be ignored.
   * For example, this includes situations where the item purchase dialog is already being displayed.
   *
   * #### Differences in behavior based on room type
   *
   * If executed during an event, the item cannot be purchased. When using {@link ClusterScript.onRequestPurchaseStatus | ClusterScript.onRequestPurchaseStatus} , the callback will receive {@link PurchaseRequestStatus.NotAvailable | PurchaseRequestStatus.NotAvailable }.
   *
   * #### Frequency Limit
   *
   * A single item can act on other ItemHandle and PlayerHandle up to 10 times per second.
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls does not surpass it.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) occurs, and the operation will fail.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * @example
   * ```ts
   * const productId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
   *
   * $.onStart(() => {
   *   // Save the player's status of owned purchasable items to the state.
   *   $.state.amounts = {};
   *   // Subscribe to purchase notifications.
   *   $.subscribePurchase(productId);
   * });
   *
   * $.onUpdate(deltaTime => {
   *   // Check the purchase status of all players regularly, every 10 seconds.
   *   let timer = $.state.timer ?? 0;
   *   timer -= deltaTime;
   *   if (timer <= 0) {
   *     timer += 10;
   *     const allPlayers = $.getPlayersNear(new Vector3(), Infinity);
   *     $.getOwnProducts(productId, allPlayers, "onUpdate");
   *   }
   *   $.state.timer = timer;
   * });
   *
   * $.onPurchaseUpdated((player, productId) => {
   *   // If the item is purchased, immediately check the player's purchase status.
   *   $.getOwnProducts(productId, player, "onPurchaseUpdated");
   * });
   *
   * $.onGetOwnProducts((ownProducts, meta, errorReason) => {
   *   // Write the status of owned purchasable items to the state.
   *   let amounts = $.state.amounts;
   *   for (let ownProduct of ownProducts) {
   *     let playerId = ownProduct.player.id;
   *     let oldAmount = amounts[playerId] ?? 0;
   *     let newAmount = ownProduct.plusAmount - ownProduct.minusAmount;
   *     amounts[playerId] = newAmount;
   *   }
   *   $.state.amounts = amounts;
   * });
   * ```
   *
   * @param productId The product ID for which a purchase is requested.
   * @param meta A string less than 100 bytes. It can be used to identify multiple requestPurchase calls. It is fine to specify an empty string or the same string multiple times.
   */
  requestPurchase(productId: string, meta: string): void;

  /**
   * Obtains the role of the player in the event.
   * If the space where the player exists is not an event, it returns `null`.
   * `null` may be returned immediately after a player enters the space.
   *
   * If the player does not exist, `null` is returned.  The existence of a player can be checked with {@link PlayerHandle.exists}.
   *
   * @returns Player Event Role
   */
  getEventRole(): EventRole | null;

  /**
   * Gets the product ID of the avatar item currently used by the player.
   *
   * If the avatar being used is not a product, it returns `null`. \
   * While the player is launching the Avatar Maker, it returns the product ID of the avatar that was used before launching the Avatar Maker. \
   * Immediately after the player changes the avatar, it may return the product ID of the avatar that was used just before. \
   * Immediately after the player enters the space, it may return `null`. \
   * If the player does not exist, `null` is returned. The existence of a player can be checked with {@link PlayerHandle.exists}.
   *
   * @returns The product ID of the avatar currently used by the player.
   */
  getAvatarProductId(): string | null;

  /**
   * Gets an array of product IDs for the accessory items currently used by the player.
   *
   * If the accessory being used is not a product, it will not be included in the array. \
   * While the player is editing accessories, it returns the product ID of the accessory that was used before editing. \
   * Immediately after the player saves accessories, it may return the product ID of the accessory that was used just before. \
   * Immediately after the player enters the space, it may return an empty array. \
   * If the player does not exist, an empty array is returned. The existence of a player can be checked with {@link PlayerHandle.exists}.
   *
   * @returns An array of product IDs for the accessories currently used by the player.
   */
  getAccessoryProductIds(): string[];

  /**
   * Applies the audio characteristics of the specified ID, included in the AudioConfigurationSets of the item's AudioConfigurationSetList component, to the player's voice.
   *
   * For more details about the AudioConfigurationSetList component and the applicable parameters, please refer to the [documentation](https://docs.cluster.mu/creatorkit/en/item-components/audio-configuration-set-list/).
   *
   * When this item is destroyed, the applied voice audio characteristics will be cleared.
   *
   * An error will occur if this is executed on a craft item.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   *
   * @param itemAudioConfigurationId Specify the Id from AudioConfigurationSets. An error will occur if a non-existent ID is specified.
   */
  setVoiceConfiguration(itemAudioConfigurationId: string): void;

  /**
   * Clear the applied voice audio characteristics.
   * 
   * #### Rate limitations
   * 
   * An item can manipulate other handles up to 10 times per second.
   * This can be exceeded momentarily, but please keep the average below this limit.
   * If the limit is exceeded, a {@link ClusterScriptError} (`rateLimitExceeded`) error will occur and the operation will fail.
   * 
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   */
  clearVoiceConfiguration(): void;

  /**
   * Requests to grant a product to the player.
   *
   * When a product is granted, the player is considered to have purchased the product and can use it as if they own it.\
   * The result of the execution is provided via the callback set in {@link ClusterScript.onRequestGrantProductResult}.
   *
   * #### Grantable Products
   *
   * The following types of products can be granted:
   * - Craft Item products
   * - Accessory products
   * - Avatar products
   *
   * The product must be published and available for sale in the store. Once a product is published in the store, it can still be granted even if its visibility settings are later changed.
   *
   * #### Restrictions on Product Grant Execution
   *
   * When calling this method from a world item, the product can only be granted if the item's creator is the same as the product's seller.\
   * When calling this method from a craft item, the same condition applies: the craft item’s creator must match the product’s seller.\
   * For example, you cannot grant a product sold by someone else. However, if the product’s seller publishes a craft item that grants their own product, other players can purchase and use it to grant that product.
   *
   * These restrictions are subject to change with updates.
   *
   * #### Differences in behavior based on room type
   *
   * When called in a test space, the callback argument {@link ProductGrantResult.status | result.status} will return `"Granted"` regardless of whether the target player is the seller or already owns the product. However, the product is not actually granted.
   *
   * #### Flow Control
   *
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   *
   * @example
   * ```ts
   * const productId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
   *
   * // Register callback to receive result of PlayerHandle.requestGrantProduct
   * $.onRequestGrantProductResult((result) => {
   *     $.log(`status: ${result.status}, productId: ${result.productId}, productName: ${result.productName}, playerId: ${result.player.id}, meta: ${result.meta}, errorReason: ${result.errorReason}`);
   *     const status = result.status;
   *     switch (status) {
   *         case "Granted":
   *         case "AlreadyOwned":
   *             if (result.player.exists()) {
   *                 $.log(`${result.player.userDisplayName} was granted product: ${result.productName}`);
   *             }
   *             break;
   *         default:
   *             $.log(`status: ${status}, errorReason: ${result.errorReason}`);
   *             break;
   *     }
   * });
   *
   * // Requests to grant product to the player who interacted.
   * $.onInteract((player) => {
   *     player.requestGrantProduct(productId, `${productId}_${player.id}`);
   * });
   * ```
   *
   * @param productId The ID of the product to grant. You can copy the ID from the "Allow Sales of This Item in Worlds & Events" section of each product's details page in [Manage Products](https://cluster.mu/account/products/avatars) page.
   * @param meta A string less than 100 bytes. It can be used to identify multiple `requestGrantProduct` calls. It is fine to specify an empty string or the same string multiple times.
   */
  requestGrantProduct(productId: string, meta: string): void;

  /**
   * Retrieves the player's organization information.
   * Organization information is a feature granted only to certain users. This feature is offered only for paid users.
   * If the player does not belong to any organization, this function returns `null`.
   */
  getOrganization(): Organization;
}

/**
 * A handle to manipulate audio.
 * @item
 */
interface ApiAudio {
  /**
   * Plays the audio.
   * 
   * When called against an audio already in playback, the playback will stop, then restart from the beginning.
   */
  play(): void;

  /**
   * Stops the audio.
   */
  stop(): void;

  /**
   * A property representing the volume of the audio.
   * This property cannot be accessed at the top level of the script.
   * 
   * The default is 1. The volume can be a number between 0 and 2.5.
   */
  volume: number;

  /**
   * Set the spatial origin of the audio's positional playback to the specified `SubNode`.
   *
   * By default, the audio's spatial origin is the item's root position. \
   * If a non-existent `SubNode` is specified, the audio's spatial origin will be set to the item's root position.
   *
   * @param v
   */
  attach(subNode: SubNode): void;

  /**
   * Set the spatial origin of the audio's positional playback to the item's root position.
   */
  attachToRoot(): void;
}

/**
 * A quaternion.
 * 
 * Methods that manipulate values are generally destructive. To preserve the original values, explicitly call `clone()` to create a duplicate instance.
 */
declare class Quaternion {
  x: number;
  y: number;
  z: number;
  w: number;

  /**
   * Creates an instance with component values initialized as an identity rotation, which represents no rotation.
   * The `x`, `y`, `z`, `w` components are initialized to `0`, `0`, `0`, `1` respectively.
   */
  constructor();
  /**
   * Creates an instance with the specified `x`, `y`, `z`, `w` component values.
   *
   * @param x x component
   * @param y y component
   * @param z z component
   * @param w w component
   */
  constructor(x: number, y: number, z: number, w: number);

  /**
   * Compares the quaternion to `v`, and returns `true` if they are approximately equal.
   *
   * @param v
   */
  equals(v: Quaternion): boolean;
  /**
   * Sets the quaternion's component values to those specified in `x`, `y`, `z`, and `w`.
   * 
   * @param x 
   * @param y 
   * @param z 
   * @param w 
   */
  set(x: number, y: number, z: number, w: number): this;
  /**
   * Updates the quaternion to a value that represents a rotation of `degree` degrees around the `axis`.
   * 
   * @example
   * ```ts
   * new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), 90);
   * ```
   * 
   * @param axis 
   * @param degree 
   * 
   */
  setFromAxisAngle(axis: Vector3, degree: number): this;
  /**
   * Updates the quaternion to a value that represents a rotation in Euler angles. Axes are applied in the order of ZXY.
   * 
   * @example
   * ```ts
   * new Quaternion().setFromEulerAngles(new Vector3(90, 0, 0));
   * ```
   * 
   * @param v 
   */
  setFromEulerAngles(v: Vector3): this;
  /**
   * Updates the quaternion to a value that represents a rotation in Euler angles. Axes are applied in the order of ZXY.
   * 
   * @example
   * ```ts
   * new Quaternion().setFromEulerAngles(90, 0, 0);
   * ```
   * 
   * @param x 
   * @param y 
   * @param z 
   */
  setFromEulerAngles(x: number, y: number, z: number): this;
  /**
   * Returns a value that represents the current rotation in Euler angles.
   */
  createEulerAngles(): Vector3;
  /**
   * Clones the instance.
   */
  clone(): Quaternion;
  /**
   * Multiplies the quaternion's value by `v`.
   * 
   * @param v 
   */
  multiply(v: Quaternion): this;
  /**
   * Updates the quaternion's value to the identity rotation. This is the state of having no rotation.
   */
  identity(): this;
  /**
   * Inverts the quaternion's value.
   */
  invert(): this;
  /**
   * Normalizes the quaternion's value.
   */
  normalize(): this;
  /**
   * Returns the dot product of the quaternion and `v`.
   * @param v 
   */
  dot(v: Quaternion): number;
  /**
   * Returns the quaternion's length when viewed as a 4-dimensional vector.
   */
  length(): number;
  /**
   * Returns the quaternion's squared length when viewed as a 4-dimensional vector.
   */
  lengthSq(): number;
  /**
   * Calculates the spherical linear interpolation (slerp) between the current value and `v`, using `a` as the interpolation factor, then updates the quaternion's value to the result.
   * 
   * @example
   * ```ts
   * let min = new Quaternion().identity();
   * let max = new Quaternion().setFromEulerAngles(0, 45, 0);
   * min.clone().slerp(max, 0.5);
   * ```
   * 
   * @param v 
   * @param a The interpolation factor, specified as a number between [0, 1].
   */
  slerp(v: Quaternion, a: number): this;

  /**
   * Gets the axis and angle values that represent the current rotation.
   */
  toAxisAngle(): AxisAngle;

  /**
   * Gets the quaternion by the value that represents a rotation in Euler angles. Axes are applied in the order of ZXY.
   * 
   * @param angles 
   * 
   * @group Static Methods
   */
  static euler(angles: Vector3): Quaternion;

  /**
   * Gets the quaternion by the value that represents a rotation in Euler angles. Axes are applied in the order of ZXY.
   * 
   * @param x
   * @param y
   * @param z
   * 
   * @group Static Methods
   */
  static euler(x: number, y: number, z: number): Quaternion;

  /**
   * Gets the quaternion that represents a rotation of `degree` degrees around the `axis`.
   * 
   * @example
   * ```ts
   * let q = Quaternion.axisAngle(new Vector3(0, 1, 0), 90);
   * ```
   * 
   * @param axis 
   * @param angle 
   * 
   * @group Static Methods
   */
  static axisAngle(axis: Vector3, angle: number): Quaternion;

  /**
   * Gets a Quaternion that changes orientation from `from` direction to another direction `to`.
   * 
   * @param from 
   * @param to 
   * 
   * @group Static Methods
   */
  static fromToRotation(from: Vector3, to: Vector3): Quaternion;

  /**
   * Creates a Quaternion looking towards `forward` direction with the upward direction being `up`.
   * 
   * `up` is optional, and if omitted, it will be treated as if `new Vector3(0, 1, 0)` was specified.
   * 
   * @param forward 
   * @param up 
   * 
   * @group Static Methods
   */
  static lookRotation(forward: Vector3, up: Vector3): Quaternion;
}

/** 
 * A data that represents rotation as a pair of an axis and an angle.
 * The value can be obtained by {@link Quaternion.toAxisAngle | Quaternion.toAxisAngle}.
 */
interface AxisAngle {

  /** 
   * A vector that represents the axis of rotation.
   */
  readonly axis: Vector3;

  /** 
   * The angle of rotation in degrees, from 0 to 360.
   */
  readonly angle: number;
}

/**
 * A 3-dimensional vector.
 * 
 * Methods that manipulate values are generally destructive. To preserve the original values, explicitly call `clone()` to create a duplicate instance.
 */
declare class Vector3 {
  x: number;
  y: number;
  z: number;

  /**
   * Creates an instance with all components initialized to 0.
   */
  constructor();
  /**
   * Creates an instance with the specified `x`, `y`, and `z` component values.
   *
   * @param x x component
   * @param y y component
   * @param z z component
   */
  constructor(x: number, y: number, z: number);

  /**
   * Compares the vector to `v`, and returns `true` if they are approximately equal.
   * 
   * @param v
   */
  equals(v: Vector3): boolean;
  /**
   * Sets the vector's component values to those specified in `x`, `y`, and `z`.
   * 
   * @param x 
   * @param y 
   * @param z 
   */
  set(x: number, y: number, z: number): this;
  /**
   * Clones the instance.
   */
  clone(): Vector3;
  /**
   * Adds `v` to the vector's value.
   * 
   * @param v 
   */
  add(v: Vector3): this;
  /**
   * Adds the scalar value `s` to the vector's `x`, `y`, and `z` components.
   * @param s 
   */
  addScalar(s: number): this;
  /**
   * Subtracts `v` from the vector's value.
   * 
   * @param v 
   */
  sub(v: Vector3): this;
  /**
   * Subtracts the scalar value `s` from the vector's `x`, `y`, and `z` components.
   * @param s 
   */
  subScalar(s: number): this;
  /**
   * Multiplies the vector by `v`.
   * 
   * @param v 
   */
  multiply(v: Vector3): this;
  /**
   * Multiplies the vector by the scalar value `s`.
   * 
   * @param s 
   */
  multiplyScalar(s: number): this;
  /**
   * Divides the vector by `v`.
   * 
   * @param v 
   */
  divide(v: Vector3): this;
  /**
   * Divides the vector by the scalar value `s`.
   * 
   * @param s 
   */
  divideScalar(s: number): this;
  /**
   * Negates the vector's value.
   */
  negate(): this;
  /**
   * Normalizes the vector's value.
   */
  normalize(): this;
  /**
   * Returns the dot product of the vector and `v`.
   * 
   * @param v 
   */
  dot(v: Vector3): number;
  /**
   * Updates the vector's value to the cross product of the vector and `v`.
   * 
   * @param v 
   */
  cross(v: Vector3): this;
  /**
   * Returns the vector's length.
   */
  length(): number;
  /**
   * Returns the vector's squared length.
   */
  lengthSq(): number;
  /**
   * Calculates the linear interpolation (lerp) between the current value and `v`, using `a` as the interpolation factor, then updates the vector's value to the result.
   * 
   * @param v 
   * @param a The interpolation factor, specified as a number between [0, 1].
   */
  lerp(v: Vector3, a: number): this;
  /**
   * Applies the rotation `q` to the vector.
   * 
   * @param q 
   */
  applyQuaternion(q: Quaternion): this
}

/**
 * A 2-dimensional vector.
 * 
 * Methods that manipulate values are generally destructive. To preserve the original values, explicitly call `clone()` to create a duplicate instance.
 */
declare class Vector2 {
  x: number;
  y: number;

  /**
   * Creates an instance with all components initialized to 0.
   */
  constructor();
  /**
   * Creates an instance with the specified `x` and `y` component values.
   *
   * @param x x component
   * @param y y component
   */
  constructor(x: number, y: number)

  /**
   * Compares the vector to `v`, and returns `true` if they are approximately equal.
   * 
   * @param v
   */
  equals(v: Vector2): boolean;
  /**
   * Sets the vector's component values to those specified in `x` and `y`.
   * 
   * @param x 
   * @param y 
   */
  set(x: number, y: number): this;
  /**
   * Clones the instance.
   */
  clone(): Vector2;
  /**
   * Adds `v` to the vector's value.
   * 
   * @param v 
   */
  add(v: Vector2): this;
  /**
   * Adds the scalar value `s` to the vector's `x` and `y` components.
   * @param s 
   */
  addScalar(s: number): this;
  /**
   * Subtracts `v` from the vector's value.
   * 
   * @param v 
   */
  sub(v: Vector2): this;
  /**
   * Subtracts the scalar value `s` from the vector's `x` and `y` components.
   * @param s 
   */
  subScalar(s: number): this;
  /**
   * Multiplies the vector by `v`.
   * 
   * @param v 
   */
  multiply(v: Vector2): this;
  /**
   * Multiplies the vector by the scalar value `s`.
   * 
   * @param s 
   */
  multiplyScalar(s: number): this;
  /**
   * Divides the vector by `v`.
   * 
   * @param v 
   */
  divide(v: Vector2): this;
  /**
   * Divides the vector by the scalar value `s`.
   * 
   * @param s 
   */
  divideScalar(s: number): this;
  /**
   * Negates the vector's value.
   */
  negate(): this;
  /**
   * Normalizes the vector's value.
   */
  normalize(): this;
  /**
   * Returns the dot product of the vector and `v`.
   * 
   * @param v 
   */
  dot(v: Vector2): number;
  /**
   * Returns the size of the 2-dimensional cross product of the vector and `v`.
   * 
   * @param v 
   */
  cross(v: Vector2): number;
  /**
   * Returns the vector's length.
   */
  length(): number;
  /**
   * Returns the vector's squared length.
   */
  lengthSq(): number;
  /**
   * Calculates the linear interpolation (lerp) between the current value and `v`, using `a` as the interpolation factor, then updates the vector's value to the result.
   * 
   * @param v 
   * @param a The interpolation factor, specified as a number between [0, 1].
   */
  lerp(v: Vector2, a: number): this;
}

/**
 * A 4-dimensional vector.
 * 
 * Methods that manipulate values are generally destructive. To preserve the original values, explicitly call `clone()` to create a duplicate instance.
 */
declare class Vector4 {
  x: number;
  y: number;
  z: number;
  w: number;

  /**
   * Creates an instance with all components initialized to 0.
   */
  constructor();
  /**
   * Creates an instance with the specified `x`, `y`, `z`, and `w` component values.
   *
   * @param x x component
   * @param y y component
   * @param z z component
   * @param w w component
   */
  constructor(x: number, y: number, z: number, w: number);

  /**
   * Compares the vector to `v`, and returns `true` if they are approximately equal.
   *
   * @param v
   */
  equals(v: Vector4): boolean;

  /**
   * Sets the vector's component values to those specified in `x`, `y`, `z` and `w`.
   * 
   * @param x 
   * @param y 
   * @param z 
   * @param w
   */
  set(x: number, y: number, z: number, w: number): this;

  /**
   * Clones the instance.
   */
  clone(): Vector4;

  /**
   * Calculates the linear interpolation (lerp) between the current value and `v`, using `a` as the interpolation factor, then updates the vector's value to the result.
   * 
   * @param v 
   * @param a The interpolation factor, specified as a number between [0, 1].
   */
  lerp(v: Vector4, a: number): this;
}

/**
 * A color value.
 * Tha value of each component `r`, `g`, `b`, `a` is specified between [0, 1].
 * 
 * Methods that manipulate values are generally destructive. To preserve the original values, explicitly call `clone()` to create a duplicate instance.
 */
declare class Color {
  r: number;
  g: number;
  b: number;
  a: number;

  /** 
   * Creates an instance with all components initialized to 0.
   */
  constructor();

  /** 
   * Creates an instance with the specified `r`, `g`, and `b` component values.
   * `a` is set to 1.
   */
  constructor(r: number, g: number, b: number);
  
  /** 
   * Instantiate the color value with specified component value `r`, `g`, `b` and `a`.
   */
  constructor(r: number, g: number, b: number, a: number);

  /**
   * Compares the vector to `v`, and returns `true` if they are approximately equal.
   * 
   * @param v
   */
  equals(v: Color): boolean;

  /**
   * Sets the color's component values to those specified in `r`, `g`, `b` and `a`.
   * 
   * @param r 
   * @param g
   * @param b
   * @param a
   */
  set(r: number, g: number, b: number, a: number): this;

  /**
   * Sets RGB value based on HSV component values. `a` value does not change by this method.
   * 
   * Each value `h`, `s`, `v` should be between [0, 1].
   * 
   * @param h 
   * @param s 
   * @param v 
   */
  setFromHsv(h: number, s: number, v: number): this;

  /**
   * Clones the instance.
   */
  clone(): Color;

  /**
   * Calculates the linear interpolation (lerp) between the current value and `c`, using `t` as the interpolation factor, then updates the vector's value to the result.
   * 
   * @param c 
   * @param t The interpolation factor, specified as a number between [0, 1].
   */
  lerp(c: Color, t: number): this;
}

/**
 * A class representing a rectangle.
 */
declare class Rect {
  /**
   * The minimum X coordinate of the rectangle.
   * This has the same value as `xMin`.
   * When this value is set, the value of `xMax` is also updated to maintain `width`.
   */
  x: number;
  /**
   * The minimum Y coordinate of the rectangle.
   * This has the same value as `yMin`.
   * When this value is set, the value of `yMax` is also updated to maintain `height`.
   */
  y: number;
  /**
   * The difference between the maximum and minimum X coordinates of the rectangle.
   * When this value is set, the value of `xMax` is also updated to maintain `xMin`.
   */
  width: number;
  /**
   * The difference between the maximum and minimum Y coordinates of the rectangle.
   * When this value is set, the value of `yMax` is also updated to maintain `yMin`.
   */
  height: number;
  /**
   * The minimum X coordinate of the rectangle.
   * This has the same value as `x`.
   * When this value is set, the value of `width` is also updated to maintain `xMax`.
   */
  xMin: number;
  /**
   * The maximum X coordinate of the rectangle.
   * When this value is set, the value of `width` is also updated to maintain `xMin`.
   */
  xMax: number;
  /**
   * The minimum Y coordinate of the rectangle.
   * This has the same value as `y`.
   * When this value is set, the value of `height` is also updated to maintain `yMax`.
   */
  yMin: number;
  /**
   * The maximum Y coordinate of the rectangle.
   * When this value is set, the value of `height` is also updated to maintain `yMin`.
   */
  yMax: number;

  /**
   * Creates an instance with all properties initialized to 0.
   */
  constructor();
  /**
   * Creates an instance with the specified values.
   *
   * @param x The minimum X coordinate of the rectangle
   * @param y The minimum Y coordinate of the rectangle
   * @param width The width of the rectangle
   * @param height The height of the rectangle
   */
  constructor(x: number, y: number, width: number, height: number);

  /**
   * Compares the rectangle to `v`, and returns `true` if they are equal.
   *
   * @param v
   */
  equals(v: Rect): boolean;

  /**
   * Sets the rectangle's `x`, `y`, `width`, `height` values.
   *
   * @param x The minimum X coordinate of the rectangle
   * @param y The minimum Y coordinate of the rectangle
   * @param width The width of the rectangle
   * @param height The height of the rectangle
   */
  set(x: number, y: number, width: number, height: number): this;

  /**
   * Clones the instance.
   */
  clone(): Rect;
}

/**
 * Bones for humanoid models.
 */
declare enum HumanoidBone {
  Hips,
  LeftUpperLeg,
  RightUpperLeg,
  LeftLowerLeg,
  RightLowerLeg,
  LeftFoot,
  RightFoot,
  Spine,
  Chest,
  Neck,
  Head,
  LeftShoulder,
  RightShoulder,
  LeftUpperArm,
  RightUpperArm,
  LeftLowerArm,
  RightLowerArm,
  LeftHand,
  RightHand,
  LeftToes,
  RightToes,
  LeftEye,
  RightEye,
  Jaw,
  LeftThumbProximal,
  LeftThumbIntermediate,
  LeftThumbDistal,
  LeftIndexProximal,
  LeftIndexIntermediate,
  LeftIndexDistal,
  LeftMiddleProximal,
  LeftMiddleIntermediate,
  LeftMiddleDistal,
  LeftRingProximal,
  LeftRingIntermediate,
  LeftRingDistal,
  LeftLittleProximal,
  LeftLittleIntermediate,
  LeftLittleDistal,
  RightThumbProximal,
  RightThumbIntermediate,
  RightThumbDistal,
  RightIndexProximal,
  RightIndexIntermediate,
  RightIndexDistal,
  RightMiddleProximal,
  RightMiddleIntermediate,
  RightMiddleDistal,
  RightRingProximal,
  RightRingIntermediate,
  RightRingDistal,
  RightLittleProximal,
  RightLittleIntermediate,
  RightLittleDistal,
  UpperChest,
}

/**
 * A status code that represents the outcome of a text input request made to the player. Refer to {@link PlayerHandle.requestTextInput | PlayerHandle.requestTextInput} and {@link ClusterScript.onTextInput | ClusterScript.onTextInput} for details.
 * @item
 */
declare enum TextInputStatus {
  /** Indicates the player has successfully inputted a text string. */
  Success,
  /** Indicates the request was automatically refused, due to the player being unable to input text at the time. */
  Busy,
  /** Indicates the player has intentionally refused the input request. */
  Refused,
}

/**
 * An exception that will occur when a non-permitted operation is attempted.
 * Any API may throw this exception.
 * 
 * Permission to perform an operation may dynamically change based on various factors,
 * such as beta permission status, distance, processing load in the space, user status, etc.
 * 
 * Depending on the type of the permission missing, the exception's corresponding boolean fields will be set to `true`.
 * 
 * If multiple permissions were missing,
 * multiple fields may be set to `true` simultaneously.
 */
interface ClusterScriptError extends Error {
  /**
   * This field remains for backward compatibility and will always be `false`.
   */
  distanceLimitExceeded: boolean;
  /**
   * If the operation was refused due to rate limitations, this will be `true`.
   */
  rateLimitExceeded: boolean;
  /**
   * If the operation was refused due to request size limitations, this will be `true`.
   */
  requestSizeLimitExceeded: boolean;
  /**
   * If the operation was refused due to the operation not being allowed, this will be `true`.
   * 
   * An example of this is when a beta-only API was called in an environment that didn't have access to beta features.
   */
  executionNotAllowed: boolean;
  /**
   * The error message.
   */
  message: string;
}

/**
 * The configuration values for post-process effects.
 *
 * Created in the constructor and set for the player using {@link PlayerHandle.setPostProcessEffects | PlayerHandle.setPostProcessEffects} or {@link PlayerScript.setPostProcessEffects | PlayerScript.setPostProcessEffects}.
 *
 * The `active` property of each settings determines whether the settings will be used.
 *
 * The post-process set with {@link PlayerHandle.setPostProcessEffects | PlayerHandle.setPostProcessEffects} or {@link PlayerScript.setPostProcessEffects | PlayerScript.setPostProcessEffects} is represented as a Global Volume in Unity's PostProcessing, with Priority set to 100.
 *
 * By executing the `clear` on each settings, it is possible to apply the enabled state of PostProcessingVolume placed in the world uploaded with Creato Kit that has a Priority lower than 100.
 * The default value for `enabled` is true, and there is usually no need to change it from true in most use cases.
 * @beta
 */
declare class PostProcessEffects {
  grain: GrainSettings;
  bloom: BloomSettings;
  chromaticAberration: ChromaticAberrationSettings;
  colorGrading: ColorGradingSettings;
  depthOfField: DepthOfFieldSettings;
  lensDistortion: LensDistortionSettings;
  motionBlur: MotionBlurSettings;
  vignette: VignetteSettings;
  fog: FogSettings;

  /**
   * Creates an instance with default settings.
   */
  constructor();
}

/**
 * The configuration values for the post-process Bloom effect.
 * @item @beta
 */
interface BloomSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the intensity of the Bloom effect.
   * Values greater than or equal to 0 can be set.
   * If a value less than 0 is set, 0 will be applied.
   */
  intensity: PostProcessFloatProperty;

  /**
   * Sets the threshold of the Bloom effect.
   * Values greater than or equal to 0 can be set.
   * If a value less than 0 is set, 0 will be applied.
   */
  threshold: PostProcessFloatProperty;

  /**
   * Sets the softness of the threshold for the Bloom effect.
   * The specified value is clamped between 0 and 1.
   */
  softKnee: PostProcessFloatProperty;

  /**
   * Sets the clamp of the Bloom effect.
   * Values greater than or equal to 0 can be set.
   * If a value less than 0 is set, 0 will be applied.
   */
  clamp: PostProcessFloatProperty;

  /**
   * Sets the anamorphic ratio of the Bloom effect.
   * The specified value is clamped between -1 and 1.
   */
  anamorphicRatio: PostProcessFloatProperty;

  /**
   * Sets the color of the Bloom effect.
   */
  color: PostProcessColorProperty;
}

/**
 * The configuration values for the post-process ChromaticAberration effect.
 * @item @beta
 */
interface ChromaticAberrationSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the intensity of the ChromaticAberration effect.
   * Values between 0 and 1 can be set.
   * If a value less than 0 is set, 0 will be applied.
   * If a value greater than 1 is set, 1 will be applied.
   */
  intensity: PostProcessFloatProperty;
}

/**
 * The configuration values for the post-process ColorGrading effect.
 * @item @beta
 */
interface ColorGradingSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the temperature for the ColorGrading effect.
   * Values between -100 and 100 can be set.
   * If a value less than -100 is set, -100 will be applied.
   * If a value greater than 100 is set, 100 will be applied.
   */
  temperature: PostProcessFloatProperty;

  /**
   * Sets the tint for the ColorGrading effect.
   * Values between -100 and 100 can be set.
   * If a value less than -100 is set, -100 will be applied.
   * If a value greater than 100 is set, 100 will be applied.
   */
  tint: PostProcessFloatProperty;

  /**
   * Sets the color filter for the ColorGrading effect.
   */
  colorFilter: PostProcessColorProperty;

  /**
   * Sets the hue shift for the ColorGrading effect.
   * Values between -180 and 180 can be set.
   * If a value less than -180 is set, -180 will be applied.
   * If a value greater than 180 is set, 180 will be applied.
   */
  hueShift: PostProcessFloatProperty;

  /**
   * Sets the saturation for the ColorGrading effect.
   * Values between -100 and 100 can be set.
   * If a value less than -100 is set, -100 will be applied.
   * If a value greater than 100 is set, 100 will be applied.
   */
  saturation: PostProcessFloatProperty;

  /**
   * Sets the brightness for the ColorGrading effect.
   * Values between -100 and 100 can be set.
   * If a value less than -100 is set, -100 will be applied.
   * If a value greater than 100 is set, 100 will be applied.
   */
  brightness: PostProcessFloatProperty;

  /**
   * Sets the contrast for the ColorGrading effect.
   * Values between -100 and 100 can be set.
   * If a value less than -100 is set, -100 will be applied.
   * If a value greater than 100 is set, 100 will be applied.
   */
  contrast: PostProcessFloatProperty;

  /**
   * Sets the channel mixer for the ColorGrading effect.
   */
  channelMixerRed: ChannelMixerProperty;

  /**
   * Sets the green channel mixier for the ColorGrading effect.
   */
  channelMixerGreen: ChannelMixerProperty;

  /**
   * Sets the blue channel mixier for the ColorGrading effect.
   */
  channelMixerBlue: ChannelMixerProperty;

  /**
   * Sets the lift for the ColorGrading effect.
   * Specify the color with x/y/z and the amount of lift with w.
   */
  lift: PostProcessVector4Property;

  /**
   * Sets the gamma for the ColorGrading effect.
   * Specify the color with x/y/z and the amount of gamma with w.
   */
  gamma: PostProcessVector4Property;

  /**
   * Sets the gain for the ColorGrading effect.
   * Specify the color with x/y/z and the amount of gain with w.
   */
  gain: PostProcessVector4Property;
}

/**
 * The configuration values for the post-process DepthOfField effect.
 * @item @beta
 */
interface DepthOfFieldSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the focus distance for the DepthOfField effect.
   * Values greater than or equal to 0.1 can be set.
   * If a value less than 0.1 is set, 0.1 will be applied.
   */
  focusDistance: PostProcessFloatProperty;

  /**
   * Sets the aperture for the DepthOfField effect.
   * Values between 0.05 and 32 can be set.
   * If a value less than 0.05 is set, 0.05 will be applied.
   * If a value greater than 32 is set, 32 will be applied.
   */
  aperture: PostProcessFloatProperty;

  /**
   * Sets the focal length for the DepthOfField effect.
   * Values between 1 and 300 can be set.
   * If a value less than 1 is set, 1 will be applied.
   * If a value greater than 300 is set, 300 will be applied.

   */
  focalLength: PostProcessFloatProperty;
}

/**
 * The configuration values for the post-process Fog effect.
 * @item @beta
 */
interface FogSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the color for the Fog effect.
   */
  color: PostProcessColorProperty;

  /**
   * Sets the mode for the Fog effect.
   * You can specify one of the following values: `"Linear"`, `"Exponential"`, or `"ExponentialSquared"`.
   * If any other string is specified, it will be set as if it were cleared.
   */
  mode: PostProcessStringProperty;

  /**
   * Sets the starting position for the Fog effect.
   * Used when the mode is `"Linear"`.
   */
  start: PostProcessFloatProperty;

  /**
   * Sets the ending position for the Fog effect.
   * Used when the mode is `"Linear"`.
   */
  end: PostProcessFloatProperty;

  /**
   * Sets the density for the Fog effect.
   * Used when the mode is `"Exponential"` or `"ExponentialSquared"`.
   */
  density: PostProcessFloatProperty;
}

/**
 * The configuration values for the post-process Grain effect.
 * @item @beta
 */
interface GrainSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets whether the Grain effect is colored.
   */
  colored: PostProcessBoolProperty;

  /**
   * Sets the intensity of the Grain effect.
   * The specified value is clamped between 0 and 1.
   */
  intensity: PostProcessFloatProperty;

  /**
   * Sets the size of the Grain effect.
   * The specified value is clamped between 0.3 and 3.
   */
  size: PostProcessFloatProperty;

  /**
   * Sets the luminance contribution of the Grain effect.
   * The specified value is clamped between 0 and 1.
   */
  luminanceContribution: PostProcessFloatProperty;
}

/**
 * The configuration values for the post-process LensDistortion effect.
 * @item @beta
 */
interface LensDistortionSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the intensity of the LensDistortion effect.
   * The specified value is clamped between -100 and 100.
   */
  intensity: PostProcessFloatProperty;

  /**
   * Sets the x multiplier of the LensDistortion effect.
   * The specified value is clamped between 0 and 1.
   */
  xMultiplier: PostProcessFloatProperty;

  /**
   * Sets the y multiplier of the LensDistortion effect.
   * The specified value is clamped between 0 and 1.
   */
  yMultiplier: PostProcessFloatProperty;

  /**
   * Sets the center of the x coordinate for the LensDistortion effect.
   * The specified value is clamped between -1 and 1.
   */
  centerX: PostProcessFloatProperty;

  /**
   * Sets the center of the y coordinate for the LensDistortion effect.
   * The specified value is clamped between -1 and 1.
   */
  centerY: PostProcessFloatProperty;

  /**。
   * Sets the scale of the LensDistortion effect.
   * The specified value is clamped between 0.01 and 5.
   */
  scale: PostProcessFloatProperty;
}

/**
 * The configuration values for the post-process MotionBlur effect.
 * @item @beta
 */
interface MotionBlurSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the shutter angle for the MotionBlur effect.
   * The specified value is clamped between 0 and 360.
   */
  shutterAngle: PostProcessFloatProperty;

  /**
   * Sets the sample count for the MotionBlur effect.
   * The specified value is clamped between 4 and 32.
   */
  sampleCount: PostProcessIntProperty;
}

/**
 * The configuration values for the post-process Vignette effect.
 * @item @beta
 */
interface VignetteSettings {
  active: boolean;
  enabled: PostProcessBoolProperty;

  /**
   * Sets the color for the Vignette effect.
   */
  color: PostProcessColorProperty;

  /**
   * Sets the center of the Vignette effect.
   * It is represented in a coordinate system where the bottom left of the screen is (0, 0) and the top right is (1, 1).
   * To set the center of the screen as the center of the effect, please set it to (0.5, 0.5).
   */
  center: PostProcessVector2Property;

  /**
   * Sets the intensity of the Vignette effect.
   * The specified value is clamped between 0 and 1.
   */
  intensity: PostProcessFloatProperty;

  /**
   * Sets the smoothness of the Vignette effect.
   * The specified value is clamped between 0.01 and 1.
   */
  smoothness: PostProcessFloatProperty;

  /**
   * Sets the roundness of the Vignette effect.
   * The specified value is clamped between 0 and 1.
   */
  roundness: PostProcessFloatProperty;

  /**
   * Sets whether Vignette effect is rounded.
   */
  rounded: PostProcessBoolProperty;
}

/**
 * The property for the post-process boolean value.
 * @item @beta
 */
interface PostProcessBoolProperty {
  /**
   * Sets the value of the property.
   *
   * @param value The value to set
   */
  setValue(value: boolean): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process numeric value.
 * @item @beta
 */
interface PostProcessFloatProperty {
  /**
   * Sets the value of the property.
   *
   * @param value The value to set
   */
  setValue(value: number): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process integer value.
 * @item @beta
 */
interface PostProcessIntProperty {
  /**
   * Sets the value of the property.
   *
   * @param value The value to set
   */
  setValue(value: number): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process color value.
 * @item @beta
 */
interface PostProcessColorProperty {
  /**
   * Sets the value of the property.
   * Colors should be specified in the linear color space.
   * Putting values greater than 1 in the r, g, b components allows for specifying HDR colors.
   * The specified value is clamped between 0 and 1.
   *
   * @param r Value for the red component
   * @param g Value for the green component
   * @param b Value for the blue component
   * @param a Value for the alpha component
   */
  setValue(r: number, g: number, b: number, a: number): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process strings value.
 * @item @beta
 */
interface PostProcessStringProperty {
  /**
   * Sets the value of the property.
   *
   * @param value The value to set
   */
  setValue(value: string): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process 2D vector value.
 * @item @beta
 */
interface PostProcessVector2Property {
  /**
   * Sets the value of the property.
   *
   * @param x Value for the x component
   * @param y Value for the y component
   */
  setValue(x: number, y: number): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process 4D vector value.
 * @item @beta
 */
interface PostProcessVector4Property {
  /**
   * Sets the value of the property.
   *
   * @param x Value for the x component
   * @param y Value for the y component
   * @param z Value for the z component
   * @param w Value for the w component
   */
  setValue(x: number, y: number, z: number, w: number): void;

  /**
   * Clears the property value, setting it to an unset state.
   */
  clear(): void;
}

/**
 * The property for the post-process channel mixer value.
 * @item @beta
 */
interface ChannelMixerProperty {
  /**
   * Specifies the value for red.
   * Values can be set between -200 and 200.
   */
  red: PostProcessFloatProperty;

  /**
   * Specifies the value for green.
   * Values can be set between -200 and 200.
   */
  green: PostProcessFloatProperty;

  /**
   * Specifies the value for blue.
   * Values can be set between -200 and 200.
   */
  blue: PostProcessFloatProperty;
}

/**
 * A handle for manipulating materials from scripts.
 * @item
 */
interface MaterialHandle {
  /**
   * Sets the base color of the material.
   * The value passed to this method is treated as a value in the sRGB color space.
   *
   * Each specified RGBA value is clamped between 0 and 1.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   */
  setBaseColor(r: number, g: number, b: number, a: number): void;

  /**
   * Sets the base color of the material.
   * The value passed to this method is treated as a value in the sRGB color space.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   */
  setBaseColor(color: Color): void;

  /**
   * Sets the material's Emissive color.
   * The value passed to this method is treated as an HDR value in Linear's color space.
   *
   * r, g, and b take values greater than or equal to 0.
   * If a value is less than 0, 0 is passed to material.
   *
   * The specified value `a` is clamped between 0 and 1.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   */
  setEmissionColor(r: number, g: number, b: number, a: number): void;

  /**
   * Sets the material's Emissive color.
   * The value passed to this method is treated as an HDR value in Linear's color space.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   */
  setEmissionColor(color: Color): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Sets the value of the material's Color property.
   *
   * r, g, and b take values greater than or equal to 0.
   * If a value is less than 0, 0 is passed to material.
   *
   * The specified value `a` is clamped between 0 and 1.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setColor(propertyName: string, r: number, g: number, b: number, a: number): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Sets the value of the material's Color property.
   *
   * If any element is NaN, Infinity, or -Infinity, calling this method has no effect.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setColor(propertyName: string, color: Color): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Sets the Float value property of the material.
   * If value is NaN, Infinity, or -Infinity, calling this method has no effect.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat(propertyName: string, value: number): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Set the properties of the material's Float2 value.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat2(propertyName: string, x: number, y: number): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Set the properties of the material's Float3 value.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat3(propertyName: string, x: number, y: number, z: number): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Set the properties of the material's Float3 value.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat3(propertyName: string, v: Vector3): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Set the properties of the material's Float4 value.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat4(propertyName: string, x: number, y: number, z: number, w: number): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Set the properties of the material's Float4 value.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * Gamma for HDR and color space follows the `[HDR]` and `[Gamma]` property specification in ShaderLab.
   * `propertyName` supports up to 64 characters.
   */
  setFloat4(propertyName: string, v: Vector4): void;

  /**
   * This API is only available for worlds uploaded from the Creator Kit.
   * This API is not available from Craft Items.
   *
   * Sets the properties of a material's matrix value.
   *
   * Pass a Float32Array of 16 elements.
   * If the number of elements is not 16, an error will occur.
   * If any element is NaN, Infinity, or -Infinity, the call to this method will be ignored.
   *
   * `propertyName` supports up to 64 characters.
   */
  setMatrix(propertyName: string, matrix: Float32Array): void;
}

/**
 * Handle for operating AudioLink from a script.  
 * You can obtain this handle via {@link ClusterScript.audioLink}.  
 *
 * If the target is a craft item or an item that does not have an AudioLink component,
 * calls to AudioLinkHandle methods are ignored.
 * 
 * @example
 * ```ts
 * // Example: receive a sent message and change the AudioLink gain
 * const al = $.audioLink();
 *
 * $.onReceive((messageType, args, sender) => {
 *   if (messageType === "SetParam") {
 *     if (args.prop === "Gain") {
 *       al.setGain(args.value);
 *       al.applySettings();
 *     }
 *   }
 * });
 * ```
 * 
 * @item
 */
interface AudioLinkHandle {
  /**
   * Sets the gain.
   *
   * The specified value is clamped between 0 and 2.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param gain
   */
  setGain(gain: number): void;

  /**
   * Sets the bass amplification factor.
   *
   * The specified value is clamped between 0 and 2.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param bass
   */
  setBass(bass: number): void;

  /**
   * Sets the treble amplification factor.
   *
   * The specified value is clamped between 0 and 2.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param treble
   */
  setTreble(treble: number): void;

  /**
   * Sets the crossover point for the bass band.  
   * The frequency of the crossover is adjusted according to the given value.
   *
   * The specified value is clamped between 0 and 0.168.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param crossoverPoint
   */
  setCrossover0(crossoverPoint: number): void;

  /**
   * Sets the crossover point between the bass and low-mid bands.  
   * The frequency of the crossover is adjusted according to the given value.
   *
   * The specified value is clamped between 0.242 and 0.387.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param crossoverPoint
   */
  setCrossover1(crossoverPoint: number): void;

  /**
   * Sets the crossover point between the low-mid and mid-high bands.  
   * The frequency of the crossover is adjusted according to the given value.
   *
   * The specified value is clamped between 0.461 and 0.628.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param crossoverPoint
   */
  setCrossover2(crossoverPoint: number): void;

  /**
   * Sets the crossover point between the mid-high and treble bands.  
   * The frequency of the crossover is adjusted according to the given value.
   *
   * The specified value is clamped between 0.704 and 0.953.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param crossoverPoint
   */
  setCrossover3(crossoverPoint: number): void;

  /**
   * Sets the threshold level for the bass band.  
   * Lower values make the band more sensitive.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param threshold
   */
  setThreshold0(threshold: number): void;

  /**
   * Sets the threshold level for the low-mid band.  
   * Lower values make the band more sensitive.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param threshold
   */
  setThreshold1(threshold: number): void;

  /**
   * Sets the threshold level for the mid-high band.  
   * Lower values make the band more sensitive.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param threshold
   */
  setThreshold2(threshold: number): void;

  /**
   * Sets the threshold level for the treble band.  
   * Lower values make the band more sensitive.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param threshold
   */
  setThreshold3(threshold: number): void;

  /**
   * Sets the fade length.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param fadeLength
   */
  setFadeLength(fadeLength: number): void;

  /**
   * Sets the fade exponential fall-off.  
   * Higher values result in a steeper exponential decay.
   *
   * The specified value is clamped between 0 and 1.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param fadeExpFalloff
   */
  setFadeExpFalloff(fadeExpFalloff: number): void;

  /**
   * Enables or disables autogain.
   * 
   * @param enableAutogain
   */
  setEnableAutogain(enableAutogain: boolean): void;

  /**
   * Sets the influence of autogain.  
   * Larger values increase the influence.
   *
   * The specified value is clamped between 0.001 and 1.0.  
   * If the value is NaN, Infinity, or -Infinity, the call is ignored.
   * 
   * @param derate
   */
  setAutogainDerate(derate: number): void;

  /**
   * Applies the property values that have been set to AudioLink.
   */
  applySettings(): void;
}

/**
 * The `_` object is an instance of PlayerScript.
 *
 * Available only within the script of the [Player Script component](https://docs.cluster.mu/creatorkit/en/item-components/player-script/).
 * You can set the script of the Player Script component to a player by calling `$.setPlayerScript(playerHandle)`.
 *
 * The execution environment differs from that of Scriptable Item scripts.
 * Scriptable Item and Player Script scripts run independently.
 *
 * Player Script scripts do not automatically share variables, etc. with Scriptable Item scripts.
 * To pass values between Scriptable Item and Player Script scripts, use {@link PlayerScript.sendTo | PlayerScript.sendTo} or {@link PlayerHandle.send | PlayerHandle.send}.
 *
 * Unlike Scriptable Item scripts, PlayerScript scripts do not reset the environment periodically.
 * Therefore, you can save the state in a global variable and use it across callbacks.
 *
 * @example
 * The following is an example of a Scriptable Item script that sets a Player Script.
 * The Player Script script is set to the player who "interact" the item.
 * If the Player Script component is not attached to this item, an error will result.
 * ```ts
 * $.onInteract((player) => {
 *   // Set PlayerScript for player
 *   $.setPlayerScript(player);
 * });
 * ```
 *
 * The following is an example script for a Player Script component that logs on initialization.
 * When used in conjunction with the Scriptable Item above, it will log when the player uses the item.
 * ```ts
 * // The following log display is executed when PlayerScript is set
 * _.log("PlayerScript is initialized.");
 * _.log("Source Item ID is " + _.sourceItemId.id);
 * ```
 *
 * @example
 * The following is an example script of a Player Script component that sends back a message in the next frame for an ItemId received in a message.
 *
 * By using the Scriptable Item component script below together with the Player Script component script, you can see how to send a message from ScriptableItem to PlayerScript and how to send a message from PlayerScript to ScriptableItem to PlayerScript.
 *
 * First, write the following script in Scriptable Item.
 *
 * ```ts
 * $.onStart(() => {
 *   // Record the history of the player who gave the PlayerScript in state.
 *   $.state.players = [];
 * });
 *
 * $.onInteract((player) => {
 *   if ($.state.players.find(p => p.id === player.id)) {
 *     // Send a message to players who have already given PlayerScript
 *     player.send("send", "")
 *   } else {
 *     // If a player does not exist in the state history,
 *     // give it a PlayerScript and record it in the history.
 *     $.setPlayerScript(player);
 *     $.state.players = [...$.state.players, player]
 *   }
 *
 *   // Remove players that no longer exist from the history
 *   $.state.players = $.state.players.filter(p => p.exists());
 * });
 *
 * $.onReceive((messageType, arg, sender) => {
 *   if (messageType === "hello") {
 *     // Display in log when "hello" message is received
 *     $.log("hello " + arg);
 *   }
 * }, { player: true });
 * ```
 *
 * This script does the following.
 * - When a new user "interact" this item, it gives the PlayerScript to the user.
 * - Sends a message when a user who has already been given the PlayerScript "interact" the item.
 * - Display the `"hello"` message in the log when it is received.
 *
 * Next, write the following script in the Player Script component.
 *
 * ```ts
 * // Prepare a variable to store the message sender's ItemId.
 * let itemId = null;
 *
 * // Register a callback when PlayerScript receives a message
 * _.onReceive((messageType, arg, sender) => {
 *   switch (messageType) {
 *     case "send":
 *       if (sender instanceof ItemId) {
 *         // Display log when a "send" message is received from an Item
 *         _.log("Received from ItemId: " + sender.id);
 *         // Assigns sender to the global variable itemId
 *         itemId = sender;
 *       }
 *       break;
 *    }
 * });
 *
 * // Register a callback to be called every frame in PlayerScript
 * _.onFrame((deltaTime) => {
 *   if (itemId !== null) {
 *     // If itemId is not null, send "hello" message to itemId to make itemId null
 *     _.sendTo(itemId, "hello", "world");
 *     itemId = null;
 *   }
 * });
 * ```
 *
 * This script does the following.
 * - When it receives a message `"send"`, it records the sender's ItemId in the variable `itemId`.
 * - checks the variable `itemId` every frame to see if it is null, and if not, sends the message and assigns null to it
 * @player
 */
declare const _: PlayerScript;

/**
 * A handle to manipulate PlayerScript. It can be accessed from `_` objects.
 *
 * PlayerScript is generated by setting {@link ClusterScript.setPlayerScript | ClusterScript.setPlayerScript}.
 * @player
 */
interface PlayerScript {
  /**
   * {@link ItemId | ItemId} of the source Item that has the Player Script component that called {@link ClusterScript.setPlayerScript | ClusterScript.setPlayerScript}.
   */
  readonly sourceItemId: ItemId;

  /**
   * Player's {@link PlayerId | PlayerId}.
   */
  readonly playerId: PlayerId;

  /**
   * Output the `toString` contents of `v` to the log.
   *
   * @param v
   */
  log(v: any): void;

  /**
   * Calculate the data size when sending data from PlayerScript and return the number of bytes.
   * 
   * If the data is not a {@link PlayerScriptSendable}, a {@link TypeError} will occur.
   */
  computeSendableSize(arg: PlayerScriptSendable): number;

  /**
   * Register a callback that will be called every frame.
   * This callback is guaranteed to be called every frame.
   *
   * If called multiple times, only the last registration is valid.
   *
   * @example
   * ```ts
   * // Output logs at 10 second intervals.
   * let t = 0;
   * _.onFrame(deltaTime => {
   *     t += deltaTime;
   *     if (t > 10) {
   *         _.log("10 sec elapsed.");
   *         t -= 10;
   *     }
   * });
   * ```
   *
   * @param callback
   */
  onFrame(callback: (deltaTime: number) => void): void;

  /**
   * Registers a callback to be called when this item receives a message sent from {@link PlayerHandle.send | PlayerHandle.send} or sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} to {@link PlayerId | PlayerId}.
   *
   * If called multiple times, only the last registration will be valid.
   *
   * #### option
   * You can specify the type of message to receive with option.
   *
   * If option is not set, it will receive both messages from {@link PlayerHandle.send | PlayerHandle.send} and messages sent to {@link PlayerId | PlayerId} by {@link PlayerScript.sendTo | PlayerScript.sendTo}. PlayerScript.sendTo | PlayerScript.sendTo}.
   *
   * - If `option.item` is `true`, then messages sent from {@link PlayerHandle.send | PlayerHandle.send} will be received.
   * - If `option.item` is `false`, then messages sent from {@link PlayerHandle.send | PlayerHandle.send} will be ignored.
   * - If `option.item` is unset, then messages sent from {@link PlayerHandle.send | PlayerHandle.send} will be received.
   * - If `option.player` is `true`, then messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be received.
   * - If `option.player` is `false`, then messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be ignored.
   * - If `option.player` is unset, then messages sent from {@link PlayerScript.sendTo | PlayerScript.sendTo} will be received.
   *
   * @example
   * ```ts
   * // Output log of messages sent.
   * _.onReceive((messageType, arg, sender) => {
   *   _.log(`Received message: ${messageType}, ${arg}`);
   * });
   * ```
   *
   * @example
   * ```ts
   * // Outputs a log of messages sent. Receive only messages from items.
   * _.onReceive((messageType, arg, sender) => {
   *   _.log(`Received message: ${messageType}, ${arg}`);
   * }, { player: false, item: true });
   * ```
   *
   * @param callback sender represents the item or player from which it is sent.
   * @param option Option to register callbacks. You can specify the type of message to receive。
   */
  onReceive(callback: (messageType: string, arg: PlayerScriptSendable, sender: ItemId | PlayerId) => void, option?: { player: boolean, item: boolean }): void;

  /**
   * Send a message to the item or player.\
   * An item can receive the sent message in a callback set in {@link ClusterScript.onReceive | ClusterScript.onReceive} with `{ player: true }` specified.\
   * A player can receive the sent message in a callback set in {@link PlayerScript.onReceive | PlayerScript.onReceive}.\
   * See {@link PlayerScriptSendable} for data that can be used in the message payload (the `arg` argument).
   *
   * Ignored for deleted items and for invalid ItemId.\
   * Ignored for players who have left the room and for invalid PlayerId.
   *
   * If sent for an ItemId, {@link PlayerScriptSendable} will be converted to {@link Sendable}.
   *
   * If a non-PlayerScriptSendable value, such as `undefined`, is passed to `arg` argument as the message's payload, it will be ignored.
   * This behaviour may change in future releases.
   *
   * #### Frequency Limit
   *
   * There is a limit on how often `sendTo` can be called.
   * - When called from a craft item, it must not exceed 10 calls per second per item
   * - When called from a world item, the total number of calls to {@link ItemHandle.send}, {@link PlayerHandle.send}, and {@link PlayerScript.sendTo} from all world items in the space must not exceed 3000 calls per second
   *
   * It is possible to momentarily exceed this limit, but please ensure the average number of calls stays below this limit.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   *
   * #### Flow Control
   * 
   * When APIs subject to Flow Control, including this API, are called excessively frequently beyond the limit within a space, the results may be applied with significant delays.
   * For more details, please refer to [Flow Control](https://docs.cluster.mu/creatorkit/en/world/cluster-script/flow-control/).
   * 
   * #### Limitations from Flow Control
   * 
   * If the item running this script is a world item, the `sendTo` operation will only succeed if Flow Control Delay is 30 seconds or less.
   * If the limit is exceeded, {@link ClusterScriptError} (`rateLimitExceeded`) occurs and the operation fails.
   * 
   * #### Capacity Limit
   *
   * Encoded size of `arg` must meet the following limits.
   *
   * - When sending a message from the PlayerScript of a world item, 100kB or less.
   * - When sending a message from the PlayerScript of a craft item, 1000 bytes or less.
   *
   * If the data size exceeds the limit, either a warning will be displayed or {@link ClusterScriptError} (`requestSizeLimitExceeded`) will occur and the send will fail.
   * The data size can be calculated with {@link PlayerScript.computeSendableSize}.
   * 
   * @param id target item or player
   * @param messageType A short string to describe the message type
   * @param arg The message payload
   */
  sendTo(id: PlayerId | ItemId, messageType: string, arg: PlayerScriptSendable): void;

  /**
   * Gets whether the player is using VR devices.
   */
  readonly isVr: boolean;

  /**
   * Gets whether the player is in a desktop environment.
   *
   * Returns false if in a VR or mobile environment.
   */
  readonly isDesktop: boolean;

  /**
   * Gets whether the player is in a mobile environment.
   *
   * Returns false if in a VR or desktop environment.
   */
  readonly isMobile: boolean;

  /**
   * Gets whether the player is in a Windows environment.
   */
  readonly isWindows: boolean;

  /**
   * Gets whether the player is in a macOS environment.
   */
  readonly isMacOs: boolean;

  /**
   * Gets whether the player is in an Android environment.
   *
   * Returns true if in a Quest environment.
   */
  readonly isAndroid: boolean;

  /**
   * Gets whether the player is in an iOS environment.
   */
  readonly isIos: boolean;
  /**
   * @beta
   * Gets the icon object corresponding to the specified iconId defined by Icon Asset List component.
   * See details of the component at [Icon Asset List](https://docs.cluster.mu/creatorkit/en/item-components/icon-asset-list/).
   * You can use the data with {@link PlayerScript.showButton | PlayerScript.showButton} to show the buttons with specified icon.
   *
   * @param iconId Id of the icon asset
   */
  iconAsset(iconId: string) : IconAsset;

  /**
   * @beta
   *
   * Displays a button UI corresponding to the specified integer value, or starts monitoring key/mouse click inputs that are treated as equivalent to a button.
   * If called on a button that is already displayed, the icon will be updated.
   * Up to four button inputs can be presented in this way.
   *
   * To display buttons with this function, the `Use Cluster HUD v2` option must be enabled on the world's [WorldRuntimeSetting](https://docs.cluster.mu/creatorkit/en/world-components/world-runtime-setting/) component.
   * Use {@link PlayerScript.onButton | PlayerScript.onButton} to register the callback for the buttons.
   *
   * In desktop and mobile environments, the button corresponding to `index = 0` is the same as the "Use" button of the item with UseItemTrigger component.
   * Other buttons are only displayed by calling this function.
   * If this function is called with `index = 0`, the display content of the button set by this function and the callback registered with {@link PlayerScript.onButton | PlayerScript.onButton} will take priority over the "Use" button of the item until {@link PlayerScript.hideButton | PlayerScript.hideButton} is called with `index = 0`.
   * Pressing a button will not fire UseItemTrigger and {@link ClusterScript.onUse | ClusterScript.onUse } callback.
   *
   * Buttons displayed by this function will be hidden when {@link PlayerScript.hideButton | PlayerScript.hideButton} is called or when the validity period of the Player Script expires.
   *
   * In a mobile environment, buttons are placed in specific positions according to their numbers.
   * In a desktop environment, the following key assignments are applied to buttons 0, 1, 2, and 3.
   *
   * - 0: Left click
   * - 1: Right click
   * - 2: E key
   * - 3: R key
   *
   * In a VR environment, when one or more buttons are enabled, pulling the trigger on the right-hand controller will display a pie menu. Tilting the stick then inputs the corresponding button.
   * On the pie menu, the buttons correspond to 0, 1, 2, and 3, arranged counterclockwise starting from the right.
   * 
   * In a desktop environment, mouse cursor operation on the screen is locked while one or more buttons are displayed, and clicks and key inputs during mouse lock are treated as button inputs.
   * If buttons are displayed and hidden very frequently, this automatic mouse lock will be disabled for a certain period of time.
   *
   * @param index The button number, either 0, 1, 2, or 3. Other value will result an error.
   * @param icon The icon to show on the button. When the icon is invalid, then treated as the icon is not specified.
   */
  showButton(index: number, icon: IconAsset) : void;

  /**
   * @beta
   * Hides the button shown by {@link PlayerScript.showButton | PlayerScript.showButton}.
   * Does nothing if the specified button is already hidden.
   *
   * In desktop and mobile environments, when called with `index = 0`, the behavior of the "Use" button will revert to normal, and the button availability will be controlled by UseItemTrigger and {@link ClusterScript.onUse | ClusterScript.onUse } callback.
   *
   * @param index The button number, either 0, 1, 2, or 3. Other value will result an error.
   */
  hideButton(index: number) : void;

  /**
   * @beta
   * Registers the callback method for the button shown by {@link PlayerScript.showButton | PlayerScript.showButton}.
   * The callback will be called with `isDown = true` when pressed, and called again with `isDown = false` when the button is released.
   * The method is available before showing the button, and the registration state is maintained even if the button is hidden.
   *
   * If called multiple times, only the last registration will be valid per button index.
   *
   * This callback is not necessarily called with `isDown = false` after being called with `isDown = true`.
   * For example, if you press a button and then call `hideButton` to hide the button, the callback with `isDown = false` will not be called.
   *
   * @param index The button number, either 0, 1, 2, or 3. Other value will result an error.
   * @param callback method that is called when the button is pressed or released.
   */
  onButton(index: number, callback: (isDown: boolean) => void): void;

  /**
   * Locates an animation entry with the ID `humanoidAnimationId` within the item's `HumanoidAnimationList`, and returns a {@link HumanoidAnimation} object referring to it.
   *
   * For details on `HumanoidAnimationList`, refer to the [documentation](https://docs.cluster.mu/creatorkit/en/item-components/humanoid-animation-list/).
   *
   * @param humanoidAnimationId
   */
  humanoidAnimation(humanoidAnimationId: string): HumanoidAnimation;

  /**
   * Obtains the current position of the player themselves in global coordinates. \
   * This method obtains the player's position before it is synchronized to the space.
   *
   * Returns `null` if the value cannot be obtained.
   *
   * You can also get player's movement status with {@link PlayerScript.getAvatarMovementFlags | PlayerScript.getAvatarMovementFlags}.
   *
   * @returns The player's position
   */
  getPosition() : Vector3 | null;

  /**
   * Obtains the current rotation of the player themselves in global coordinates. \
   * This method obtains the player's rotation before it is synchronized to the space.
   *
   * Returns `null` if the value cannot be obtained.
   *
   * You can also get player's movement status with {@link PlayerScript.getAvatarMovementFlags | PlayerScript.getAvatarMovementFlags}.
   *
   * @returns The player's rotation
   */
  getRotation() : Quaternion | null;

  /**
   * Sets the position of the player themselves in global coordinate. \
   * This method sets the player's position before it is synchronized to the space.
   *
   * @param position The player's position
   */
  setPosition(position: Vector3): void;

  /**
   * Sets the rotation of the player themselves in global coordinate. \
   * This method sets the player's rotation before it is synchronized to the space.
   *
   * Note the body orientation will stay vertical.
   *
   * @param rotation The player's rotation
   */
  setRotation(rotation: Quaternion): void;

  /**
   * Obtains the current position of the specified player synchronized in the space, in global coordinates.
   *
   * Returns `null` if the value cannot be obtained.
   *
   * @param playerId PlayerId of the player whose value is to be obtained
   * @returns The player's position
   */
  getPositionOf(playerId: PlayerId) : Vector3 | null;

  /**
   * Obtains the current rotation of the specified player synchronized in the space, in global coordinates.
   *
   * Returns `null` if the value cannot be obtained.
   *
   * @param playerId PlayerId of the player whose value is to be obtained
   * @returns The player's rotation
   */
  getRotationOf(playerId: PlayerId) : Quaternion | null;


  /**
   * Obtains the position of a player's `HumanoidBone`.
   * Values are in global coordinates.
   * If the avatar has not finished loading yet, or the specified bone does not exist on the avatar, returns `null`.
   *
   * @param bone Humanoid bone
   */
  getHumanoidBonePosition(bone: HumanoidBone): Vector3 | null;

  /**
   * Obtains the rotation of a player's `HumanoidBone`.
   * Values are in global coordinates.
   * If the avatar has not finished loading yet, or the specified bone does not exist on the avatar, returns `null`.
   *
   * @param bone Humanoid bone
   */
  getHumanoidBoneRotation(bone: HumanoidBone): Quaternion | null;

  /**
   * Overwrites the pose of the player's avatar model with the specified `HumanoidPose`.
   * The pose specified by this method is applied only to that frame and does not affect the next frame or later.
   *
   * If the `rootPosition`, `rootRotation`, or `muscle` of the given `HumanoidPose` are not defined, they will not be overwritten.
   *
   * `weight` represents the application rate of the specified pose as a number between 0 and 1. Calling the method with `weight = 1` applies the pose completely.
   * `weight` is optional, and treated as `1` is specified if omitted.
   *
   * The pose specified by this function takes precedence over {@link PlayerHandle.setHumanoidPose | PlayerHandle.setHumanoidPose}.
   * In VR, items held by the player will follow the specified pose, but the first-person camera and UI operations are not affected.
   *
   * @param pose The pose to apply
   * @param weight The weight to apply the pose
   */
  setHumanoidPoseOnFrame(pose: HumanoidPose, weight: number): void;

  /**
   * Sets the specified bone's rotation.
   * Values are in global coordinates.
   * The rotation specified by this method is applied only to that frame and does not affect the next frame or later.
   *
   * This method does nothing when the specified bone does not exist in the avatar.
   *
   * The bone rotations specified by this function take precedence over the pose specified by {@link PlayerHandle.setHumanoidPose | PlayerHandle.setHumanoidPose}.
   * In VR, items held by the player will follow the specified pose, but the first-person camera and UI operations are not affected.
   *
   * @param bone Bone to rotate
   * @param rotation Rotation of the bone
   */
  setHumanoidBoneRotationOnFrame(bone: HumanoidBone, rotation: Quaternion): void;

  /**
   * Gets the handle to control camera movement.
   */
  readonly cameraHandle: CameraHandle;

  /**
   * Gets the handle to control vibration of the controllers or devices of the player.
   */
  readonly hapticsHandle: HapticsHandle;

  /**
   * Returns an {@link ItemId} object that references the Item specified by `worldItemReferenceId` in the item's WorldItemReferenceList.
   *
   * For details on `WorldItmeReferenceList`, see [documentation](https://docs.cluster.mu/creatorkit/en/item-components/world-item-reference-list/).
   *
   * @example
   * ```ts
   * // Item that sends message "button" to the specified item when button 0 is pressed
   * const target = _.worldItemReference("target");
   *
   * _.onButton(0, isDown => {
   *   if (isDown) _.sendTo(target, "button", null);
   * });
   * ```
   *
   * @param worldItemReferenceId
   */
  worldItemReference(worldItemReferenceId: string): ItemId;

  /**
   * Casts a ray, and returns the first object it collided with.
   *
   * @param position Origin of the ray (global coordinates)
   * @param direction Direction of the ray (global coordinates)
   * @param maxDistance Maximum distance for performing collision detection
   *
   * @returns The collided object (`null` if no collision)
   */
  raycast(position: Vector3, direction: Vector3, maxDistance: number): PlayerScriptRaycastResult | null;

  /**
   * Casts a ray, and returns all the objects it collided with.
   *
   * When a large number of colliders are included in the range, it may not be possible to retrieve all ItemHandles that meet the condition.
   * In this case, a warning message will be output to the console.
   *
   * @param position Origin of the ray (global coordinates)
   * @param direction Direction of the ray (global coordinates)
   * @param maxDistance Maximum distance for performing collision detection
   *
   * @returns An array of the collided objects (order is undefined)
   */
  raycastAll(position: Vector3, direction: Vector3, maxDistance: number): PlayerScriptRaycastResult[];

  /**
   * Gets the avatar's movement and motion status as a list of bitmasked flags.
   * The defined bitflags are as follows:
   *
   * - `0x0001`: On if the avatar is on the ground, off if in the air due to jumping or falling
   * - `0x0002`: On if the avatar is climbing, off otherwise
   * - `0x0004`: On if the avatar is riding on items, off otherwise
   *
   * Flags may be added in future updates, so use a value with the bitflag masked.
   * @example
   * ```ts
   * // Example of a function to get bit flags and output logs
   * function getStatus() {
   *   let flags = _.getAvatarMovementFlags();
   *   let isGrounded = (flags & 0x0001) !== 0;
   *   let isClimbing = (flags & 0x0002) !== 0;
   *   let isRiding = (flags & 0x0004) !== 0;
   *   _.log(`isGrounded: ${isGrounded}, isClimbing: ${isClimbing}, isRiding: ${isRiding}`);
   * }
   * ```
   *
   * @returns Flags about avatar movement status
   */
  getAvatarMovementFlags(): number;

  /**
   * Overwrites data in the player's PlayerStorage.
   * 
   * See {@link PlayerScriptSendable} for data that can be saved (the `data` argument).
   * 
   * This API is not available from Craft Items.
   * 
   * #### PlayerStorage
   * 
   * PlayerStorage is an area for saving data that exists per player in each world or event.
   * If `setPlayerStorageData` has never been called, `null` is stored in the PlayerStorage.
   * 
   * In worlds, the data in PlayerStorage is saved even if the player leaves the world.
   * When the player returns to the world, they can get the saved data.
   * PlayerStorage can also store `PlayerId` and `ItemId`, but these do not necessarily represent players or items that are valid in other spaces.
   * 
   * In events, each time a player enters, PlayerStorage is initialized, and `null` is set.
   * Even if the data in PlayerStorage is overwritten during an event, the data in PlayerStorage of the original Event Venue remains unchanged.
   * 
   * The data in PlayerStorage can be deleted from the World Manager.
   * See [Resetting world save data](https://docs.cluster.mu/creatorkit/en/world/manage-data/save/#resetting-world-save-data) for details.
   * 
   * #### Capacity Limit
   * 
   * The data size of the encoded `data` must be less than or equal to 10,000 bytes.
   * The data size can be calculated using {@link PlayerScript.computeSendableSize}.
   * 
   * If the data size is larger than the limit, {@link ClusterScriptError} (`requestSizeLimitExceeded`) will occur and `setPlayerStorageData` will fail.
   * 
   * @example
   * ```ts
   * // Example code that levels up when receiving a levelUp message and saves the result.
   * let level = 1;
   * _.onReceive((messageType, arg, sender) => {
   *   if (messageType === "levelUp") {
   *     level += 1;
   *     _.setPlayerStorageData({ level });
   *   }
   * });
   * ```
   * 
   * @param Data to overwrite in PlayerStorage
   */
  setPlayerStorageData(data: PlayerScriptSendable): void;

  /**
   * Gets data in the player's PlayerStorage.
   * 
   * This API is not available from Craft Items.
   * 
   * For details on PlayerStorage, see {@link PlayerScript.setPlayerStorageData}.
   * 
   * @example
   * ```ts
   * // Example code to get the saved level when a player starts the game
   * let level;
   * const storageData = _.getPlayerStorageData();
   * if (storageData === null) {
   *   level = 1;
   * } else {
   *   level = storageData.level;
   * }
   * ```
   * 
   * @returns The data currently saved in PlayerStorage
   */
  getPlayerStorageData(): PlayerScriptSendable;

  /**
   * Gets the object specified by `id` in Player Local Object Reference List.
   * See detail at [Player Local Object Reference List](https://docs.cluster.mu/creatorkit/en/item-components/player-local-object-reference-list/).
   * Returns `null` if id is not defined in the component or the object does not match the condition defined in the component page.
   * 
   * @param id id of the object
   */
  playerLocalObject(id: string): PlayerLocalObject | null;

  /**
   * Respawns the player.
   */
  respawn(): void;

  /**
   * Adds a velocity to the player.
   * The actual movement speed of the player is determined from both the added velocity and player input.
   * While the player is in contact with the ground, the added velocity will gradually decrease, similar to the effects of friction.
   *
   * @param velocity velocity (global coordinates)
   */
  addVelocity(velocity: Vector3): void;

  /**
   * Modifies the player's movement speed multiplier. The default is 1.
   *
   * The setting is shared with {@link PlayerHandle.setMoveSpeedRate | PlayerHandle.setMoveSpeedRate}.
   * The value of the one called later will overwrite it.
   *
   * @param moveSpeedRate Movement speed multiplier
   */
  setMoveSpeedRate(moveSpeedRate: number): void

  /**
   * Modifies the player's jumping speed multiplier. The default is 1.
   *
   * The setting is shared with {@link PlayerHandle.setJumpSpeedRate | PlayerHandle.setJumpSpeedRate}.
   * The value of the one called later will overwrite it.
   *
   * @param jumpSpeedRate Jumping speed multiplier
   */
  setJumpSpeedRate(jumpSpeedRate: number): void

  /**
   * Modifies the gravitational acceleration applied to the player. (Units are in m/s^2.) The default is -9.81.
   *
   * The setting is shared with {@link PlayerHandle.setGravity | PlayerHandle.setGravity}.
   * The value of the one called later will overwrite it.
   *
   * @param gravity Gravitational acceleration value
   */
  setGravity(gravity: number): void

  /**
   * Resets any movement velocity, jumping speed, and gravity applied to the player.
   * The movement speed, jump speed, and gravity specified by {@link PlayerHandle} will also be reset.
   */
  resetPlayerEffects(): void

  /**
   * @beta
   * Sets post-process effects for the player.
   *
   * Each time this method is called, the previously set PostProcessEffects are overwritten with the new PostProcessEffects.
   *
   * Setting null clears all effects.
   *
   * The settings are shared with {@link PlayerHandle.setPostProcessEffects | PlayerHandle.setPostProcessEffects}.
   * The value of the one called later will overwrite it.
   *
   * @example
   * ```ts
   * // A button that becomes very bright when pressed.
   * _.onButton(0, (isDown) => {
   *     if (!isDown) return;
   *     const effects = new PostProcessEffects();
   *     effects.bloom.active = true;
   *     effects.bloom.threshold.setValue(0.5);
   *     effects.bloom.intensity.setValue(10.0);
   *     _.setPostProcessEffects(effects);
   * });
   * ```
   *
   * @param effects An instance of PostProcessEffects.
   */
  setPostProcessEffects(effects: PostProcessEffects | null): void

  /**
   * Get the player's [User ID](https://help.cluster.mu/hc/en-us/articles/115000821651-User-ID).
   * Users can change their own User ID, but no two different users can have the same User ID at the same time.
   * `null` is returned for players who have left the room or for invalid PlayerId.
   *
   * @param playerId PlayerId of the player whose value is to be obtained
   */
  getUserId(playerId: PlayerId): string | null;

  /**
   * Get the player's [display name](https://help.cluster.mu/hc/en-us/articles/115000827152-Display-name).
   * Users can change their display names, and different users can use the same display name.
   * It returns `null` for players who have left the room or for invalid PlayerId.
   *
   * @param playerId PlayerId of the player whose value is to be obtained
   */
  getUserDisplayName(playerId: PlayerId): string | null;

  /**
   * Get the value of [IDFC](https://docs.cluster.mu/creatorkit/en/world/manage-data/#idfc-identifier-for-creator) of the player.
   * The IDFC is a string that creators can use to uniquely identify a user.
   * This string is 32 characters long, using the characters `0123456789abcdef`.
   * This string is determined by the combination of the account that uploaded the item that is the source of the PlayerScript and the user's account.
   * The source item is the item that called `$.setPlayerScript()` and can be obtained with `_.sourceItemId`.
   * It does not change depending on the device or space used by the user.
   * It returns `null` for players who have left the room or for invalid PlayerId.
   *
   * This string can be used to improve the content experience. We may restrict its use without notice if we deem it inappropriate.
   *
   * @param playerId PlayerId of the player whose value is to be obtained
   */
  getIdfc(playerId: PlayerId): string | null;

  /**
   * The handle to receive or send Open Sound Control (OSC) messages.
   */
  readonly oscHandle: OscHandle;

  /**
   * Gets the product ID of the avatar item currently used by the player.
   *
   * If the avatar being used is not a product, it returns `null`. \
   * While the player is launching the Avatar Maker, it returns the product ID of the avatar that was used before launching the Avatar Maker. \
   * Immediately after the player changes the avatar, it may return the product ID of the avatar that was used just before. \
   * Immediately after the player enters the space, it may return `null`.
   *
   * @returns The product ID of the avatar currently used by the player.
   */
  getAvatarProductId(): string | null;

  /**
   * Gets an array of product IDs for the accessory items currently used by the player.
   *
   * If the accessory being used is not a product, it will not be included in the array. \
   * While the player is editing accessories, it returns the product ID of the accessory that was used before editing. \
   * Immediately after the player saves accessories, it may return the product ID of the accessory that was used just before. \
   * Immediately after the player enters the space, it may return an empty array.
   *
   * @returns An array of product IDs for the accessories currently used by the player.
   */
  getAccessoryProductIds(): string[];

   /**
   * Set the voice volume of the specified player that the player executing the Player Script hears.
   * Changes made to one's own player will be ignored.
   *
   * The value specified in this method will be reset when the validity period of the Player Script expires.
   *
   * @param playerId PlayerId of the player whose value is to be set
   * @param rate The rate of the volume to be set. The specified value is clamped between 0 and 1.
   */
  setVoiceVolumeRateOf(playerId: PlayerId, rate: number): void;

  /**
   * Sends analytics data to Cluster's server.
   * This feature is offered only for paid users.
   *
   * It might not be sent depending on the data size, frequency, or network conditions.
   *
   * @param analyticsId ID for analysis
   * @param extensionsJson Analytics data. It is expected to be in JSON format.
   */
  sendAnalytics(analyticsId: string, extensionsJson: string): void;

  /**
   * Registers a callback function that is called when a pan (view direction) input is received in a non-VR environment.
   * The registered callback is called regardless of whether the view direction actually changed.
   *
   * If called multiple times, only the last registration is effective.
   *
   * In special modes (such as during accessory editing), this callback will not be called.
   * In VR environments, this callback will not be called.
   *
   * @param callback
   * delta = The approximate amount the view direction would change in degrees, if the view direction changes (x is horizontal, positive toward the right; y is vertical, positive upward)
   * This value reflects the user's operation sensitivity and inversion settings.
   */
  onPan(callback: (delta: Vector2) => void): void;

  /**
   * Returns whether a mouse button or touch is being pressed.
   *
   * Returns false if the corresponding pointing device does not exist.
   *
   * The value is not updated when the application is inactive.
   *
   * @param pressType The type of mouse button or touch to check if pressed.
   *
   * `"leftClick"`, `"rightClick"`, `"middleClick"`, `"touch"` are available.
   * @returns Whether the mouse button or touch is pressed.
   */
  isPointerPress(pressType: PressType): boolean;

  /**
   * Returns whether the mouse is locked.
   *
   * Returns false in mobile and Quest environments.
   *
   * @returns Whether the mouse is locked.
   */
  isMouseLocked(): boolean;

  /**
   * Returns the current pointer position.
   * The coordinate system has the bottom-left of the screen at (0, 0) and the top-right at (1, 1).
   *
   * For touchscreens, returns the last touch position when not being touched.
   *
   * The value is not updated when the application is inactive.
   *
   * Returns an undefined value when the mouse is locked or in Quest environments.
   *
   * @returns The current pointer position.
   */
  getPointerPosition(): Vector2;

  /**
   * Returns the scroll amount for this frame from a mouse wheel or similar input.
   *
   * Only captures scrolling performed within the application while it is active.
   *
   * Returns the zero vector if there is no input device that supports scrolling.
   *
   * @returns The scroll amount for this frame in pixels (x is horizontal, positive toward the right; y is vertical, positive upward). This value may vary significantly depending on the device.
   */
  getScroll(): Vector2;

  /**
   * Returns the current screen size of the Cluster application.
   *
   * Returns an undefined value in Quest environments.
   *
   * @returns The window size in pixels (x is horizontal, y is vertical).
   */
  getScreenSize(): Vector2;
}

/**
 * The handle to control the player's camera movement.
 * You can access the handle with {@link PlayerScript.cameraHandle | PlayerScript.cameraHandle}.
 * @player
 */
interface CameraHandle {

  /**
   * Gets whether the player is using first person view.
   *
   * This methods always returns `true` for the player in VR.
   * When the player is not in VR environment, returns `true` if the player is using first person view and returns `false` otherwise.
   *
   * This methods will returns a valid value even if camera is in specific modes.
   * You can validate the current camera by calling {@link CameraHandle.getPosition | CameraHandle.getPosition} or {@link CameraHandle.getRotation | CameraHandle.getRotation} and check the result is not `null`.
   *
   * @returns Whether the player is using first person view.
   */
  isFirstPersonView(): boolean;

  /**
   * Obtains the current position of the camera in global coordinates.
   * In VR environment, the result indicates the player's eye position.
   * In non-VR environment, the result indicates the camera position based on the current perspective.
   *
   * When the player is in non-VR environment and editing accessories, this method returns the camera position that will be applied after the acccessory edit is finished.
   */
  getPosition(): Vector3;

  /**
   * Obtains the current rotation of the camera in global coordinates.
   * In VR environment, the result indicates the player's eye position.
   * In non-VR environment, the result indicates the camera rotation based on the current perspective.
   *
   * When the player is in non-VR environment and editing accessories, this method returns the camera rotation that will be applied after the acccessory edit is finished.
   */
  getRotation(): Quaternion;

  /**
   * Specifies the camera position in global coordinates.
   * 
   * The behavior when this method is called is as follows
   * - In VR environment
   *   - It does not affect the camera position in VR environment
   * - In non-VR environment
   *   - If first person view was active just before this method is called, it switches to the third person view camera
   *   - The specified camera position is reflected
   *   - Disables the switching operation between first person and third person views
   *   - The avatar's head always faces the direction of movement unless the camera mode's "Look at camera" is on
   *   - The rendering quality of the avatar changes depending on the distance from the specified camera position
   *     - However, the quality of the avatar's motion and audio may decrease significantly when far from the player
   *   - The following aspects are the same as in the usual third person view
   *     - Avatar movement controls
   *     - The source of the player's voice
   *     - The way sounds are heard
   *     - Item selection methods
   * - In other special modes (such as when editing accessories)
   *   - The camera position can be specified, but it is not reflected immediately and is reflected after the special mode ends
   *
   * The values specified by this method will reset when called with `null` for `position` or when the Player Script ends.
   * After reset, the switching operation between first person and third person views will be enabled again.
   * Additionally, if the view was in first person before calling this method, it will return to first person after the reset.
   *
   * @param position The global coordinates of the camera.
   */
  setPosition(position: Vector3 | null): void;
  
  /**
   * Specifies the camera rotation in global coordinates.
   * 
   * The behavior when this method is called is as follows
   * - In VR environment
   *   - It does not affect the camera rotation in VR environment
   * - In non-VR environment, first person view
   *   - The specified camera rotation is reflected
   *   - Disables camera rotation through mouse dragging
   *   - Does not affect the camera rotation
   * - In non-VR environment, third person view
   *   - The specified camera rotation is reflected
   *   - Disables camera rotation through mouse dragging
   *   - The camera position is changed according to the camera rotation and the player's position
   * - In other special modes (such as when editing accessories)
   *   - The camera rotation can be specified, but it is not reflected immediately and is reflected after the special mode ends
   * 
   * When this method is called with `null` for `rotation` or when the Player Script ends, the player will be able to manipulate the camera rotation again. 
   * At this point, the camera rotation will be reset to what it was last specified in `setRotation()`, excluding the roll angle.
   *
   * @param rotation The global rotation of the camera.
   */
  setRotation(rotation: Quaternion | null): void;
  
  /**
   * Calculates the camera position as if camera posture is not operated with `setPosition()` and `setRotation()`.
   * 
   * In VR environment, it ignores `rotation` and `isFirstPersonView` values, returning the same value as `getPosition()`.
   * In non-VR environment, it calculates the camera position based on the view state specified by `rotation` and `isFirstPersonView`.
   *
   * @param rotation The global rotation of the camera, ignoring the roll angle.
   * @param isFirstPersonView `true` for first person view, `false` for third person view.
   */
  calculateDefaultPosition(rotation: Quaternion, isFirstPersonView: boolean): Vector3;

  /**
   * Sets the default value of the field of view for players who are not in VR environment.
   * The field of view is specified as the vertical angle from the bottom to the top of the screen.
   *
   * This method has no effect in VR.
   * After changing the field of view by this method, the player can still zoom in and out, and switch between first and third person perspectives using zoom.
   *
   * The value specified in this method will be reset when calling the method with `value` is `null`, or when the validity period of the Player Script expires.
   *
   * @param value The default value of the field of view in degrees, between 10 and 80. The outsided value will be clamped.
   * @param immediate If `true`, the value is applied immediately without interpolation. This parameter is optional, and if omitted, it is treated as `false`.
   */
  setFieldOfView(value: number | null, immediate: boolean): void;

  /**
   * Specifies the maximum distance between the avatar and the camera in third-person view in meters.
   *
   * The actual distance between the camera and the avatar may not be equal to the specified value.
   * If there are walls or ceilings around the avatar, the camera will be closer than the specified distance.
   *
   * This function can be executed even when the player is in a VR environment or in first-person view, but it does not affect the behavior in a VR environment or in first-person view.
   *
   * The value specified in this method will be reset when calling the method with `distance` is `null`, or when the validity period of the Player Script expires.
   *
   * @param distance The maximum distance between the avatar and the camera. The minimum value is 0.2, and smaller value will be treated same as 0.2.
   * @param immediate If `true`, the interpolation is skipped and the value is applied immediately. This value is optional and is treated as `false` if omitted.
   */
  setThirdPersonDistance(distance: number | null, immediate: boolean): void;

  /**
   * In third-person view, specifies the position on the screen near the avatar's head in screen coordinates.
   * The left edge of the screen corresponds to `x=0`, and the right edge corresponds to `x=1`.
   * The bottom edge of the screen corresponds to `y=0`, and the top edge corresponds to `y=1`.
   *
   * This function can be executed when the player is in a VR environment or in first-person view, but it does not affect behavior in a VR environment or in first-person view.
   *
   * The value specified in this method will be reset when calling the method with `pos` is `null`, or when the validity period of the Player Script expires.
   *
   * @param pos The position on the screen near the avatar's head. Both x and y components are clamped between 0 and 1.
   * @param immediate If `true`, the interpolation is skipped and the value is applied immediately. This value is optional and is treated as `false` if omitted.
   */
  setThirdPersonAvatarScreenPosition(pos: Vector2 | null, immediate: boolean): void;

  /**
   * In third-person view, sets whether to fix the avatar's orientation so that it faces forward.
   * This method can be used for the case that the avatar should aim to objects in the world in third-person view.
   *
   * This function can also be executed when the player is in a VR environment or first-person view, but it does not affect behavior in a VR environment or first-person view.
   *
   * The value specified in this method will be reset when calling the method with `value` is `null`, or when the validity period of the Player Script expires.
   *
   * @param value Whether to fix the avatar's orientation to face forward
   */
  setThirdPersonAvatarForwardLock(value: boolean | null): void;

  /**
   * Switches to first-person view.
   *
   * This function can be called while the player is in VR or already in first-person view, but it has no effect in VR or when the player is in first-person view.
   * Also, if the camera position has been specified with {@link CameraHandle.setPosition | CameraHandle.setPosition}, calling this function does not change the perspective.
   */
  switchToFirstPersonView(): void;

  /**
   * Switches to third-person view.
   *
   * This function can be called while the player is in VR or already in third-person view, but it has no effect in VR or when the player is in third-person view.
   * Also, if the camera position has been specified with {@link CameraHandle.setPosition | CameraHandle.setPosition}, calling this function does not change the perspective.
   */
  switchToThirdPersonView(): void;

  /**
   * Locks switching between first-person and third-person views via HUD and zoom in/out.
   *
   * This function can be called while the player is in VR, but it does not affect behavior in VR.
   * Even while switching is locked by this function, the script can still change the camera position and the view.
   * When the validity period of the Player Script expires, switching via the HUD and zoom in/out becomes available again.
   *
   * @param isLocked Whether to lock switching
   */
  setPerspectiveSwitchingLocked(isLocked: boolean): void;
}

/**
 * The handle to control vibration of the controllers or devices of the player.
 * You can access the handle with {@link PlayerScript.hapticsHandle | PlayerScript.hapticsHandle}.
 * @player
 */
interface HapticsHandle {
  /**
   * Gets whether the device's vibration function is available.
   *
   * Returns true if the device supports vibration and vibration feedback is not disabled in "Settings".
   *
   * In mobile environments, vibration can be enabled or disabled with "Vibration" at "Haptic feedback" in the "Controls" tab of "Settings".
   *
   */
  isAvailable(): boolean;

  /**
   * Returns the absolute frequency value in Hz when `0` is specified to {@link HapticsEffect.frequency | HapticsEffect.frequency }.
   *
   * The frequency setting will not be reflected in the actual vibration feedback in the following cases:
   *
   * - This API returns `null`.
   * - The device does not support vibration frequency setting.
   */
  readonly minFrequencyHz: number | null;

  /**
   * Returns the absolute frequency value in Hz when `1` is specified to {@link HapticsEffect.frequency | HapticsEffect.frequency }.
   *
   * The frequency setting will not be reflected in the actual vibration feedback in the following cases:
   *
   * - This API returns `null`.
   * - The device does not support vibration frequency setting.
   */
  readonly maxFrequencyHz: number | null;

  /**
   * Plays vibration feedback if vibration is supported by the controller or device of the player.
   *
   * In VR environments, the controllers will provide vibration feedback. \
   * If `target` is set to `"left"` or `"right"`, vibration feedback will be played on the corresponding left or right controller. \
   * If `target` is an unsupported value or `null`, vibration feedback will be played on both controllers.
   *
   * On mobile devices that support vibration, the device itself will provide vibration feedback. \
   * `target` value is ignored.
   *
   * If vibration is not available on the device, the call to `playEffect()` will be ignored.
   *
   * @example
   * ```ts
   * // Plays vibration feedback, by both controllers in VR environment, or by the device itself in mobile environment.
   * const effect = new HapticsEffect();
   * effect.frequency = 0.1;
   * effect.amplitude = 1;
   * effect.duration = 0.1;
   * _.hapticsHandle.playEffect(effect, null);
   * ```
   *
   * @param effect The content of the vibration feedback
   * @param target A string value indicating the target to vibrate (`"left"` or `"right"`), or `null` for unspecified
   */
  playEffect(effect: HapticsEffect, target: HapticsTarget | null): void;
}

/**
 * A reference to an item that can be handled from PlayerScript.
 * When receiving messages sent by {@link PlayerHandle.send | PlayerHandle.send}, ItemHandle is converted to ItemId.
 * @player
 */
declare class ItemId {
  /** @internal */
  private constructor();

  /**
   * A string representation of an ID that uniquely represents an item in the space.
   * An ItemId with equal id points to the same item.
   * The same as the value of {@link ItemHandle.id | ItemHandle.id}.
   */
  readonly id: string;

  /**
   * Returns string "item".
   * This value can be used to distinguish {@link ItemId} and {@link PlayerId}.
   */
  readonly type: "item";
}

/**
 * A reference to a player that can be handled from PlayerScript.
 * PlayerHandle is converted to PlayerId when receiving messages sent by {@link PlayerHandle.send | PlayerHandle.send}.
 * @player
 */
declare class PlayerId {
  /** @internal */
  private constructor();

  /**
   * A string representation of an ID that uniquely represents a player in the space.
   * PlayerId with equal id points to the same player.
   * This value is different for each entry, even for the same user.
   * The same as the value of {@link PlayerHandle.id | PlayerHandle.id}.
   */
  readonly id: string;

  /**
   * Returns string "player".
   * This value can be used to distinguish {@link ItemId} and {@link PlayerId}.
   */
  readonly type: "player";
}

/**
 * The reference to the icon asset which can be fetched by {@link PlayerScript.iconAsset | PlayerScript.iconAsset}.
 * Use this value to show icon of the buttons with {@link PlayerScript.showButton | PlayerScript.showButton}.
 * @player @beta
 */
interface IconAsset {
}

/**
 * A read-only type describing the result of a raycast obtained by methods in {@link PlayerScript | PlayerScript}.
 *
 * Unlike {@link RaycastResult | RaycastResult }, This values does not include the detail about hit object.
 * @player
 */
interface PlayerScriptRaycastResult {
  /**
   * Describes a hit.
   */
  readonly hit: Hit;
}

/**
 * A status code that indicates the result of a purchasable item purchase. Refer to {@link PlayerHandle.requestPurchase | PlayerHandle.requestPurchase} and {@link ClusterScript.onRequestPurchaseStatus | ClusterScript.onRequestPurchaseStatus} for details.
 * @item
 */
declare enum PurchaseRequestStatus {
  /** Indicates that it is unclear whether the purchase was made due to reasons such as a network error. */
  Unknown = 0,
  /** Indicates that the player has purchased the item. */
  Purchased = 1,
  /** Indicates that the purchase request was automatically refused, due to the player could not display the item purchase dialog. */
  Busy = 2,
  /** Indicates that the player closed the item purchase dialog without making a purchase. */
  UserCanceled = 3,
  /** Indicates that the purchase dialog failed to display, due to the specified item is not available. */
  NotAvailable = 4,
  /** Indicates that the player attempted to purchase the item but the purchase failed. */
  Failed = 5,
}

/**
 * Describing the status of owned purchasable items.
 * Refer to {@link ClusterScript.getOwnProducts | ClusterScript.getOwnProducts} and {@link ClusterScript.onGetOwnProducts | ClusterScript.onGetOwnProducts} for details.
 * @item
 */
interface OwnProduct {
  /**
   * The product ID of the purchasable item.
   */
  readonly productId: string;
  /**
   * The player who owns the purchasable item.
   */
  readonly player: PlayerHandle;
  /**
   * The total number of purchasable items that the player has purchased.
   */
  readonly plusAmount: number;
  /**
   * The total number of purchasable items that the player has received a refund.
   */
  readonly minusAmount: number;
}

/**
 * @player
 * The handle of the object which can be referred in Player Script.
 */
interface PlayerLocalObject {

  /**
   * Gets the handle of the child object of this object, by specified name.
   * 
   * This method ignores the objects with `Item` component and its children.
   * Use {@link ClusterScript | ClusterScript } or {@link SubNode | SubNode } to control the object with `Item` component.
   * 
   * @param name 
   * @returns The handle of the object with specified name, or `null` if not found
   */
  findObject(name: string): PlayerLocalObject | null;

  /**
   * The name of the object.
   */
  readonly name: string;

  /**
   * Sets the object's activeness.
   * When the object is inactive, the object and all its children will not be rendered.
   * 
   * This method throws error if the object is a parent or child of `Item`.
   * This is a restriction to avoid control conflicts with `Item` components and `Scriptable Item`.
   * 
   * @param v true to activate the object, false otherwise
   */
  setEnabled(v: boolean): void;

  /**
   * Gets the activeness of the object.
   * 
   * Returns `null` if the value cannot be obtained.
   */
  getEnabled(): boolean;

  /**
   * Gets the total activeness of the object.
   * Returns `true` if the object itself and all its parent objects are active.
   * 
   * Returns `null` if the value cannot be obtained.
   */
  getTotalEnabled(): boolean;

  /**
   * Gets the handle of the Unity component attached to this object by type name.
   * The available type names are defined in {@link UnityComponent}.
   * 
   * If the object has multiple components, returns first component.
   * 
   * This method throws error if the object is a parent or child of `Item`.
   * This is a restriction to avoid control conflicts with `Item` components and `Scriptable Item`.
   * 
   * @param type 
   * @returns The component specified by type name, or `null` if not found
   */
  getUnityComponent(type: string) : UnityComponent | null;
}

/**
 * The handle of the Unity component attached to an object.
 *
 * This handle can be obtained by the following APIs.
 *
 * - {@link ClusterScript.getUnityComponent | ClusterScript.getUnityComponent}
 * - {@link SubNode.getUnityComponent | SubNode.getUnityComponent}
 * - {@link PlayerLocalObject.getUnityComponent | PlayerLocalObject.getUnityComponent}
 *
 * If the instance is obtained by {@link ClusterScript.getUnityComponent | ClusterScript.getUnityComponent} or {@link SubNode.getUnityComponent | SubNode.getUnityComponent}, operations on the handle will modify the appearance and behavior of the item, visible to all players.
 *
 * If the instance is obtained by {@link PlayerLocalObject.getUnityComponent | PlayerLocalObject.getUnityComponent}, operations on the handle will modify the appearance and behavior of the item, visible only to that player.
 *
 * These APIs support the same list of component names.
 * The following is the list of available type names for the `getUnityComponent` method.
 *
 * - "AimConstraint"
 * - "Animator"
 * - "AudioSource"
 * - "BoxCollider"
 * - "Button"
 * - "Camera"
 * - "Canvas"
 * - "CanvasGroup"
 * - "CapsuleCollider"
 * - "CharacterJoint"
 * - "ConfigurableJoint"
 * - "Dropdown"
 * - "FixedJoint"
 * - "GridLayoutGroup"
 * - "HingeJoint"
 * - "HorizontalLayoutGroup"
 * - "Image"
 * - "InputField"
 * - "LayoutElement"
 * - "Light"
 * - "LineRenderer"
 * - "LookAtConstraint"
 * - "Mask"
 * - "MeshCollider"
 * - "MeshRenderer"
 * - "NavMeshAgent"
 * - "Outline"
 * - "ParentConstraint"
 * - "ParticleSystem"
 * - "PlayableDirector"
 * - "PositionConstraint"
 * - "PostProcessVolume"
 * - "RawImage"
 * - "RectTransform"
 * - "Rigidbody"
 * - "RotationConstraint"
 * - "ScaleConstraint"
 * - "Scrollbar"
 * - "ScrollRect"
 * - "Shadow"
 * - "SkinnedMeshRenderer"
 * - "Slider"
 * - "SphereCollider"
 * - "SpringJoint"
 * - "Text"
 * - "TextMesh"
 * - "TextMeshPro"
 * - "TextMeshProUGUI"
 * - "TMP_Dropdown"
 * - "TMP_InputField"
 * - "Toggle"
 * - "ToggleGroup"
 * - "TrailRenderer"
 * - "Transform"
 * - "VerticalLayoutGroup"
 * - "VideoPlayer"
 * - "WheelCollider"
 *
 */
interface UnityComponent { 

  /**
   * A handle to access properties of the Unity component.
   *
   * This API requires the exact name of the property as defined in the Unity component.
   * The property name shown in the Unity Editor may differ from the actual property name.
   * Please refer to the Unity API reference for details.
   *
   * The properties that can be accessed with `unityProp` must be one of the following data types:
   * `bool`, `int`, `float`, `double`, `string`, `Vector2`, `Vector3`, `Vector4`, `Quaternion`, `Color`, `Rect`, or a derived type of `Enum`.
   * If you attempt to access a property of a different data type, `null` will be returned when getting the property, and an exception will be thrown when setting the property.
   *
   * `Enum` types are represented as `int` values.
   * Similarly, when setting a property of type `Enum`, specify an `int` value.
   * Please refer to the Unity API reference for the correspondence between `Enum` values and their internal `int` representation.
   *
   * When setting property values from this handle, changes are applied after the script execution completes.
   * If you get a property value immediately after setting it within the same callback, you will not receive the updated value.
   *
   * #### Usage in Player Script
   *
   * In `Player Script`, properties updated via this API are reflected only in the player running the script.
   *
   * @example
   * ```ts
   * // An example for Player Script to set the property of the component in PlayerLocalObject
   * let imageObject = _.playerLocalObject("ImageObject");
   * let image = imageObject.getUnityComponent("Image");
   * image.unityProp.color = new Color(1, 0, 0, 1);
   *
   * let textObject = _.playerLocalObject("TextObject");
   * let textComponent = textObject.getUnityComponent("Text");
   * textComponent.unityProp.text = "Hello, World!";
   * ```
   *
   * In `Player Script`, all properties with supported data types can be read and written.
   *
   * #### Usage in Scriptable Item
   *
   * In `Scriptable Item`, property values set via this API are synchronized over the network.
   * Please be aware that updates may not be reflected immediately, and no interpolation is applied to the values.
   *
   * @example
   * ```ts
   * // An example for Scriptable Item to set the property of the component in SubNode
   * let node = $.subNode("Cube");
   * let meshRenderer = node.getUnityComponent("MeshRenderer");
   * meshRenderer.unityProp.receiveShadows = false;
   *
   * let transform = node.getUnityComponent("Transform");
   * transform.unityProp.localScale = new Vector3(2, 2, 2);
   * ```
   *
   * #### Important: Undefined Behavior
   *
   * In `Scriptable Item`, the following scenarios will result in undefined behavior.
   * These operations may cause the item state to desynchronize between players.
   *
   * - When this API and other Cluster Script APIs both update the same property internally
   *   - For example, {@link SubNode.setPosition | SubNode.setPosition} internally updates `Transform.localPosition`, so updating `Transform.localPosition` with this API while also using `setPosition` will result in undefined behavior
   * - When this API and gimmick components both update the same property internally
   * - When this API and Unity features (e.g., Animator) both update the same property
   * - When updating a property with this API triggers changes in the internal state of a Unity component
   *
   * To avoid undefined behavior:
   *
   * - Do not control properties updated by this API using Animator or other components
   * - Prefer using dedicated APIs when available over this API
   *
   * For example, use {@link ClusterScript.setPosition | ClusterScript.setPosition} to change an item's position instead of updating `Transform.localPosition` with this API.
   *
   * #### Restrictions on Editable Properties
   *
   * In `Scriptable Item`, the properties accessible via this API are restricted to ensure proper synchronization between players.
   * The following properties can be read and written for each component type:
   *
   * - AimConstraint
   *   - enabled
   *   - aimVector
   *   - constraintActive
   *   - rotationAtRest
   *   - rotationAxis
   *   - rotationOffset
   *   - upVector
   *   - weight
   *   - worldUpVector
   * - Animator
   *   - enabled
   * - AudioSource
   *   - enabled
   *   - bypassEffects
   *   - bypassListenerEffects
   *   - bypassReverbZones
   *   - dopplerLevel
   *   - loop
   *   - maxDistance
   *   - minDistance
   *   - mute
   *   - panStereo
   *   - pitch
   *   - playOnAwake
   *   - priority
   *   - spatialize
   *   - spatializePostEffects
   *   - volume
   * - BoxCollider
   *   - enabled
   *   - center
   *   - isTrigger
   *   - size
   * - Button
   *   - enabled
   *   - interactable
   *   - transition
   * - Camera
   *   - enabled
   *   - allowHDR
   *   - allowMSAA
   *   - anamorphism
   *   - aperture
   *   - backgroundColor
   *   - barrelClipping
   *   - bladeCount
   *   - curvature
   *   - depth
   *   - farClipPlane
   *   - fieldOfView
   *   - focalLength
   *   - focusDistance
   *   - forceIntoRenderTexture
   *   - iso
   *   - lensShift
   *   - nearClipPlane
   *   - orthographic
   *   - orthographicSize
   *   - rect
   *   - sensorSize
   *   - shutterSpeed
   *   - stereoConvergence
   *   - stereoSeparation
   *   - useOcclusionCulling
   *   - usePhysicalProperties
   * - Canvas
   *   - enabled
   *   - normalizedSortingGridSize
   *   - overridePixelPerfect
   *   - overrideSorting
   *   - pixelPerfect
   *   - planeDistance
   * - CanvasGroup
   *   - enabled
   *   - alpha
   *   - blocksRaycasts
   *   - ignoreParentGroups
   *   - interactable
   * - CapsuleCollider
   *   - enabled
   *   - center
   *   - height
   *   - isTrigger
   *   - radius
   * - CharacterJoint
   *   - enableProjection
   *   - projectionAngle
   *   - projectionDistance
   * - ConfigurableJoint
   *   - configuredInWorldSpace
   *   - enableCollision
   *   - enablePreprocessing
   *   - projectionAngle
   *   - projectionDistance
   *   - swapBodies
   *   - targetAngularVelocity
   *   - targetPosition
   *   - targetRotation
   *   - targetVelocity
   * - Dropdown
   *   - enabled
   *   - alphaFadeSpeed
   *   - interactable
   *   - transition
   *   - value
   * - FixedJoint
   *   - breakForce
   *   - breakTorque
   *   - enableCollision
   *   - enablePreprocessing
   * - GridLayoutGroup
   *   - enabled
   *   - cellSize
   *   - childAlignment
   *   - constraint
   *   - constraintCount
   *   - spacing
   *   - startAxis
   *   - startCorner
   * - HingeJoint
   *   - breakForce
   *   - breakTorque
   *   - enableCollision
   *   - enablePreprocessing
   *   - useLimits
   *   - useMotor
   *   - useSpring
   * - HorizontalLayoutGroup
   *   - enabled
   *   - childAlignment
   *   - childControlHeight
   *   - childControlWidth
   *   - childForceExpandHeight
   *   - childForceExpandWidth
   *   - childScaleHeight
   *   - childScaleWidth
   *   - reverseArrangement
   *   - spacing
   * - Image
   *   - enabled
   *   - color
   *   - fillAmount
   *   - fillCenter
   *   - fillClockwise
   *   - fillMethod
   *   - fillOrigin
   *   - maskable
   *   - pixelsPerUnitMultiplier
   *   - preserveAspect
   *   - raycastPadding
   *   - raycastTarget
   *   - type
   *   - useSpriteMesh
   * - InputField
   *   - enabled
   *   - caretBlinkRate
   *   - caretWidth
   *   - characterLimit
   *   - characterValidation
   *   - contentType
   *   - customCaretColor
   *   - interactable
   *   - lineType
   *   - readOnly
   *   - selectionColor
   *   - text
   *   - transition
   * - LayoutElement
   *   - enabled
   *   - flexibleHeight
   *   - flexibleWidth
   *   - ignoreLayout
   *   - layoutPriority
   *   - minHeight
   *   - minWidth
   *   - preferredHeight
   *   - preferredWidth
   * - Light
   *   - enabled
   *   - bounceIntensity
   *   - color
   *   - colorTemperature
   *   - intensity
   *   - range
   *   - shadowBias
   *   - shadowNearPlane
   *   - shadowNormalBias
   *   - shadowStrength
   *   - spotAngle
   * - LineRenderer
   *   - enabled
   *   - loop
   *   - meshLodSelectionBias
   *   - receiveShadows
   *   - rendererPriority
   *   - sortingOrder
   *   - useWorldSpace
   *   - widthMultiplier
   * - LookAtConstraint
   *   - enabled
   *   - constraintActive
   *   - roll
   *   - rotationAtRest
   *   - rotationOffset
   *   - useUpObject
   *   - weight
   * - Mask
   *   - enabled
   *   - showMaskGraphic
   * - MeshCollider
   *   - enabled
   *   - convex
   *   - isTrigger
   * - MeshRenderer
   *   - enabled
   *   - meshLodSelectionBias
   *   - receiveShadows
   *   - rendererPriority
   *   - sortingOrder
   * - NavMeshAgent
   *   - enabled
   *   - acceleration
   *   - agentTypeID
   *   - angularSpeed
   *   - areaMask
   *   - autoBraking
   *   - autoRepath
   *   - autoTraverseOffMeshLink
   *   - avoidancePriority
   *   - baseOffset
   *   - desiredVelocity
   *   - destination
   *   - hasPath
   *   - height
   *   - isOnNavMesh
   *   - isOnOffMeshLink
   *   - isPathStale
   *   - isStopped
   *   - obstacleAvoidanceType
   *   - pathEndPosition
   *   - pathPending
   *   - pathStatus
   *   - radius
   *   - remainingDistance
   *   - speed
   *   - steeringTarget
   *   - stoppingDistance
   *   - updatePosition
   *   - updateRotation
   *   - updateUpAxis
   * - Outline
   *   - enabled
   *   - effectColor
   *   - effectDistance
   *   - useGraphicAlpha
   * - ParentConstraint
   *   - enabled
   *   - constraintActive
   *   - rotationAtRest
   *   - rotationAxis
   *   - translationAtRest
   *   - translationAxis
   *   - weight
   * - PlayableDirector
   *   - enabled
   * - PositionConstraint
   *   - enabled
   *   - constraintActive
   *   - translationAtRest
   *   - translationAxis
   *   - translationOffset
   *   - weight
   * - PostProcessVolume
   *   - enabled
   *   - blendDistance
   *   - isGlobal
   *   - priority
   *   - weight
   * - RawImage
   *   - enabled
   *   - color
   *   - maskable
   *   - raycastPadding
   *   - raycastTarget
   *   - uvRect
   * - RectTransform
   *   - anchorMax
   *   - anchorMin
   *   - anchoredPosition
   *   - localPosition
   *   - localRotation
   *   - localScale
   *   - pivot
   *   - rect
   *   - sizeDelta
   * - Rigidbody
   *   - angularDamping
   *   - centerOfMass
   *   - inertiaTensor
   *   - inertiaTensorRotation
   *   - isKinematic
   *   - linearDamping
   *   - mass
   *   - useGravity
   * - RotationConstraint
   *   - enabled
   *   - constraintActive
   *   - rotationAtRest
   *   - rotationAxis
   *   - rotationOffset
   *   - weight
   * - ScaleConstraint
   *   - enabled
   *   - constraintActive
   *   - scaleAtRest
   *   - scaleOffset
   *   - scalingAxis
   *   - weight
   * - ScrollRect
   *   - enabled
   *   - decelerationRate
   *   - elasticity
   *   - horizontal
   *   - inertia
   *   - movementType
   *   - scrollSensitivity
   *   - vertical
   * - Scrollbar
   *   - enabled
   *   - direction
   *   - interactable
   *   - numberOfSteps
   *   - size
   *   - transition
   *   - value
   * - Shadow
   *   - enabled
   *   - effectColor
   *   - effectDistance
   *   - useGraphicAlpha
   * - SkinnedMeshRenderer
   *   - enabled
   *   - meshLodSelectionBias
   *   - receiveShadows
   *   - rendererPriority
   *   - skinnedMotionVectors
   *   - sortingOrder
   *   - updateWhenOffscreen
   * - Slider
   *   - enabled
   *   - direction
   *   - interactable
   *   - maxValue
   *   - minValue
   *   - transition
   *   - value
   *   - wholeNumbers
   * - SphereCollider
   *   - enabled
   *   - center
   *   - isTrigger
   *   - radius
   * - SpringJoint
   *   - breakForce
   *   - breakTorque
   *   - damper
   *   - enableCollision
   *   - enablePreprocessing
   *   - maxDistance
   *   - minDistance
   *   - spring
   *   - tolerance
   * - TMP_Dropdown
   *   - enabled
   *   - alphaFadeSpeed
   *   - interactable
   *   - transition
   *   - value
   * - TMP_InputField
   *   - enabled
   *   - caretBlinkRate
   *   - caretColor
   *   - caretWidth
   *   - characterLimit
   *   - characterValidation
   *   - contentType
   *   - customCaretColor
   *   - interactable
   *   - lineLimit
   *   - onFocusSelectAll
   *   - pointSize
   *   - readOnly
   *   - richText
   *   - selectionColor
   *   - text
   *   - transition
   * - Text
   *   - enabled
   *   - color
   *   - maskable
   *   - text
   *   - raycastPadding
   *   - raycastTarget
   * - TextMesh
   *   - characterSize
   *   - fontSize
   *   - lineSpacing
   *   - offsetZ
   *   - richText
   *   - tabSize
   *   - text
   * - TextMeshPro
   *   - enabled
   *   - color
   *   - enableAutoSizing
   *   - enableCulling
   *   - extraPadding
   *   - fontSize
   *   - fontSizeMax
   *   - fontSizeMin
   *   - fontStyle
   *   - lineSpacing
   *   - margin
   *   - maskable
   *   - overflowMode
   *   - overrideColorTags
   *   - pageToDisplay
   *   - parseCtrlCharacters
   *   - raycastTarget
   *   - richText
   *   - text
   *   - textWrappingMode
   *   - vertexBufferAutoSizeReduction
   * - TextMeshProUGUI
   *   - enabled
   *   - color
   *   - enableAutoSizing
   *   - enableCulling
   *   - extraPadding
   *   - fontSize
   *   - fontSizeMax
   *   - fontSizeMin
   *   - fontStyle
   *   - lineSpacing
   *   - margin
   *   - maskable
   *   - overflowMode
   *   - overrideColorTags
   *   - pageToDisplay
   *   - parseCtrlCharacters
   *   - raycastTarget
   *   - richText
   *   - text
   *   - textWrappingMode
   *   - vertexBufferAutoSizeReduction
   * - Toggle
   *   - enabled
   *   - interactable
   *   - isOn
   *   - transition
   * - ToggleGroup
   *   - enabled
   *   - allowSwitchOff
   * - TrailRenderer
   *   - enabled
   *   - autodestruct
   *   - emitting
   *   - meshLodSelectionBias
   *   - minVertexDistance
   *   - receiveShadows
   *   - rendererPriority
   *   - sortingOrder
   *   - time
   *   - widthMultiplier
   * - Transform
   *   - localPosition
   *   - localRotation
   *   - localScale
   * - VerticalLayoutGroup
   *   - enabled
   *   - childAlignment
   *   - childControlHeight
   *   - childControlWidth
   *   - childForceExpandHeight
   *   - childForceExpandWidth
   *   - childScaleHeight
   *   - childScaleWidth
   *   - reverseArrangement
   *   - spacing
   * - VideoPlayer
   *   - enabled
   *   - isLooping
   *   - playOnAwake
   *   - playbackSpeed
   *   - sendFrameReadyEvents
   *   - skipOnDrop
   *   - targetCameraAlpha
   *   - waitForFirstFrame
   * - WheelCollider
   *   - enabled
   *   - center
   *   - forceAppPointDistance
   *   - mass
   *   - radius
   *   - suspensionDistance
   *   - wheelDampingRate
   *
   */
  readonly unityProp : UnityComponentPropertyProxy;

  /** 
   * Plays the component if the handled component is `PlayableDirector`, `AudioSource`, `ParticleSystem`, or `VideoPlayer`.
   * 
   * An error will occur for other components.
   * 
   * If the instance is obtained by {@link ClusterScript.getUnityComponent | ClusterScript.getUnityComponent} by {@link SubNode.getUnityComponent | SubNode.getUnityComponent} and the handled component is `PlayableDirector`, `AudioSource`, its time will look same for all players.
   * The beginning of the playback may be skipped.
   * 
   * When `play()` is called for already playing component, the component will stop and restart playing.
   * 
   * For `ParticleSystem`, this method also plays particles attached in children objects.
   * If both a parent and child object have `ParticleSystem`, please execute `play()` or `stop()` on the particles of the parent only.
   * If `play()` or `stop()` is called for multiple `ParticleSystem`s in a parent-child relationship, they may not play correctly.
   * 
   * For `VideoPlayer`, it is recommended to specify `Video Clip` for `Source` and `Material Override` for `Render Mode`.
   * If `Source` is set to `Video Clip`, the playback time will look same for all players.
   * The beginning of the playback may be skipped.
   * Also, depending on the size of the video and the encoding method, it may take some time for playback to start.
   * 
   * If `Source` is `URL`, there will be a large delay until the playback actually starts. 
   * Also, the playback start timing and playback time will not be consistent for each player.
   * 
   * If the rendering result of `VideoPlayer` is applied to `Render Texture`, the rendering state when not playing will change depending on the OS and texture settings.
   * Consider to hide the texture when `VideoPlayer` is not playing.
   * 
   */
  play(): void;

  /** 
   * Stops the component playback if the handled component is `PlayableDirector`, `AudioSource`, `ParticleSystem`, or `VideoPlayer`.
   * 
   * An error will occur for other components.
   * 
   * Playback time will be reset when `stop()` is called for `PlayableDirector` and `VideoPlayer`.
   * 
   * For `ParticleSystem`, this method also stops particles attached in children objects.
   * If both a parent and child object have `ParticleSystem`, please execute `play()` or `stop()` on the particles of the parent only.
   * If `play()` or `stop()` is called for multiple `ParticleSystem`s in a parent-child relationship, they may not play correctly.
   * 
   */
  stop(): void;

  /**
   * Sets `Trigger` of the AnimatorController, if the handled component is `Animator`.
   * An error will occur for other components.
   * 
   * This method does nothing if the parameter does not exist, or if it is not `Trigger`.
   * 
   * @param id The name of the parameter
   */
  setTrigger(id: string): void;

  /**
   * Sets `Bool` parameter value of the AnimatorController, if the handled component is `Animator`.
   * An error will occur for other components.
   * 
   * This method does nothing if the parameter does not exist, or if it is not `Bool`.
   * 
   * @param id Name of the parameter
   * @param value The value to set
   */
  setBool(id: string, value: boolean): void;

  /**
   * Sets `Integer` parameter value of the AnimatorController, if the handled component is `Animator`.
   * An error will occur for other components.
   * 
   * This method does nothing if the parameter does not exist, or if it is not `Integer`.
   * 
   * @param id Name of the parameter
   * @param value The value to set
   */
  setInteger(id: string, value: number): void;

  /**
   * Sets `Float` parameter value of the AnimatorController, if the handled component is `Animator`.
   * An error will occur for other components.
   * 
   * This method does nothing if the parameter does not exist, or if it is not `Float`.
   * 
   * @param id Name of the parameter
   * @param value The value to set
   */
  setFloat(id: string, value: number): void;

  /**
   * Registers a callback function to be called when a `Button` in a Player Local UI is interacted with.
   * 
   * The component should be a `Button` and should be obtained by {@link PlayerLocalObject.getUnityComponent | PlayerLocalObject.getUnityComponent}.
   * If the component is not a `Button`, or the instance is obtained by {@link ClusterScript.getUnityComponent | ClusterScript.getUnityComponent} or {@link SubNode.getUnityComponent | SubNode.getUnityComponent}, an error will occur.
   * 
   * If the same callback is registered multiple times for a `Button` component, only the last registration will take effect.
   * 
   * The callback will be called with `isDown = true` when pressed, and called again with `isDown = false` when the button is released.
   * This callback is not necessarily called with `isDown = false` after being called with `isDown = true`.
   * For example, if you hold down the button, move the pointer outside of the button, and then release it, the `isDown = false` callback will not be triggered.
   * 
   * @param callback method that is called when the button is pressed or released.
   */
  onClick(callback: (isDown: boolean) => void): void;
}

/** @internal */
type UnityComponentPropertyProxy = {
  [propName: string]: UnityComponentPropertyValue;
};

/** @internal */
type UnityComponentPropertyValue = boolean | number | string | Vector2 | Vector3 | Vector4 | Quaternion | Color | Rect;

/**
 * @item
 * 
 * The gift sent in an event by a player.
 * The value can be obtained by {@link ClusterScript.onGiftSent | ClusterScript.onGiftSent}.
 * 
 */
interface GiftInfo {

  /**
   * The string representation of the ID that uniquely identifies a gift in the event.
   * A gift with different id specifies a different gift, even when other properties including {@link senderDisplayName} and {@link timestamp} are same.
   * 
   */
  readonly id: string;

  /**
   * The player who has sent the gift.
   * The value will be `null` when the player is a ghost or a group viewing participant.
   * 
   * It is possible that `sender.exists()` is `false`, when the player who sent the gift has already left the event.
   * 
   */
  readonly sender: PlayerHandle | null;

  /**
   * The display name of the player who has sent the gift.
   * 
   * Unlike {@link GiftInfo.sender}, this property returns valid name when the player is a ghost or a group viewing participant.
   * 
   */
  readonly senderDisplayName: string;

  /**
   * Obtains the initial position of the gift in global coordinates.
   * 
   * Initial position specifies where the gift appears in the space.
   * The position is near the hand of the player who sent the gift.
   * 
   * When generating an item at this position, the item may collide with the gift and the gift effect may start at an unintended position.
   * To avoid collision with the gift, do not attach a Collider to the item or set the layer of the generated item to VenueLayer0, VenueLayer1, VenueLayer2, etc.
   * 
   * Please see [Layers](https://docs.cluster.mu/creatorkit/en/world/unity-spec/layer/) about available layers in the world.
   * 
   */
  readonly initialPosition: Vector3;

  /**
   * Obtains the initial rotation of the gift in global coordinates.
   * 
   * Initial rotation specifies the orientation of the gift when it appears in the space.
   */
  readonly initialRotation: Quaternion;

  /**
   * Obtains the initial velocity of the gift in global coordinates.
   * 
   * Initial velocity specifies the speed of the gift when it appears in the space.
   * 
   * The gift is not affected by the gravity set by {@link PlayerHandle.setGravity | PlayerHandle.setGravity} and other methods, and moves in a parabolic trajectory with a constant downward acceleration.
   */
  readonly initialVelocity: Vector3;

  /**
   * Obtains the price of the gift as an integer value of Cluster Coin.
   */
  readonly price: number;
 
  /**
   * Obtains the time when the gift was sent in UTC, in total milliseconds since Unix epoch.
   */
  readonly timestamp: number;  

  /**
   * Obtains the string which identifies the type of the gift.
   * When gifts has same shape but different colors, then `giftType` will be different.
   * 
   * Please see [List of Gift Items](https://docs.cluster.mu/creatorkit/en/appendix/gift-list) about relationship between `giftType` values and actual gifts.
   * 
   */
  readonly giftType: string;
}


/**
 * The comment that can be obtained with {@link ClusterScript.getLatestComments | ClusterScript.getLatestComments} and {@link ClusterScript.onCommentReceived | ClusterScript.onCommentReceived}.
 */
interface Comment {

    /**
     * A unique ID for each comment.
     */
    id: string,

    /**
     * The PlayerHandle of the player who made the comment.
     *
     * It returns null in the following cases.
     * - If the comment is from YouTube
     * - If the comment is from a ghost or group viewing
     */
    sender: PlayerHandle | null,

    /**
     * The display name of the user who commented in Cluster or from YouTube.
     */
    displayName: string,

    /**
     * The text of the comment.
     */
    body: string,

    /**
     * The time the comment was made.
     * Returns the number of milliseconds that have elapsed since the UNIX epoch.
     *
     * If `via` is `“YouTube”`, the timestamp of the comment will always have the last three digits as 000, and only the accuracy to the second is guaranteed.
     */
    timestamp: number,

    /**
     * A string that indicates where the comment was made.
     * Currently, it takes either the value `“cluster”` or `“YouTube”`.
     * This may be added in a future update.
     */
    via: "cluster" | "YouTube",
}

/**
 * @player
 * 
 * Represents a single value in an Open Sound Control (OSC) message.
 */
declare class OscValue {
  /** @internal */
  private constructor();

  /**
   * Gets the value as an integer.
   * If the value cannot be interpreted as an integer, `null` is returned.
   */
  getInt(): number | null;

  /**
   * Gets the value as a floating-point number.
   * If the value cannot be interpreted as a floating-point number, `null` is returned.
   */
  getFloat(): number | null;

  /**
   * Gets the value as an ASCII string.
   * If the value cannot be interpreted as an ASCII string, `null` is returned.
   */
  getAsciiString(): string | null;

  /**
   * Gets the BLOB data as a UTF-8 string.
   * If the BLOB data does not exist or cannot be interpreted as UTF-8, `null` is returned.
   */
  getBlobAsUtf8String(): string | null;

  /**
   * Gets the BLOB data as a `Uint8Array`.
   * If the BLOB data does not exist, `null` is returned.
   */
  getBlobAsUint8Array(): Uint8Array | null;

  /**
   * Gets the value as a boolean.
   * If the value cannot be interpreted as a boolean, `null` is returned.
   */
  getBool(): boolean | null;

  /**
   * Creates an `OscValue` the represents an interger value based on the passed argument.\
   */
  static int(value: number): OscValue;

  /**
   * Creates an `OscValue` the represents a float value based on the passed argument.\
   */
  static float(value: number): OscValue;

  /**
   * Creates an `OscValue` the represents an ASCII string value based on the passed argument.\
   * If the argument is not an ASCII string value, an error is thrown.
   */
  static asciiString(value: string): OscValue;

  /**
   * Creates an `OscValue` the represents an BLOB data value based on the passed argument.\
   * If the argument is a string, the `OscValue` will contain the UTF-8 encoded string value.\
   * If the argument is a `Uint8Array`, the `OscValue` will contain the binary data as the value.\
   * If the argument cannot be interpreted as a BLOB value, an error is thrown.
   */
  static blob(value: string | Uint8Array): OscValue;

  /**
   * Creates an `OscValue` the represents a boolean value based on the passed argument.\
   */
  static bool(value: boolean): OscValue;
}

/**
 * @player
 * 
 * Represents a single Open Sound Control (OSC) message.
 */
declare class OscMessage {
  /**
   * Creates an instance of an OSC message.
   *
   * If values is omitted, it will be an empty array. 
   *
   * @param address The address for this message.
   * @param values The values to be contained in this message.
   * */
  constructor(address: string, values?: OscValue[]);

  /**
   * Represents the timestamp of this OSC message.
   * 
   * If this message was received as part of an OSC bundle, returns the timestamp as total milliseconds since Unix epoch.
   * 
   * When sending a message, this value is not used.
   */
  readonly timestamp: number;

  /**
   * Represents the address of this OSC message.
   */
  readonly address: string;

  /**
   * The array of values contained in this message.
   */
  readonly values: OscValue[];
}

/**
 * @player
 *
 * Represents a single Open Sound Control (OSC) bundle.
 * An OSC bundle can receive an arbitrary amount of OSC messages.
 */
declare class OscBundle {
  /**
   * Creates an instance of an OSC bundle.
   *
   * If timestamp is omitted, the current time on the device is set.
   *
   * @param messages The messages to be contained in this bundle
   * @param timestamp The timestamp of this bundle
   */
  constructor(messages: OscMessage[], timestamp?: number);

  /**
   * Represents the timestamp of this OSC bundle.
   * Returns total milliseconds since Unix epoch.
   */
  readonly timestamp: number;

  /**
   * The array of messages contained in this bundle.
   */
  readonly messages: OscMessage[];
}



/**
 * @player
 * 
 * The handle to receive or send Open Sound Control (OSC) messages.
 * This handle can be obtained by {@link PlayerScript.oscHandle | PlayerScript.oscHandle}.
 * 
 * For more information about OSC, please also refer to the [OSC](https://docs.cluster.mu/creatorkit/en/world/cluster-script/player-script/#osc) section in the documentation.
 */
interface OscHandle {
  /**
   * Registers a callback to be called when an OSC message is received.
   * The `callback` is called with an array of {@link OscMessage} received between the previous frame and the current frame.
   * If called multiple times, only the last registration is valid.
   * 
   * However, the callback is not called if any of the following conditions are met:
   * - When {@link isReceiveEnabled} is `false`
   * - When the network settings such as a firewall prevent receiving OSC messages
   * - When the address of the received OSC message starts with `/cluster/` (reserved by the system)
   * 
   * @example
   * ```ts
   * // Log the received OSC messages
   * _.oscHandle.onReceive(messages => {
   *   const lines = [];
   * 
   *   messages.forEach((message, i) => {
   *     const { address, timestamp, values } = message;
   * 
   *     lines.push(`== message [${i + 1}/${messages.length}]`);
   *     lines.push(`address: ${address}`);
   *     lines.push(`timestamp: ${new Date(timestamp).toLocaleString()}`);
   * 
   *     values.forEach((value, j) => {
   *       lines.push(`= value [${j + 1}/${values.length}]`);
   * 
   *       lines.push(`getInt(): ${value.getInt()}`);
   *       lines.push(`getFloat(): ${value.getFloat()}`);
   *       lines.push(`getAsciiString(): ${value.getAsciiString()}`);
   *       lines.push(`getBlobAsUint8Array(): ${value.getBlobAsUint8Array()}`);
   *       lines.push(`getBlobAsUtf8String(): ${value.getBlobAsUtf8String()}`);
   *       lines.push(`getBool(): ${value.getBool()}`);
   *     });
   *   });
   * 
   *   _.log(lines.join("\n"));
   * });
   * ```
   * 
   * @param callback
   * messages: The array of received OSC messages.
   */
  onReceive(callback: (messages: OscMessage[]) => void): void;

  /**
   * Attempts to send an OSC bundle or an OSC message.
   *
   * If any of the following conditions are met, a {@link ClusterScriptError} will occur and the bundle or message will fail to be sent.
   *
   * - {@link isSendEnabled} is `false`
   * - The address of the OSC message to be sent does not start with `/`
   * - The address of the OSC message to be sent starts with `/cluster/` (reserved by the system)
   * - The OSC message to be sent contains an invalid message or OscValue
   *
   * Due to the nature of the OSC system, there is no guarantee that the data you send will reach the destination server.
   *
   * @example
   * ```ts
   * // Send various OSC bundles and OSC messages
   * _.oscHandle.send(new OscBundle([new OscMessage("/int", [OscValue.int(1)])]));
   * _.oscHandle.send(new OscMessage("/float", [OscValue.float(2.3)]));
   * _.oscHandle.send(new OscMessage("/string", [OscValue.asciiString("456")]));
   * _.oscHandle.send(new OscMessage("/blob", [OscValue.blob("789")]));
   * _.oscHandle.send(new OscMessage("/bool", [OscValue.bool(false)]));
   * ```
   *
   * @param payload The bundle or message to be sent
   */
  send(payload: OscBundle | OscMessage): void;

  /**
   * Gets whether the user has enabled OSC input.
   * 
   * You can set it from "Enable OSC Receiver" in the "Other" tab of "Settings".
   */
  isReceiveEnabled(): boolean;

  /**
   * Gets whether the user has enabled OSC output.
   *
   * You can set it from "Enable OSC Sender" in the "Other" tab of "Settings".
   */
  isSendEnabled(): boolean;
}

/**
 * @item
 *
 * A readonly type that represents the result of a product grant operation performed using {@link PlayerHandle.requestGrantProduct | PlayerHandle.requestGrantProduct} and {@link ClusterScript.onRequestGrantProductResult | ClusterScript.onRequestGrantProductResult}.
 */
interface ProductGrantResult {
  /**
   * The meta string specified in {@link PlayerHandle.requestGrantProduct | PlayerHandle.requestGrantProduct}.
   */
  readonly meta: string;

  /**
   * The ID of the granted product.
   */
  readonly productId: string;

  /**
   * The name of the granted product.
   */
  readonly productName: string;

  /**
   * The {@link PlayerHandle | PlayerHandle} of the player who was granted the product.
   */
  readonly player: PlayerHandle;

  /**
   * A string indicating the result of the product grant request.
   * - `"Unknown"` .. Indicates that it cannot be determined whether the grant was performed due to reasons such as network errors.
   * - `"Granted"` .. Indicates that the product was granted to the player.
   * - `"AlreadyOwned"` .. Indicates that the player already owned the product.
   * - `"Failed"` .. Indicates that an attempt was made to grant the product, but the grant failed.
   */
  readonly status: ProductGrantStatus;

  /**
   * A string indicating the reason for failure when {@link ProductGrantResult.status | status} is `"Unknown"` or `"Failed"`.
   *
   * Returns `null` for other {@link ProductGrantResult.status | status} values.
   */
  readonly errorReason: string;
}

/** @internal @item */
type ProductGrantStatus = "Unknown" | "Granted" | "AlreadyOwned" | "Failed";

/**
 * Specifies the vibration feedback content.
 * @player
 */
declare class HapticsEffect {
  /**
   * Create an vibration pattern with default settings.
   */
  constructor();

  /**
   * Specifies the frequency of the vibration feedback. \
   * The higher the number, the higher the frequency. \
   * The specified value is clamped between 0 and 1. \
   * If not specified or `null` is specified, vibration feedback will be played at the default frequency.
   * 
   * Some devices do not support frequency settings.
   * In that case, frequency setting is ignored.
   * 
   * Notably, frequency settings are not supported in the following environments:
   * 
   * - iOS
   * - Android
   * - Quest environment
   * - PCVR environment, using Quest Link
   */
  frequency?: number;

  /**
   * Specifies the strength of the vibration feedback.
   * The higher the number, the stronger the vibration. \
   * The specified value is clamped between 0 and 1. \
   * If not specified or `null` is specified, vibration feedback will be played at the default strength.
   * 
   * How the strength of the vibration feedbacks feel may differ across devices. 
   */
  amplitude?: number;

  /**
   * Specifies the duration of the vibration feedback in seconds. \
   * If a negative value, no value, or `null` is specified, the vibration feedback will be played for the default duration.
   *
   * In some devices, the actual duration of the vibration feedback may be shorter than the specified value.
   */
  duration?: number;
}

/** @internal @player */
type HapticsTarget = "left" | "right";

/**
 * Represents a pressed mouse button or touch.
 * @internal @player
 */
type PressType = "leftClick" | "rightClick" | "middleClick" | "touch";

/**
 * @item
 *
 * A readonly type that represents the player's organization information.
 * Organization information is a feature granted only to certain users. This feature is offered only for paid users.
 */
interface Organization {
  /**
   * Represents the name of the organization.
   */
  readonly displayName: string;

  /**
   * Represents the role in the organization.
   */
  readonly role: OrganizationRole;
}

/**
 * @item
 *
 * A readonly type that represents the role in the organization.
 */
interface OrganizationRole {
  /**
   * Represents the name of the role.
   */
  readonly displayName: string;
}
