@wandelbots/nova-js 3.3.3 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -1
  2. package/dist/{AutoReconnectingWebsocket-Qcrbm3Kb.d.cts → AutoReconnectingWebsocket-By6EZkXv.d.mts} +1 -1
  3. package/dist/{AutoReconnectingWebsocket-Qcrbm3Kb.d.cts.map → AutoReconnectingWebsocket-By6EZkXv.d.mts.map} +1 -1
  4. package/dist/{AutoReconnectingWebsocket-dHe-kceU.d.mts → AutoReconnectingWebsocket-dO-Xkvgo.d.cts} +1 -1
  5. package/dist/{AutoReconnectingWebsocket-dHe-kceU.d.mts.map → AutoReconnectingWebsocket-dO-Xkvgo.d.cts.map} +1 -1
  6. package/dist/{LoginWithAuth0-DBe9CXOr.mjs → LoginWithAuth0-BAGhME4k.mjs} +1 -1
  7. package/dist/{LoginWithAuth0-DBe9CXOr.mjs.map → LoginWithAuth0-BAGhME4k.mjs.map} +1 -1
  8. package/dist/{LoginWithAuth0-iXpPiCcz.cjs → LoginWithAuth0-qpkGkrJo.cjs} +11 -7
  9. package/dist/{LoginWithAuth0-iXpPiCcz.cjs.map → LoginWithAuth0-qpkGkrJo.cjs.map} +1 -1
  10. package/dist/{NovaClient-j40sHBBq.cjs → NovaClient-CKpbwv53.cjs} +29 -29
  11. package/dist/{NovaClient-j40sHBBq.cjs.map → NovaClient-CKpbwv53.cjs.map} +1 -1
  12. package/dist/{NovaClient-PNinV5c4.d.cts → NovaClient-CZDpg0Pn.d.cts} +2 -2
  13. package/dist/{NovaClient-C0GXOu4w.d.mts.map → NovaClient-CZDpg0Pn.d.cts.map} +1 -1
  14. package/dist/{NovaClient-C0GXOu4w.d.mts → NovaClient-D8C3LxqM.d.mts} +2 -2
  15. package/dist/{NovaClient-PNinV5c4.d.cts.map → NovaClient-D8C3LxqM.d.mts.map} +1 -1
  16. package/dist/{NovaClient-C27dk3Ql.mjs → NovaClient-DImFdEQS.mjs} +2 -2
  17. package/dist/{NovaClient-C27dk3Ql.mjs.map → NovaClient-DImFdEQS.mjs.map} +1 -1
  18. package/dist/index.cjs +2 -2
  19. package/dist/index.d.cts +2 -2
  20. package/dist/index.d.cts.map +1 -1
  21. package/dist/index.d.mts +2 -2
  22. package/dist/index.mjs +2 -2
  23. package/dist/lib/v1/index.cjs +5 -5
  24. package/dist/lib/v1/index.d.cts +2 -2
  25. package/dist/lib/v1/index.d.mts +2 -2
  26. package/dist/lib/v1/index.mjs +2 -2
  27. package/dist/lib/v2/index.cjs +24 -24
  28. package/dist/lib/v2/index.cjs.map +1 -1
  29. package/dist/lib/v2/index.d.cts +1 -1
  30. package/dist/lib/v2/index.d.cts.map +1 -1
  31. package/dist/lib/v2/index.d.mts +1 -1
  32. package/dist/lib/v2/index.d.mts.map +1 -1
  33. package/dist/lib/v2/index.mjs +1 -1
  34. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"NovaClient-j40sHBBq.cjs","names":["MOTION_DELTA_THRESHOLD","tryParseJson","nova: NovaClient","controller: ControllerInstance","motionGroup: MotionGroupPhysical","initialMotionState: MotionGroupStateResponse","motionStateSocket: AutoReconnectingWebsocket","isVirtual: boolean","tcps: RobotTcp[]","motionGroupSpecification: MotionGroupSpecification","safetySetup: SafetySetup","mounting: Mounting | null","initialControllerState: RobotControllerState","controllerStateSocket: AutoReconnectingWebsocket","THREE","motionStream: MotionStreamConnection","opts: JoggerConnectionOpts","tryParseJson","commands: Command[]","isSameCoordinateSystem","Vector3","jointVelocityLimits: number[]","Vector3","tryParseJson","nova: NovaClient","controller: ControllerInstance","motionGroup: MotionGroupPhysical","initialMotionState: MotionGroupStateResponse","motionStateSocket: AutoReconnectingWebsocket","cellId: string","opts: BaseConfiguration & {\n axiosInstance?: AxiosInstance\n mock?: boolean\n }","SystemApi","CellApi","DeviceConfigurationApi","MotionGroupApi","MotionGroupInfosApi","ControllerApi","ProgramApi","ProgramValuesApi","ControllerIOsApi","MotionGroupKinematicApi","MotionApi","CoordinateSystemsApi","ApplicationApi","MotionGroupJoggingApi","VirtualRobotApi","VirtualRobotSetupApi","VirtualRobotModeApi","VirtualRobotBehaviorApi","LibraryProgramMetadataApi","LibraryProgramApi","LibraryRecipeMetadataApi","LibraryRecipeApi","StoreObjectApi","StoreCollisionComponentsApi","StoreCollisionScenesApi","pathToRegexp","AxiosError","availableStorage","parseNovaInstanceUrl","config","loginWithAuth0","AutoReconnectingWebsocket"],"sources":["../src/lib/v1/wandelscriptUtils.ts","../src/lib/v1/motionStateUpdate.ts","../src/lib/v1/ConnectedMotionGroup.ts","../src/lib/v1/JoggerConnection.ts","../src/lib/v1/MotionStreamConnection.ts","../src/lib/v1/NovaCellAPIClient.ts","../src/lib/v1/mock/MockNovaInstance.ts","../src/lib/v1/NovaClient.ts"],"sourcesContent":["import type { Pose } from \"@wandelbots/nova-api/v1\"\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","import type { TcpPose } from \"@wandelbots/nova-api/v1\"\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 // biome-ignore lint/style/noNonNullAssertion: legacy code\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.x - newTcp.orientation.x)\n changedDelta += Math.abs(oldTcp.orientation.y - newTcp.orientation.y)\n changedDelta += Math.abs(oldTcp.orientation.z - newTcp.orientation.z)\n changedDelta += Math.abs(oldTcp.position.x - newTcp.position.x)\n changedDelta += Math.abs(oldTcp.position.y - newTcp.position.y)\n changedDelta += Math.abs(oldTcp.position.z - newTcp.position.z)\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 type {\n ControllerInstance,\n MotionGroupPhysical,\n MotionGroupSpecification,\n MotionGroupStateResponse,\n Mounting,\n RobotControllerState,\n RobotControllerStateOperationModeEnum,\n RobotControllerStateSafetyStateEnum,\n RobotTcp,\n SafetySetup,\n} from \"@wandelbots/nova-api/v1\"\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\"\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: ControllerInstance[],\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?.physical_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 MotionGroupStateResponse\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 // Check if robot is virtual or physical\n const config = await nova.api.controller.getRobotController(\n controller.controller,\n )\n const isVirtual = config.configuration.kind === \"VirtualController\"\n\n // If there's a configured mounting, we need it to show the right\n // position of the robot model\n const mounting = await (async () => {\n try {\n const mounting = await nova.api.motionGroupInfos.getMounting(\n motionGroup.motion_group,\n )\n return mounting\n } catch (err) {\n console.error(\n `Error fetching mounting for ${motionGroup.motion_group}`,\n err,\n )\n return null\n }\n })()\n\n // Open the websocket to monitor controller state for e.g. e-stop\n const controllerStateSocket = nova.openReconnectingWebsocket(\n `/controllers/${controller.controller}/state-stream?response_rate=1000`,\n )\n\n // Wait for the first message to get the initial state\n const firstControllerMessage = await controllerStateSocket.firstMessage()\n const initialControllerState = tryParseJson(firstControllerMessage.data)\n ?.result as RobotControllerState\n\n if (!initialControllerState) {\n throw new Error(\n `Unable to parse initial controller state message ${firstControllerMessage.data}`,\n )\n }\n\n console.log(\n `Connected controller state websocket to controller ${controller.controller}. Initial state:\\n `,\n initialControllerState,\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 // biome-ignore lint/style/noNonNullAssertion: legacy code\n tcps!,\n motionGroupSpecification,\n safetySetup,\n mounting,\n initialControllerState,\n controllerStateSocket,\n )\n }\n\n connectedJoggingCartesianSocket: WebSocket | null = null\n connectedJoggingJointsSocket: WebSocket | null = null\n // biome-ignore lint/suspicious/noExplicitAny: legacy code\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: MotionGroupStateResponse\n\n // Response rate on the websocket should be a bit slower on this one since\n // we don't use the motion data\n controllerState: RobotControllerState\n\n /**\n * Reflects activation state of the motion group / robot servos. The\n * movement controls in the UI should only be enabled in the \"active\" state\n */\n activationState: \"inactive\" | \"activating\" | \"deactivating\" | \"active\" =\n \"inactive\"\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: ControllerInstance,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupStateResponse,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n readonly isVirtual: boolean,\n readonly tcps: RobotTcp[],\n readonly motionGroupSpecification: MotionGroupSpecification,\n readonly safetySetup: SafetySetup,\n readonly mounting: Mounting | null,\n readonly initialControllerState: RobotControllerState,\n readonly controllerStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n this.controllerState = initialControllerState\n\n // Track controller state updates (e.g. safety state and operation mode)\n controllerStateSocket.addEventListener(\"message\", (event) => {\n const data = tryParseJson(event.data)?.result\n\n if (!data) {\n return\n }\n\n runInAction(() => {\n this.controllerState = data\n })\n })\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupStateResponse\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.state.joint_position.joints,\n motionStateResponse.state.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.state = motionStateResponse.state\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.state.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 /** Gets the robot mounting position offset in 3D viz coordinates */\n get mountingPosition(): [number, number, number] {\n if (!this.mounting) {\n return [0, 0, 0]\n }\n\n return [\n this.mounting.pose.position.x / 1000,\n this.mounting.pose.position.y / 1000,\n this.mounting.pose.position.z / 1000,\n ]\n }\n\n /** Gets the robot mounting position rotation in 3D viz coordinates */\n get mountingQuaternion() {\n const rotationVector = new THREE.Vector3(\n this.mounting?.pose.orientation?.x || 0,\n this.mounting?.pose.orientation?.y || 0,\n this.mounting?.pose.orientation?.z || 0,\n )\n\n const magnitude = rotationVector.length()\n const axis = rotationVector.normalize()\n\n return new THREE.Quaternion().setFromAxisAngle(axis, magnitude)\n }\n\n /**\n * Whether the controller is currently in a safety state\n * corresponding to an emergency stop\n */\n get isEstopActive() {\n const estopStates: RobotControllerStateSafetyStateEnum[] = [\n \"SAFETY_STATE_ROBOT_EMERGENCY_STOP\",\n \"SAFETY_STATE_DEVICE_EMERGENCY_STOP\",\n ]\n\n return estopStates.includes(this.controllerState.safety_state)\n }\n\n /**\n * Whether the controller is in a safety state\n * that may be non-functional for robot pad purposes\n */\n get isMoveableSafetyState() {\n const goodSafetyStates: RobotControllerStateSafetyStateEnum[] = [\n \"SAFETY_STATE_NORMAL\",\n \"SAFETY_STATE_REDUCED\",\n ]\n\n return goodSafetyStates.includes(this.controllerState.safety_state)\n }\n\n /**\n * Whether the controller is in an operation mode that allows movement\n */\n get isMoveableOperationMode() {\n const goodOperationModes: RobotControllerStateOperationModeEnum[] = [\n \"OPERATION_MODE_AUTO\",\n \"OPERATION_MODE_MANUAL\",\n \"OPERATION_MODE_MANUAL_T1\",\n \"OPERATION_MODE_MANUAL_T2\",\n ]\n\n return goodOperationModes.includes(this.controllerState.operation_mode)\n }\n\n /**\n * Whether the robot is currently active and can be moved, based on the\n * safety state, operation mode and servo toggle activation state.\n */\n get canBeMoved() {\n return (\n this.isMoveableSafetyState &&\n this.isMoveableOperationMode &&\n this.activationState === \"active\"\n )\n }\n\n async deactivate() {\n if (this.activationState !== \"active\") {\n console.error(\"Tried to deactivate while already deactivating\")\n return\n }\n\n runInAction(() => {\n this.activationState = \"deactivating\"\n })\n\n try {\n await this.nova.api.controller.setDefaultMode(\n this.controllerId,\n \"MODE_MONITOR\",\n )\n\n runInAction(() => {\n this.activationState = \"inactive\"\n })\n } catch (err) {\n runInAction(() => {\n this.activationState = \"active\"\n })\n throw err\n }\n }\n\n async activate() {\n if (this.activationState !== \"inactive\") {\n console.error(\"Tried to activate while already activating\")\n return\n }\n\n runInAction(() => {\n this.activationState = \"activating\"\n })\n\n try {\n await this.nova.api.controller.setDefaultMode(\n this.controllerId,\n \"MODE_CONTROL\",\n )\n\n runInAction(() => {\n this.activationState = \"active\"\n })\n } catch (err) {\n runInAction(() => {\n this.activationState = \"inactive\"\n })\n throw err\n }\n }\n\n toggleActivation() {\n if (this.activationState === \"inactive\") {\n this.activate()\n } else if (this.activationState === \"active\") {\n this.deactivate()\n }\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 { Command, Joints, TcpPose } from \"@wandelbots/nova-api/v1\"\nimport { Vector3 } from \"three/src/math/Vector3.js\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { isSameCoordinateSystem, tryParseJson } from \"../converters\"\nimport type { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport type { NovaClient } from \"./NovaClient\"\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}\n\nexport class JoggerConnection {\n // Currently a separate websocket is needed for each mode, pester API people\n // to merge these for simplicity\n cartesianWebsocket: AutoReconnectingWebsocket | null = null\n jointWebsocket: AutoReconnectingWebsocket | null = null\n cartesianJoggingOpts: {\n tcpId?: string\n coordSystemId?: string\n } = {}\n\n static async open(\n nova: NovaClient,\n motionGroupId: string,\n opts: JoggerConnectionOpts = {},\n ) {\n const motionStream = await nova.connectMotionStream(motionGroupId)\n\n return new JoggerConnection(motionStream, opts)\n }\n\n constructor(\n readonly motionStream: MotionStreamConnection,\n readonly opts: JoggerConnectionOpts = {},\n ) {}\n\n get motionGroupId() {\n return this.motionStream.motionGroupId\n }\n\n get nova() {\n return this.motionStream.nova\n }\n\n get numJoints() {\n return this.motionStream.joints.length\n }\n\n get activeJoggingMode() {\n if (this.cartesianWebsocket) return \"cartesian\"\n if (this.jointWebsocket) return \"joint\"\n return \"increment\"\n }\n\n get activeWebsocket() {\n return this.cartesianWebsocket || this.jointWebsocket\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\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: { x: 0, y: 0, z: 0 },\n rotation_direction: { x: 0, y: 0, z: 0 },\n position_velocity: 0,\n rotation_velocity: 0,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n if (this.jointWebsocket) {\n this.jointWebsocket.sendJson({\n motion_group: this.motionGroupId,\n joint_velocities: new Array(this.numJoints).fill(0),\n })\n }\n }\n\n dispose() {\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n }\n\n if (this.jointWebsocket) {\n this.jointWebsocket.dispose()\n }\n }\n\n setJoggingMode(\n mode: \"cartesian\" | \"joint\" | \"increment\",\n cartesianJoggingOpts?: {\n tcpId?: string\n coordSystemId?: string\n },\n ) {\n console.log(\"Setting jogging mode to\", mode)\n if (cartesianJoggingOpts) {\n // Websocket needs to be reopened to change options\n if (\n JSON.stringify(this.cartesianJoggingOpts) !==\n JSON.stringify(cartesianJoggingOpts)\n ) {\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n this.cartesianWebsocket = null\n }\n }\n\n this.cartesianJoggingOpts = cartesianJoggingOpts\n }\n\n if (mode !== \"cartesian\" && this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n this.cartesianWebsocket = null\n }\n\n if (mode !== \"joint\" && this.jointWebsocket) {\n this.jointWebsocket.dispose()\n this.jointWebsocket = null\n }\n\n if (mode === \"cartesian\" && !this.cartesianWebsocket) {\n this.cartesianWebsocket = this.nova.openReconnectingWebsocket(\n `/motion-groups/move-tcp`,\n )\n\n this.cartesianWebsocket.addEventListener(\n \"message\",\n (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\n if (mode === \"joint\" && !this.jointWebsocket) {\n this.jointWebsocket = this.nova.openReconnectingWebsocket(\n `/motion-groups/move-joint`,\n )\n\n this.jointWebsocket.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\n /**\n * Start rotation of a single robot joint at the specified velocity\n */\n async startJointRotation({\n joint,\n direction,\n velocityRadsPerSec,\n }: {\n /** Index of the joint to rotate */\n joint: number\n /** Direction of rotation (\"+\" or \"-\") */\n direction: \"+\" | \"-\"\n /** Speed of the rotation in radians per second */\n velocityRadsPerSec: number\n }) {\n if (!this.jointWebsocket) {\n throw new Error(\n \"Joint jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const jointVelocities = new Array(this.numJoints).fill(0)\n\n jointVelocities[joint] =\n direction === \"-\" ? -velocityRadsPerSec : velocityRadsPerSec\n\n this.jointWebsocket.sendJson({\n motion_group: this.motionGroupId,\n joint_velocities: jointVelocities,\n })\n }\n\n /**\n * Start the TCP moving along a specified axis at a given velocity\n */\n async startTCPTranslation({\n axis,\n direction,\n velocityMmPerSec,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n velocityMmPerSec: number\n }) {\n if (!this.cartesianWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const zeroVector = { x: 0, y: 0, z: 0 }\n const joggingVector = Object.assign({}, zeroVector)\n joggingVector[axis] = direction === \"-\" ? -1 : 1\n\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: joggingVector,\n rotation_direction: zeroVector,\n position_velocity: velocityMmPerSec,\n rotation_velocity: 0,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n /**\n * Start the TCP rotating around a specified axis at a given velocity\n */\n async startTCPRotation({\n axis,\n direction,\n velocityRadsPerSec,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n velocityRadsPerSec: number\n }) {\n if (!this.cartesianWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const zeroVector = { x: 0, y: 0, z: 0 }\n const joggingVector = Object.assign({}, zeroVector)\n joggingVector[axis] = direction === \"-\" ? -1 : 1\n\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: zeroVector,\n rotation_direction: joggingVector,\n position_velocity: 0,\n rotation_velocity: velocityRadsPerSec,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n /**\n * Move the robot by a fixed distance in a single cartesian\n * axis, either rotating or translating relative to the TCP.\n * Promise resolves only after the motion has completed.\n */\n async runIncrementalCartesianMotion({\n currentTcpPose,\n currentJoints,\n coordSystemId,\n velocityInRelevantUnits,\n axis,\n direction,\n motion,\n }: {\n currentTcpPose: TcpPose\n currentJoints: Joints\n coordSystemId: string\n velocityInRelevantUnits: number\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n motion:\n | {\n type: \"rotate\"\n distanceRads: number\n }\n | {\n type: \"translate\"\n distanceMm: number\n }\n }) {\n const commands: Command[] = []\n\n if (\n !isSameCoordinateSystem(currentTcpPose.coordinate_system, coordSystemId)\n ) {\n throw new Error(\n `Current TCP pose coordinate system ${currentTcpPose.coordinate_system} does not match target coordinate system ${coordSystemId}`,\n )\n }\n\n if (motion.type === \"translate\") {\n const targetTcpPosition = Object.assign({}, currentTcpPose.position)\n targetTcpPosition[axis] +=\n motion.distanceMm * (direction === \"-\" ? -1 : 1)\n\n commands.push({\n settings: {\n limits_override: {\n tcp_velocity_limit: velocityInRelevantUnits,\n },\n },\n line: {\n position: targetTcpPosition,\n orientation: currentTcpPose.orientation,\n coordinate_system: coordSystemId,\n },\n })\n } else if (motion.type === \"rotate\") {\n // Concatenate rotations expressed by rotation vectors\n // Equations taken from https://physics.stackexchange.com/a/287819\n\n // Compute axis and angle of current rotation vector\n const currentRotationVector = new Vector3(\n currentTcpPose.orientation.x,\n currentTcpPose.orientation.y,\n currentTcpPose.orientation.z,\n )\n\n const currentRotationRad = currentRotationVector.length()\n const currentRotationDirection = currentRotationVector.clone().normalize()\n\n // Compute axis and angle of difference rotation vector\n const differenceRotationRad =\n motion.distanceRads * (direction === \"-\" ? -1 : 1)\n\n const differenceRotationDirection = new Vector3(0.0, 0.0, 0.0)\n differenceRotationDirection[axis] = 1.0\n\n // Some abbreviations to make the following equations more readable\n const f1 =\n Math.cos(0.5 * differenceRotationRad) *\n Math.cos(0.5 * currentRotationRad)\n const f2 =\n Math.sin(0.5 * differenceRotationRad) *\n Math.sin(0.5 * currentRotationRad)\n const f3 =\n Math.sin(0.5 * differenceRotationRad) *\n Math.cos(0.5 * currentRotationRad)\n const f4 =\n Math.cos(0.5 * differenceRotationRad) *\n Math.sin(0.5 * currentRotationRad)\n\n const dotProduct = differenceRotationDirection.dot(\n currentRotationDirection,\n )\n\n const crossProduct = differenceRotationDirection\n .clone()\n .cross(currentRotationDirection)\n\n // Compute angle of concatenated rotation\n const newRotationRad = 2.0 * Math.acos(f1 - f2 * dotProduct)\n\n // Compute rotation vector of concatenated rotation\n const f5 = newRotationRad / Math.sin(0.5 * newRotationRad)\n\n const targetTcpOrientation = new Vector3()\n .addScaledVector(crossProduct, f2)\n .addScaledVector(differenceRotationDirection, f3)\n .addScaledVector(currentRotationDirection, f4)\n .multiplyScalar(f5)\n\n commands.push({\n settings: {\n limits_override: {\n tcp_orientation_velocity_limit: velocityInRelevantUnits,\n },\n },\n line: {\n position: currentTcpPose.position,\n orientation: targetTcpOrientation,\n coordinate_system: coordSystemId,\n },\n })\n }\n\n const motionPlanRes = await this.nova.api.motion.planMotion({\n motion_group: this.motionGroupId,\n start_joint_position: currentJoints,\n tcp: this.cartesianJoggingOpts.tcpId,\n commands,\n })\n\n const plannedMotion = motionPlanRes.plan_successful_response?.motion\n if (!plannedMotion) {\n throw new Error(\n `Failed to plan jogging increment motion ${JSON.stringify(motionPlanRes)}`,\n )\n }\n\n await this.nova.api.motion.streamMoveForward(\n plannedMotion,\n 100,\n undefined,\n undefined,\n undefined,\n {\n // Might take a while at low velocity\n timeout: 1000 * 60,\n },\n )\n }\n\n /**\n * Rotate a single robot joint by a fixed number of radians\n * Promise resolves only after the motion has completed.\n */\n async runIncrementalJointRotation({\n joint,\n currentJoints,\n velocityRadsPerSec,\n direction,\n distanceRads,\n }: {\n joint: number\n currentJoints: Joints\n velocityRadsPerSec: number\n direction: \"-\" | \"+\"\n distanceRads: number\n }) {\n const targetJoints = [...currentJoints.joints]\n // biome-ignore lint/style/noNonNullAssertion: legacy code\n targetJoints[joint]! += distanceRads * (direction === \"-\" ? -1 : 1)\n\n const jointVelocityLimits: number[] = new Array(\n currentJoints.joints.length,\n ).fill(velocityRadsPerSec)\n\n const motionPlanRes = await this.nova.api.motion.planMotion({\n motion_group: this.motionGroupId,\n start_joint_position: currentJoints,\n commands: [\n {\n settings: {\n limits_override: {\n joint_velocity_limits: {\n joints: jointVelocityLimits,\n },\n },\n },\n joint_ptp: {\n joints: targetJoints,\n },\n },\n ],\n })\n\n const plannedMotion = motionPlanRes.plan_successful_response?.motion\n if (!plannedMotion) {\n console.error(\"Failed to plan jogging increment motion\", motionPlanRes)\n return\n }\n\n await this.nova.api.motion.streamMoveForward(\n plannedMotion,\n 100,\n undefined,\n undefined,\n undefined,\n {\n // Might take a while at low velocity\n timeout: 1000 * 60,\n },\n )\n }\n}\n","/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */\nimport type {\n ControllerInstance,\n MotionGroupPhysical,\n MotionGroupStateResponse,\n Vector3d,\n} from \"@wandelbots/nova-api/v1\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport { Vector3 } from \"three\"\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\nfunction unwrapRotationVector(\n newRotationVectorApi: Vector3d,\n currentRotationVectorApi: Vector3d,\n): Vector3d {\n const currentRotationVector = new Vector3(\n currentRotationVectorApi.x,\n currentRotationVectorApi.y,\n currentRotationVectorApi.z,\n )\n\n const newRotationVector = new Vector3(\n newRotationVectorApi.x,\n newRotationVectorApi.y,\n newRotationVectorApi.z,\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 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 { instances: 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?.physical_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 MotionGroupStateResponse\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: MotionGroupStateResponse\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: ControllerInstance,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupStateResponse,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupStateResponse\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.state.joint_position.joints,\n motionStateResponse.state.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.state = motionStateResponse.state\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 if (this.rapidlyChangingMotionState.tcp_pose == null) {\n this.rapidlyChangingMotionState.tcp_pose =\n motionStateResponse.tcp_pose\n } else {\n this.rapidlyChangingMotionState.tcp_pose = {\n position: motionStateResponse.tcp_pose!.position,\n orientation: unwrapRotationVector(\n motionStateResponse.tcp_pose!.orientation,\n this.rapidlyChangingMotionState.tcp_pose!.orientation,\n ),\n tcp: motionStateResponse.tcp_pose!.tcp,\n coordinate_system:\n motionStateResponse.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.state.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n dispose() {\n this.motionStateSocket.close()\n }\n}\n","/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */\n/** biome-ignore-all lint/suspicious/noExplicitAny: legacy code */\nimport type {\n BaseAPI,\n Configuration as BaseConfiguration,\n} from \"@wandelbots/nova-api/v1\"\nimport {\n ApplicationApi,\n CellApi,\n ControllerApi,\n ControllerIOsApi,\n CoordinateSystemsApi,\n DeviceConfigurationApi,\n LibraryProgramApi,\n LibraryProgramMetadataApi,\n LibraryRecipeApi,\n LibraryRecipeMetadataApi,\n MotionApi,\n MotionGroupApi,\n MotionGroupInfosApi,\n MotionGroupJoggingApi,\n MotionGroupKinematicApi,\n ProgramApi,\n ProgramValuesApi,\n StoreCollisionComponentsApi,\n StoreCollisionScenesApi,\n StoreObjectApi,\n SystemApi,\n VirtualRobotApi,\n VirtualRobotBehaviorApi,\n VirtualRobotModeApi,\n VirtualRobotSetupApi,\n} from \"@wandelbots/nova-api/v1\"\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 deviceConfig = this.withCellId(DeviceConfigurationApi)\n\n readonly motionGroup = this.withCellId(MotionGroupApi)\n readonly motionGroupInfos = this.withCellId(MotionGroupInfosApi)\n\n readonly controller = this.withCellId(ControllerApi)\n\n readonly program = this.withCellId(ProgramApi)\n readonly programValues = this.withCellId(ProgramValuesApi)\n\n readonly controllerIOs = this.withCellId(ControllerIOsApi)\n\n readonly motionGroupKinematic = this.withCellId(MotionGroupKinematicApi)\n readonly motion = this.withCellId(MotionApi)\n\n readonly coordinateSystems = this.withCellId(CoordinateSystemsApi)\n\n readonly application = this.withCellId(ApplicationApi)\n readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)\n\n readonly motionGroupJogging = this.withCellId(MotionGroupJoggingApi)\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 libraryProgramMetadata = this.withCellId(LibraryProgramMetadataApi)\n readonly libraryProgram = this.withCellId(LibraryProgramApi)\n readonly libraryRecipeMetadata = this.withCellId(LibraryRecipeMetadataApi)\n readonly libraryRecipe = this.withCellId(LibraryRecipeApi)\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 {\n ControllerInstanceList,\n MotionGroupSpecification,\n MotionGroupStateResponse,\n RobotController,\n SafetySetup,\n} from \"@wandelbots/nova-api/v1\"\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 * 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 instances: [\n {\n controller: \"mock-ur5e\",\n model_name: \"UniversalRobots::Controller\",\n host: \"mock-ur5e\",\n allow_software_install_on_controller: true,\n physical_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 ControllerInstanceList\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 {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: 1330,\n z: -1850,\n },\n {\n x: 865,\n y: 1330,\n z: -1850,\n },\n {\n x: 865,\n y: -720,\n z: -1850,\n },\n {\n x: 1650,\n y: -720,\n z: -1850,\n },\n {\n x: 1650,\n y: 1330,\n z: -920,\n },\n {\n x: 865,\n y: 1330,\n z: -920,\n },\n {\n x: 865,\n y: -720,\n z: -920,\n },\n {\n x: 1650,\n y: -720,\n z: -920,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: 1330,\n z: -600,\n },\n {\n x: 865,\n y: 1330,\n z: -600,\n },\n {\n x: 865,\n y: 430,\n z: -600,\n },\n {\n x: 1650,\n y: 430,\n z: -600,\n },\n {\n x: 1650,\n y: 1330,\n z: -1250,\n },\n {\n x: 865,\n y: 1330,\n z: -1250,\n },\n {\n x: 865,\n y: 430,\n z: -1250,\n },\n {\n x: 1650,\n y: 430,\n z: -1250,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: -760,\n z: -440,\n },\n {\n x: 900,\n y: -760,\n z: -440,\n },\n {\n x: 900,\n y: -1330,\n z: -440,\n },\n {\n x: 1650,\n y: -1330,\n z: -440,\n },\n {\n x: 1650,\n y: -760,\n z: -1800,\n },\n {\n x: 900,\n y: -760,\n z: -1800,\n },\n {\n x: 900,\n y: -1330,\n z: -1800,\n },\n {\n x: 1650,\n y: -1330,\n z: -1800,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: -200,\n y: -200,\n z: -1900,\n },\n {\n x: 200,\n y: -200,\n z: -1900,\n },\n {\n x: 200,\n y: 200,\n z: -1900,\n },\n {\n x: -200,\n y: 200,\n z: -1900,\n },\n {\n x: -200,\n y: -200,\n z: -350,\n },\n {\n x: 200,\n y: -200,\n z: -350,\n },\n {\n x: 200,\n y: 200,\n z: -350,\n },\n {\n x: -200,\n y: 200,\n z: -350,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: -70,\n y: -70,\n z: -50,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: -450,\n y: 40,\n z: 170,\n },\n orientation: {\n x: 0,\n y: -Math.SQRT1_2,\n z: 0,\n w: Math.SQRT1_2,\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: {\n x: -110,\n y: 10,\n z: -100,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: 0,\n y: 300,\n z: 40,\n },\n orientation: {\n x: -Math.SQRT1_2,\n y: 0,\n z: 0,\n w: Math.SQRT1_2,\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: {\n x: 0,\n y: 0,\n z: -50,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: 0,\n y: 0,\n z: 0,\n },\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: {\n x: 0,\n y: 0,\n z: 0,\n },\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: {\n x: -200,\n y: 300,\n z: 150,\n },\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 x: 6.437331889439328,\n y: -628.4123774830913,\n z: 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 x: 6.437331889439328,\n y: -628.4123774830913,\n z: 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 x: -2.763015284002938,\n y: -630.2151479701106,\n z: 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 x: -2.763015284002938,\n y: -630.2151479701106,\n z: 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 state: {\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: {\n x: 1.3300010259703043,\n y: -409.2680714682808,\n z: 531.0203477065281,\n },\n orientation: {\n x: 1.7564919306270736,\n y: -1.7542521568325058,\n z: 0.7326972590614671,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: {\n x: 1.3300010259703043,\n y: -409.2680714682808,\n z: 531.0203477065281,\n },\n orientation: {\n x: 1.7564919306270736,\n y: -1.7542521568325058,\n z: 0.7326972590614671,\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: [false, false, false, false, false, false],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"1\",\n },\n tcp_pose: {\n position: {\n x: 302.90748476115556,\n y: -152.87065869452337,\n z: 424.0454619321661,\n },\n orientation: {\n x: 2.3403056115045353,\n y: -1.1706836379431356,\n z: 0.9772511964246311,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n } satisfies MotionGroupStateResponse,\n}\n","/**\n * @fileoverview\n * @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.\n */\n\nimport type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v1\"\nimport type { AxiosRequestConfig } from \"axios\"\nimport axios, { isAxiosError } from \"axios\"\nimport urlJoin from \"url-join\"\nimport { loginWithAuth0 } from \"../../LoginWithAuth0.js\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket.js\"\nimport { availableStorage } from \"../availableStorage.js\"\nimport { parseNovaInstanceUrl } from \"../converters.js\"\nimport { ConnectedMotionGroup } from \"./ConnectedMotionGroup.js\"\nimport { JoggerConnection } from \"./JoggerConnection.js\"\nimport { MotionStreamConnection } from \"./MotionStreamConnection.js\"\nimport { NovaCellAPIClient } from \"./NovaCellAPIClient.js\"\nimport { MockNovaInstance } from \"./mock/MockNovaInstance.js\"\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 * Client for connecting to a Nova instance and controlling robots.\n * @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.\n */\nexport class NovaClient {\n readonly api: NovaCellAPIClient\n readonly config: NovaClientConfigWithDefaults\n readonly mock?: MockNovaInstance\n readonly instanceUrl: URL\n authPromise: Promise<string | null> | null = null\n accessToken: string | null = null\n\n constructor(config: NovaClientConfig) {\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 this.instanceUrl = parseNovaInstanceUrl(this.config.instanceUrl)\n\n // Set up Axios instance with interceptor for token fetching\n const axiosInstance = axios.create({\n baseURL: urlJoin(this.config.instanceUrl, \"/api/v1\"),\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.instanceUrl.href, \"/api/v1\"),\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n baseOptions: {\n ...(this.mock\n ? ({\n adapter: (config) => {\n // biome-ignore lint/style/noNonNullAssertion: legacy code\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 const storedToken = availableStorage.getString(\"wbjs.access_token\")\n if (storedToken && this.accessToken !== storedToken) {\n // Might be newer than the one we have\n this.accessToken = storedToken\n return\n }\n\n // Otherwise, perform login flow\n this.authPromise = loginWithAuth0(this.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.instanceUrl.href,\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 /**\n * Connect to the jogging websocket(s) for a given motion group\n */\n async connectJogger(motionGroupId: string) {\n return await JoggerConnection.open(this, motionGroupId)\n }\n\n async connectMotionGroups(\n motionGroupIds: string[],\n ): Promise<ConnectedMotionGroup[]> {\n const { instances } = await this.api.controller.listControllers()\n\n return Promise.all(\n motionGroupIds.map((motionGroupId) =>\n ConnectedMotionGroup.connect(this, motionGroupId, instances),\n ),\n )\n }\n\n async connectMotionGroup(\n motionGroupId: string,\n ): Promise<ConnectedMotionGroup> {\n const motionGroups = await this.connectMotionGroups([motionGroupId])\n // biome-ignore lint/style/noNonNullAssertion: legacy code\n return motionGroups[0]!\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAMA,SAAgB,yBACd,MACA;CACA,MAAM,WAAW;EAAC,KAAK,SAAS;EAAG,KAAK,SAAS;EAAG,KAAK,SAAS;EAAE;CACpE,MAAM,cAAc;EAClB,KAAK,aAAa,KAAK;EACvB,KAAK,aAAa,KAAK;EACvB,KAAK,aAAa,KAAK;EACxB;CAED,MAAM,iBAAiB,SAAS,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC;CAExD,MAAM,iBAAiB,YAAY,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC;AAE3D,QAAO,IAAI,eAAe,OAAO,eAAe,CAAC,KAAK,KAAK,CAAC;;;;;AClB9D,SAAgB,iBACd,gBACA,gBACA,sBACS;AACT,KAAI,eAAe,WAAW,eAAe,OAC3C,QAAO;AAGT,MAAK,IAAI,aAAa,GAAG,aAAa,eAAe,QAAQ,aAC3D,KAEE,KAAK,IAAI,eAAe,cAAe,eAAe,YAAa,GACnE,qBAEA,QAAO;AAIX,QAAO;;AAGT,SAAgB,aACd,QACA,QACA,sBACS;AAET,KAAK,WAAW,UAAa,UAAY,UAAU,WAAW,OAC5D,QAAO;AAIT,KAAI,WAAW,UAAa,WAAW,OACrC,QAAO;CAGT,IAAI,eAAe;AACnB,iBAAgB,KAAK,IAAI,OAAO,YAAY,IAAI,OAAO,YAAY,EAAE;AACrE,iBAAgB,KAAK,IAAI,OAAO,YAAY,IAAI,OAAO,YAAY,EAAE;AACrE,iBAAgB,KAAK,IAAI,OAAO,YAAY,IAAI,OAAO,YAAY,EAAE;AACrE,iBAAgB,KAAK,IAAI,OAAO,SAAS,IAAI,OAAO,SAAS,EAAE;AAC/D,iBAAgB,KAAK,IAAI,OAAO,SAAS,IAAI,OAAO,SAAS,EAAE;AAC/D,iBAAgB,KAAK,IAAI,OAAO,SAAS,IAAI,OAAO,SAAS,EAAE;AAE/D,KAAI,eAAe,qBACjB,QAAO;AAGT,QACE,OAAO,sBAAsB,OAAO,qBACpC,OAAO,QAAQ,OAAO;;;;;AClC1B,MAAMA,2BAAyB;;;;AAS/B,IAAa,uBAAb,MAAa,qBAAqB;CAChC,aAAa,QACX,MACA,eACA,aACA;EACA,MAAM,CAAC,mBAAmB,gBAAgB,cAAc,MAAM,IAAI;EAIlE,MAAM,aAAa,YAAY,MAAM,MAAM,EAAE,eAAe,aAAa;EACzE,MAAM,cAAc,YAAY,uBAAuB,MACpD,OAAO,GAAG,iBAAiB,cAC7B;AACD,MAAI,CAAC,cAAc,CAAC,YAClB,OAAM,IAAI,MACR,cAAc,aAAa,mBAAmB,cAAc,YAC7D;EAGH,MAAM,oBAAoB,KAAK,0BAC7B,kBAAkB,cAAc,eACjC;EAGD,MAAM,eAAe,MAAM,kBAAkB,cAAc;EAC3D,MAAM,qBAAqBC,oCAAa,aAAa,KAAK,EACtD;AAEJ,MAAI,CAAC,mBACH,OAAM,IAAI,MACR,gDAAgD,aAAa,OAC9D;AAGH,UAAQ,IACN,oDAAoD,YAAY,aAAa,uBAC7E,mBACD;EAMD,MAAM,aAHS,MAAM,KAAK,IAAI,WAAW,mBACvC,WAAW,WACZ,EACwB,cAAc,SAAS;EAIhD,MAAM,WAAW,OAAO,YAAY;AAClC,OAAI;AAIF,WAHiB,MAAM,KAAK,IAAI,iBAAiB,YAC/C,YAAY,aACb;YAEM,KAAK;AACZ,YAAQ,MACN,+BAA+B,YAAY,gBAC3C,IACD;AACD,WAAO;;MAEP;EAGJ,MAAM,wBAAwB,KAAK,0BACjC,gBAAgB,WAAW,WAAW,kCACvC;EAGD,MAAM,yBAAyB,MAAM,sBAAsB,cAAc;EACzE,MAAM,yBAAyBA,oCAAa,uBAAuB,KAAK,EACpE;AAEJ,MAAI,CAAC,uBACH,OAAM,IAAI,MACR,oDAAoD,uBAAuB,OAC5E;AAGH,UAAQ,IACN,sDAAsD,WAAW,WAAW,uBAC5E,uBACD;EAGD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,iBAAiB,SAAS,cAAc;AAQxE,SAAO,IAAI,qBACT,MACA,YACA,aACA,oBACA,mBACA,WAEA,MAbA,MAAM,KAAK,IAAI,iBAAiB,4BAA4B,cAAc,EAG1E,MAAM,KAAK,IAAI,iBAAiB,eAAe,cAAc,EAa7D,UACA,wBACA,sBACD;;CAwBH,YACE,AAASC,MACT,AAASC,YACT,AAASC,aACT,AAASC,oBACT,AAASC,mBACT,AAASC,WACT,AAASC,MACT,AAASC,0BACT,AAASC,aACT,AAASC,UACT,AAASC,wBACT,AAASC,uBACT;EAZS;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;yCAjCyC;sCACH;yBAGvB;yBAexB;AAgBA,OAAK,6BAA6B;AAClC,OAAK,kBAAkB;AAGvB,wBAAsB,iBAAiB,YAAY,UAAU;GAC3D,MAAM,OAAOZ,oCAAa,MAAM,KAAK,EAAE;AAEvC,OAAI,CAAC,KACH;AAGF,+BAAkB;AAChB,SAAK,kBAAkB;KACvB;IACF;AAEF,oBAAkB,iBAAiB,YAAY,UAAU;GACvD,MAAM,sBAAsBA,oCAAa,MAAM,KAAK,EAAE;AAItD,OAAI,CAAC,oBACH,OAAM,IAAI,MACR,kCAAkC,KAAK,cAAc,IAAI,MAAM,OAChE;AAIH,OACE,CAAC,iBACC,KAAK,2BAA2B,MAAM,eAAe,QACrD,oBAAoB,MAAM,eAAe,QACzCD,yBACD,CAED,6BAAkB;AAChB,SAAK,2BAA2B,QAAQ,oBAAoB;KAC5D;AAIJ,OACE,CAAC,aACC,KAAK,2BAA2B,UAChC,oBAAoB,UACpBA,yBACD,CAED,6BAAkB;AAChB,SAAK,2BAA2B,WAC9B,oBAAoB;KACtB;IAEJ;AACF,+BAAmB,KAAK;;CAG1B,IAAI,gBAAgB;AAClB,SAAO,KAAK,YAAY;;CAG1B,IAAI,eAAe;AACjB,SAAO,KAAK,WAAW;;CAGzB,IAAI,sBAAsB;AACxB,SAAO,KAAK,YAAY;;CAG1B,IAAI,yBAAyB;EAC3B,MAAM,MAAM,KAAK,cAAc,MAAM,IAAI,CAAC;AAC1C,SAAO,GAAG,KAAK,aAAa,WAAW,KAAK,IAAI,CAAC,GAAG;;;CAItD,IAAI,sBAAsB;AACxB,SAAQ,KAAK,kBAAkB,KAAK,KAAM;;CAG5C,IAAI,SAAS;AACX,SAAO,KAAK,mBAAmB,MAAM,eAAe,OAAO,KAAK,GAAG,MAAM;AACvE,UAAO,EACL,OAAO,GACR;IACD;;CAGJ,IAAI,eAAe;AACjB,SAAO,KAAK,yBAAyB;;CAGvC,IAAI,cAAc;AAChB,SAAO,KAAK,YAAY;;;CAI1B,IAAI,mBAA6C;AAC/C,MAAI,CAAC,KAAK,SACR,QAAO;GAAC;GAAG;GAAG;GAAE;AAGlB,SAAO;GACL,KAAK,SAAS,KAAK,SAAS,IAAI;GAChC,KAAK,SAAS,KAAK,SAAS,IAAI;GAChC,KAAK,SAAS,KAAK,SAAS,IAAI;GACjC;;;CAIH,IAAI,qBAAqB;EACvB,MAAM,iBAAiB,IAAIc,MAAM,QAC/B,KAAK,UAAU,KAAK,aAAa,KAAK,GACtC,KAAK,UAAU,KAAK,aAAa,KAAK,GACtC,KAAK,UAAU,KAAK,aAAa,KAAK,EACvC;EAED,MAAM,YAAY,eAAe,QAAQ;EACzC,MAAM,OAAO,eAAe,WAAW;AAEvC,SAAO,IAAIA,MAAM,YAAY,CAAC,iBAAiB,MAAM,UAAU;;;;;;CAOjE,IAAI,gBAAgB;AAMlB,SAL2D,CACzD,qCACA,qCACD,CAEkB,SAAS,KAAK,gBAAgB,aAAa;;;;;;CAOhE,IAAI,wBAAwB;AAM1B,SALgE,CAC9D,uBACA,uBACD,CAEuB,SAAS,KAAK,gBAAgB,aAAa;;;;;CAMrE,IAAI,0BAA0B;AAQ5B,SAPoE;GAClE;GACA;GACA;GACA;GACD,CAEyB,SAAS,KAAK,gBAAgB,eAAe;;;;;;CAOzE,IAAI,aAAa;AACf,SACE,KAAK,yBACL,KAAK,2BACL,KAAK,oBAAoB;;CAI7B,MAAM,aAAa;AACjB,MAAI,KAAK,oBAAoB,UAAU;AACrC,WAAQ,MAAM,iDAAiD;AAC/D;;AAGF,8BAAkB;AAChB,QAAK,kBAAkB;IACvB;AAEF,MAAI;AACF,SAAM,KAAK,KAAK,IAAI,WAAW,eAC7B,KAAK,cACL,eACD;AAED,+BAAkB;AAChB,SAAK,kBAAkB;KACvB;WACK,KAAK;AACZ,+BAAkB;AAChB,SAAK,kBAAkB;KACvB;AACF,SAAM;;;CAIV,MAAM,WAAW;AACf,MAAI,KAAK,oBAAoB,YAAY;AACvC,WAAQ,MAAM,6CAA6C;AAC3D;;AAGF,8BAAkB;AAChB,QAAK,kBAAkB;IACvB;AAEF,MAAI;AACF,SAAM,KAAK,KAAK,IAAI,WAAW,eAC7B,KAAK,cACL,eACD;AAED,+BAAkB;AAChB,SAAK,kBAAkB;KACvB;WACK,KAAK;AACZ,+BAAkB;AAChB,SAAK,kBAAkB;KACvB;AACF,SAAM;;;CAIV,mBAAmB;AACjB,MAAI,KAAK,oBAAoB,WAC3B,MAAK,UAAU;WACN,KAAK,oBAAoB,SAClC,MAAK,YAAY;;CAIrB,UAAU;AACR,OAAK,kBAAkB,OAAO;AAC9B,MAAI,KAAK,gCACP,MAAK,gCAAgC,OAAO;AAC9C,MAAI,KAAK,6BACP,MAAK,6BAA6B,OAAO;;CAG7C,mBAAmB,UAAkB;AACnC,OAAK,kBAAkB;;;;;;AClZ3B,IAAa,mBAAb,MAAa,iBAAiB;CAU5B,aAAa,KACX,MACA,eACA,OAA6B,EAAE,EAC/B;AAGA,SAAO,IAAI,iBAFU,MAAM,KAAK,oBAAoB,cAAc,EAExB,KAAK;;CAGjD,YACE,AAASC,cACT,AAASC,OAA6B,EAAE,EACxC;EAFS;EACA;4BAnB4C;wBACJ;8BAI/C,EAAE;;CAiBN,IAAI,gBAAgB;AAClB,SAAO,KAAK,aAAa;;CAG3B,IAAI,OAAO;AACT,SAAO,KAAK,aAAa;;CAG3B,IAAI,YAAY;AACd,SAAO,KAAK,aAAa,OAAO;;CAGlC,IAAI,oBAAoB;AACtB,MAAI,KAAK,mBAAoB,QAAO;AACpC,MAAI,KAAK,eAAgB,QAAO;AAChC,SAAO;;CAGT,IAAI,kBAAkB;AACpB,SAAO,KAAK,sBAAsB,KAAK;;CAGzC,MAAM,OAAO;AAKX,MAAI,KAAK,mBACP,MAAK,mBAAmB,SAAS;GAC/B,cAAc,KAAK;GACnB,oBAAoB;IAAE,GAAG;IAAG,GAAG;IAAG,GAAG;IAAG;GACxC,oBAAoB;IAAE,GAAG;IAAG,GAAG;IAAG,GAAG;IAAG;GACxC,mBAAmB;GACnB,mBAAmB;GACnB,KAAK,KAAK,qBAAqB;GAC/B,mBAAmB,KAAK,qBAAqB;GAC9C,CAAC;AAGJ,MAAI,KAAK,eACP,MAAK,eAAe,SAAS;GAC3B,cAAc,KAAK;GACnB,kBAAkB,IAAI,MAAM,KAAK,UAAU,CAAC,KAAK,EAAE;GACpD,CAAC;;CAIN,UAAU;AACR,MAAI,KAAK,mBACP,MAAK,mBAAmB,SAAS;AAGnC,MAAI,KAAK,eACP,MAAK,eAAe,SAAS;;CAIjC,eACE,MACA,sBAIA;AACA,UAAQ,IAAI,2BAA2B,KAAK;AAC5C,MAAI,sBAAsB;AAExB,OACE,KAAK,UAAU,KAAK,qBAAqB,KACzC,KAAK,UAAU,qBAAqB,EAEpC;QAAI,KAAK,oBAAoB;AAC3B,UAAK,mBAAmB,SAAS;AACjC,UAAK,qBAAqB;;;AAI9B,QAAK,uBAAuB;;AAG9B,MAAI,SAAS,eAAe,KAAK,oBAAoB;AACnD,QAAK,mBAAmB,SAAS;AACjC,QAAK,qBAAqB;;AAG5B,MAAI,SAAS,WAAW,KAAK,gBAAgB;AAC3C,QAAK,eAAe,SAAS;AAC7B,QAAK,iBAAiB;;AAGxB,MAAI,SAAS,eAAe,CAAC,KAAK,oBAAoB;AACpD,QAAK,qBAAqB,KAAK,KAAK,0BAClC,0BACD;AAED,QAAK,mBAAmB,iBACtB,YACC,OAAqB;IACpB,MAAM,OAAOC,oCAAa,GAAG,KAAK;AAClC,QAAI,QAAQ,WAAW,KACrB,KAAI,KAAK,KAAK,QACZ,MAAK,KAAK,QAAQ,GAAG,KAAK;QAE1B,OAAM,IAAI,MAAM,GAAG,KAAK;KAI/B;;AAGH,MAAI,SAAS,WAAW,CAAC,KAAK,gBAAgB;AAC5C,QAAK,iBAAiB,KAAK,KAAK,0BAC9B,4BACD;AAED,QAAK,eAAe,iBAAiB,YAAY,OAAqB;IACpE,MAAM,OAAOA,oCAAa,GAAG,KAAK;AAClC,QAAI,QAAQ,WAAW,KACrB,KAAI,KAAK,KAAK,QACZ,MAAK,KAAK,QAAQ,GAAG,KAAK;QAE1B,OAAM,IAAI,MAAM,GAAG,KAAK;KAG5B;;;;;;CAON,MAAM,mBAAmB,EACvB,OACA,WACA,sBAQC;AACD,MAAI,CAAC,KAAK,eACR,OAAM,IAAI,MACR,mEACD;EAGH,MAAM,kBAAkB,IAAI,MAAM,KAAK,UAAU,CAAC,KAAK,EAAE;AAEzD,kBAAgB,SACd,cAAc,MAAM,CAAC,qBAAqB;AAE5C,OAAK,eAAe,SAAS;GAC3B,cAAc,KAAK;GACnB,kBAAkB;GACnB,CAAC;;;;;CAMJ,MAAM,oBAAoB,EACxB,MACA,WACA,oBAKC;AACD,MAAI,CAAC,KAAK,mBACR,OAAM,IAAI,MACR,uEACD;EAGH,MAAM,aAAa;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;GAAG;EACvC,MAAM,gBAAgB,OAAO,OAAO,EAAE,EAAE,WAAW;AACnD,gBAAc,QAAQ,cAAc,MAAM,KAAK;AAE/C,OAAK,mBAAmB,SAAS;GAC/B,cAAc,KAAK;GACnB,oBAAoB;GACpB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,KAAK,KAAK,qBAAqB;GAC/B,mBAAmB,KAAK,qBAAqB;GAC9C,CAAC;;;;;CAMJ,MAAM,iBAAiB,EACrB,MACA,WACA,sBAKC;AACD,MAAI,CAAC,KAAK,mBACR,OAAM,IAAI,MACR,uEACD;EAGH,MAAM,aAAa;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;GAAG;EACvC,MAAM,gBAAgB,OAAO,OAAO,EAAE,EAAE,WAAW;AACnD,gBAAc,QAAQ,cAAc,MAAM,KAAK;AAE/C,OAAK,mBAAmB,SAAS;GAC/B,cAAc,KAAK;GACnB,oBAAoB;GACpB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,KAAK,KAAK,qBAAqB;GAC/B,mBAAmB,KAAK,qBAAqB;GAC9C,CAAC;;;;;;;CAQJ,MAAM,8BAA8B,EAClC,gBACA,eACA,eACA,yBACA,MACA,WACA,UAiBC;EACD,MAAMC,WAAsB,EAAE;AAE9B,MACE,CAACC,8CAAuB,eAAe,mBAAmB,cAAc,CAExE,OAAM,IAAI,MACR,sCAAsC,eAAe,kBAAkB,2CAA2C,gBACnH;AAGH,MAAI,OAAO,SAAS,aAAa;GAC/B,MAAM,oBAAoB,OAAO,OAAO,EAAE,EAAE,eAAe,SAAS;AACpE,qBAAkB,SAChB,OAAO,cAAc,cAAc,MAAM,KAAK;AAEhD,YAAS,KAAK;IACZ,UAAU,EACR,iBAAiB,EACf,oBAAoB,yBACrB,EACF;IACD,MAAM;KACJ,UAAU;KACV,aAAa,eAAe;KAC5B,mBAAmB;KACpB;IACF,CAAC;aACO,OAAO,SAAS,UAAU;GAKnC,MAAM,wBAAwB,IAAIC,kCAChC,eAAe,YAAY,GAC3B,eAAe,YAAY,GAC3B,eAAe,YAAY,EAC5B;GAED,MAAM,qBAAqB,sBAAsB,QAAQ;GACzD,MAAM,2BAA2B,sBAAsB,OAAO,CAAC,WAAW;GAG1E,MAAM,wBACJ,OAAO,gBAAgB,cAAc,MAAM,KAAK;GAElD,MAAM,8BAA8B,IAAIA,kCAAQ,GAAK,GAAK,EAAI;AAC9D,+BAA4B,QAAQ;GAGpC,MAAM,KACJ,KAAK,IAAI,KAAM,sBAAsB,GACrC,KAAK,IAAI,KAAM,mBAAmB;GACpC,MAAM,KACJ,KAAK,IAAI,KAAM,sBAAsB,GACrC,KAAK,IAAI,KAAM,mBAAmB;GACpC,MAAM,KACJ,KAAK,IAAI,KAAM,sBAAsB,GACrC,KAAK,IAAI,KAAM,mBAAmB;GACpC,MAAM,KACJ,KAAK,IAAI,KAAM,sBAAsB,GACrC,KAAK,IAAI,KAAM,mBAAmB;GAEpC,MAAM,aAAa,4BAA4B,IAC7C,yBACD;GAED,MAAM,eAAe,4BAClB,OAAO,CACP,MAAM,yBAAyB;GAGlC,MAAM,iBAAiB,IAAM,KAAK,KAAK,KAAK,KAAK,WAAW;GAG5D,MAAM,KAAK,iBAAiB,KAAK,IAAI,KAAM,eAAe;GAE1D,MAAM,uBAAuB,IAAIA,mCAAS,CACvC,gBAAgB,cAAc,GAAG,CACjC,gBAAgB,6BAA6B,GAAG,CAChD,gBAAgB,0BAA0B,GAAG,CAC7C,eAAe,GAAG;AAErB,YAAS,KAAK;IACZ,UAAU,EACR,iBAAiB,EACf,gCAAgC,yBACjC,EACF;IACD,MAAM;KACJ,UAAU,eAAe;KACzB,aAAa;KACb,mBAAmB;KACpB;IACF,CAAC;;EAGJ,MAAM,gBAAgB,MAAM,KAAK,KAAK,IAAI,OAAO,WAAW;GAC1D,cAAc,KAAK;GACnB,sBAAsB;GACtB,KAAK,KAAK,qBAAqB;GAC/B;GACD,CAAC;EAEF,MAAM,gBAAgB,cAAc,0BAA0B;AAC9D,MAAI,CAAC,cACH,OAAM,IAAI,MACR,2CAA2C,KAAK,UAAU,cAAc,GACzE;AAGH,QAAM,KAAK,KAAK,IAAI,OAAO,kBACzB,eACA,KACA,QACA,QACA,QACA,EAEE,SAAS,MAAO,IACjB,CACF;;;;;;CAOH,MAAM,4BAA4B,EAChC,OACA,eACA,oBACA,WACA,gBAOC;EACD,MAAM,eAAe,CAAC,GAAG,cAAc,OAAO;AAE9C,eAAa,UAAW,gBAAgB,cAAc,MAAM,KAAK;EAEjE,MAAMC,sBAAgC,IAAI,MACxC,cAAc,OAAO,OACtB,CAAC,KAAK,mBAAmB;EAE1B,MAAM,gBAAgB,MAAM,KAAK,KAAK,IAAI,OAAO,WAAW;GAC1D,cAAc,KAAK;GACnB,sBAAsB;GACtB,UAAU,CACR;IACE,UAAU,EACR,iBAAiB,EACf,uBAAuB,EACrB,QAAQ,qBACT,EACF,EACF;IACD,WAAW,EACT,QAAQ,cACT;IACF,CACF;GACF,CAAC;EAEF,MAAM,gBAAgB,cAAc,0BAA0B;AAC9D,MAAI,CAAC,eAAe;AAClB,WAAQ,MAAM,2CAA2C,cAAc;AACvE;;AAGF,QAAM,KAAK,KAAK,IAAI,OAAO,kBACzB,eACA,KACA,QACA,QACA,QACA,EAEE,SAAS,MAAO,IACjB,CACF;;;;;;ACldL,MAAM,yBAAyB;AAE/B,SAAS,qBACP,sBACA,0BACU;CACV,MAAM,wBAAwB,IAAIC,cAChC,yBAAyB,GACzB,yBAAyB,GACzB,yBAAyB,EAC1B;CAED,MAAM,oBAAoB,IAAIA,cAC5B,qBAAqB,GACrB,qBAAqB,GACrB,qBAAqB,EACtB;CAED,MAAM,eAAe,sBAAsB,QAAQ;CACnD,MAAM,cAAc,sBAAsB,WAAW;CAErD,IAAI,WAAW,kBAAkB,QAAQ;CACzC,IAAI,UAAU,kBAAkB,WAAW;AAG3C,KAAI,QAAQ,IAAI,YAAY,GAAG,GAAG;AAChC,aAAW,CAAC;AACZ,YAAU,QAAQ,eAAe,GAAK;;CAKxC,IAAI,kBAAkB,WAAW;AACjC,oBACE,IAAM,KAAK,KAAK,KAAK,OAAO,kBAAkB,KAAK,OAAO,IAAM,KAAK,IAAI;AAE3E,YAAW,eAAe;AAE1B,QAAO,QAAQ,eAAe,SAAS;;;;;AAMzC,IAAa,yBAAb,MAAa,uBAAuB;CAClC,aAAa,KAAK,MAAkB,eAAuB;EACzD,MAAM,EAAE,WAAW,gBACjB,MAAM,KAAK,IAAI,WAAW,iBAAiB;EAE7C,MAAM,CAAC,mBAAmB,gBAAgB,cAAc,MAAM,IAAI;EAIlE,MAAM,aAAa,YAAY,MAAM,MAAM,EAAE,eAAe,aAAa;EACzE,MAAM,cAAc,YAAY,uBAAuB,MACpD,OAAO,GAAG,iBAAiB,cAC7B;AACD,MAAI,CAAC,cAAc,CAAC,YAClB,OAAM,IAAI,MACR,cAAc,aAAa,mBAAmB,cAAc,YAC7D;EAGH,MAAM,oBAAoB,KAAK,0BAC7B,kBAAkB,cAAc,eACjC;EAGD,MAAM,eAAe,MAAM,kBAAkB,cAAc;EAC3D,MAAM,qBAAqBC,oCAAa,aAAa,KAAK,EACtD;AAEJ,MAAI,CAAC,mBACH,OAAM,IAAI,MACR,gDAAgD,aAAa,OAC9D;AAGH,UAAQ,IACN,oDAAoD,YAAY,aAAa,uBAC7E,mBACD;AAED,SAAO,IAAI,uBACT,MACA,YACA,aACA,oBACA,kBACD;;CAOH,YACE,AAASC,MACT,AAASC,YACT,AAASC,aACT,AAASC,oBACT,AAASC,mBACT;EALS;EACA;EACA;EACA;EACA;AAET,OAAK,6BAA6B;AAElC,oBAAkB,iBAAiB,YAAY,UAAU;GACvD,MAAM,sBAAsBL,oCAAa,MAAM,KAAK,EAAE;AAItD,OAAI,CAAC,oBACH,OAAM,IAAI,MACR,kCAAkC,KAAK,cAAc,IAAI,MAAM,OAChE;AAIH,OACE,CAAC,iBACC,KAAK,2BAA2B,MAAM,eAAe,QACrD,oBAAoB,MAAM,eAAe,QACzC,uBACD,CAED,6BAAkB;AAChB,SAAK,2BAA2B,QAAQ,oBAAoB;KAC5D;AAIJ,OACE,CAAC,aACC,KAAK,2BAA2B,UAChC,oBAAoB,UACpB,uBACD,CAED,6BAAkB;AAChB,QAAI,KAAK,2BAA2B,YAAY,KAC9C,MAAK,2BAA2B,WAC9B,oBAAoB;QAEtB,MAAK,2BAA2B,WAAW;KACzC,UAAU,oBAAoB,SAAU;KACxC,aAAa,qBACX,oBAAoB,SAAU,aAC9B,KAAK,2BAA2B,SAAU,YAC3C;KACD,KAAK,oBAAoB,SAAU;KACnC,mBACE,oBAAoB,SAAU;KACjC;KAEH;IAEJ;AACF,+BAAmB,KAAK;;CAG1B,IAAI,gBAAgB;AAClB,SAAO,KAAK,YAAY;;CAG1B,IAAI,eAAe;AACjB,SAAO,KAAK,WAAW;;CAGzB,IAAI,sBAAsB;AACxB,SAAO,KAAK,YAAY;;CAG1B,IAAI,yBAAyB;EAC3B,MAAM,MAAM,KAAK,cAAc,MAAM,IAAI,CAAC;AAC1C,SAAO,GAAG,KAAK,aAAa,WAAW,KAAK,IAAI,CAAC,GAAG;;CAGtD,IAAI,SAAS;AACX,SAAO,KAAK,mBAAmB,MAAM,eAAe,OAAO,KAAK,GAAG,MAAM;AACvE,UAAO,EACL,OAAO,GACR;IACD;;CAGJ,UAAU;AACR,OAAK,kBAAkB,OAAO;;;;;;;;;;AC7IlC,IAAa,oBAAb,MAA+B;CAC7B,YACE,AAASM,QACT,AAASC,MAIT;EALS;EACA;gBAkFO,KAAK,2BAA2BC,mCAAU;cAC5C,KAAK,2BAA2BC,iCAAQ;sBAEhC,KAAK,WAAWC,gDAAuB;qBAExC,KAAK,WAAWC,wCAAe;0BAC1B,KAAK,WAAWC,6CAAoB;oBAE1C,KAAK,WAAWC,uCAAc;iBAEjC,KAAK,WAAWC,oCAAW;uBACrB,KAAK,WAAWC,0CAAiB;uBAEjC,KAAK,WAAWC,0CAAiB;8BAE1B,KAAK,WAAWC,iDAAwB;gBACtD,KAAK,WAAWC,mCAAU;2BAEf,KAAK,WAAWC,8CAAqB;qBAE3C,KAAK,WAAWC,wCAAe;2BACzB,KAAK,2BAA2BA,wCAAe;4BAE9C,KAAK,WAAWC,+CAAsB;sBAE5C,KAAK,WAAWC,yCAAgB;2BAC3B,KAAK,WAAWC,8CAAqB;0BACtC,KAAK,WAAWC,6CAAoB;8BAChC,KAAK,WAAWC,iDAAwB;gCAEtC,KAAK,WAAWC,mDAA0B;wBAClD,KAAK,WAAWC,2CAAkB;+BAC3B,KAAK,WAAWC,kDAAyB;uBACjD,KAAK,WAAWC,0CAAiB;qBAEnC,KAAK,WAAWC,wCAAe;kCAClB,KAAK,WACvCC,qDACD;8BAC+B,KAAK,WAAWC,iDAAwB;;;;;;;CA9GxE,AAAQ,WACN,gBAKA;EACA,MAAM,YAAY,IAAI,eACpB;GACE,GAAG,KAAK;GACR,aAAa,SAAiB;AAC5B,WAAO,SAAS;;GAEnB,EACD,KAAK,KAAK,YAAY,IACtB,KAAK,KAAK,iBAAiB,cAAM,QAAQ,CAC1C;AAID,OAAK,MAAM,OAAO,QAAQ,QAAQ,QAAQ,eAAe,UAAU,CAAE,CACnE,KAAI,QAAQ,iBAAiB,OAAO,UAAU,SAAS,YAAY;GACjE,MAAM,mBAAmB,UAAU;AACnC,aAAU,QAAQ,GAAG,SAAgB;AACnC,WAAO,iBACJ,MAAM,WAAW,CAAC,KAAK,QAAQ,GAAG,KAAK,CAAC,CACxC,MAAM,QAAa,IAAI,KAAK;;;AAKrC,SAAO;;;;;CAMT,AAAQ,2BACN,gBAKA;EACA,MAAM,YAAY,IAAI,eACpB;GACE,GAAG,KAAK;GACR,aAAa,SAAiB;AAC5B,WAAO,SAAS;;GAEnB,EACD,KAAK,KAAK,YAAY,IACtB,KAAK,KAAK,iBAAiB,cAAM,QAAQ,CAC1C;AAID,OAAK,MAAM,OAAO,QAAQ,QAAQ,QAAQ,eAAe,UAAU,CAAE,CACnE,KAAI,QAAQ,iBAAiB,OAAO,UAAU,SAAS,YAAY;GACjE,MAAM,mBAAmB,UAAU;AACnC,aAAU,QAAQ,GAAG,SAAgB;AACnC,WAAO,iBACJ,MAAM,WAAW,KAAK,CACtB,MAAM,QAAa,IAAI,KAAK;;;AAKrC,SAAO;;;;;;;;;AC7HX,IAAa,mBAAb,MAA8B;;qBACwB,EAAE;;CAEtD,MAAM,iBACJ,QACwB;EACxB,MAAM,cAAc;GAClB;IACE,QAAQ;IACR,MAAM;IACN,SAAS;AACP,YAAO,EACL,WAAW,CACT;MACE,YAAY;MACZ,YAAY;MACZ,MAAM;MACN,sCAAsC;MACtC,wBAAwB,CACtB;OACE,cAAc;OACd,sBAAsB;OACtB,QAAQ;OACR,uBAAuB;OACxB,CACF;MACD,WAAW;MACX,eAAe;MAChB,CACF,EACF;;IAEJ;GACD;IACE,QAAQ;IACR,MAAM;IACN,SAAS;AACP,YAAO;MACL,eAAe;OACb,MAAM;OACN,cAAc;OACd,UAAU;OACV,MAAM;OACP;MACD,MAAM;MACP;;IAEJ;GACD;IACE,QAAQ;IACR,MAAM;IACN,SAAS;AACP,YAAO;MACL,eAAe;OACb;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACF;MACD,yBAAyB;OACvB;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACF;MACF;;IAEJ;GACD;IACE,QAAQ;IACR,MAAM;IACN,SAAS;AACP,YAAO;MACL,iBAAiB,CACf;OACE,cAAc;OACd,UAAU;QACR,uBAAuB;SACrB;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACF;QACD,uBAAuB;SACrB;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACF;QACD,2BAA2B,EAAE;QAC7B,qBAAqB,EAAE;QACvB,oBAAoB;QACrB;OACF,CACF;MACD,cAAc;OACZ;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,UAAU,EACR,kBAAkB;UAChB;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACF;MACD,wBAAwB;OACtB;QACE,YAAY;QACZ,UAAU;SACR,QAAQ,EACN,QAAQ,KACT;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACF;OACD;QACE,YAAY;QACZ,UAAU;SACR,SAAS;UACP,QAAQ;UACR,iBAAiB;UAClB;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG,CAAC,KAAK;WACT,GAAG;WACH,GAAG,KAAK;WACT;UACF;SACD,IAAI;SACL;QACF;OACD;QACE,YAAY;QACZ,UAAU;SACR,QAAQ,EACN,QAAQ,KACT;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WA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"}
