{"version":3,"sources":["../../../src/lib/v2/index.ts","../../../src/lib/v2/ConnectedMotionGroup.ts","../../../src/lib/converters.ts","../../../src/lib/v2/motionStateUpdate.ts","../../../src/lib/v2/vectorUtils.ts","../../../src/lib/v2/JoggerConnection.ts","../../../src/lib/v2/MotionStreamConnection.ts","../../../src/lib/v2/NovaCellAPIClient.ts","../../../src/lib/v2/NovaClient.ts","../../../src/LoginWithAuth0.ts","../../../src/lib/AutoReconnectingWebsocket.ts","../../../src/lib/availableStorage.ts","../../../src/lib/v2/mock/MockNovaInstance.ts","../../../src/lib/v2/ProgramStateConnection.ts"],"sourcesContent":["export * from \"@wandelbots/nova-api/v2\"\nexport * from \"./ConnectedMotionGroup\"\nexport * from \"./JoggerConnection\"\nexport * from \"./MotionStreamConnection\"\nexport * from \"./NovaCellAPIClient\"\nexport * from \"./NovaClient\"\nexport * from \"./ProgramStateConnection\"\n","import type {\n  Controller,\n  MotionGroupPhysical,\n  MotionGroupSpecification,\n  MotionGroupState,\n  RobotTcp,\n  SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nexport type MotionGroupOption = {\n  selectionId: string\n} & MotionGroupPhysical\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class ConnectedMotionGroup {\n  static async connect(\n    nova: NovaClient,\n    motionGroupId: string,\n    controllers: Controller[],\n  ) {\n    const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n      string,\n      string,\n    ]\n    const controller = controllers.find((c) => c.controller === controllerId)\n    const motionGroup = controller?.motion_groups.find(\n      (mg) => mg.motion_group === motionGroupId,\n    )\n    if (!controller || !motionGroup) {\n      throw new Error(\n        `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n      )\n    }\n\n    const motionStateSocket = nova.openReconnectingWebsocket(\n      `/motion-groups/${motionGroupId}/state-stream`,\n    )\n\n    // Wait for the first message to get the initial state\n    const firstMessage = await motionStateSocket.firstMessage()\n    const initialMotionState = tryParseJson(firstMessage.data)\n      ?.result as MotionGroupState\n\n    if (!initialMotionState) {\n      throw new Error(\n        `Unable to parse initial motion state message ${firstMessage.data}`,\n      )\n    }\n\n    console.log(\n      `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n  `,\n      initialMotionState,\n    )\n\n    // This is used to determine if the robot is virtual or physical\n    let isVirtual = false\n    try {\n      const opMode =\n        await nova.api.virtualRobotMode.getOperationMode(controllerId)\n\n      if (opMode) isVirtual = true\n    } catch (err) {\n      if (err instanceof AxiosError) {\n        console.log(\n          `Received ${err.status} from getOperationMode, concluding that ${controllerId} is physical`,\n        )\n      } else {\n        throw err\n      }\n    }\n\n    // Find out what TCPs this motion group has (we need it for jogging)\n    const { tcps } = await nova.api.motionGroupInfos.listTcps(motionGroupId)\n\n    const motionGroupSpecification =\n      await nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId)\n\n    const safetySetup =\n      await nova.api.motionGroupInfos.getSafetySetup(motionGroupId)\n\n    return new ConnectedMotionGroup(\n      nova,\n      controller,\n      motionGroup,\n      initialMotionState,\n      motionStateSocket,\n      isVirtual,\n      tcps!,\n      motionGroupSpecification,\n      safetySetup,\n    )\n  }\n\n  connectedJoggingCartesianSocket: WebSocket | null = null\n  connectedJoggingJointsSocket: WebSocket | null = null\n  planData: any | null // tmp\n  joggingVelocity: number = 10\n\n  // Not mobx-observable as this changes very fast; should be observed\n  // using animation frames\n  rapidlyChangingMotionState: MotionGroupState\n\n  constructor(\n    readonly nova: NovaClient,\n    readonly controller: Controller,\n    readonly motionGroup: MotionGroupPhysical,\n    readonly initialMotionState: MotionGroupState,\n    readonly motionStateSocket: AutoReconnectingWebsocket,\n    readonly isVirtual: boolean,\n    readonly tcps: RobotTcp[],\n    readonly motionGroupSpecification: MotionGroupSpecification,\n    readonly safetySetup: SafetySetup,\n  ) {\n    this.rapidlyChangingMotionState = initialMotionState\n\n    motionStateSocket.addEventListener(\"message\", (event) => {\n      const motionStateResponse = tryParseJson(event.data)?.result as\n        | MotionGroupState\n        | undefined\n\n      if (!motionStateResponse) {\n        throw new Error(\n          `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n        )\n      }\n\n      // handle motionState message\n      if (\n        !jointValuesEqual(\n          this.rapidlyChangingMotionState.joint_position.joints,\n          motionStateResponse.joint_position.joints,\n          MOTION_DELTA_THRESHOLD,\n        )\n      ) {\n        runInAction(() => {\n          this.rapidlyChangingMotionState = motionStateResponse\n        })\n      }\n\n      // handle tcpPose message\n      if (\n        !tcpPoseEqual(\n          this.rapidlyChangingMotionState.tcp_pose,\n          motionStateResponse.tcp_pose,\n          MOTION_DELTA_THRESHOLD,\n        )\n      ) {\n        runInAction(() => {\n          this.rapidlyChangingMotionState.tcp_pose =\n            motionStateResponse.tcp_pose\n        })\n      }\n    })\n    makeAutoObservable(this)\n  }\n\n  get motionGroupId() {\n    return this.motionGroup.motion_group\n  }\n\n  get controllerId() {\n    return this.controller.controller\n  }\n\n  get modelFromController() {\n    return this.motionGroup.model_from_controller\n  }\n\n  get wandelscriptIdentifier() {\n    const num = this.motionGroupId.split(\"@\")[0]\n    return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n  }\n\n  /** Jogging velocity in radians for rotation and joint movement */\n  get joggingVelocityRads() {\n    return (this.joggingVelocity * Math.PI) / 180\n  }\n\n  get joints() {\n    return this.initialMotionState.joint_position.joints.map((_, i) => {\n      return {\n        index: i,\n      }\n    })\n  }\n\n  get dhParameters() {\n    return this.motionGroupSpecification.dh_parameters\n  }\n\n  get safetyZones() {\n    return this.safetySetup.safety_zones\n  }\n\n  dispose() {\n    this.motionStateSocket.close()\n    if (this.connectedJoggingCartesianSocket)\n      this.connectedJoggingCartesianSocket.close()\n    if (this.connectedJoggingJointsSocket)\n      this.connectedJoggingJointsSocket.close()\n  }\n\n  setJoggingVelocity(velocity: number) {\n    this.joggingVelocity = velocity\n  }\n}\n","import type { Pose } from \"@wandelbots/nova-api/v1\"\n\n/** Try to parse something as JSON; return undefined if we can't */\nexport function tryParseJson(json: unknown): any {\n  try {\n    return JSON.parse(json as string)\n  } catch {\n    return undefined\n  }\n}\n\n/** Try to turn something into JSON; return undefined if we can't */\nexport function tryStringifyJson(json: unknown): string | undefined {\n  try {\n    return JSON.stringify(json)\n  } catch {\n    return undefined\n  }\n}\n\n/**\n * Converts object parameters to query string.\n * e.g. { a: \"1\", b: \"2\" } => \"?a=1&b=2\"\n *      {} => \"\"\n */\nexport function makeUrlQueryString(obj: Record<string, string>): string {\n  const str = new URLSearchParams(obj).toString()\n  return str ? `?${str}` : \"\"\n}\n\n/** Convert radians to degrees */\nexport function radiansToDegrees(radians: number): number {\n  return radians * (180 / Math.PI)\n}\n\n/** Convert degrees to radians */\nexport function degreesToRadians(degrees: number): number {\n  return degrees * (Math.PI / 180)\n}\n\n/**\n * Convert a Pose object representing a motion group position\n * into a string which represents that pose in Wandelscript.\n */\nexport function poseToWandelscriptString(\n  pose: Pick<Pose, \"position\" | \"orientation\">,\n) {\n  const position = [pose.position.x, pose.position.y, pose.position.z]\n  const orientation = [\n    pose.orientation?.x ?? 0,\n    pose.orientation?.y ?? 0,\n    pose.orientation?.z ?? 0,\n  ]\n\n  const positionValues = position.map((v) => v.toFixed(1))\n  // Rotation needs more precision since it's in radians\n  const rotationValues = orientation.map((v) => v.toFixed(4))\n\n  return `(${positionValues.concat(rotationValues).join(\", \")})`\n}\n\n/**\n * Check for coordinate system id equivalence, accounting for the \"world\" default\n * on empty/undefined values.\n */\nexport function isSameCoordinateSystem(\n  firstCoordSystem: string | undefined,\n  secondCoordSystem: string | undefined,\n) {\n  if (!firstCoordSystem) firstCoordSystem = \"world\"\n  if (!secondCoordSystem) secondCoordSystem = \"world\"\n\n  return firstCoordSystem === secondCoordSystem\n}\n","import type { TcpPose } from \"@wandelbots/nova-api/v2\"\n\nexport function jointValuesEqual(\n  oldJointValues: number[],\n  newJointValues: number[],\n  changeDeltaThreshold: number,\n): boolean {\n  if (newJointValues.length !== oldJointValues.length) {\n    return true\n  }\n\n  for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {\n    if (\n      Math.abs(newJointValues[jointIndex]! - oldJointValues[jointIndex]!) >\n      changeDeltaThreshold\n    ) {\n      return false\n    }\n  }\n\n  return true\n}\n\nexport function tcpPoseEqual(\n  oldTcp: TcpPose | undefined,\n  newTcp: TcpPose | undefined,\n  changeDeltaThreshold: number,\n): boolean {\n  // undefined -> defined (+reverse) transition\n  if ((oldTcp === undefined && newTcp) || (oldTcp && newTcp === undefined)) {\n    return false\n  }\n\n  // the typechecker cannot resolve states to \"!= undefined\" if \"&&\" is used\n  if (oldTcp === undefined || newTcp === undefined) {\n    return true\n  }\n\n  let changedDelta = 0\n  changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0])\n  changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1])\n  changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2])\n  changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0])\n  changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1])\n  changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2])\n\n  if (changedDelta > changeDeltaThreshold) {\n    return false\n  }\n\n  return (\n    oldTcp.coordinate_system === newTcp.coordinate_system &&\n    oldTcp.tcp === newTcp.tcp\n  )\n}\n","import * as THREE from \"three\"\n\n// Vector used by api endpoints\nexport type Vector3d = [number, number, number]\n\nexport function axisToIndex(axis: \"x\" | \"y\" | \"z\"): number {\n  switch (axis) {\n    case \"x\":\n      return 0\n    case \"y\":\n      return 1\n    case \"z\":\n      return 2\n  }\n}\n\nexport function indexToAxis(index: number): \"x\" | \"y\" | \"z\" | null {\n  switch (index) {\n    case 0:\n      return \"x\"\n    case 1:\n      return \"y\"\n    case 2:\n      return \"z\"\n    default:\n      return null\n  }\n}\n\nexport function vector3FromArray(vector: Vector3d): THREE.Vector3 {\n  return new THREE.Vector3(vector[0], vector[1], vector[2])\n}\n\nexport function vector3ToArray(vector: THREE.Vector3): Vector3d {\n  return [vector.x, vector.y, vector.z]\n}\n","import type {\n  InitializeJoggingRequest,\n  JoggingResponse,\n  JointVelocityRequest,\n  MotionGroupState,\n  TcpVelocityRequest,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { axisToIndex } from \"./vectorUtils\"\n\nexport type JoggerConnectionOpts = {\n  /**\n   * When an error message is received from the jogging websocket, it\n   * will be passed here. If this handler is not provided, the error will\n   * instead be thrown as an unhandled error.\n   */\n  onError?: (err: unknown) => void\n} & Omit<InitializeJoggingRequest, \"message_type\">\n\nexport class JoggerConnection {\n  // Currently a separate websocket is needed for each mode, pester API people\n  // to merge these for simplicity\n  joggingWebsocket: AutoReconnectingWebsocket | null = null\n  lastVelocityRequest: JointVelocityRequest | TcpVelocityRequest | null = null\n  lastResponse: JoggingResponse | null = null\n\n  static async open(\n    nova: NovaClient,\n    cell: string,\n    motionGroupId: string,\n    opts: JoggerConnectionOpts,\n  ) {\n    const motionGroupState =\n      await nova.api.motionGroupInfos.getCurrentMotionGroupState(motionGroupId)\n\n    return new JoggerConnection(\n      nova,\n      cell,\n      motionGroupId,\n      motionGroupState,\n      opts,\n    )\n  }\n\n  constructor(\n    readonly nova: NovaClient,\n    readonly cell: string,\n    readonly motionGroupId: string,\n    readonly motionGroupState: MotionGroupState,\n    readonly opts: JoggerConnectionOpts,\n  ) {\n    this.joggingWebsocket = nova.openReconnectingWebsocket(\n      `/cells/${cell}/execution/jogging`,\n    )\n    this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n      const data = tryParseJson(ev.data) as JoggingResponse\n      if (data && \"error\" in data) {\n        if (this.opts.onError) {\n          this.opts.onError(ev.data)\n        } else {\n          throw new Error(ev.data)\n        }\n      }\n    })\n\n    this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n      const data = tryParseJson(ev.data)\n      if (data && \"error\" in data) {\n        if (this.opts.onError) {\n          this.opts.onError(ev.data)\n        } else {\n          throw new Error(ev.data)\n        }\n      }\n    })\n  }\n\n  get jointCount() {\n    return this.motionGroupState.joint_current?.joints.length\n  }\n\n  get activeWebsocket() {\n    return this.joggingWebsocket\n  }\n\n  async stop() {\n    // Why not call the stopJogging API endpoint?\n    // Because this results in the websocket closing and we\n    // would like to keep it open for now.\n    if (!this.joggingWebsocket) {\n      return\n    }\n\n    if (this.lastVelocityRequest?.message_type === \"JointVelocityRequest\") {\n      this.joggingWebsocket.sendJson({\n        message_type: \"JointVelocityRequest\",\n        velocity: {\n          joints: Array.from(new Array(this.jointCount).keys()).map(() => 0),\n        },\n      } as JointVelocityRequest)\n    }\n\n    if (this.lastVelocityRequest?.message_type === \"TcpVelocityRequest\") {\n      this.joggingWebsocket.sendJson({\n        message_type: \"TcpVelocityRequest\",\n        rotation: [0, 0, 0],\n        translation: [0, 0, 0],\n      } as TcpVelocityRequest)\n    }\n  }\n\n  dispose() {\n    if (this.joggingWebsocket) {\n      this.joggingWebsocket.dispose()\n    }\n  }\n\n  /**\n   * Start rotation of a single robot joint at the specified velocity\n   */\n  async startJointRotation({\n    joint,\n    velocityRadsPerSec,\n  }: {\n    /** Index of the joint to rotate */\n    joint: number\n    /** Speed of the rotation in radians per second */\n    velocityRadsPerSec: number\n  }) {\n    if (!this.joggingWebsocket) {\n      throw new Error(\n        \"Joint jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n      )\n    }\n\n    const jointVelocities = new Array(this.jointCount).fill(0)\n    jointVelocities[joint] = velocityRadsPerSec\n\n    this.joggingWebsocket.sendJson({\n      message_type: \"JointVelocityRequest\",\n      velocity: {\n        joints: jointVelocities,\n      },\n    } as JointVelocityRequest)\n  }\n\n  /**\n   * Start the TCP moving along a specified axis at a given velocity\n   */\n  async startTCPTranslation({\n    axis,\n    velocityMmPerSec,\n    useToolCoordinateSystem,\n  }: {\n    axis: \"x\" | \"y\" | \"z\"\n    velocityMmPerSec: number\n    useToolCoordinateSystem: boolean\n  }) {\n    if (!this.joggingWebsocket) {\n      throw new Error(\n        \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n      )\n    }\n\n    const joggingVector = [0, 0, 0]\n    joggingVector[axisToIndex(axis)] = velocityMmPerSec\n\n    this.joggingWebsocket.sendJson({\n      message_type: \"TcpVelocityRequest\",\n\n      translation: joggingVector,\n      rotation: [0, 0, 0],\n      use_tool_coordinate_system: useToolCoordinateSystem,\n    } as TcpVelocityRequest)\n  }\n\n  /**\n   * Start the TCP rotating around a specified axis at a given velocity\n   */\n  async startTCPRotation({\n    axis,\n    velocityRadsPerSec,\n    useToolCoordinateSystem,\n  }: {\n    axis: \"x\" | \"y\" | \"z\"\n    velocityRadsPerSec: number\n    useToolCoordinateSystem: boolean\n  }) {\n    if (!this.joggingWebsocket) {\n      throw new Error(\n        \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n      )\n    }\n\n    const joggingVector = [0, 0, 0]\n    joggingVector[axisToIndex(axis)] = velocityRadsPerSec\n\n    this.joggingWebsocket.sendJson({\n      message_type: \"TcpVelocityRequest\",\n      rotation: joggingVector,\n      translation: [0, 0, 0],\n      use_tool_coordinate_system: useToolCoordinateSystem,\n    } as TcpVelocityRequest)\n  }\n}\n","import type {\n  Controller,\n  MotionGroupPhysical,\n  MotionGroupState,\n} from \"@wandelbots/nova-api/v2\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport * as THREE from \"three\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { Vector3d, vector3ToArray } from \"./vectorUtils\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nfunction unwrapRotationVector(\n  newRotationVectorApi: Vector3d,\n  currentRotationVectorApi: Vector3d,\n): Vector3d {\n  const currentRotationVector = new THREE.Vector3(\n    currentRotationVectorApi[0],\n    currentRotationVectorApi[1],\n    currentRotationVectorApi[2],\n  )\n\n  const newRotationVector = new THREE.Vector3(\n    newRotationVectorApi[0],\n    newRotationVectorApi[1],\n    newRotationVectorApi[2],\n  )\n\n  const currentAngle = currentRotationVector.length()\n  const currentAxis = currentRotationVector.normalize()\n\n  let newAngle = newRotationVector.length()\n  let newAxis = newRotationVector.normalize()\n\n  // Align rotation axes\n  if (newAxis.dot(currentAxis) < 0) {\n    newAngle = -newAngle\n    newAxis = newAxis.multiplyScalar(-1.0)\n  }\n\n  // Shift rotation angle close to previous one to extend domain of rotation angles beyond [0, pi]\n  // - this simplifies interpolation and prevents abruptly changing signs of the rotation angles\n  let angleDifference = newAngle - currentAngle\n  angleDifference -=\n    2.0 * Math.PI * Math.floor((angleDifference + Math.PI) / (2.0 * Math.PI))\n\n  newAngle = currentAngle + angleDifference\n\n  return vector3ToArray(newAxis.multiplyScalar(newAngle))\n}\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class MotionStreamConnection {\n  static async open(nova: NovaClient, motionGroupId: string) {\n    const { controllers: controllers } =\n      await nova.api.controller.listControllers()\n\n    const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n      string,\n      string,\n    ]\n    const controller = controllers.find((c) => c.controller === controllerId)\n    const motionGroup = controller?.motion_groups.find(\n      (mg) => mg.motion_group === motionGroupId,\n    )\n    if (!controller || !motionGroup) {\n      throw new Error(\n        `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n      )\n    }\n\n    const motionStateSocket = nova.openReconnectingWebsocket(\n      `/motion-groups/${motionGroupId}/state-stream`,\n    )\n\n    // Wait for the first message to get the initial state\n    const firstMessage = await motionStateSocket.firstMessage()\n    console.log(\"got first message\", firstMessage)\n    const initialMotionState = tryParseJson(firstMessage.data)\n      ?.result as MotionGroupState\n\n    if (!initialMotionState) {\n      throw new Error(\n        `Unable to parse initial motion state message ${firstMessage.data}`,\n      )\n    }\n\n    console.log(\n      `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n  `,\n      initialMotionState,\n    )\n\n    return new MotionStreamConnection(\n      nova,\n      controller,\n      motionGroup,\n      initialMotionState,\n      motionStateSocket,\n    )\n  }\n\n  // Not mobx-observable as this changes very fast; should be observed\n  // using animation frames\n  rapidlyChangingMotionState: MotionGroupState\n\n  constructor(\n    readonly nova: NovaClient,\n    readonly controller: Controller,\n    readonly motionGroup: MotionGroupPhysical,\n    readonly initialMotionState: MotionGroupState,\n    readonly motionStateSocket: AutoReconnectingWebsocket,\n  ) {\n    this.rapidlyChangingMotionState = initialMotionState\n\n    motionStateSocket.addEventListener(\"message\", (event) => {\n      const motionState = tryParseJson(event.data)?.result as\n        | MotionGroupState\n        | undefined\n\n      if (!motionState) {\n        throw new Error(\n          `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n        )\n      }\n\n      // handle motionState message\n      if (\n        !jointValuesEqual(\n          this.rapidlyChangingMotionState.joint_position.joints,\n          motionState.joint_position.joints,\n          MOTION_DELTA_THRESHOLD,\n        )\n      ) {\n        runInAction(() => {\n          this.rapidlyChangingMotionState = motionState\n        })\n      }\n\n      // handle tcpPose message\n      if (\n        !tcpPoseEqual(\n          this.rapidlyChangingMotionState.tcp_pose,\n          motionState.tcp_pose,\n          MOTION_DELTA_THRESHOLD,\n        )\n      ) {\n        runInAction(() => {\n          if (this.rapidlyChangingMotionState.tcp_pose == undefined) {\n            this.rapidlyChangingMotionState.tcp_pose = motionState.tcp_pose\n          } else {\n            this.rapidlyChangingMotionState.tcp_pose = {\n              position: motionState.tcp_pose!.position,\n              orientation: unwrapRotationVector(\n                motionState.tcp_pose!.orientation as Vector3d,\n                this.rapidlyChangingMotionState.tcp_pose!\n                  .orientation as Vector3d,\n              ),\n              tcp: motionState.tcp_pose!.tcp,\n              coordinate_system: motionState.tcp_pose!.coordinate_system,\n            }\n          }\n        })\n      }\n    })\n    makeAutoObservable(this)\n  }\n\n  get motionGroupId() {\n    return this.motionGroup.motion_group\n  }\n\n  get controllerId() {\n    return this.controller.controller\n  }\n\n  get modelFromController() {\n    return this.motionGroup.model_from_controller\n  }\n\n  get wandelscriptIdentifier() {\n    const num = this.motionGroupId.split(\"@\")[0]\n    return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n  }\n\n  get joints() {\n    return this.initialMotionState.joint_position.joints.map((_, i) => {\n      return {\n        index: i,\n      }\n    })\n  }\n\n  dispose() {\n    this.motionStateSocket.close()\n  }\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport {\n  ApplicationApi,\n  CellApi,\n  ControllerApi,\n  ControllerInputsOutputsApi,\n  CoordinateSystemsApi,\n  JoggingApi,\n  MotionGroupApi,\n  MotionGroupInfoApi,\n  MotionGroupKinematicsApi,\n  ProgramApi,\n  ProgramOperatorApi,\n  StoreCollisionComponentsApi,\n  StoreCollisionScenesApi,\n  StoreObjectApi,\n  SystemApi,\n  TrajectoryExecutionApi,\n  TrajectoryPlanningApi,\n  VirtualRobotApi,\n  VirtualRobotBehaviorApi,\n  VirtualRobotModeApi,\n  VirtualRobotSetupApi,\n} from \"@wandelbots/nova-api/v2\"\nimport type { BaseAPI } from \"@wandelbots/nova-api/v2/base\"\nimport type { AxiosInstance } from \"axios\"\nimport axios from \"axios\"\n\ntype OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R\n  ? (...args: P) => R\n  : never\n\ntype UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any\n  ? (\n      ...a: Parameters<T>\n    ) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never>\n  : never\n\nexport type WithCellId<T> = {\n  [P in keyof T]: UnwrapAxiosResponseReturn<OmitFirstArg<T[P]>>\n}\n\nexport type WithUnwrappedAxiosResponse<T> = {\n  [P in keyof T]: UnwrapAxiosResponseReturn<T[P]>\n}\n\n/**\n * API client providing type-safe access to all the Nova API REST endpoints\n * associated with a specific cell id.\n */\nexport class NovaCellAPIClient {\n  constructor(\n    readonly cellId: string,\n    readonly opts: BaseConfiguration & {\n      axiosInstance?: AxiosInstance\n      mock?: boolean\n    },\n  ) {}\n\n  /**\n   * Some TypeScript sorcery which alters the API class methods so you don't\n   * have to pass the cell id to every single one, and de-encapsulates the\n   * response data\n   */\n  private withCellId<T extends BaseAPI>(\n    ApiConstructor: new (\n      config: BaseConfiguration,\n      basePath: string,\n      axios: AxiosInstance,\n    ) => T,\n  ) {\n    const apiClient = new ApiConstructor(\n      {\n        ...this.opts,\n        isJsonMime: (mime: string) => {\n          return mime === \"application/json\"\n        },\n      },\n      this.opts.basePath ?? \"\",\n      this.opts.axiosInstance ?? axios.create(),\n    ) as {\n      [key: string | symbol]: any\n    }\n\n    for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n      if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n        const originalFunction = apiClient[key]\n        apiClient[key] = (...args: any[]) => {\n          return originalFunction\n            .apply(apiClient, [this.cellId, ...args])\n            .then((res: any) => res.data)\n        }\n      }\n    }\n\n    return apiClient as WithCellId<T>\n  }\n\n  /**\n   * As withCellId, but only does the response unwrapping\n   */\n  private withUnwrappedResponsesOnly<T extends BaseAPI>(\n    ApiConstructor: new (\n      config: BaseConfiguration,\n      basePath: string,\n      axios: AxiosInstance,\n    ) => T,\n  ) {\n    const apiClient = new ApiConstructor(\n      {\n        ...this.opts,\n        isJsonMime: (mime: string) => {\n          return mime === \"application/json\"\n        },\n      },\n      this.opts.basePath ?? \"\",\n      this.opts.axiosInstance ?? axios.create(),\n    ) as {\n      [key: string | symbol]: any\n    }\n\n    for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n      if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n        const originalFunction = apiClient[key]\n        apiClient[key] = (...args: any[]) => {\n          return originalFunction\n            .apply(apiClient, args)\n            .then((res: any) => res.data)\n        }\n      }\n    }\n\n    return apiClient as WithUnwrappedAxiosResponse<T>\n  }\n\n  readonly system = this.withUnwrappedResponsesOnly(SystemApi)\n  readonly cell = this.withUnwrappedResponsesOnly(CellApi)\n\n  readonly motionGroup = this.withCellId(MotionGroupApi)\n  readonly motionGroupInfos = this.withCellId(MotionGroupInfoApi)\n\n  readonly controller = this.withCellId(ControllerApi)\n\n  readonly program = this.withCellId(ProgramApi)\n  readonly programOperator = this.withCellId(ProgramOperatorApi)\n\n  readonly controllerIOs = this.withCellId(ControllerInputsOutputsApi)\n\n  readonly motionGroupKinematic = this.withCellId(MotionGroupKinematicsApi)\n  readonly trajectoryPlanning = this.withCellId(TrajectoryPlanningApi)\n  readonly trajectoryExecution = this.withCellId(TrajectoryExecutionApi)\n\n  readonly coordinateSystems = this.withCellId(CoordinateSystemsApi)\n\n  readonly application = this.withCellId(ApplicationApi)\n  readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)\n\n  readonly jogging = this.withCellId(JoggingApi)\n\n  readonly virtualRobot = this.withCellId(VirtualRobotApi)\n  readonly virtualRobotSetup = this.withCellId(VirtualRobotSetupApi)\n  readonly virtualRobotMode = this.withCellId(VirtualRobotModeApi)\n  readonly virtualRobotBehavior = this.withCellId(VirtualRobotBehaviorApi)\n\n  readonly storeObject = this.withCellId(StoreObjectApi)\n  readonly storeCollisionComponents = this.withCellId(\n    StoreCollisionComponentsApi,\n  )\n  readonly storeCollisionScenes = this.withCellId(StoreCollisionScenesApi)\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport type { AxiosRequestConfig } from \"axios\"\nimport axios, { isAxiosError } from \"axios\"\nimport urlJoin from \"url-join\"\nimport { loginWithAuth0 } from \"../../LoginWithAuth0\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { availableStorage } from \"../availableStorage\"\nimport { ConnectedMotionGroup } from \"./ConnectedMotionGroup\"\nimport { MockNovaInstance } from \"./mock/MockNovaInstance\"\nimport { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport { NovaCellAPIClient } from \"./NovaCellAPIClient\"\n\nexport type NovaClientConfig = {\n  /**\n   * Url of the deployed Nova instance to connect to\n   * e.g. https://saeattii.instance.wandelbots.io\n   */\n  instanceUrl: string | \"https://mock.example.com\"\n\n  /**\n   * Identifier of the cell on the Nova instance to connect this client to.\n   * If omitted, the default identifier \"cell\" is used.\n   **/\n  cellId?: string\n\n  /**\n   * Username for basic auth to the Nova instance.\n   * @deprecated use accessToken instead\n   */\n  username?: string\n\n  /**\n   * Password for basic auth to the Nova instance.\n   * @deprecated use accessToken instead\n   */\n  password?: string\n\n  /**\n   * Access token for Bearer authentication.\n   */\n  accessToken?: string\n} & Omit<BaseConfiguration, \"isJsonMime\" | \"basePath\">\n\ntype NovaClientConfigWithDefaults = NovaClientConfig & { cellId: string }\n\n/**\n * EXPERIMENTAL\n *\n * This client provides a starting point to migrate NOVA api v2.\n * As v2 is still in development, this client has to be considered unstable\n *\n * Client for connecting to a Nova instance and controlling robots.\n */\nexport class NovaClient {\n  readonly api: NovaCellAPIClient\n  readonly config: NovaClientConfigWithDefaults\n  readonly mock?: MockNovaInstance\n  authPromise: Promise<string | null> | null = null\n  accessToken: string | null = null\n\n  constructor(config: NovaClientConfig) {\n    console.warn(\"Using experimental NOVA v2 client\")\n    const cellId = config.cellId ?? \"cell\"\n    this.config = {\n      cellId,\n      ...config,\n    }\n    this.accessToken =\n      config.accessToken ||\n      availableStorage.getString(\"wbjs.access_token\") ||\n      null\n\n    if (this.config.instanceUrl === \"https://mock.example.com\") {\n      this.mock = new MockNovaInstance()\n    }\n\n    // Set up Axios instance with interceptor for token fetching\n    const axiosInstance = axios.create({\n      baseURL: urlJoin(this.config.instanceUrl, \"/api/v2\"),\n      // TODO - backend needs to set proper CORS headers for this\n      headers:\n        typeof window !== \"undefined\" &&\n        window.location.origin.includes(\"localhost\")\n          ? {}\n          : {\n              // Identify the client to the backend for logging purposes\n              \"X-Wandelbots-Client\": \"Wandelbots-Nova-JS-SDK\",\n            },\n    })\n\n    axiosInstance.interceptors.request.use(async (request) => {\n      if (!request.headers.Authorization) {\n        if (this.accessToken) {\n          request.headers.Authorization = `Bearer ${this.accessToken}`\n        } else if (this.config.username && this.config.password) {\n          request.headers.Authorization = `Basic ${btoa(config.username + \":\" + config.password)}`\n        }\n      }\n      return request\n    })\n\n    if (typeof window !== \"undefined\") {\n      axiosInstance.interceptors.response.use(\n        (r) => r,\n        async (error) => {\n          if (isAxiosError(error)) {\n            if (error.response?.status === 401) {\n              // If we hit a 401, attempt to login the user and retry with\n              // a new access token\n              try {\n                await this.renewAuthentication()\n\n                if (error.config) {\n                  if (this.accessToken) {\n                    error.config.headers.Authorization = `Bearer ${this.accessToken}`\n                  } else {\n                    delete error.config.headers.Authorization\n                  }\n                  return axiosInstance.request(error.config)\n                }\n              } catch (err) {\n                return Promise.reject(err)\n              }\n            } else if (error.response?.status === 503) {\n              // Check if the server as a whole is down\n              const res = await fetch(window.location.href)\n              if (res.status === 503) {\n                // Go to 503 page\n                window.location.reload()\n              }\n            }\n          }\n\n          return Promise.reject(error)\n        },\n      )\n    }\n\n    this.api = new NovaCellAPIClient(cellId, {\n      ...config,\n      basePath: urlJoin(this.config.instanceUrl, \"/api/v1\"),\n      isJsonMime: (mime: string) => {\n        return mime === \"application/json\"\n      },\n      baseOptions: {\n        ...(this.mock\n          ? ({\n              adapter: (config) => {\n                return this.mock!.handleAPIRequest(config)\n              },\n            } satisfies AxiosRequestConfig)\n          : {}),\n        ...config.baseOptions,\n      },\n      axiosInstance,\n    })\n  }\n\n  async renewAuthentication(): Promise<void> {\n    if (this.authPromise) {\n      // Don't double up\n      return\n    }\n\n    this.authPromise = loginWithAuth0(this.config.instanceUrl)\n    try {\n      this.accessToken = await this.authPromise\n      if (this.accessToken) {\n        // Cache access token so we don't need to log in every refresh\n        availableStorage.setString(\"wbjs.access_token\", this.accessToken)\n      } else {\n        availableStorage.delete(\"wbjs.access_token\")\n      }\n    } finally {\n      this.authPromise = null\n    }\n  }\n\n  makeWebsocketURL(path: string): string {\n    const url = new URL(\n      urlJoin(\n        this.config.instanceUrl,\n        `/api/v1/cells/${this.config.cellId}`,\n        path,\n      ),\n    )\n    url.protocol = url.protocol.replace(\"http\", \"ws\")\n    url.protocol = url.protocol.replace(\"https\", \"wss\")\n\n    // If provided, add basic auth credentials to the URL\n    // NOTE - basic auth is deprecated on websockets and doesn't work in Safari\n    // use tokens instead\n    if (this.accessToken) {\n      url.searchParams.append(\"token\", this.accessToken)\n    } else if (this.config.username && this.config.password) {\n      url.username = this.config.username\n      url.password = this.config.password\n    }\n\n    return url.toString()\n  }\n\n  /**\n   * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.\n   * If you explicitly want to reconnect an existing websocket, call `reconnect`\n   * on the returned object.\n   */\n  openReconnectingWebsocket(path: string) {\n    return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {\n      mock: this.mock,\n    })\n  }\n\n  /**\n   * Connect to the motion state websocket(s) for a given motion group\n   */\n  async connectMotionStream(motionGroupId: string) {\n    return await MotionStreamConnection.open(this, motionGroupId)\n  }\n\n  async connectMotionGroups(\n    motionGroupIds: string[],\n  ): Promise<ConnectedMotionGroup[]> {\n    const { controllers } = await this.api.controller.listControllers()\n\n    return Promise.all(\n      motionGroupIds.map((motionGroupId) =>\n        ConnectedMotionGroup.connect(this, motionGroupId, controllers),\n      ),\n    )\n  }\n\n  async connectMotionGroup(\n    motionGroupId: string,\n  ): Promise<ConnectedMotionGroup> {\n    const motionGroups = await this.connectMotionGroups([motionGroupId])\n    return motionGroups[0]!\n  }\n}\n","const DOMAIN_SUFFIX = \"wandelbots.io\"\n\n/** Mapping of stages to Auth0 configurations */\nconst auth0ConfigMap = {\n  dev: {\n    domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,\n    clientId: process.env.NOVA_AUTH0_DEV_CLIENT_ID,\n  },\n  stg: {\n    domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,\n    clientId: process.env.NOVA_AUTH0_STG_CLIENT_ID,\n  },\n  prod: {\n    domain: `https://auth.portal.${DOMAIN_SUFFIX}`,\n    clientId: process.env.NOVA_AUTH0_PROD_CLIENT_ID,\n  },\n}\n\n/** Determine which Auth0 configuration to use based on instance URL  */\nconst getAuth0Config = (instanceUrl: string) => {\n  if (instanceUrl.includes(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev\n  if (instanceUrl.includes(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg\n  if (instanceUrl.includes(DOMAIN_SUFFIX)) return auth0ConfigMap.prod\n  throw new Error(\n    \"Unsupported instance URL. Cannot determine Auth0 configuration.\",\n  )\n}\n\n/**\n * Initializes Auth0 login process using redirect if necessary and retrieves an access token.\n * Returns null when an access token should not be needed to authenticate (i.e. cookie auth\n * when deployed on the instance domain)\n */\nexport const loginWithAuth0 = async (\n  instanceUrl: string,\n): Promise<string | null> => {\n  if (typeof window === \"undefined\") {\n    throw new Error(\n      `Access token must be set to use NovaClient when not in a browser environment.`,\n    )\n  }\n\n  const auth0Config = getAuth0Config(instanceUrl)\n\n  if (new URL(instanceUrl).origin === window.location.origin) {\n    // When deployed on the instance itself, our auth is handled by cookies\n    // and no access token is needed-- just need to reload the page and it'll\n    // login again / set cookie as needed\n    window.location.reload()\n    throw new Error(\n      \"Failed to reload page to get auth details, please refresh manually\",\n    )\n  }\n\n  // If we're on localhost or another domain, we need to do the full oauth flow\n  // Note this will ONLY work for origins which are whitelisted as a redirect_uri\n  // in the auth0 config, currently\n  const { Auth0Client } = await import(\"@auth0/auth0-spa-js\")\n\n  const auth0Client = new Auth0Client({\n    domain: auth0Config.domain,\n    clientId: auth0Config.clientId ?? \"\",\n    useRefreshTokens: false,\n    authorizationParams: {\n      audience: \"nova-api\",\n      redirect_uri: window.location.origin,\n    },\n  })\n\n  // If the URL includes a redirect result, handle it\n  if (\n    window.location.search.includes(\"code=\") &&\n    window.location.search.includes(\"state=\")\n  ) {\n    const { appState } = await auth0Client.handleRedirectCallback()\n    // Return to the URL the user was originally on before the redirect\n    window.history.replaceState(\n      {},\n      document.title,\n      appState?.returnTo || window.location.pathname,\n    )\n  } else {\n    // Initiate login with redirect\n    await auth0Client.loginWithRedirect()\n  }\n\n  // Once logged in, retrieve the access token silently\n  const accessToken = await auth0Client.getTokenSilently()\n  return accessToken\n}\n","import ReconnectingWebSocket, { type ErrorEvent } from \"reconnecting-websocket\"\nimport * as v2 from \"./v2/mock/MockNovaInstance\"\nimport * as v1 from \"./v1/mock/MockNovaInstance\"\n\nexport class AutoReconnectingWebsocket extends ReconnectingWebSocket {\n  receivedFirstMessage?: MessageEvent\n  targetUrl: string\n  disposed = false\n\n  constructor(\n    targetUrl: string,\n    readonly opts: {\n      mock?: v1.MockNovaInstance | v2.MockNovaInstance\n      onDispose?: () => void\n    } = {},\n  ) {\n    console.log(\"Opening websocket to\", targetUrl)\n\n    super(() => this.targetUrl || targetUrl, undefined, {\n      startClosed: true,\n    })\n\n    // Reconnecting websocket doesn't set this properly with startClosed\n    Object.defineProperty(this, \"url\", {\n      get() {\n        return this.targetUrl\n      },\n    })\n\n    this.targetUrl = targetUrl\n\n    this.addEventListener(\"open\", () => {\n      console.log(`Websocket to ${this.url} opened`)\n    })\n\n    this.addEventListener(\"message\", (ev) => {\n      if (!this.receivedFirstMessage) {\n        this.receivedFirstMessage = ev\n      }\n    })\n\n    this.addEventListener(\"close\", () => {\n      console.log(`Websocket to ${this.url} closed`)\n    })\n\n    const origReconnect = this.reconnect\n    this.reconnect = () => {\n      if (this.opts.mock) {\n        this.opts.mock.handleWebsocketConnection(this)\n      } else {\n        origReconnect.apply(this)\n      }\n    }\n\n    this.reconnect()\n  }\n\n  changeUrl(targetUrl: string) {\n    this.receivedFirstMessage = undefined\n    this.targetUrl = targetUrl\n    this.reconnect()\n  }\n\n  sendJson(data: unknown) {\n    if (this.opts.mock) {\n      this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data))\n    } else {\n      this.send(JSON.stringify(data))\n    }\n  }\n\n  /**\n   * Permanently close this websocket and indicate that\n   * this object should not be used again.\n   **/\n  dispose() {\n    this.close()\n    this.disposed = true\n    if (this.opts.onDispose) {\n      this.opts.onDispose()\n    }\n  }\n\n  /**\n   * Returns a promise that resolves once the websocket\n   * is in the OPEN state. */\n  async opened() {\n    return new Promise<void>((resolve, reject) => {\n      if (this.readyState === WebSocket.OPEN) {\n        resolve()\n      } else {\n        this.addEventListener(\"open\", () => resolve())\n        this.addEventListener(\"error\", reject)\n      }\n    })\n  }\n\n  /**\n   * Returns a promise that resolves once the websocket\n   * is in the CLOSED state. */\n  async closed() {\n    return new Promise<void>((resolve, reject) => {\n      if (this.readyState === WebSocket.CLOSED) {\n        resolve()\n      } else {\n        this.addEventListener(\"close\", () => resolve())\n        this.addEventListener(\"error\", reject)\n      }\n    })\n  }\n\n  /**\n   * Returns a promise that resolves when the first message\n   * is received from the websocket. Resolves immediately if\n   * the first message has already been received.\n   */\n  async firstMessage() {\n    if (this.receivedFirstMessage) {\n      return this.receivedFirstMessage\n    }\n\n    return new Promise<MessageEvent>((resolve, reject) => {\n      const onMessage = (ev: MessageEvent) => {\n        this.receivedFirstMessage = ev\n        this.removeEventListener(\"message\", onMessage)\n        this.removeEventListener(\"error\", onError)\n        resolve(ev)\n      }\n\n      const onError = (ev: ErrorEvent) => {\n        this.removeEventListener(\"message\", onMessage)\n        this.removeEventListener(\"error\", onError)\n        reject(ev)\n      }\n\n      this.addEventListener(\"message\", onMessage)\n      this.addEventListener(\"error\", onError)\n    })\n  }\n\n  /**\n   * Returns a promise that resolves when the next message\n   * is received from the websocket.\n   */\n  async nextMessage() {\n    return new Promise<MessageEvent>((resolve, reject) => {\n      const onMessage = (ev: MessageEvent) => {\n        this.removeEventListener(\"message\", onMessage)\n        this.removeEventListener(\"error\", onError)\n        resolve(ev)\n      }\n\n      const onError = (ev: ErrorEvent) => {\n        this.removeEventListener(\"message\", onMessage)\n        this.removeEventListener(\"error\", onError)\n        reject(ev)\n      }\n\n      this.addEventListener(\"message\", onMessage)\n      this.addEventListener(\"error\", onError)\n    })\n  }\n}\n","/**\n * Safety wrapper around browser localStorage providing context availability\n * checks and JSON parsing\n */\nclass AvailableStorage {\n  available = typeof window !== \"undefined\" && !!window.localStorage\n\n  getJSON<T>(key: string): Partial<T> | null {\n    if (!this.available) return null\n\n    const result = window.localStorage.getItem(key)\n    if (result === null) return null\n\n    try {\n      return JSON.parse(result)\n    } catch (err) {\n      return null\n    }\n  }\n\n  setJSON(key: string, obj: any) {\n    if (!this.available) return null\n\n    window.localStorage.setItem(key, JSON.stringify(obj))\n  }\n\n  delete(key: string) {\n    if (!this.available) return null\n\n    window.localStorage.removeItem(key)\n  }\n\n  setString(key: string, value: string) {\n    if (!this.available) return null\n\n    window.localStorage.setItem(key, value)\n  }\n\n  getString(key: string): string | null {\n    if (!this.available) return null\n\n    return window.localStorage.getItem(key)\n  }\n}\n\nexport const availableStorage = new AvailableStorage()\n","import type {\n  ControllersList,\n  MotionGroupSpecification,\n  MotionGroupState,\n  RobotController,\n  SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AxiosResponse, InternalAxiosRequestConfig } from \"axios\"\nimport { AxiosError } from \"axios\"\nimport * as pathToRegexp from \"path-to-regexp\"\nimport type { AutoReconnectingWebsocket } from \"../../AutoReconnectingWebsocket\"\n\n/**\n * EXPERIMENTAL\n * Ultra-simplified mock Nova server for testing stuff\n */\nexport class MockNovaInstance {\n  readonly connections: AutoReconnectingWebsocket[] = []\n\n  async handleAPIRequest(\n    config: InternalAxiosRequestConfig,\n  ): Promise<AxiosResponse> {\n    const apiHandlers = [\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/controllers\",\n        handle() {\n          return {\n            controllers: [\n              {\n                controller: \"mock-ur5e\",\n                model_name: \"UniversalRobots::Controller\",\n                host: \"mock-ur5e\",\n                allow_software_install_on_controller: true,\n                motion_groups: [\n                  {\n                    motion_group: \"0@mock-ur5e\",\n                    name_from_controller: \"UR5e\",\n                    active: false,\n                    model_from_controller: \"UniversalRobots_UR5e\",\n                  },\n                ],\n                has_error: false,\n                error_details: \"\",\n              },\n            ],\n          } satisfies ControllersList\n        },\n      },\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/controllers/:controllerId\",\n        handle() {\n          return {\n            configuration: {\n              kind: \"VirtualController\",\n              manufacturer: \"universalrobots\",\n              position: \"[0,-1.571,-1.571,-1.571,1.571,-1.571,0]\",\n              type: \"universalrobots-ur5e\",\n            },\n            name: \"mock-ur5\",\n          } satisfies RobotController\n        },\n      },\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/motion-groups/:motionGroupId/specification\",\n        handle() {\n          return {\n            dh_parameters: [\n              {\n                alpha: 1.5707963267948966,\n                theta: 0,\n                a: 0,\n                d: 162.25,\n                reverse_rotation_direction: false,\n              },\n              {\n                alpha: 0,\n                theta: 0,\n                a: -425,\n                d: 0,\n                reverse_rotation_direction: false,\n              },\n              {\n                alpha: 0,\n                theta: 0,\n                a: -392.2,\n                d: 0,\n                reverse_rotation_direction: false,\n              },\n              {\n                alpha: 1.5707963267948966,\n                theta: 0,\n                a: 0,\n                d: 133.3,\n                reverse_rotation_direction: false,\n              },\n              {\n                alpha: -1.5707963267948966,\n                theta: 0,\n                a: 0,\n                d: 99.7,\n                reverse_rotation_direction: false,\n              },\n              {\n                alpha: 0,\n                theta: 0,\n                a: 0,\n                d: 99.6,\n                reverse_rotation_direction: false,\n              },\n            ],\n            mechanical_joint_limits: [\n              {\n                joint: \"JOINTNAME_AXIS_1\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n              {\n                joint: \"JOINTNAME_AXIS_2\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n              {\n                joint: \"JOINTNAME_AXIS_3\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n              {\n                joint: \"JOINTNAME_AXIS_4\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n              {\n                joint: \"JOINTNAME_AXIS_5\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n              {\n                joint: \"JOINTNAME_AXIS_6\",\n                lower_limit: -6.335545063018799,\n                upper_limit: 6.335545063018799,\n                unlimited: false,\n              },\n            ],\n          } satisfies MotionGroupSpecification\n        },\n      },\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/motion-groups/:motionGroupId/safety-setup\",\n        handle() {\n          return {\n            safety_settings: [\n              {\n                safety_state: \"SAFETY_NORMAL\",\n                settings: {\n                  joint_position_limits: [\n                    {\n                      joint: \"JOINTNAME_AXIS_1\",\n                      lower_limit: -2.96705961227417,\n                      upper_limit: 2.96705961227417,\n                      unlimited: false,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_2\",\n                      lower_limit: -1.7453292608261108,\n                      upper_limit: 2.7925267219543457,\n                      unlimited: false,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_3\",\n                      lower_limit: -3.3161256313323975,\n                      upper_limit: 0.40142571926116943,\n                      unlimited: false,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_4\",\n                      lower_limit: -3.4906585216522217,\n                      upper_limit: 3.4906585216522217,\n                      unlimited: false,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_5\",\n                      lower_limit: -2.4434609413146973,\n                      upper_limit: 2.4434609413146973,\n                      unlimited: false,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_6\",\n                      lower_limit: -4.71238899230957,\n                      upper_limit: 4.71238899230957,\n                      unlimited: false,\n                    },\n                  ],\n                  joint_velocity_limits: [\n                    {\n                      joint: \"JOINTNAME_AXIS_1\",\n                      limit: 3.1415927410125732,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_2\",\n                      limit: 3.1415927410125732,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_3\",\n                      limit: 3.4906585216522217,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_4\",\n                      limit: 6.108652591705322,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_5\",\n                      limit: 6.108652591705322,\n                    },\n                    {\n                      joint: \"JOINTNAME_AXIS_6\",\n                      limit: 6.981317043304443,\n                    },\n                  ],\n                  joint_acceleration_limits: [],\n                  joint_torque_limits: [],\n                  tcp_velocity_limit: 1800,\n                },\n              },\n            ],\n            safety_zones: [\n              {\n                id: 1,\n                priority: 0,\n                geometry: {\n                  compound: {\n                    child_geometries: [\n                      {\n                        convex_hull: {\n                          vertices: [\n                            { vertex: [-800, -1330, -1820] },\n                            { vertex: [1650, -1330, -1820] },\n                            { vertex: [1650, 1330, -1820] },\n                            { vertex: [-800, 1330, -1820] },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                      {\n                        convex_hull: {\n                          vertices: [\n                            {\n                              vertex: [-800, -1330, -1820],\n                            },\n                            {\n                              vertex: [1650, -1330, -1820],\n                            },\n                            {\n                              vertex: [1650, -1330, 1500],\n                            },\n                            {\n                              vertex: [-800, -1330, 1500],\n                            },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                      {\n                        convex_hull: {\n                          vertices: [\n                            {\n                              vertex: [-800, -1330, -1820],\n                            },\n                            {\n                              vertex: [-800, 1330, -1820],\n                            },\n                            {\n                              vertex: [-800, 1330, 1500],\n                            },\n                            {\n                              vertex: [-800, -1330, 1500],\n                            },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                      {\n                        convex_hull: {\n                          vertices: [\n                            {\n                              vertex: [1650, 1330, 1500],\n                            },\n                            {\n                              vertex: [-800, 1330, 1500],\n                            },\n                            {\n                              vertex: [-800, -1330, 1500],\n                            },\n                            {\n                              vertex: [1650, -1330, 1500],\n                            },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                      {\n                        convex_hull: {\n                          vertices: [\n                            {\n                              vertex: [1650, 1330, 1500],\n                            },\n                            {\n                              vertex: [-800, 1330, 1500],\n                            },\n                            {\n                              vertex: [-800, 1330, -1820],\n                            },\n                            {\n                              vertex: [1650, 1330, -1820],\n                            },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                      {\n                        convex_hull: {\n                          vertices: [\n                            {\n                              vertex: [1650, 1330, 1500],\n                            },\n                            {\n                              vertex: [1650, -1330, 1500],\n                            },\n                            {\n                              vertex: [1650, -1330, -1820],\n                            },\n                            {\n                              vertex: [1650, 1330, -1820],\n                            },\n                          ],\n                        },\n                        init_pose: {\n                          position: [0, 0, 0],\n                          orientation: [0, 0, 0, 1],\n                        },\n                        id: \"box\",\n                      },\n                    ],\n                  },\n                  init_pose: {\n                    position: [0, 0, 0],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"Cell workzone\",\n                },\n                motion_group_uid: 1,\n              },\n              {\n                id: 2,\n                priority: 0,\n                geometry: {\n                  convex_hull: {\n                    vertices: [\n                      {\n                        vertex: [1650, 1330, -1850],\n                      },\n                      {\n                        vertex: [865, 1330, -1850],\n                      },\n                      {\n                        vertex: [865, -720, -1850],\n                      },\n                      {\n                        vertex: [1650, -720, -1850],\n                      },\n                      {\n                        vertex: [1650, 1330, -920],\n                      },\n                      {\n                        vertex: [865, 1330, -920],\n                      },\n                      {\n                        vertex: [865, -720, -920],\n                      },\n                      {\n                        vertex: [1650, -720, -920],\n                      },\n                    ],\n                  },\n                  init_pose: {\n                    position: [0, 0, 0],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"Transport\",\n                },\n                motion_group_uid: 1,\n              },\n              {\n                id: 3,\n                priority: 0,\n                geometry: {\n                  convex_hull: {\n                    vertices: [\n                      {\n                        vertex: [1650, 1330, -600],\n                      },\n                      {\n                        vertex: [865, 1330, -600],\n                      },\n                      {\n                        vertex: [865, 430, -600],\n                      },\n                      {\n                        vertex: [1650, 430, -600],\n                      },\n                      {\n                        vertex: [1650, 1330, -1250],\n                      },\n                      {\n                        vertex: [865, 1330, -1250],\n                      },\n                      {\n                        vertex: [865, 430, -1250],\n                      },\n                      {\n                        vertex: [1650, 430, -1250],\n                      },\n                    ],\n                  },\n                  init_pose: {\n                    position: [0, 0, 0],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"Tunel\",\n                },\n                motion_group_uid: 1,\n              },\n              {\n                id: 4,\n                priority: 0,\n                geometry: {\n                  convex_hull: {\n                    vertices: [\n                      {\n                        vertex: [1650, -760, -440],\n                      },\n                      {\n                        vertex: [900, -760, -440],\n                      },\n                      {\n                        vertex: [900, -1330, -440],\n                      },\n                      {\n                        vertex: [1650, -1330, -440],\n                      },\n                      {\n                        vertex: [1650, -760, -1800],\n                      },\n                      {\n                        vertex: [900, -760, -1800],\n                      },\n                      {\n                        vertex: [900, -1330, -1800],\n                      },\n                      {\n                        vertex: [1650, -1330, -1800],\n                      },\n                    ],\n                  },\n                  init_pose: {\n                    position: [0, 0, 0],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"Fanuc controller\",\n                },\n                motion_group_uid: 1,\n              },\n              {\n                id: 6,\n                priority: 0,\n                geometry: {\n                  convex_hull: {\n                    vertices: [\n                      {\n                        vertex: [-200, -200, -1900],\n                      },\n                      {\n                        vertex: [200, -200, -1900],\n                      },\n                      {\n                        vertex: [200, 200, -1900],\n                      },\n                      {\n                        vertex: [-200, 200, -1900],\n                      },\n                      {\n                        vertex: [-200, -200, -350],\n                      },\n                      {\n                        vertex: [200, -200, -350],\n                      },\n                      {\n                        vertex: [200, 200, -350],\n                      },\n                      {\n                        vertex: [-200, 200, -350],\n                      },\n                    ],\n                  },\n                  init_pose: {\n                    position: [0, 0, 0],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"Robot base\",\n                },\n                motion_group_uid: 1,\n              },\n            ],\n            robot_model_geometries: [\n              {\n                link_index: 1,\n                geometry: {\n                  sphere: {\n                    radius: 270,\n                  },\n                  init_pose: {\n                    position: [-70, -70, -50],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"link1_sphere\",\n                },\n              },\n              {\n                link_index: 2,\n                geometry: {\n                  capsule: {\n                    radius: 160,\n                    cylinder_height: 800,\n                  },\n                  init_pose: {\n                    position: [-450, 40, 170],\n                    orientation: [\n                      0, -0.7071067811865475, 0, 0.7071067811865476,\n                    ],\n                  },\n                  id: \"link2_capsule\",\n                },\n              },\n              {\n                link_index: 3,\n                geometry: {\n                  sphere: {\n                    radius: 270,\n                  },\n                  init_pose: {\n                    position: [-110, 10, -100],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"link3_sphere\",\n                },\n              },\n              {\n                link_index: 4,\n                geometry: {\n                  capsule: {\n                    radius: 110,\n                    cylinder_height: 600,\n                  },\n                  init_pose: {\n                    position: [0, 300, 40],\n                    orientation: [\n                      -0.7071067811865475, 0, 0, 0.7071067811865476,\n                    ],\n                  },\n                  id: \"link4_capsule\",\n                },\n              },\n              {\n                link_index: 5,\n                geometry: {\n                  sphere: {\n                    radius: 75,\n                  },\n                  init_pose: {\n                    position: [0, 0, -50],\n                    orientation: [0, 0, 0, 1],\n                  },\n                  id: \"link5_sphere\",\n                },\n              },\n            ],\n            tool_geometries: [],\n          } satisfies SafetySetup\n        },\n      },\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/coordinate-systems\",\n        handle() {\n          return {\n            coordinatesystems: [\n              {\n                coordinate_system: \"\",\n                name: \"world\",\n                reference_uid: \"\",\n                position: [0, 0, 0],\n                rotation: {\n                  angles: [0, 0, 0],\n                  type: \"ROTATION_VECTOR\",\n                },\n              },\n            ],\n          } //satisfies CoordinateSystems\n        },\n      },\n      {\n        method: \"GET\",\n        path: \"/cells/:cellId/motion-groups/:motionGroupId/tcps\",\n        handle() {\n          return {\n            tcps: [\n              {\n                id: \"Flange\",\n                readable_name: \"Default-Flange\",\n                position: [0, 0, 0],\n                rotation: {\n                  angles: [0, 0, 0, 0],\n                  type: \"ROTATION_VECTOR\",\n                },\n              },\n              {\n                id: \"complex-tcp-position\",\n                readable_name: \"Complex TCP Position\",\n                position: [-200, 300, 150],\n                rotation: {\n                  angles: [\n                    -0.12139440409113832, -0.06356210998212003,\n                    -0.2023240068185639, 0,\n                  ],\n                  type: \"ROTATION_VECTOR\",\n                },\n              },\n            ],\n          }\n        },\n      },\n    ]\n\n    const method = config.method?.toUpperCase() || \"GET\"\n    const path = \"/cells\" + config.url?.split(\"/cells\")[1]?.split(\"?\")[0]\n\n    for (const handler of apiHandlers) {\n      const match = pathToRegexp.match(handler.path)(path || \"\")\n      if (method === handler.method && match) {\n        const json = handler.handle()\n        return {\n          status: 200,\n          statusText: \"Success\",\n          data: JSON.stringify(json),\n          headers: {},\n          config,\n          request: {\n            responseURL: config.url,\n          },\n        }\n      }\n    }\n\n    throw new AxiosError(\n      `No mock handler matched this request: ${method} ${path}`,\n      \"404\",\n      config,\n    )\n\n    // return {\n    //   status: 404,\n    //   statusText: \"Not Found\",\n    //   data: \"\",\n    //   headers: {},\n    //   config,\n    //   request: {\n    //     responseURL: config.url,\n    //   },\n    // }\n  }\n\n  handleWebsocketConnection(socket: AutoReconnectingWebsocket) {\n    this.connections.push(socket)\n\n    setTimeout(() => {\n      socket.dispatchEvent(new Event(\"open\"))\n\n      console.log(\"Websocket connection opened from\", socket.url)\n\n      if (socket.url.includes(\"/state-stream\")) {\n        socket.dispatchEvent(\n          new MessageEvent(\"message\", {\n            data: JSON.stringify(defaultMotionState),\n          }),\n        )\n      }\n\n      if (socket.url.includes(\"/move-joint\")) {\n        socket.dispatchEvent(\n          new MessageEvent(\"message\", {\n            data: JSON.stringify({\n              result: {\n                motion_group: \"0@ur\",\n                state: {\n                  controller: \"ur\",\n                  operation_mode: \"OPERATION_MODE_AUTO\",\n                  safety_state: \"SAFETY_STATE_NORMAL\",\n                  timestamp: \"2024-09-18T12:48:26.096266444Z\",\n                  velocity_override: 100,\n                  motion_groups: [\n                    {\n                      motion_group: \"0@ur\",\n                      controller: \"ur\",\n                      joint_position: {\n                        joints: [\n                          1.3492152690887451, -1.5659207105636597,\n                          1.6653711795806885, -1.0991662740707397,\n                          -1.829018235206604, 1.264623761177063,\n                        ],\n                      },\n                      joint_velocity: {\n                        joints: [0, 0, 0, 0, 0, 0],\n                      },\n                      flange_pose: {\n                        position: [\n                          6.437331889439328, -628.4123774830913,\n                          577.0569957147832,\n                        ],\n                        orientation: {\n                          x: -1.683333649797158,\n                          y: -1.9783363827298732,\n                          z: -0.4928031860165713,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      tcp_pose: {\n                        position: [\n                          6.437331889439328, -628.4123774830913,\n                          577.0569957147832,\n                        ],\n                        orientation: {\n                          x: -1.683333649797158,\n                          y: -1.9783363827298732,\n                          z: -0.4928031860165713,\n                        },\n                        coordinate_system: \"\",\n                        tcp: \"Flange\",\n                      },\n                      velocity: {\n                        linear: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        angular: {\n                          x: -0,\n                          y: 0,\n                          z: 0,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      force: {\n                        force: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        moment: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      joint_limit_reached: {\n                        limit_reached: [\n                          false,\n                          false,\n                          false,\n                          false,\n                          false,\n                          false,\n                        ],\n                      },\n                      joint_current: {\n                        joints: [0, 0, 0, 0, 0, 0],\n                      },\n                      sequence_number: \"671259\",\n                    },\n                  ],\n                  sequence_number: \"671259\",\n                },\n                movement_state: \"MOVEMENT_STATE_MOVING\",\n              },\n            }),\n          }),\n        )\n      }\n\n      if (socket.url.includes(\"/move-tcp\")) {\n        socket.dispatchEvent(\n          new MessageEvent(\"message\", {\n            data: JSON.stringify({\n              result: {\n                motion_group: \"0@ur\",\n                state: {\n                  controller: \"ur\",\n                  operation_mode: \"OPERATION_MODE_AUTO\",\n                  safety_state: \"SAFETY_STATE_NORMAL\",\n                  timestamp: \"2024-09-18T12:43:12.188335774Z\",\n                  velocity_override: 100,\n                  motion_groups: [\n                    {\n                      motion_group: \"0@ur\",\n                      controller: \"ur\",\n                      joint_position: {\n                        joints: [\n                          1.3352527618408203, -1.5659207105636597,\n                          1.6653711795806885, -1.110615611076355,\n                          -1.829018235206604, 1.264623761177063,\n                        ],\n                      },\n                      joint_velocity: {\n                        joints: [0, 0, 0, 0, 0, 0],\n                      },\n                      flange_pose: {\n                        position: [\n                          -2.763015284002938, -630.2151479701106,\n                          577.524509114342,\n                        ],\n                        orientation: {\n                          x: -1.704794877102097,\n                          y: -1.9722372952861567,\n                          z: -0.4852079204210754,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      tcp_pose: {\n                        position: [\n                          -2.763015284002938, -630.2151479701106,\n                          577.524509114342,\n                        ],\n                        orientation: {\n                          x: -1.704794877102097,\n                          y: -1.9722372952861567,\n                          z: -0.4852079204210754,\n                        },\n                        coordinate_system: \"\",\n                        tcp: \"Flange\",\n                      },\n                      velocity: {\n                        linear: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        angular: {\n                          x: -0,\n                          y: 0,\n                          z: 0,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      force: {\n                        force: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        moment: {\n                          x: 0,\n                          y: 0,\n                          z: 0,\n                        },\n                        coordinate_system: \"\",\n                      },\n                      joint_limit_reached: {\n                        limit_reached: [\n                          false,\n                          false,\n                          false,\n                          false,\n                          false,\n                          false,\n                        ],\n                      },\n                      joint_current: {\n                        joints: [0, 0, 0, 0, 0, 0],\n                      },\n                      sequence_number: \"627897\",\n                    },\n                  ],\n                  sequence_number: \"627897\",\n                },\n                movement_state: \"MOVEMENT_STATE_MOVING\",\n              },\n            }),\n          }),\n        )\n      }\n    }, 10)\n  }\n\n  handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string) {\n    console.log(`Received message on ${socket.url}`, message)\n  }\n}\n\nconst defaultMotionState = {\n  result: {\n    motion_group: \"0@universalrobots-ur5e\",\n    controller: \"universalrobots-ur5e\",\n    joint_position: {\n      joints: [\n        1.1699999570846558, -1.5700000524520874, 1.3600000143051147,\n        1.0299999713897705, 1.2899999618530273, 1.2799999713897705,\n      ],\n    },\n    joint_velocity: {\n      joints: [0, 0, 0, 0, 0, 0],\n    },\n    flange_pose: {\n      position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n      orientation: [\n        1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n      ],\n      coordinate_system: \"\",\n    },\n    tcp_pose: {\n      position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n      orientation: [\n        1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n      ],\n      coordinate_system: \"\",\n      tcp: \"Flange\",\n    },\n    velocity: {\n      linear: [0, 0, 0],\n      angular: [0, 0, 0],\n      coordinate_system: \"\",\n    },\n    force: {\n      force: [0, 0, 0],\n      moment: [0, 0, 0],\n      coordinate_system: \"\",\n    },\n    joint_limit_reached: {\n      limit_reached: [false, false, false, false, false, false],\n    },\n    joint_current: {\n      joints: [0, 0, 0, 0, 0, 0],\n    },\n  } satisfies MotionGroupState,\n}\n","import { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport type { NovaClient } from \"./NovaClient\"\n\nexport type ProgramRunnerLogEntry = {\n  timestamp: number\n  message: string\n  level?: \"warn\" | \"error\"\n}\n\nexport enum ProgramState {\n  NotStarted = \"not started\",\n  Running = \"running\",\n  Stopped = \"stopped\",\n  Failed = \"failed\",\n  Completed = \"completed\",\n}\n\nexport type CurrentProgram = {\n  id?: string\n  wandelscript?: string\n  state?: ProgramState\n}\n\ntype ProgramStateMessage = {\n  type: string\n  runner: {\n    id: string\n    state: ProgramState\n    start_time?: number | null\n    execution_time?: number | null\n  }\n}\n\n/**\n * Interface for running Wandelscript programs on the Nova instance and\n * tracking their progress and output\n */\nexport class ProgramStateConnection {\n  currentProgram: CurrentProgram = {}\n  logs: ProgramRunnerLogEntry[] = []\n\n  executionState = \"idle\" as \"idle\" | \"starting\" | \"executing\" | \"stopping\"\n  currentlyExecutingProgramRunnerId = null as string | null\n\n  programStateSocket: AutoReconnectingWebsocket\n\n  constructor(readonly nova: NovaClient) {\n    makeAutoObservable(this, {}, { autoBind: true })\n\n    this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`)\n\n    this.programStateSocket.addEventListener(\"message\", (ev) => {\n      const msg = tryParseJson(ev.data)\n\n      if (!msg) {\n        console.error(\"Failed to parse program state message\", ev.data)\n        return\n      }\n      if (msg.type === \"update\") {\n        this.handleProgramStateMessage(msg)\n      }\n    })\n  }\n\n  /** Handle a program state update from the backend */\n  async handleProgramStateMessage(msg: ProgramStateMessage) {\n    const { runner } = msg\n\n    // Ignoring other programs for now\n    // TODO - show if execution state is busy from another source\n    if (runner.id !== this.currentlyExecutingProgramRunnerId) return\n\n    if (runner.state === ProgramState.Failed) {\n      try {\n        const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n        // TODO - wandelengine should send print statements in real time over\n        // websocket as well, rather than at the end\n        const stdout = (runnerState as any).stdout\n        if (stdout) {\n          this.log(stdout)\n        }\n        this.logError(\n          `Program runner ${runner.id} failed with error: ${runnerState.error}\\n${runnerState.traceback}`,\n        )\n      } catch (err) {\n        this.logError(\n          `Failed to retrieve results for program ${runner.id}: ${err}`,\n        )\n      }\n\n      this.currentProgram.state = ProgramState.Failed\n\n      this.gotoIdleState()\n    } else if (runner.state === ProgramState.Stopped) {\n      try {\n        const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n        const stdout = (runnerState as any).stdout\n        if (stdout) {\n          this.log(stdout)\n        }\n\n        this.currentProgram.state = ProgramState.Stopped\n        this.log(`Program runner ${runner.id} stopped`)\n      } catch (err) {\n        this.logError(\n          `Failed to retrieve results for program ${runner.id}: ${err}`,\n        )\n      }\n\n      this.gotoIdleState()\n    } else if (runner.state === ProgramState.Completed) {\n      try {\n        const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n        const stdout = (runnerState as any).stdout\n        if (stdout) {\n          this.log(stdout)\n        }\n        this.log(\n          `Program runner ${runner.id} finished successfully in ${runner.execution_time?.toFixed(2)} seconds`,\n        )\n\n        this.currentProgram.state = ProgramState.Completed\n      } catch (err) {\n        this.logError(\n          `Failed to retrieve results for program ${runner.id}: ${err}`,\n        )\n      }\n\n      this.gotoIdleState()\n    } else if (runner.state === ProgramState.Running) {\n      this.currentProgram.state = ProgramState.Running\n      this.log(`Program runner ${runner.id} now running`)\n    } else if (runner.state !== ProgramState.NotStarted) {\n      console.error(runner)\n      this.logError(\n        `Program runner ${runner.id} entered unexpected state: ${runner.state}`,\n      )\n      this.currentProgram.state = ProgramState.NotStarted\n      this.gotoIdleState()\n    }\n  }\n\n  /** Call when a program is no longer executing */\n  gotoIdleState() {\n    runInAction(() => {\n      this.executionState = \"idle\"\n    })\n    this.currentlyExecutingProgramRunnerId = null\n  }\n\n  async executeProgram(\n    wandelscript: string,\n    initial_state?: Object,\n    activeRobot?: MotionStreamConnection,\n  ) {\n    this.currentProgram = {\n      wandelscript: wandelscript,\n      state: ProgramState.NotStarted,\n    }\n\n    const { currentProgram: openProgram } = this\n    if (!openProgram) return\n    runInAction(() => {\n      this.executionState = \"starting\"\n    })\n\n    // WOS-1539: Wandelengine parser currently breaks if there are empty lines with indentation\n    const trimmedCode = openProgram.wandelscript!.replaceAll(/^\\s*$/gm, \"\")\n\n    try {\n      const programRunnerRef = await this.nova.api.program.createProgramRun(\n        {\n          code: trimmedCode,\n          initial_state: initial_state,\n          default_robot: activeRobot?.wandelscriptIdentifier,\n        } as any,\n        {\n          headers: {\n            \"Content-Type\": \"application/json\",\n          },\n        },\n      )\n\n      this.log(`Created program runner ${programRunnerRef.id}\"`)\n      runInAction(() => {\n        this.executionState = \"executing\"\n      })\n      this.currentlyExecutingProgramRunnerId = programRunnerRef.id\n    } catch (error) {\n      if (error instanceof AxiosError && error.response && error.request) {\n        this.logError(\n          `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`,\n        )\n      } else {\n        this.logError(JSON.stringify(error))\n      }\n      runInAction(() => {\n        this.executionState = \"idle\"\n      })\n    }\n  }\n\n  async stopProgram() {\n    if (!this.currentlyExecutingProgramRunnerId) return\n    runInAction(() => {\n      this.executionState = \"stopping\"\n    })\n\n    try {\n      await this.nova.api.program.stopProgramRun(\n        this.currentlyExecutingProgramRunnerId,\n      )\n    } catch (err) {\n      // Reactivate the stop button so user can try again\n      runInAction(() => {\n        this.executionState = \"executing\"\n      })\n      throw err\n    }\n  }\n\n  reset() {\n    this.currentProgram = {}\n  }\n\n  log(message: string) {\n    console.log(message)\n    this.logs.push({\n      timestamp: Date.now(),\n      message,\n    })\n  }\n\n  logError(message: string) {\n    console.log(message)\n    this.logs.push({\n      timestamp: Date.now(),\n      message,\n      level: \"error\",\n    })\n  }\n}\n"],"mappings":"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","names":["import_mobx","THREE","MOTION_DELTA_THRESHOLD","import_axios","axios","import_axios","ReconnectingWebSocket","import_axios","match","axios","urlJoin","_a","config","import_axios","import_mobx","ProgramState"]}