1
+ {"version":3,"file":"NovaClient-CKpbwv53.cjs","names":["MOTION_DELTA_THRESHOLD","tryParseJson","nova: NovaClient","controller: ControllerInstance","motionGroup: MotionGroupPhysical","initialMotionState: MotionGroupStateResponse","motionStateSocket: AutoReconnectingWebsocket","isVirtual: boolean","tcps: RobotTcp[]","motionGroupSpecification: MotionGroupSpecification","safetySetup: SafetySetup","mounting: Mounting | null","initialControllerState: RobotControllerState","controllerStateSocket: AutoReconnectingWebsocket","THREE","motionStream: MotionStreamConnection","opts: JoggerConnectionOpts","tryParseJson","commands: Command[]","isSameCoordinateSystem","Vector3","jointVelocityLimits: number[]","Vector3","tryParseJson","nova: NovaClient","controller: ControllerInstance","motionGroup: MotionGroupPhysical","initialMotionState: MotionGroupStateResponse","motionStateSocket: AutoReconnectingWebsocket","cellId: string","opts: BaseConfiguration & {\n axiosInstance?: AxiosInstance\n mock?: boolean\n }","SystemApi","CellApi","DeviceConfigurationApi","MotionGroupApi","MotionGroupInfosApi","ControllerApi","ProgramApi","ProgramValuesApi","ControllerIOsApi","MotionGroupKinematicApi","MotionApi","CoordinateSystemsApi","ApplicationApi","MotionGroupJoggingApi","VirtualRobotApi","VirtualRobotSetupApi","VirtualRobotModeApi","VirtualRobotBehaviorApi","LibraryProgramMetadataApi","LibraryProgramApi","LibraryRecipeMetadataApi","LibraryRecipeApi","StoreObjectApi","StoreCollisionComponentsApi","StoreCollisionScenesApi","pathToRegexp","AxiosError","availableStorage","parseNovaInstanceUrl","config","loginWithAuth0","AutoReconnectingWebsocket"],"sources":["../src/lib/v1/wandelscriptUtils.ts","../src/lib/v1/motionStateUpdate.ts","../src/lib/v1/ConnectedMotionGroup.ts","../src/lib/v1/JoggerConnection.ts","../src/lib/v1/MotionStreamConnection.ts","../src/lib/v1/NovaCellAPIClient.ts","../src/lib/v1/mock/MockNovaInstance.ts","../src/lib/v1/NovaClient.ts"],"sourcesContent":["import type { Pose } from \"@wandelbots/nova-api/v1\"\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","import type { TcpPose } from \"@wandelbots/nova-api/v1\"\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 // biome-ignore lint/style/noNonNullAssertion: legacy code\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.x - newTcp.orientation.x)\n changedDelta += Math.abs(oldTcp.orientation.y - newTcp.orientation.y)\n changedDelta += Math.abs(oldTcp.orientation.z - newTcp.orientation.z)\n changedDelta += Math.abs(oldTcp.position.x - newTcp.position.x)\n changedDelta += Math.abs(oldTcp.position.y - newTcp.position.y)\n changedDelta += Math.abs(oldTcp.position.z - newTcp.position.z)\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 type {\n ControllerInstance,\n MotionGroupPhysical,\n MotionGroupSpecification,\n MotionGroupStateResponse,\n Mounting,\n RobotControllerState,\n RobotControllerStateOperationModeEnum,\n RobotControllerStateSafetyStateEnum,\n RobotTcp,\n SafetySetup,\n} from \"@wandelbots/nova-api/v1\"\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\"\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: ControllerInstance[],\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?.physical_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 MotionGroupStateResponse\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 // Check if robot is virtual or physical\n const config = await nova.api.controller.getRobotController(\n controller.controller,\n )\n const isVirtual = config.configuration.kind === \"VirtualController\"\n\n // If there's a configured mounting, we need it to show the right\n // position of the robot model\n const mounting = await (async () => {\n try {\n const mounting = await nova.api.motionGroupInfos.getMounting(\n motionGroup.motion_group,\n )\n return mounting\n } catch (err) {\n console.error(\n `Error fetching mounting for ${motionGroup.motion_group}`,\n err,\n )\n return null\n }\n })()\n\n // Open the websocket to monitor controller state for e.g. e-stop\n const controllerStateSocket = nova.openReconnectingWebsocket(\n `/controllers/${controller.controller}/state-stream?response_rate=1000`,\n )\n\n // Wait for the first message to get the initial state\n const firstControllerMessage = await controllerStateSocket.firstMessage()\n const initialControllerState = tryParseJson(firstControllerMessage.data)\n ?.result as RobotControllerState\n\n if (!initialControllerState) {\n throw new Error(\n `Unable to parse initial controller state message ${firstControllerMessage.data}`,\n )\n }\n\n console.log(\n `Connected controller state websocket to controller ${controller.controller}. Initial state:\\n `,\n initialControllerState,\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 // biome-ignore lint/style/noNonNullAssertion: legacy code\n tcps!,\n motionGroupSpecification,\n safetySetup,\n mounting,\n initialControllerState,\n controllerStateSocket,\n )\n }\n\n connectedJoggingCartesianSocket: WebSocket | null = null\n connectedJoggingJointsSocket: WebSocket | null = null\n // biome-ignore lint/suspicious/noExplicitAny: legacy code\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: MotionGroupStateResponse\n\n // Response rate on the websocket should be a bit slower on this one since\n // we don't use the motion data\n controllerState: RobotControllerState\n\n /**\n * Reflects activation state of the motion group / robot servos. The\n * movement controls in the UI should only be enabled in the \"active\" state\n */\n activationState: \"inactive\" | \"activating\" | \"deactivating\" | \"active\" =\n \"inactive\"\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: ControllerInstance,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupStateResponse,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n readonly isVirtual: boolean,\n readonly tcps: RobotTcp[],\n readonly motionGroupSpecification: MotionGroupSpecification,\n readonly safetySetup: SafetySetup,\n readonly mounting: Mounting | null,\n readonly initialControllerState: RobotControllerState,\n readonly controllerStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n this.controllerState = initialControllerState\n\n // Track controller state updates (e.g. safety state and operation mode)\n controllerStateSocket.addEventListener(\"message\", (event) => {\n const data = tryParseJson(event.data)?.result\n\n if (!data) {\n return\n }\n\n runInAction(() => {\n this.controllerState = data\n })\n })\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupStateResponse\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.state.joint_position.joints,\n motionStateResponse.state.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.state = motionStateResponse.state\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.state.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 /** Gets the robot mounting position offset in 3D viz coordinates */\n get mountingPosition(): [number, number, number] {\n if (!this.mounting) {\n return [0, 0, 0]\n }\n\n return [\n this.mounting.pose.position.x / 1000,\n this.mounting.pose.position.y / 1000,\n this.mounting.pose.position.z / 1000,\n ]\n }\n\n /** Gets the robot mounting position rotation in 3D viz coordinates */\n get mountingQuaternion() {\n const rotationVector = new THREE.Vector3(\n this.mounting?.pose.orientation?.x || 0,\n this.mounting?.pose.orientation?.y || 0,\n this.mounting?.pose.orientation?.z || 0,\n )\n\n const magnitude = rotationVector.length()\n const axis = rotationVector.normalize()\n\n return new THREE.Quaternion().setFromAxisAngle(axis, magnitude)\n }\n\n /**\n * Whether the controller is currently in a safety state\n * corresponding to an emergency stop\n */\n get isEstopActive() {\n const estopStates: RobotControllerStateSafetyStateEnum[] = [\n \"SAFETY_STATE_ROBOT_EMERGENCY_STOP\",\n \"SAFETY_STATE_DEVICE_EMERGENCY_STOP\",\n ]\n\n return estopStates.includes(this.controllerState.safety_state)\n }\n\n /**\n * Whether the controller is in a safety state\n * that may be non-functional for robot pad purposes\n */\n get isMoveableSafetyState() {\n const goodSafetyStates: RobotControllerStateSafetyStateEnum[] = [\n \"SAFETY_STATE_NORMAL\",\n \"SAFETY_STATE_REDUCED\",\n ]\n\n return goodSafetyStates.includes(this.controllerState.safety_state)\n }\n\n /**\n * Whether the controller is in an operation mode that allows movement\n */\n get isMoveableOperationMode() {\n const goodOperationModes: RobotControllerStateOperationModeEnum[] = [\n \"OPERATION_MODE_AUTO\",\n \"OPERATION_MODE_MANUAL\",\n \"OPERATION_MODE_MANUAL_T1\",\n \"OPERATION_MODE_MANUAL_T2\",\n ]\n\n return goodOperationModes.includes(this.controllerState.operation_mode)\n }\n\n /**\n * Whether the robot is currently active and can be moved, based on the\n * safety state, operation mode and servo toggle activation state.\n */\n get canBeMoved() {\n return (\n this.isMoveableSafetyState &&\n this.isMoveableOperationMode &&\n this.activationState === \"active\"\n )\n }\n\n async deactivate() {\n if (this.activationState !== \"active\") {\n console.error(\"Tried to deactivate while already deactivating\")\n return\n }\n\n runInAction(() => {\n this.activationState = \"deactivating\"\n })\n\n try {\n await this.nova.api.controller.setDefaultMode(\n this.controllerId,\n \"MODE_MONITOR\",\n )\n\n runInAction(() => {\n this.activationState = \"inactive\"\n })\n } catch (err) {\n runInAction(() => {\n this.activationState = \"active\"\n })\n throw err\n }\n }\n\n async activate() {\n if (this.activationState !== \"inactive\") {\n console.error(\"Tried to activate while already activating\")\n return\n }\n\n runInAction(() => {\n this.activationState = \"activating\"\n })\n\n try {\n await this.nova.api.controller.setDefaultMode(\n this.controllerId,\n \"MODE_CONTROL\",\n )\n\n runInAction(() => {\n this.activationState = \"active\"\n })\n } catch (err) {\n runInAction(() => {\n this.activationState = \"inactive\"\n })\n throw err\n }\n }\n\n toggleActivation() {\n if (this.activationState === \"inactive\") {\n this.activate()\n } else if (this.activationState === \"active\") {\n this.deactivate()\n }\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 { Command, Joints, TcpPose } from \"@wandelbots/nova-api/v1\"\nimport { Vector3 } from \"three/src/math/Vector3.js\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { isSameCoordinateSystem, tryParseJson } from \"../converters\"\nimport type { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport type { NovaClient } from \"./NovaClient\"\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}\n\nexport class JoggerConnection {\n // Currently a separate websocket is needed for each mode, pester API people\n // to merge these for simplicity\n cartesianWebsocket: AutoReconnectingWebsocket | null = null\n jointWebsocket: AutoReconnectingWebsocket | null = null\n cartesianJoggingOpts: {\n tcpId?: string\n coordSystemId?: string\n } = {}\n\n static async open(\n nova: NovaClient,\n motionGroupId: string,\n opts: JoggerConnectionOpts = {},\n ) {\n const motionStream = await nova.connectMotionStream(motionGroupId)\n\n return new JoggerConnection(motionStream, opts)\n }\n\n constructor(\n readonly motionStream: MotionStreamConnection,\n readonly opts: JoggerConnectionOpts = {},\n ) {}\n\n get motionGroupId() {\n return this.motionStream.motionGroupId\n }\n\n get nova() {\n return this.motionStream.nova\n }\n\n get numJoints() {\n return this.motionStream.joints.length\n }\n\n get activeJoggingMode() {\n if (this.cartesianWebsocket) return \"cartesian\"\n if (this.jointWebsocket) return \"joint\"\n return \"increment\"\n }\n\n get activeWebsocket() {\n return this.cartesianWebsocket || this.jointWebsocket\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\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: { x: 0, y: 0, z: 0 },\n rotation_direction: { x: 0, y: 0, z: 0 },\n position_velocity: 0,\n rotation_velocity: 0,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n if (this.jointWebsocket) {\n this.jointWebsocket.sendJson({\n motion_group: this.motionGroupId,\n joint_velocities: new Array(this.numJoints).fill(0),\n })\n }\n }\n\n dispose() {\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n }\n\n if (this.jointWebsocket) {\n this.jointWebsocket.dispose()\n }\n }\n\n setJoggingMode(\n mode: \"cartesian\" | \"joint\" | \"increment\",\n cartesianJoggingOpts?: {\n tcpId?: string\n coordSystemId?: string\n },\n ) {\n console.log(\"Setting jogging mode to\", mode)\n if (cartesianJoggingOpts) {\n // Websocket needs to be reopened to change options\n if (\n JSON.stringify(this.cartesianJoggingOpts) !==\n JSON.stringify(cartesianJoggingOpts)\n ) {\n if (this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n this.cartesianWebsocket = null\n }\n }\n\n this.cartesianJoggingOpts = cartesianJoggingOpts\n }\n\n if (mode !== \"cartesian\" && this.cartesianWebsocket) {\n this.cartesianWebsocket.dispose()\n this.cartesianWebsocket = null\n }\n\n if (mode !== \"joint\" && this.jointWebsocket) {\n this.jointWebsocket.dispose()\n this.jointWebsocket = null\n }\n\n if (mode === \"cartesian\" && !this.cartesianWebsocket) {\n this.cartesianWebsocket = this.nova.openReconnectingWebsocket(\n `/motion-groups/move-tcp`,\n )\n\n this.cartesianWebsocket.addEventListener(\n \"message\",\n (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\n if (mode === \"joint\" && !this.jointWebsocket) {\n this.jointWebsocket = this.nova.openReconnectingWebsocket(\n `/motion-groups/move-joint`,\n )\n\n this.jointWebsocket.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\n /**\n * Start rotation of a single robot joint at the specified velocity\n */\n async startJointRotation({\n joint,\n direction,\n velocityRadsPerSec,\n }: {\n /** Index of the joint to rotate */\n joint: number\n /** Direction of rotation (\"+\" or \"-\") */\n direction: \"+\" | \"-\"\n /** Speed of the rotation in radians per second */\n velocityRadsPerSec: number\n }) {\n if (!this.jointWebsocket) {\n throw new Error(\n \"Joint jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const jointVelocities = new Array(this.numJoints).fill(0)\n\n jointVelocities[joint] =\n direction === \"-\" ? -velocityRadsPerSec : velocityRadsPerSec\n\n this.jointWebsocket.sendJson({\n motion_group: this.motionGroupId,\n joint_velocities: jointVelocities,\n })\n }\n\n /**\n * Start the TCP moving along a specified axis at a given velocity\n */\n async startTCPTranslation({\n axis,\n direction,\n velocityMmPerSec,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n velocityMmPerSec: number\n }) {\n if (!this.cartesianWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const zeroVector = { x: 0, y: 0, z: 0 }\n const joggingVector = Object.assign({}, zeroVector)\n joggingVector[axis] = direction === \"-\" ? -1 : 1\n\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: joggingVector,\n rotation_direction: zeroVector,\n position_velocity: velocityMmPerSec,\n rotation_velocity: 0,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n /**\n * Start the TCP rotating around a specified axis at a given velocity\n */\n async startTCPRotation({\n axis,\n direction,\n velocityRadsPerSec,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n velocityRadsPerSec: number\n }) {\n if (!this.cartesianWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected; call setJoggingMode first\",\n )\n }\n\n const zeroVector = { x: 0, y: 0, z: 0 }\n const joggingVector = Object.assign({}, zeroVector)\n joggingVector[axis] = direction === \"-\" ? -1 : 1\n\n this.cartesianWebsocket.sendJson({\n motion_group: this.motionGroupId,\n position_direction: zeroVector,\n rotation_direction: joggingVector,\n position_velocity: 0,\n rotation_velocity: velocityRadsPerSec,\n tcp: this.cartesianJoggingOpts.tcpId,\n coordinate_system: this.cartesianJoggingOpts.coordSystemId,\n })\n }\n\n /**\n * Move the robot by a fixed distance in a single cartesian\n * axis, either rotating or translating relative to the TCP.\n * Promise resolves only after the motion has completed.\n */\n async runIncrementalCartesianMotion({\n currentTcpPose,\n currentJoints,\n coordSystemId,\n velocityInRelevantUnits,\n axis,\n direction,\n motion,\n }: {\n currentTcpPose: TcpPose\n currentJoints: Joints\n coordSystemId: string\n velocityInRelevantUnits: number\n axis: \"x\" | \"y\" | \"z\"\n direction: \"-\" | \"+\"\n motion:\n | {\n type: \"rotate\"\n distanceRads: number\n }\n | {\n type: \"translate\"\n distanceMm: number\n }\n }) {\n const commands: Command[] = []\n\n if (\n !isSameCoordinateSystem(currentTcpPose.coordinate_system, coordSystemId)\n ) {\n throw new Error(\n `Current TCP pose coordinate system ${currentTcpPose.coordinate_system} does not match target coordinate system ${coordSystemId}`,\n )\n }\n\n if (motion.type === \"translate\") {\n const targetTcpPosition = Object.assign({}, currentTcpPose.position)\n targetTcpPosition[axis] +=\n motion.distanceMm * (direction === \"-\" ? -1 : 1)\n\n commands.push({\n settings: {\n limits_override: {\n tcp_velocity_limit: velocityInRelevantUnits,\n },\n },\n line: {\n position: targetTcpPosition,\n orientation: currentTcpPose.orientation,\n coordinate_system: coordSystemId,\n },\n })\n } else if (motion.type === \"rotate\") {\n // Concatenate rotations expressed by rotation vectors\n // Equations taken from https://physics.stackexchange.com/a/287819\n\n // Compute axis and angle of current rotation vector\n const currentRotationVector = new Vector3(\n currentTcpPose.orientation.x,\n currentTcpPose.orientation.y,\n currentTcpPose.orientation.z,\n )\n\n const currentRotationRad = currentRotationVector.length()\n const currentRotationDirection = currentRotationVector.clone().normalize()\n\n // Compute axis and angle of difference rotation vector\n const differenceRotationRad =\n motion.distanceRads * (direction === \"-\" ? -1 : 1)\n\n const differenceRotationDirection = new Vector3(0.0, 0.0, 0.0)\n differenceRotationDirection[axis] = 1.0\n\n // Some abbreviations to make the following equations more readable\n const f1 =\n Math.cos(0.5 * differenceRotationRad) *\n Math.cos(0.5 * currentRotationRad)\n const f2 =\n Math.sin(0.5 * differenceRotationRad) *\n Math.sin(0.5 * currentRotationRad)\n const f3 =\n Math.sin(0.5 * differenceRotationRad) *\n Math.cos(0.5 * currentRotationRad)\n const f4 =\n Math.cos(0.5 * differenceRotationRad) *\n Math.sin(0.5 * currentRotationRad)\n\n const dotProduct = differenceRotationDirection.dot(\n currentRotationDirection,\n )\n\n const crossProduct = differenceRotationDirection\n .clone()\n .cross(currentRotationDirection)\n\n // Compute angle of concatenated rotation\n const newRotationRad = 2.0 * Math.acos(f1 - f2 * dotProduct)\n\n // Compute rotation vector of concatenated rotation\n const f5 = newRotationRad / Math.sin(0.5 * newRotationRad)\n\n const targetTcpOrientation = new Vector3()\n .addScaledVector(crossProduct, f2)\n .addScaledVector(differenceRotationDirection, f3)\n .addScaledVector(currentRotationDirection, f4)\n .multiplyScalar(f5)\n\n commands.push({\n settings: {\n limits_override: {\n tcp_orientation_velocity_limit: velocityInRelevantUnits,\n },\n },\n line: {\n position: currentTcpPose.position,\n orientation: targetTcpOrientation,\n coordinate_system: coordSystemId,\n },\n })\n }\n\n const motionPlanRes = await this.nova.api.motion.planMotion({\n motion_group: this.motionGroupId,\n start_joint_position: currentJoints,\n tcp: this.cartesianJoggingOpts.tcpId,\n commands,\n })\n\n const plannedMotion = motionPlanRes.plan_successful_response?.motion\n if (!plannedMotion) {\n throw new Error(\n `Failed to plan jogging increment motion ${JSON.stringify(motionPlanRes)}`,\n )\n }\n\n await this.nova.api.motion.streamMoveForward(\n plannedMotion,\n 100,\n undefined,\n undefined,\n undefined,\n {\n // Might take a while at low velocity\n timeout: 1000 * 60,\n },\n )\n }\n\n /**\n * Rotate a single robot joint by a fixed number of radians\n * Promise resolves only after the motion has completed.\n */\n async runIncrementalJointRotation({\n joint,\n currentJoints,\n velocityRadsPerSec,\n direction,\n distanceRads,\n }: {\n joint: number\n currentJoints: Joints\n velocityRadsPerSec: number\n direction: \"-\" | \"+\"\n distanceRads: number\n }) {\n const targetJoints = [...currentJoints.joints]\n // biome-ignore lint/style/noNonNullAssertion: legacy code\n targetJoints[joint]! += distanceRads * (direction === \"-\" ? -1 : 1)\n\n const jointVelocityLimits: number[] = new Array(\n currentJoints.joints.length,\n ).fill(velocityRadsPerSec)\n\n const motionPlanRes = await this.nova.api.motion.planMotion({\n motion_group: this.motionGroupId,\n start_joint_position: currentJoints,\n commands: [\n {\n settings: {\n limits_override: {\n joint_velocity_limits: {\n joints: jointVelocityLimits,\n },\n },\n },\n joint_ptp: {\n joints: targetJoints,\n },\n },\n ],\n })\n\n const plannedMotion = motionPlanRes.plan_successful_response?.motion\n if (!plannedMotion) {\n console.error(\"Failed to plan jogging increment motion\", motionPlanRes)\n return\n }\n\n await this.nova.api.motion.streamMoveForward(\n plannedMotion,\n 100,\n undefined,\n undefined,\n undefined,\n {\n // Might take a while at low velocity\n timeout: 1000 * 60,\n },\n )\n }\n}\n","/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */\nimport type {\n ControllerInstance,\n MotionGroupPhysical,\n MotionGroupStateResponse,\n Vector3d,\n} from \"@wandelbots/nova-api/v1\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport { Vector3 } from \"three\"\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\nfunction unwrapRotationVector(\n newRotationVectorApi: Vector3d,\n currentRotationVectorApi: Vector3d,\n): Vector3d {\n const currentRotationVector = new Vector3(\n currentRotationVectorApi.x,\n currentRotationVectorApi.y,\n currentRotationVectorApi.z,\n )\n\n const newRotationVector = new Vector3(\n newRotationVectorApi.x,\n newRotationVectorApi.y,\n newRotationVectorApi.z,\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 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 { instances: 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?.physical_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 MotionGroupStateResponse\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: MotionGroupStateResponse\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: ControllerInstance,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupStateResponse,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupStateResponse\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.state.joint_position.joints,\n motionStateResponse.state.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.state = motionStateResponse.state\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 if (this.rapidlyChangingMotionState.tcp_pose == null) {\n this.rapidlyChangingMotionState.tcp_pose =\n motionStateResponse.tcp_pose\n } else {\n this.rapidlyChangingMotionState.tcp_pose = {\n position: motionStateResponse.tcp_pose!.position,\n orientation: unwrapRotationVector(\n motionStateResponse.tcp_pose!.orientation,\n this.rapidlyChangingMotionState.tcp_pose!.orientation,\n ),\n tcp: motionStateResponse.tcp_pose!.tcp,\n coordinate_system:\n motionStateResponse.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.state.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n dispose() {\n this.motionStateSocket.close()\n }\n}\n","/** biome-ignore-all lint/style/noNonNullAssertion: legacy code */\n/** biome-ignore-all lint/suspicious/noExplicitAny: legacy code */\nimport type {\n BaseAPI,\n Configuration as BaseConfiguration,\n} from \"@wandelbots/nova-api/v1\"\nimport {\n ApplicationApi,\n CellApi,\n ControllerApi,\n ControllerIOsApi,\n CoordinateSystemsApi,\n DeviceConfigurationApi,\n LibraryProgramApi,\n LibraryProgramMetadataApi,\n LibraryRecipeApi,\n LibraryRecipeMetadataApi,\n MotionApi,\n MotionGroupApi,\n MotionGroupInfosApi,\n MotionGroupJoggingApi,\n MotionGroupKinematicApi,\n ProgramApi,\n ProgramValuesApi,\n StoreCollisionComponentsApi,\n StoreCollisionScenesApi,\n StoreObjectApi,\n SystemApi,\n VirtualRobotApi,\n VirtualRobotBehaviorApi,\n VirtualRobotModeApi,\n VirtualRobotSetupApi,\n} from \"@wandelbots/nova-api/v1\"\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 deviceConfig = this.withCellId(DeviceConfigurationApi)\n\n readonly motionGroup = this.withCellId(MotionGroupApi)\n readonly motionGroupInfos = this.withCellId(MotionGroupInfosApi)\n\n readonly controller = this.withCellId(ControllerApi)\n\n readonly program = this.withCellId(ProgramApi)\n readonly programValues = this.withCellId(ProgramValuesApi)\n\n readonly controllerIOs = this.withCellId(ControllerIOsApi)\n\n readonly motionGroupKinematic = this.withCellId(MotionGroupKinematicApi)\n readonly motion = this.withCellId(MotionApi)\n\n readonly coordinateSystems = this.withCellId(CoordinateSystemsApi)\n\n readonly application = this.withCellId(ApplicationApi)\n readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)\n\n readonly motionGroupJogging = this.withCellId(MotionGroupJoggingApi)\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 libraryProgramMetadata = this.withCellId(LibraryProgramMetadataApi)\n readonly libraryProgram = this.withCellId(LibraryProgramApi)\n readonly libraryRecipeMetadata = this.withCellId(LibraryRecipeMetadataApi)\n readonly libraryRecipe = this.withCellId(LibraryRecipeApi)\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 {\n ControllerInstanceList,\n MotionGroupSpecification,\n MotionGroupStateResponse,\n RobotController,\n SafetySetup,\n} from \"@wandelbots/nova-api/v1\"\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 * 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 instances: [\n {\n controller: \"mock-ur5e\",\n model_name: \"UniversalRobots::Controller\",\n host: \"mock-ur5e\",\n allow_software_install_on_controller: true,\n physical_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 ControllerInstanceList\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 {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: -800,\n y: -1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: -1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: 1500,\n },\n {\n x: -800,\n y: 1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n x: 1650,\n y: 1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: 1500,\n },\n {\n x: 1650,\n y: -1330,\n z: -1820,\n },\n {\n x: 1650,\n y: 1330,\n z: -1820,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\n },\n id: \"box\",\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: 1330,\n z: -1850,\n },\n {\n x: 865,\n y: 1330,\n z: -1850,\n },\n {\n x: 865,\n y: -720,\n z: -1850,\n },\n {\n x: 1650,\n y: -720,\n z: -1850,\n },\n {\n x: 1650,\n y: 1330,\n z: -920,\n },\n {\n x: 865,\n y: 1330,\n z: -920,\n },\n {\n x: 865,\n y: -720,\n z: -920,\n },\n {\n x: 1650,\n y: -720,\n z: -920,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: 1330,\n z: -600,\n },\n {\n x: 865,\n y: 1330,\n z: -600,\n },\n {\n x: 865,\n y: 430,\n z: -600,\n },\n {\n x: 1650,\n y: 430,\n z: -600,\n },\n {\n x: 1650,\n y: 1330,\n z: -1250,\n },\n {\n x: 865,\n y: 1330,\n z: -1250,\n },\n {\n x: 865,\n y: 430,\n z: -1250,\n },\n {\n x: 1650,\n y: 430,\n z: -1250,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: 1650,\n y: -760,\n z: -440,\n },\n {\n x: 900,\n y: -760,\n z: -440,\n },\n {\n x: 900,\n y: -1330,\n z: -440,\n },\n {\n x: 1650,\n y: -1330,\n z: -440,\n },\n {\n x: 1650,\n y: -760,\n z: -1800,\n },\n {\n x: 900,\n y: -760,\n z: -1800,\n },\n {\n x: 900,\n y: -1330,\n z: -1800,\n },\n {\n x: 1650,\n y: -1330,\n z: -1800,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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 x: -200,\n y: -200,\n z: -1900,\n },\n {\n x: 200,\n y: -200,\n z: -1900,\n },\n {\n x: 200,\n y: 200,\n z: -1900,\n },\n {\n x: -200,\n y: 200,\n z: -1900,\n },\n {\n x: -200,\n y: -200,\n z: -350,\n },\n {\n x: 200,\n y: -200,\n z: -350,\n },\n {\n x: 200,\n y: 200,\n z: -350,\n },\n {\n x: -200,\n y: 200,\n z: -350,\n },\n ],\n },\n init_pose: {\n position: {\n x: 0,\n y: 0,\n z: 0,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: -70,\n y: -70,\n z: -50,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: -450,\n y: 40,\n z: 170,\n },\n orientation: {\n x: 0,\n y: -Math.SQRT1_2,\n z: 0,\n w: Math.SQRT1_2,\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: {\n x: -110,\n y: 10,\n z: -100,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: 0,\n y: 300,\n z: 40,\n },\n orientation: {\n x: -Math.SQRT1_2,\n y: 0,\n z: 0,\n w: Math.SQRT1_2,\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: {\n x: 0,\n y: 0,\n z: -50,\n },\n orientation: {\n x: 0,\n y: 0,\n z: 0,\n w: 1,\n },\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: {\n x: 0,\n y: 0,\n z: 0,\n },\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: {\n x: 0,\n y: 0,\n z: 0,\n },\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: {\n x: -200,\n y: 300,\n z: 150,\n },\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 x: 6.437331889439328,\n y: -628.4123774830913,\n z: 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 x: 6.437331889439328,\n y: -628.4123774830913,\n z: 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 x: -2.763015284002938,\n y: -630.2151479701106,\n z: 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 x: -2.763015284002938,\n y: -630.2151479701106,\n z: 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 state: {\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: {\n x: 1.3300010259703043,\n y: -409.2680714682808,\n z: 531.0203477065281,\n },\n orientation: {\n x: 1.7564919306270736,\n y: -1.7542521568325058,\n z: 0.7326972590614671,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: {\n x: 1.3300010259703043,\n y: -409.2680714682808,\n z: 531.0203477065281,\n },\n orientation: {\n x: 1.7564919306270736,\n y: -1.7542521568325058,\n z: 0.7326972590614671,\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: [false, false, false, false, false, false],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"1\",\n },\n tcp_pose: {\n position: {\n x: 302.90748476115556,\n y: -152.87065869452337,\n z: 424.0454619321661,\n },\n orientation: {\n x: 2.3403056115045353,\n y: -1.1706836379431356,\n z: 0.9772511964246311,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n } satisfies MotionGroupStateResponse,\n}\n","/**\n * @fileoverview\n * @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.\n */\n\nimport type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v1\"\nimport type { AxiosRequestConfig } from \"axios\"\nimport axios, { isAxiosError } from \"axios\"\nimport urlJoin from \"url-join\"\nimport { loginWithAuth0 } from \"../../LoginWithAuth0.js\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket.js\"\nimport { availableStorage } from \"../availableStorage.js\"\nimport { parseNovaInstanceUrl } from \"../converters.js\"\nimport { ConnectedMotionGroup } from \"./ConnectedMotionGroup.js\"\nimport { JoggerConnection } from \"./JoggerConnection.js\"\nimport { MotionStreamConnection } from \"./MotionStreamConnection.js\"\nimport { NovaCellAPIClient } from \"./NovaCellAPIClient.js\"\nimport { MockNovaInstance } from \"./mock/MockNovaInstance.js\"\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 * Client for connecting to a Nova instance and controlling robots.\n * @deprecated The nova v1 client is deprecated. Please use the v2 client from `@wandelbots/nova-js/v2` instead.\n */\nexport class NovaClient {\n readonly api: NovaCellAPIClient\n readonly config: NovaClientConfigWithDefaults\n readonly mock?: MockNovaInstance\n readonly instanceUrl: URL\n authPromise: Promise<string | null> | null = null\n accessToken: string | null = null\n\n constructor(config: NovaClientConfig) {\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 this.instanceUrl = parseNovaInstanceUrl(this.config.instanceUrl)\n\n // Set up Axios instance with interceptor for token fetching\n const axiosInstance = axios.create({\n baseURL: urlJoin(this.config.instanceUrl, \"/api/v1\"),\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.instanceUrl.href, \"/api/v1\"),\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n baseOptions: {\n ...(this.mock\n ? ({\n adapter: (config) => {\n // biome-ignore lint/style/noNonNullAssertion: legacy code\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 const storedToken = availableStorage.getString(\"wbjs.access_token\")\n if (storedToken && this.accessToken !== storedToken) {\n // Might be newer than the one we have\n this.accessToken = storedToken\n return\n }\n\n // Otherwise, perform login flow\n this.authPromise = loginWithAuth0(this.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.instanceUrl.href,\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 /**\n * Connect to the jogging websocket(s) for a given motion group\n */\n async connectJogger(motionGroupId: string) {\n return await JoggerConnection.open(this, motionGroupId)\n }\n\n async connectMotionGroups(\n motionGroupIds: string[],\n ): Promise<ConnectedMotionGroup[]> {\n const { instances } = await this.api.controller.listControllers()\n\n return Promise.all(\n motionGroupIds.map((motionGroupId) =>\n ConnectedMotionGroup.connect(this, motionGroupId, instances),\n ),\n )\n }\n\n async connectMotionGroup(\n motionGroupId: string,\n ): Promise<ConnectedMotionGroup> {\n const motionGroups = await this.connectMotionGroups([motionGroupId])\n // biome-ignore lint/style/noNonNullAssertion: legacy code\n return motionGroups[0]!\n }\n}\n"],"mappings":"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D;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACD;QACE,OAAO;QACP,OAAO;QACP,GAAG;QACH,GAAG;QACH,4BAA4B;QAC7B;OACF;MACD,yBAAyB;OACvB;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACD;QACE,OAAO;QACP,aAAa;QACb,aAAa;QACb,WAAW;QACZ;OACF;MACF;;IAEJ;GACD;IACE,QAAQ;IACR,MAAM;IACN,SAAS;AACP,YAAO;MACL,iBAAiB,CACf;OACE,cAAc;OACd,UAAU;QACR,uBAAuB;SACrB;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACD;UACE,OAAO;UACP,aAAa;UACb,aAAa;UACb,WAAW;UACZ;SACF;QACD,uBAAuB;SACrB;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACD;UACE,OAAO;UACP,OAAO;UACR;SACF;QACD,2BAA2B,EAAE;QAC7B,qBAAqB,EAAE;QACvB,oBAAoB;QACrB;OACF,CACF;MACD,cAAc;OACZ;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,UAAU,EACR,kBAAkB;UAChB;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACD;WACE,aAAa,EACX,UAAU;YACR;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD;aACE,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF,EACF;WACD,WAAW;YACT,UAAU;aACR,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACD,aAAa;aACX,GAAG;aACH,GAAG;aACH,GAAG;aACH,GAAG;aACJ;YACF;WACD,IAAI;WACL;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACD;QACE,IAAI;QACJ,UAAU;QACV,UAAU;SACR,aAAa,EACX,UAAU;UACR;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD;WACE,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF,EACF;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACD,kBAAkB;QACnB;OACF;MACD,wBAAwB;OACtB;QACE,YAAY;QACZ,UAAU;SACR,QAAQ,EACN,QAAQ,KACT;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACF;SACD,IAAI;SACL;QACF;OACD;QACE,YAAY;QACZ,UAAU;SACR,SAAS;UACP,QAAQ;UACR,iBAAiB;UAClB;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG,CAAC,KAAK;WACT,GAAG;WACH,GAAG,KAAK;WACT;UACF;SACD,IAAI;SACL;QACF;OACD;QACE,YAAY;QACZ,UAAU;SACR,QAAQ,EACN,QAAQ,KACT;SACD,WAAW;UACT,UAAU;WACR,GAAG;WACH,GAAG;WACH,GAAG;WACJ;UACD,aAAa;WACX,GAAG;WACH,GAAG;WACH,GAAG;WACH,GAAG;WA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"}