@wandelbots/nova-js 2.1.1 → 2.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/v2/index.ts","../../../src/lib/v2/ConnectedMotionGroup.ts","../../../src/lib/converters.ts","../../../src/lib/v2/motionStateUpdate.ts","../../../src/lib/v2/vectorUtils.ts","../../../src/lib/v2/JoggerConnection.ts","../../../src/lib/v2/MotionStreamConnection.ts","../../../src/lib/v2/NovaCellAPIClient.ts","../../../src/lib/v2/NovaClient.ts","../../../src/LoginWithAuth0.ts","../../../src/lib/AutoReconnectingWebsocket.ts","../../../src/lib/availableStorage.ts","../../../src/lib/v2/mock/MockNovaInstance.ts","../../../src/lib/v2/ProgramStateConnection.ts"],"sourcesContent":["export * from \"@wandelbots/nova-api/v2\"\nexport * from \"./ConnectedMotionGroup\"\nexport * from \"./JoggerConnection\"\nexport * from \"./MotionStreamConnection\"\nexport * from \"./NovaCellAPIClient\"\nexport * from \"./NovaClient\"\nexport * from \"./ProgramStateConnection\"\n","import type {\n Controller,\n MotionGroupPhysical,\n MotionGroupSpecification,\n MotionGroupState,\n RobotTcp,\n SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nexport type MotionGroupOption = {\n selectionId: string\n} & MotionGroupPhysical\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class ConnectedMotionGroup {\n static async connect(\n nova: NovaClient,\n motionGroupId: string,\n controllers: Controller[],\n ) {\n const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n string,\n string,\n ]\n const controller = controllers.find((c) => c.controller === controllerId)\n const motionGroup = controller?.motion_groups.find(\n (mg) => mg.motion_group === motionGroupId,\n )\n if (!controller || !motionGroup) {\n throw new Error(\n `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n )\n }\n\n const motionStateSocket = nova.openReconnectingWebsocket(\n `/motion-groups/${motionGroupId}/state-stream`,\n )\n\n // Wait for the first message to get the initial state\n const firstMessage = await motionStateSocket.firstMessage()\n const initialMotionState = tryParseJson(firstMessage.data)\n ?.result as MotionGroupState\n\n if (!initialMotionState) {\n throw new Error(\n `Unable to parse initial motion state message ${firstMessage.data}`,\n )\n }\n\n console.log(\n `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n `,\n initialMotionState,\n )\n\n // This is used to determine if the robot is virtual or physical\n let isVirtual = false\n try {\n const opMode =\n await nova.api.virtualRobotMode.getOperationMode(controllerId)\n\n if (opMode) isVirtual = true\n } catch (err) {\n if (err instanceof AxiosError) {\n console.log(\n `Received ${err.status} from getOperationMode, concluding that ${controllerId} is physical`,\n )\n } else {\n throw err\n }\n }\n\n // Find out what TCPs this motion group has (we need it for jogging)\n const { tcps } = await nova.api.motionGroupInfos.listTcps(motionGroupId)\n\n const motionGroupSpecification =\n await nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId)\n\n const safetySetup =\n await nova.api.motionGroupInfos.getSafetySetup(motionGroupId)\n\n return new ConnectedMotionGroup(\n nova,\n controller,\n motionGroup,\n initialMotionState,\n motionStateSocket,\n isVirtual,\n tcps!,\n motionGroupSpecification,\n safetySetup,\n )\n }\n\n connectedJoggingCartesianSocket: WebSocket | null = null\n connectedJoggingJointsSocket: WebSocket | null = null\n planData: any | null // tmp\n joggingVelocity: number = 10\n\n // Not mobx-observable as this changes very fast; should be observed\n // using animation frames\n rapidlyChangingMotionState: MotionGroupState\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: Controller,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupState,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n readonly isVirtual: boolean,\n readonly tcps: RobotTcp[],\n readonly motionGroupSpecification: MotionGroupSpecification,\n readonly safetySetup: SafetySetup,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupState\n | undefined\n\n if (!motionStateResponse) {\n throw new Error(\n `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n )\n }\n\n // handle motionState message\n if (\n !jointValuesEqual(\n this.rapidlyChangingMotionState.joint_position.joints,\n motionStateResponse.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState = motionStateResponse\n })\n }\n\n // handle tcpPose message\n if (\n !tcpPoseEqual(\n this.rapidlyChangingMotionState.tcp_pose,\n motionStateResponse.tcp_pose,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.tcp_pose =\n motionStateResponse.tcp_pose\n })\n }\n })\n makeAutoObservable(this)\n }\n\n get motionGroupId() {\n return this.motionGroup.motion_group\n }\n\n get controllerId() {\n return this.controller.controller\n }\n\n get modelFromController() {\n return this.motionGroup.model_from_controller\n }\n\n get wandelscriptIdentifier() {\n const num = this.motionGroupId.split(\"@\")[0]\n return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n }\n\n /** Jogging velocity in radians for rotation and joint movement */\n get joggingVelocityRads() {\n return (this.joggingVelocity * Math.PI) / 180\n }\n\n get joints() {\n return this.initialMotionState.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n get dhParameters() {\n return this.motionGroupSpecification.dh_parameters\n }\n\n get safetyZones() {\n return this.safetySetup.safety_zones\n }\n\n dispose() {\n this.motionStateSocket.close()\n if (this.connectedJoggingCartesianSocket)\n this.connectedJoggingCartesianSocket.close()\n if (this.connectedJoggingJointsSocket)\n this.connectedJoggingJointsSocket.close()\n }\n\n setJoggingVelocity(velocity: number) {\n this.joggingVelocity = velocity\n }\n}\n","import type { Pose } from \"@wandelbots/nova-api/v1\"\n\n/** Try to parse something as JSON; return undefined if we can't */\nexport function tryParseJson(json: unknown): any {\n try {\n return JSON.parse(json as string)\n } catch {\n return undefined\n }\n}\n\n/** Try to turn something into JSON; return undefined if we can't */\nexport function tryStringifyJson(json: unknown): string | undefined {\n try {\n return JSON.stringify(json)\n } catch {\n return undefined\n }\n}\n\n/**\n * Converts object parameters to query string.\n * e.g. { a: \"1\", b: \"2\" } => \"?a=1&b=2\"\n * {} => \"\"\n */\nexport function makeUrlQueryString(obj: Record<string, string>): string {\n const str = new URLSearchParams(obj).toString()\n return str ? `?${str}` : \"\"\n}\n\n/** Convert radians to degrees */\nexport function radiansToDegrees(radians: number): number {\n return radians * (180 / Math.PI)\n}\n\n/** Convert degrees to radians */\nexport function degreesToRadians(degrees: number): number {\n return degrees * (Math.PI / 180)\n}\n\n/**\n * Convert a Pose object representing a motion group position\n * into a string which represents that pose in Wandelscript.\n */\nexport function poseToWandelscriptString(\n pose: Pick<Pose, \"position\" | \"orientation\">,\n) {\n const position = [pose.position.x, pose.position.y, pose.position.z]\n const orientation = [\n pose.orientation?.x ?? 0,\n pose.orientation?.y ?? 0,\n pose.orientation?.z ?? 0,\n ]\n\n const positionValues = position.map((v) => v.toFixed(1))\n // Rotation needs more precision since it's in radians\n const rotationValues = orientation.map((v) => v.toFixed(4))\n\n return `(${positionValues.concat(rotationValues).join(\", \")})`\n}\n\n/**\n * Check for coordinate system id equivalence, accounting for the \"world\" default\n * on empty/undefined values.\n */\nexport function isSameCoordinateSystem(\n firstCoordSystem: string | undefined,\n secondCoordSystem: string | undefined,\n) {\n if (!firstCoordSystem) firstCoordSystem = \"world\"\n if (!secondCoordSystem) secondCoordSystem = \"world\"\n\n return firstCoordSystem === secondCoordSystem\n}\n","import type { TcpPose } from \"@wandelbots/nova-api/v2\"\n\nexport function jointValuesEqual(\n oldJointValues: number[],\n newJointValues: number[],\n changeDeltaThreshold: number,\n): boolean {\n if (newJointValues.length !== oldJointValues.length) {\n return true\n }\n\n for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {\n if (\n Math.abs(newJointValues[jointIndex]! - oldJointValues[jointIndex]!) >\n changeDeltaThreshold\n ) {\n return false\n }\n }\n\n return true\n}\n\nexport function tcpPoseEqual(\n oldTcp: TcpPose | undefined,\n newTcp: TcpPose | undefined,\n changeDeltaThreshold: number,\n): boolean {\n // undefined -> defined (+reverse) transition\n if ((oldTcp === undefined && newTcp) || (oldTcp && newTcp === undefined)) {\n return false\n }\n\n // the typechecker cannot resolve states to \"!= undefined\" if \"&&\" is used\n if (oldTcp === undefined || newTcp === undefined) {\n return true\n }\n\n let changedDelta = 0\n changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0])\n changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1])\n changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2])\n changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0])\n changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1])\n changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2])\n\n if (changedDelta > changeDeltaThreshold) {\n return false\n }\n\n return (\n oldTcp.coordinate_system === newTcp.coordinate_system &&\n oldTcp.tcp === newTcp.tcp\n )\n}\n","import * as THREE from \"three\"\n\n// Vector used by api endpoints\nexport type Vector3d = [number, number, number]\n\nexport function axisToIndex(axis: \"x\" | \"y\" | \"z\"): number {\n switch (axis) {\n case \"x\":\n return 0\n case \"y\":\n return 1\n case \"z\":\n return 2\n }\n}\n\nexport function indexToAxis(index: number): \"x\" | \"y\" | \"z\" | null {\n switch (index) {\n case 0:\n return \"x\"\n case 1:\n return \"y\"\n case 2:\n return \"z\"\n default:\n return null\n }\n}\n\nexport function vector3FromArray(vector: Vector3d): THREE.Vector3 {\n return new THREE.Vector3(vector[0], vector[1], vector[2])\n}\n\nexport function vector3ToArray(vector: THREE.Vector3): Vector3d {\n return [vector.x, vector.y, vector.z]\n}\n","import type {\n InitializeJoggingRequest,\n JoggingResponse,\n JointVelocityRequest,\n MotionGroupState,\n TcpVelocityRequest,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { axisToIndex } from \"./vectorUtils\"\n\nexport type JoggerConnectionOpts = {\n /**\n * When an error message is received from the jogging websocket, it\n * will be passed here. If this handler is not provided, the error will\n * instead be thrown as an unhandled error.\n */\n onError?: (err: unknown) => void\n} & Omit<InitializeJoggingRequest, \"message_type\">\n\nexport class JoggerConnection {\n // Currently a separate websocket is needed for each mode, pester API people\n // to merge these for simplicity\n joggingWebsocket: AutoReconnectingWebsocket | null = null\n lastVelocityRequest: JointVelocityRequest | TcpVelocityRequest | null = null\n lastResponse: JoggingResponse | null = null\n\n static async open(\n nova: NovaClient,\n cell: string,\n motionGroupId: string,\n opts: JoggerConnectionOpts,\n ) {\n const motionGroupState =\n await nova.api.motionGroupInfos.getCurrentMotionGroupState(motionGroupId)\n\n return new JoggerConnection(\n nova,\n cell,\n motionGroupId,\n motionGroupState,\n opts,\n )\n }\n\n constructor(\n readonly nova: NovaClient,\n readonly cell: string,\n readonly motionGroupId: string,\n readonly motionGroupState: MotionGroupState,\n readonly opts: JoggerConnectionOpts,\n ) {\n this.joggingWebsocket = nova.openReconnectingWebsocket(\n `/cells/${cell}/execution/jogging`,\n )\n this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n const data = tryParseJson(ev.data) as JoggingResponse\n if (data && \"error\" in data) {\n if (this.opts.onError) {\n this.opts.onError(ev.data)\n } else {\n throw new Error(ev.data)\n }\n }\n })\n\n this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n const data = tryParseJson(ev.data)\n if (data && \"error\" in data) {\n if (this.opts.onError) {\n this.opts.onError(ev.data)\n } else {\n throw new Error(ev.data)\n }\n }\n })\n }\n\n get jointCount() {\n return this.motionGroupState.joint_current?.joints.length\n }\n\n get activeWebsocket() {\n return this.joggingWebsocket\n }\n\n async stop() {\n // Why not call the stopJogging API endpoint?\n // Because this results in the websocket closing and we\n // would like to keep it open for now.\n if (!this.joggingWebsocket) {\n return\n }\n\n if (this.lastVelocityRequest?.message_type === \"JointVelocityRequest\") {\n this.joggingWebsocket.sendJson({\n message_type: \"JointVelocityRequest\",\n velocity: {\n joints: Array.from(new Array(this.jointCount).keys()).map(() => 0),\n },\n } as JointVelocityRequest)\n }\n\n if (this.lastVelocityRequest?.message_type === \"TcpVelocityRequest\") {\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n rotation: [0, 0, 0],\n translation: [0, 0, 0],\n } as TcpVelocityRequest)\n }\n }\n\n dispose() {\n if (this.joggingWebsocket) {\n this.joggingWebsocket.dispose()\n }\n }\n\n /**\n * Start rotation of a single robot joint at the specified velocity\n */\n async startJointRotation({\n joint,\n velocityRadsPerSec,\n }: {\n /** Index of the joint to rotate */\n joint: number\n /** Speed of the rotation in radians per second */\n velocityRadsPerSec: number\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Joint jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const jointVelocities = new Array(this.jointCount).fill(0)\n jointVelocities[joint] = velocityRadsPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"JointVelocityRequest\",\n velocity: {\n joints: jointVelocities,\n },\n } as JointVelocityRequest)\n }\n\n /**\n * Start the TCP moving along a specified axis at a given velocity\n */\n async startTCPTranslation({\n axis,\n velocityMmPerSec,\n useToolCoordinateSystem,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n velocityMmPerSec: number\n useToolCoordinateSystem: boolean\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const joggingVector = [0, 0, 0]\n joggingVector[axisToIndex(axis)] = velocityMmPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n\n translation: joggingVector,\n rotation: [0, 0, 0],\n use_tool_coordinate_system: useToolCoordinateSystem,\n } as TcpVelocityRequest)\n }\n\n /**\n * Start the TCP rotating around a specified axis at a given velocity\n */\n async startTCPRotation({\n axis,\n velocityRadsPerSec,\n useToolCoordinateSystem,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n velocityRadsPerSec: number\n useToolCoordinateSystem: boolean\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const joggingVector = [0, 0, 0]\n joggingVector[axisToIndex(axis)] = velocityRadsPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n rotation: joggingVector,\n translation: [0, 0, 0],\n use_tool_coordinate_system: useToolCoordinateSystem,\n } as TcpVelocityRequest)\n }\n}\n","import type {\n Controller,\n MotionGroupPhysical,\n MotionGroupState,\n} from \"@wandelbots/nova-api/v2\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport * as THREE from \"three\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { Vector3d, vector3ToArray } from \"./vectorUtils\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nfunction unwrapRotationVector(\n newRotationVectorApi: Vector3d,\n currentRotationVectorApi: Vector3d,\n): Vector3d {\n const currentRotationVector = new THREE.Vector3(\n currentRotationVectorApi[0],\n currentRotationVectorApi[1],\n currentRotationVectorApi[2],\n )\n\n const newRotationVector = new THREE.Vector3(\n newRotationVectorApi[0],\n newRotationVectorApi[1],\n newRotationVectorApi[2],\n )\n\n const currentAngle = currentRotationVector.length()\n const currentAxis = currentRotationVector.normalize()\n\n let newAngle = newRotationVector.length()\n let newAxis = newRotationVector.normalize()\n\n // Align rotation axes\n if (newAxis.dot(currentAxis) < 0) {\n newAngle = -newAngle\n newAxis = newAxis.multiplyScalar(-1.0)\n }\n\n // Shift rotation angle close to previous one to extend domain of rotation angles beyond [0, pi]\n // - this simplifies interpolation and prevents abruptly changing signs of the rotation angles\n let angleDifference = newAngle - currentAngle\n angleDifference -=\n 2.0 * Math.PI * Math.floor((angleDifference + Math.PI) / (2.0 * Math.PI))\n\n newAngle = currentAngle + angleDifference\n\n return vector3ToArray(newAxis.multiplyScalar(newAngle))\n}\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class MotionStreamConnection {\n static async open(nova: NovaClient, motionGroupId: string) {\n const { controllers: controllers } =\n await nova.api.controller.listControllers()\n\n const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n string,\n string,\n ]\n const controller = controllers.find((c) => c.controller === controllerId)\n const motionGroup = controller?.motion_groups.find(\n (mg) => mg.motion_group === motionGroupId,\n )\n if (!controller || !motionGroup) {\n throw new Error(\n `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n )\n }\n\n const motionStateSocket = nova.openReconnectingWebsocket(\n `/motion-groups/${motionGroupId}/state-stream`,\n )\n\n // Wait for the first message to get the initial state\n const firstMessage = await motionStateSocket.firstMessage()\n console.log(\"got first message\", firstMessage)\n const initialMotionState = tryParseJson(firstMessage.data)\n ?.result as MotionGroupState\n\n if (!initialMotionState) {\n throw new Error(\n `Unable to parse initial motion state message ${firstMessage.data}`,\n )\n }\n\n console.log(\n `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n `,\n initialMotionState,\n )\n\n return new MotionStreamConnection(\n nova,\n controller,\n motionGroup,\n initialMotionState,\n motionStateSocket,\n )\n }\n\n // Not mobx-observable as this changes very fast; should be observed\n // using animation frames\n rapidlyChangingMotionState: MotionGroupState\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: Controller,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupState,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionState = tryParseJson(event.data)?.result as\n | MotionGroupState\n | undefined\n\n if (!motionState) {\n throw new Error(\n `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n )\n }\n\n // handle motionState message\n if (\n !jointValuesEqual(\n this.rapidlyChangingMotionState.joint_position.joints,\n motionState.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState = motionState\n })\n }\n\n // handle tcpPose message\n if (\n !tcpPoseEqual(\n this.rapidlyChangingMotionState.tcp_pose,\n motionState.tcp_pose,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n if (this.rapidlyChangingMotionState.tcp_pose == undefined) {\n this.rapidlyChangingMotionState.tcp_pose = motionState.tcp_pose\n } else {\n this.rapidlyChangingMotionState.tcp_pose = {\n position: motionState.tcp_pose!.position,\n orientation: unwrapRotationVector(\n motionState.tcp_pose!.orientation as Vector3d,\n this.rapidlyChangingMotionState.tcp_pose!\n .orientation as Vector3d,\n ),\n tcp: motionState.tcp_pose!.tcp,\n coordinate_system: motionState.tcp_pose!.coordinate_system,\n }\n }\n })\n }\n })\n makeAutoObservable(this)\n }\n\n get motionGroupId() {\n return this.motionGroup.motion_group\n }\n\n get controllerId() {\n return this.controller.controller\n }\n\n get modelFromController() {\n return this.motionGroup.model_from_controller\n }\n\n get wandelscriptIdentifier() {\n const num = this.motionGroupId.split(\"@\")[0]\n return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n }\n\n get joints() {\n return this.initialMotionState.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n dispose() {\n this.motionStateSocket.close()\n }\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport {\n ApplicationApi,\n CellApi,\n ControllerApi,\n ControllerInputsOutputsApi,\n CoordinateSystemsApi,\n JoggingApi,\n MotionGroupApi,\n MotionGroupInfoApi,\n MotionGroupKinematicsApi,\n ProgramApi,\n ProgramOperatorApi,\n StoreCollisionComponentsApi,\n StoreCollisionScenesApi,\n StoreObjectApi,\n SystemApi,\n TrajectoryExecutionApi,\n TrajectoryPlanningApi,\n VirtualRobotApi,\n VirtualRobotBehaviorApi,\n VirtualRobotModeApi,\n VirtualRobotSetupApi,\n} from \"@wandelbots/nova-api/v2\"\nimport type { BaseAPI } from \"@wandelbots/nova-api/v2/base\"\nimport type { AxiosInstance } from \"axios\"\nimport axios from \"axios\"\n\ntype OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R\n ? (...args: P) => R\n : never\n\ntype UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any\n ? (\n ...a: Parameters<T>\n ) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never>\n : never\n\nexport type WithCellId<T> = {\n [P in keyof T]: UnwrapAxiosResponseReturn<OmitFirstArg<T[P]>>\n}\n\nexport type WithUnwrappedAxiosResponse<T> = {\n [P in keyof T]: UnwrapAxiosResponseReturn<T[P]>\n}\n\n/**\n * API client providing type-safe access to all the Nova API REST endpoints\n * associated with a specific cell id.\n */\nexport class NovaCellAPIClient {\n constructor(\n readonly cellId: string,\n readonly opts: BaseConfiguration & {\n axiosInstance?: AxiosInstance\n mock?: boolean\n },\n ) {}\n\n /**\n * Some TypeScript sorcery which alters the API class methods so you don't\n * have to pass the cell id to every single one, and de-encapsulates the\n * response data\n */\n private withCellId<T extends BaseAPI>(\n ApiConstructor: new (\n config: BaseConfiguration,\n basePath: string,\n axios: AxiosInstance,\n ) => T,\n ) {\n const apiClient = new ApiConstructor(\n {\n ...this.opts,\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n },\n this.opts.basePath ?? \"\",\n this.opts.axiosInstance ?? axios.create(),\n ) as {\n [key: string | symbol]: any\n }\n\n for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n const originalFunction = apiClient[key]\n apiClient[key] = (...args: any[]) => {\n return originalFunction\n .apply(apiClient, [this.cellId, ...args])\n .then((res: any) => res.data)\n }\n }\n }\n\n return apiClient as WithCellId<T>\n }\n\n /**\n * As withCellId, but only does the response unwrapping\n */\n private withUnwrappedResponsesOnly<T extends BaseAPI>(\n ApiConstructor: new (\n config: BaseConfiguration,\n basePath: string,\n axios: AxiosInstance,\n ) => T,\n ) {\n const apiClient = new ApiConstructor(\n {\n ...this.opts,\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n },\n this.opts.basePath ?? \"\",\n this.opts.axiosInstance ?? axios.create(),\n ) as {\n [key: string | symbol]: any\n }\n\n for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n const originalFunction = apiClient[key]\n apiClient[key] = (...args: any[]) => {\n return originalFunction\n .apply(apiClient, args)\n .then((res: any) => res.data)\n }\n }\n }\n\n return apiClient as WithUnwrappedAxiosResponse<T>\n }\n\n readonly system = this.withUnwrappedResponsesOnly(SystemApi)\n readonly cell = this.withUnwrappedResponsesOnly(CellApi)\n\n readonly motionGroup = this.withCellId(MotionGroupApi)\n readonly motionGroupInfos = this.withCellId(MotionGroupInfoApi)\n\n readonly controller = this.withCellId(ControllerApi)\n\n readonly program = this.withCellId(ProgramApi)\n readonly programOperator = this.withCellId(ProgramOperatorApi)\n\n readonly controllerIOs = this.withCellId(ControllerInputsOutputsApi)\n\n readonly motionGroupKinematic = this.withCellId(MotionGroupKinematicsApi)\n readonly trajectoryPlanning = this.withCellId(TrajectoryPlanningApi)\n readonly trajectoryExecution = this.withCellId(TrajectoryExecutionApi)\n\n readonly coordinateSystems = this.withCellId(CoordinateSystemsApi)\n\n readonly application = this.withCellId(ApplicationApi)\n readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)\n\n readonly jogging = this.withCellId(JoggingApi)\n\n readonly virtualRobot = this.withCellId(VirtualRobotApi)\n readonly virtualRobotSetup = this.withCellId(VirtualRobotSetupApi)\n readonly virtualRobotMode = this.withCellId(VirtualRobotModeApi)\n readonly virtualRobotBehavior = this.withCellId(VirtualRobotBehaviorApi)\n\n readonly storeObject = this.withCellId(StoreObjectApi)\n readonly storeCollisionComponents = this.withCellId(\n StoreCollisionComponentsApi,\n )\n readonly storeCollisionScenes = this.withCellId(StoreCollisionScenesApi)\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport type { AxiosRequestConfig } from \"axios\"\nimport axios, { isAxiosError } from \"axios\"\nimport urlJoin from \"url-join\"\nimport { loginWithAuth0 } from \"../../LoginWithAuth0\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { availableStorage } from \"../availableStorage\"\nimport { ConnectedMotionGroup } from \"./ConnectedMotionGroup\"\nimport { MockNovaInstance } from \"./mock/MockNovaInstance\"\nimport { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport { NovaCellAPIClient } from \"./NovaCellAPIClient\"\n\nexport type NovaClientConfig = {\n /**\n * Url of the deployed Nova instance to connect to\n * e.g. https://saeattii.instance.wandelbots.io\n */\n instanceUrl: string | \"https://mock.example.com\"\n\n /**\n * Identifier of the cell on the Nova instance to connect this client to.\n * If omitted, the default identifier \"cell\" is used.\n **/\n cellId?: string\n\n /**\n * Username for basic auth to the Nova instance.\n * @deprecated use accessToken instead\n */\n username?: string\n\n /**\n * Password for basic auth to the Nova instance.\n * @deprecated use accessToken instead\n */\n password?: string\n\n /**\n * Access token for Bearer authentication.\n */\n accessToken?: string\n} & Omit<BaseConfiguration, \"isJsonMime\" | \"basePath\">\n\ntype NovaClientConfigWithDefaults = NovaClientConfig & { cellId: string }\n\n/**\n * EXPERIMENTAL\n *\n * This client provides a starting point to migrate NOVA api v2.\n * As v2 is still in development, this client has to be considered unstable\n *\n * Client for connecting to a Nova instance and controlling robots.\n */\nexport class NovaClient {\n readonly api: NovaCellAPIClient\n readonly config: NovaClientConfigWithDefaults\n readonly mock?: MockNovaInstance\n authPromise: Promise<string | null> | null = null\n accessToken: string | null = null\n\n constructor(config: NovaClientConfig) {\n console.warn(\"Using experimental NOVA v2 client\")\n const cellId = config.cellId ?? \"cell\"\n this.config = {\n cellId,\n ...config,\n }\n this.accessToken =\n config.accessToken ||\n availableStorage.getString(\"wbjs.access_token\") ||\n null\n\n if (this.config.instanceUrl === \"https://mock.example.com\") {\n this.mock = new MockNovaInstance()\n }\n\n // Set up Axios instance with interceptor for token fetching\n const axiosInstance = axios.create({\n baseURL: urlJoin(this.config.instanceUrl, \"/api/v2\"),\n headers: {\n \"X-Client-SDK\": \"Wandelbots-Nova-JS-SDK\",\n \"X-SDK-Version\": \"v2\",\n },\n })\n\n axiosInstance.interceptors.request.use(async (request) => {\n if (!request.headers.Authorization) {\n if (this.accessToken) {\n request.headers.Authorization = `Bearer ${this.accessToken}`\n } else if (this.config.username && this.config.password) {\n request.headers.Authorization = `Basic ${btoa(config.username + \":\" + config.password)}`\n }\n }\n return request\n })\n\n if (typeof window !== \"undefined\") {\n axiosInstance.interceptors.response.use(\n (r) => r,\n async (error) => {\n if (isAxiosError(error)) {\n if (error.response?.status === 401) {\n // If we hit a 401, attempt to login the user and retry with\n // a new access token\n try {\n await this.renewAuthentication()\n\n if (error.config) {\n if (this.accessToken) {\n error.config.headers.Authorization = `Bearer ${this.accessToken}`\n } else {\n delete error.config.headers.Authorization\n }\n return axiosInstance.request(error.config)\n }\n } catch (err) {\n return Promise.reject(err)\n }\n } else if (error.response?.status === 503) {\n // Check if the server as a whole is down\n const res = await fetch(window.location.href)\n if (res.status === 503) {\n // Go to 503 page\n window.location.reload()\n }\n }\n }\n\n return Promise.reject(error)\n },\n )\n }\n\n this.api = new NovaCellAPIClient(cellId, {\n ...config,\n basePath: urlJoin(this.config.instanceUrl, \"/api/v1\"),\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n baseOptions: {\n ...(this.mock\n ? ({\n adapter: (config) => {\n return this.mock!.handleAPIRequest(config)\n },\n } satisfies AxiosRequestConfig)\n : {}),\n ...config.baseOptions,\n },\n axiosInstance,\n })\n }\n\n async renewAuthentication(): Promise<void> {\n if (this.authPromise) {\n // Don't double up\n return\n }\n\n this.authPromise = loginWithAuth0(this.config.instanceUrl)\n try {\n this.accessToken = await this.authPromise\n if (this.accessToken) {\n // Cache access token so we don't need to log in every refresh\n availableStorage.setString(\"wbjs.access_token\", this.accessToken)\n } else {\n availableStorage.delete(\"wbjs.access_token\")\n }\n } finally {\n this.authPromise = null\n }\n }\n\n makeWebsocketURL(path: string): string {\n const url = new URL(\n urlJoin(\n this.config.instanceUrl,\n `/api/v1/cells/${this.config.cellId}`,\n path,\n ),\n )\n url.protocol = url.protocol.replace(\"http\", \"ws\")\n url.protocol = url.protocol.replace(\"https\", \"wss\")\n\n // If provided, add basic auth credentials to the URL\n // NOTE - basic auth is deprecated on websockets and doesn't work in Safari\n // use tokens instead\n if (this.accessToken) {\n url.searchParams.append(\"token\", this.accessToken)\n } else if (this.config.username && this.config.password) {\n url.username = this.config.username\n url.password = this.config.password\n }\n\n return url.toString()\n }\n\n /**\n * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.\n * If you explicitly want to reconnect an existing websocket, call `reconnect`\n * on the returned object.\n */\n openReconnectingWebsocket(path: string) {\n return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {\n mock: this.mock,\n })\n }\n\n /**\n * Connect to the motion state websocket(s) for a given motion group\n */\n async connectMotionStream(motionGroupId: string) {\n return await MotionStreamConnection.open(this, motionGroupId)\n }\n\n async connectMotionGroups(\n motionGroupIds: string[],\n ): Promise<ConnectedMotionGroup[]> {\n const { controllers } = await this.api.controller.listControllers()\n\n return Promise.all(\n motionGroupIds.map((motionGroupId) =>\n ConnectedMotionGroup.connect(this, motionGroupId, controllers),\n ),\n )\n }\n\n async connectMotionGroup(\n motionGroupId: string,\n ): Promise<ConnectedMotionGroup> {\n const motionGroups = await this.connectMotionGroups([motionGroupId])\n return motionGroups[0]!\n }\n}\n","const DOMAIN_SUFFIX = \"wandelbots.io\"\n\n/** Mapping of stages to Auth0 configurations */\nconst auth0ConfigMap = {\n dev: {\n domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_DEV_CLIENT_ID,\n },\n stg: {\n domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_STG_CLIENT_ID,\n },\n prod: {\n domain: `https://auth.portal.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_PROD_CLIENT_ID,\n },\n}\n\n/** Determine which Auth0 configuration to use based on instance URL */\nconst getAuth0Config = (instanceUrl: string) => {\n if (instanceUrl.includes(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev\n if (instanceUrl.includes(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg\n if (instanceUrl.includes(DOMAIN_SUFFIX)) return auth0ConfigMap.prod\n throw new Error(\n \"Unsupported instance URL. Cannot determine Auth0 configuration.\",\n )\n}\n\n/**\n * Initializes Auth0 login process using redirect if necessary and retrieves an access token.\n * Returns null when an access token should not be needed to authenticate (i.e. cookie auth\n * when deployed on the instance domain)\n */\nexport const loginWithAuth0 = async (\n instanceUrl: string,\n): Promise<string | null> => {\n if (typeof window === \"undefined\") {\n throw new Error(\n `Access token must be set to use NovaClient when not in a browser environment.`,\n )\n }\n\n const auth0Config = getAuth0Config(instanceUrl)\n\n if (new URL(instanceUrl).origin === window.location.origin) {\n // When deployed on the instance itself, our auth is handled by cookies\n // and no access token is needed-- just need to reload the page and it'll\n // login again / set cookie as needed\n window.location.reload()\n throw new Error(\n \"Failed to reload page to get auth details, please refresh manually\",\n )\n }\n\n // If we're on localhost or another domain, we need to do the full oauth flow\n // Note this will ONLY work for origins which are whitelisted as a redirect_uri\n // in the auth0 config, currently\n const { Auth0Client } = await import(\"@auth0/auth0-spa-js\")\n\n const auth0Client = new Auth0Client({\n domain: auth0Config.domain,\n clientId: auth0Config.clientId ?? \"\",\n useRefreshTokens: false,\n authorizationParams: {\n audience: \"nova-api\",\n redirect_uri: window.location.origin,\n },\n })\n\n // If the URL includes a redirect result, handle it\n if (\n window.location.search.includes(\"code=\") &&\n window.location.search.includes(\"state=\")\n ) {\n const { appState } = await auth0Client.handleRedirectCallback()\n // Return to the URL the user was originally on before the redirect\n window.history.replaceState(\n {},\n document.title,\n appState?.returnTo || window.location.pathname,\n )\n } else {\n // Initiate login with redirect\n await auth0Client.loginWithRedirect()\n }\n\n // Once logged in, retrieve the access token silently\n const accessToken = await auth0Client.getTokenSilently()\n return accessToken\n}\n","import ReconnectingWebSocket, { type ErrorEvent } from \"reconnecting-websocket\"\nimport * as v2 from \"./v2/mock/MockNovaInstance\"\nimport * as v1 from \"./v1/mock/MockNovaInstance\"\n\nexport class AutoReconnectingWebsocket extends ReconnectingWebSocket {\n receivedFirstMessage?: MessageEvent\n targetUrl: string\n disposed = false\n\n constructor(\n targetUrl: string,\n readonly opts: {\n mock?: v1.MockNovaInstance | v2.MockNovaInstance\n onDispose?: () => void\n } = {},\n ) {\n console.log(\"Opening websocket to\", targetUrl)\n\n super(() => this.targetUrl || targetUrl, undefined, {\n startClosed: true,\n })\n\n // Reconnecting websocket doesn't set this properly with startClosed\n Object.defineProperty(this, \"url\", {\n get() {\n return this.targetUrl\n },\n })\n\n this.targetUrl = targetUrl\n\n this.addEventListener(\"open\", () => {\n console.log(`Websocket to ${this.url} opened`)\n })\n\n this.addEventListener(\"message\", (ev) => {\n if (!this.receivedFirstMessage) {\n this.receivedFirstMessage = ev\n }\n })\n\n this.addEventListener(\"close\", () => {\n console.log(`Websocket to ${this.url} closed`)\n })\n\n const origReconnect = this.reconnect\n this.reconnect = () => {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketConnection(this)\n } else {\n origReconnect.apply(this)\n }\n }\n\n this.reconnect()\n }\n\n changeUrl(targetUrl: string) {\n this.receivedFirstMessage = undefined\n this.targetUrl = targetUrl\n this.reconnect()\n }\n\n sendJson(data: unknown) {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data))\n } else {\n this.send(JSON.stringify(data))\n }\n }\n\n /**\n * Permanently close this websocket and indicate that\n * this object should not be used again.\n **/\n dispose() {\n this.close()\n this.disposed = true\n if (this.opts.onDispose) {\n this.opts.onDispose()\n }\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the OPEN state. */\n async opened() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.OPEN) {\n resolve()\n } else {\n this.addEventListener(\"open\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the CLOSED state. */\n async closed() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.CLOSED) {\n resolve()\n } else {\n this.addEventListener(\"close\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves when the first message\n * is received from the websocket. Resolves immediately if\n * the first message has already been received.\n */\n async firstMessage() {\n if (this.receivedFirstMessage) {\n return this.receivedFirstMessage\n }\n\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.receivedFirstMessage = ev\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n\n /**\n * Returns a promise that resolves when the next message\n * is received from the websocket.\n */\n async nextMessage() {\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n}\n","/**\n * Safety wrapper around browser localStorage providing context availability\n * checks and JSON parsing\n */\nclass AvailableStorage {\n available = typeof window !== \"undefined\" && !!window.localStorage\n\n getJSON<T>(key: string): Partial<T> | null {\n if (!this.available) return null\n\n const result = window.localStorage.getItem(key)\n if (result === null) return null\n\n try {\n return JSON.parse(result)\n } catch (err) {\n return null\n }\n }\n\n setJSON(key: string, obj: any) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, JSON.stringify(obj))\n }\n\n delete(key: string) {\n if (!this.available) return null\n\n window.localStorage.removeItem(key)\n }\n\n setString(key: string, value: string) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, value)\n }\n\n getString(key: string): string | null {\n if (!this.available) return null\n\n return window.localStorage.getItem(key)\n }\n}\n\nexport const availableStorage = new AvailableStorage()\n","import type {\n ControllersList,\n MotionGroupSpecification,\n MotionGroupState,\n RobotController,\n SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AxiosResponse, InternalAxiosRequestConfig } from \"axios\"\nimport { AxiosError } from \"axios\"\nimport * as pathToRegexp from \"path-to-regexp\"\nimport type { AutoReconnectingWebsocket } from \"../../AutoReconnectingWebsocket\"\n\n/**\n * EXPERIMENTAL\n * Ultra-simplified mock Nova server for testing stuff\n */\nexport class MockNovaInstance {\n readonly connections: AutoReconnectingWebsocket[] = []\n\n async handleAPIRequest(\n config: InternalAxiosRequestConfig,\n ): Promise<AxiosResponse> {\n const apiHandlers = [\n {\n method: \"GET\",\n path: \"/cells/:cellId/controllers\",\n handle() {\n return {\n controllers: [\n {\n controller: \"mock-ur5e\",\n model_name: \"UniversalRobots::Controller\",\n host: \"mock-ur5e\",\n allow_software_install_on_controller: true,\n motion_groups: [\n {\n motion_group: \"0@mock-ur5e\",\n name_from_controller: \"UR5e\",\n active: false,\n model_from_controller: \"UniversalRobots_UR5e\",\n },\n ],\n has_error: false,\n error_details: \"\",\n },\n ],\n } satisfies ControllersList\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/controllers/:controllerId\",\n handle() {\n return {\n configuration: {\n kind: \"VirtualController\",\n manufacturer: \"universalrobots\",\n position: \"[0,-1.571,-1.571,-1.571,1.571,-1.571,0]\",\n type: \"universalrobots-ur5e\",\n },\n name: \"mock-ur5\",\n } satisfies RobotController\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/specification\",\n handle() {\n return {\n dh_parameters: [\n {\n alpha: 1.5707963267948966,\n theta: 0,\n a: 0,\n d: 162.25,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: -425,\n d: 0,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: -392.2,\n d: 0,\n reverse_rotation_direction: false,\n },\n {\n alpha: 1.5707963267948966,\n theta: 0,\n a: 0,\n d: 133.3,\n reverse_rotation_direction: false,\n },\n {\n alpha: -1.5707963267948966,\n theta: 0,\n a: 0,\n d: 99.7,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: 0,\n d: 99.6,\n reverse_rotation_direction: false,\n },\n ],\n mechanical_joint_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n ],\n } satisfies MotionGroupSpecification\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/safety-setup\",\n handle() {\n return {\n safety_settings: [\n {\n safety_state: \"SAFETY_NORMAL\",\n settings: {\n joint_position_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n lower_limit: -2.96705961227417,\n upper_limit: 2.96705961227417,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n lower_limit: -1.7453292608261108,\n upper_limit: 2.7925267219543457,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n lower_limit: -3.3161256313323975,\n upper_limit: 0.40142571926116943,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n lower_limit: -3.4906585216522217,\n upper_limit: 3.4906585216522217,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n lower_limit: -2.4434609413146973,\n upper_limit: 2.4434609413146973,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n lower_limit: -4.71238899230957,\n upper_limit: 4.71238899230957,\n unlimited: false,\n },\n ],\n joint_velocity_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n limit: 3.1415927410125732,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n limit: 3.1415927410125732,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n limit: 3.4906585216522217,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n limit: 6.108652591705322,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n limit: 6.108652591705322,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n limit: 6.981317043304443,\n },\n ],\n joint_acceleration_limits: [],\n joint_torque_limits: [],\n tcp_velocity_limit: 1800,\n },\n },\n ],\n safety_zones: [\n {\n id: 1,\n priority: 0,\n geometry: {\n compound: {\n child_geometries: [\n {\n convex_hull: {\n vertices: [\n { vertex: [-800, -1330, -1820] },\n { vertex: [1650, -1330, -1820] },\n { vertex: [1650, 1330, -1820] },\n { vertex: [-800, 1330, -1820] },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [-800, -1330, -1820],\n },\n {\n vertex: [1650, -1330, -1820],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [-800, -1330, -1820],\n },\n {\n vertex: [-800, 1330, -1820],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, 1330, -1820],\n },\n {\n vertex: [1650, 1330, -1820],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n {\n vertex: [1650, -1330, -1820],\n },\n {\n vertex: [1650, 1330, -1820],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Cell workzone\",\n },\n motion_group_uid: 1,\n },\n {\n id: 2,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, -1850],\n },\n {\n vertex: [865, 1330, -1850],\n },\n {\n vertex: [865, -720, -1850],\n },\n {\n vertex: [1650, -720, -1850],\n },\n {\n vertex: [1650, 1330, -920],\n },\n {\n vertex: [865, 1330, -920],\n },\n {\n vertex: [865, -720, -920],\n },\n {\n vertex: [1650, -720, -920],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Transport\",\n },\n motion_group_uid: 1,\n },\n {\n id: 3,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, -600],\n },\n {\n vertex: [865, 1330, -600],\n },\n {\n vertex: [865, 430, -600],\n },\n {\n vertex: [1650, 430, -600],\n },\n {\n vertex: [1650, 1330, -1250],\n },\n {\n vertex: [865, 1330, -1250],\n },\n {\n vertex: [865, 430, -1250],\n },\n {\n vertex: [1650, 430, -1250],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Tunel\",\n },\n motion_group_uid: 1,\n },\n {\n id: 4,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, -760, -440],\n },\n {\n vertex: [900, -760, -440],\n },\n {\n vertex: [900, -1330, -440],\n },\n {\n vertex: [1650, -1330, -440],\n },\n {\n vertex: [1650, -760, -1800],\n },\n {\n vertex: [900, -760, -1800],\n },\n {\n vertex: [900, -1330, -1800],\n },\n {\n vertex: [1650, -1330, -1800],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Fanuc controller\",\n },\n motion_group_uid: 1,\n },\n {\n id: 6,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [-200, -200, -1900],\n },\n {\n vertex: [200, -200, -1900],\n },\n {\n vertex: [200, 200, -1900],\n },\n {\n vertex: [-200, 200, -1900],\n },\n {\n vertex: [-200, -200, -350],\n },\n {\n vertex: [200, -200, -350],\n },\n {\n vertex: [200, 200, -350],\n },\n {\n vertex: [-200, 200, -350],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Robot base\",\n },\n motion_group_uid: 1,\n },\n ],\n robot_model_geometries: [\n {\n link_index: 1,\n geometry: {\n sphere: {\n radius: 270,\n },\n init_pose: {\n position: [-70, -70, -50],\n orientation: [0, 0, 0, 1],\n },\n id: \"link1_sphere\",\n },\n },\n {\n link_index: 2,\n geometry: {\n capsule: {\n radius: 160,\n cylinder_height: 800,\n },\n init_pose: {\n position: [-450, 40, 170],\n orientation: [\n 0, -0.7071067811865475, 0, 0.7071067811865476,\n ],\n },\n id: \"link2_capsule\",\n },\n },\n {\n link_index: 3,\n geometry: {\n sphere: {\n radius: 270,\n },\n init_pose: {\n position: [-110, 10, -100],\n orientation: [0, 0, 0, 1],\n },\n id: \"link3_sphere\",\n },\n },\n {\n link_index: 4,\n geometry: {\n capsule: {\n radius: 110,\n cylinder_height: 600,\n },\n init_pose: {\n position: [0, 300, 40],\n orientation: [\n -0.7071067811865475, 0, 0, 0.7071067811865476,\n ],\n },\n id: \"link4_capsule\",\n },\n },\n {\n link_index: 5,\n geometry: {\n sphere: {\n radius: 75,\n },\n init_pose: {\n position: [0, 0, -50],\n orientation: [0, 0, 0, 1],\n },\n id: \"link5_sphere\",\n },\n },\n ],\n tool_geometries: [],\n } satisfies SafetySetup\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/coordinate-systems\",\n handle() {\n return {\n coordinatesystems: [\n {\n coordinate_system: \"\",\n name: \"world\",\n reference_uid: \"\",\n position: [0, 0, 0],\n rotation: {\n angles: [0, 0, 0],\n type: \"ROTATION_VECTOR\",\n },\n },\n ],\n } //satisfies CoordinateSystems\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/tcps\",\n handle() {\n return {\n tcps: [\n {\n id: \"Flange\",\n readable_name: \"Default-Flange\",\n position: [0, 0, 0],\n rotation: {\n angles: [0, 0, 0, 0],\n type: \"ROTATION_VECTOR\",\n },\n },\n {\n id: \"complex-tcp-position\",\n readable_name: \"Complex TCP Position\",\n position: [-200, 300, 150],\n rotation: {\n angles: [\n -0.12139440409113832, -0.06356210998212003,\n -0.2023240068185639, 0,\n ],\n type: \"ROTATION_VECTOR\",\n },\n },\n ],\n }\n },\n },\n ]\n\n const method = config.method?.toUpperCase() || \"GET\"\n const path = \"/cells\" + config.url?.split(\"/cells\")[1]?.split(\"?\")[0]\n\n for (const handler of apiHandlers) {\n const match = pathToRegexp.match(handler.path)(path || \"\")\n if (method === handler.method && match) {\n const json = handler.handle()\n return {\n status: 200,\n statusText: \"Success\",\n data: JSON.stringify(json),\n headers: {},\n config,\n request: {\n responseURL: config.url,\n },\n }\n }\n }\n\n throw new AxiosError(\n `No mock handler matched this request: ${method} ${path}`,\n \"404\",\n config,\n )\n\n // return {\n // status: 404,\n // statusText: \"Not Found\",\n // data: \"\",\n // headers: {},\n // config,\n // request: {\n // responseURL: config.url,\n // },\n // }\n }\n\n handleWebsocketConnection(socket: AutoReconnectingWebsocket) {\n this.connections.push(socket)\n\n setTimeout(() => {\n socket.dispatchEvent(new Event(\"open\"))\n\n console.log(\"Websocket connection opened from\", socket.url)\n\n if (socket.url.includes(\"/state-stream\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify(defaultMotionState),\n }),\n )\n }\n\n if (socket.url.includes(\"/move-joint\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify({\n result: {\n motion_group: \"0@ur\",\n state: {\n controller: \"ur\",\n operation_mode: \"OPERATION_MODE_AUTO\",\n safety_state: \"SAFETY_STATE_NORMAL\",\n timestamp: \"2024-09-18T12:48:26.096266444Z\",\n velocity_override: 100,\n motion_groups: [\n {\n motion_group: \"0@ur\",\n controller: \"ur\",\n joint_position: {\n joints: [\n 1.3492152690887451, -1.5659207105636597,\n 1.6653711795806885, -1.0991662740707397,\n -1.829018235206604, 1.264623761177063,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [\n 6.437331889439328, -628.4123774830913,\n 577.0569957147832,\n ],\n orientation: {\n x: -1.683333649797158,\n y: -1.9783363827298732,\n z: -0.4928031860165713,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [\n 6.437331889439328, -628.4123774830913,\n 577.0569957147832,\n ],\n orientation: {\n x: -1.683333649797158,\n y: -1.9783363827298732,\n z: -0.4928031860165713,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n angular: {\n x: -0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n force: {\n force: {\n x: 0,\n y: 0,\n z: 0,\n },\n moment: {\n x: 0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [\n false,\n false,\n false,\n false,\n false,\n false,\n ],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"671259\",\n },\n ],\n sequence_number: \"671259\",\n },\n movement_state: \"MOVEMENT_STATE_MOVING\",\n },\n }),\n }),\n )\n }\n\n if (socket.url.includes(\"/move-tcp\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify({\n result: {\n motion_group: \"0@ur\",\n state: {\n controller: \"ur\",\n operation_mode: \"OPERATION_MODE_AUTO\",\n safety_state: \"SAFETY_STATE_NORMAL\",\n timestamp: \"2024-09-18T12:43:12.188335774Z\",\n velocity_override: 100,\n motion_groups: [\n {\n motion_group: \"0@ur\",\n controller: \"ur\",\n joint_position: {\n joints: [\n 1.3352527618408203, -1.5659207105636597,\n 1.6653711795806885, -1.110615611076355,\n -1.829018235206604, 1.264623761177063,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [\n -2.763015284002938, -630.2151479701106,\n 577.524509114342,\n ],\n orientation: {\n x: -1.704794877102097,\n y: -1.9722372952861567,\n z: -0.4852079204210754,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [\n -2.763015284002938, -630.2151479701106,\n 577.524509114342,\n ],\n orientation: {\n x: -1.704794877102097,\n y: -1.9722372952861567,\n z: -0.4852079204210754,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n angular: {\n x: -0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n force: {\n force: {\n x: 0,\n y: 0,\n z: 0,\n },\n moment: {\n x: 0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [\n false,\n false,\n false,\n false,\n false,\n false,\n ],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"627897\",\n },\n ],\n sequence_number: \"627897\",\n },\n movement_state: \"MOVEMENT_STATE_MOVING\",\n },\n }),\n }),\n )\n }\n }, 10)\n }\n\n handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string) {\n console.log(`Received message on ${socket.url}`, message)\n }\n}\n\nconst defaultMotionState = {\n result: {\n motion_group: \"0@universalrobots-ur5e\",\n controller: \"universalrobots-ur5e\",\n joint_position: {\n joints: [\n 1.1699999570846558, -1.5700000524520874, 1.3600000143051147,\n 1.0299999713897705, 1.2899999618530273, 1.2799999713897705,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n orientation: [\n 1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n ],\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n orientation: [\n 1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n ],\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: [0, 0, 0],\n angular: [0, 0, 0],\n coordinate_system: \"\",\n },\n force: {\n force: [0, 0, 0],\n moment: [0, 0, 0],\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [false, false, false, false, false, false],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n } satisfies MotionGroupState,\n}\n","import { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport type { NovaClient } from \"./NovaClient\"\n\nexport type ProgramRunnerLogEntry = {\n timestamp: number\n message: string\n level?: \"warn\" | \"error\"\n}\n\nexport enum ProgramState {\n NotStarted = \"not started\",\n Running = \"running\",\n Stopped = \"stopped\",\n Failed = \"failed\",\n Completed = \"completed\",\n}\n\nexport type CurrentProgram = {\n id?: string\n wandelscript?: string\n state?: ProgramState\n}\n\ntype ProgramStateMessage = {\n type: string\n runner: {\n id: string\n state: ProgramState\n start_time?: number | null\n execution_time?: number | null\n }\n}\n\n/**\n * Interface for running Wandelscript programs on the Nova instance and\n * tracking their progress and output\n */\nexport class ProgramStateConnection {\n currentProgram: CurrentProgram = {}\n logs: ProgramRunnerLogEntry[] = []\n\n executionState = \"idle\" as \"idle\" | \"starting\" | \"executing\" | \"stopping\"\n currentlyExecutingProgramRunnerId = null as string | null\n\n programStateSocket: AutoReconnectingWebsocket\n\n constructor(readonly nova: NovaClient) {\n makeAutoObservable(this, {}, { autoBind: true })\n\n this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`)\n\n this.programStateSocket.addEventListener(\"message\", (ev) => {\n const msg = tryParseJson(ev.data)\n\n if (!msg) {\n console.error(\"Failed to parse program state message\", ev.data)\n return\n }\n if (msg.type === \"update\") {\n this.handleProgramStateMessage(msg)\n }\n })\n }\n\n /** Handle a program state update from the backend */\n async handleProgramStateMessage(msg: ProgramStateMessage) {\n const { runner } = msg\n\n // Ignoring other programs for now\n // TODO - show if execution state is busy from another source\n if (runner.id !== this.currentlyExecutingProgramRunnerId) return\n\n if (runner.state === ProgramState.Failed) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n // TODO - wandelengine should send print statements in real time over\n // websocket as well, rather than at the end\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n this.logError(\n `Program runner ${runner.id} failed with error: ${runnerState.error}\\n${runnerState.traceback}`,\n )\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.currentProgram.state = ProgramState.Failed\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Stopped) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n\n this.currentProgram.state = ProgramState.Stopped\n this.log(`Program runner ${runner.id} stopped`)\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Completed) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n this.log(\n `Program runner ${runner.id} finished successfully in ${runner.execution_time?.toFixed(2)} seconds`,\n )\n\n this.currentProgram.state = ProgramState.Completed\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Running) {\n this.currentProgram.state = ProgramState.Running\n this.log(`Program runner ${runner.id} now running`)\n } else if (runner.state !== ProgramState.NotStarted) {\n console.error(runner)\n this.logError(\n `Program runner ${runner.id} entered unexpected state: ${runner.state}`,\n )\n this.currentProgram.state = ProgramState.NotStarted\n this.gotoIdleState()\n }\n }\n\n /** Call when a program is no longer executing */\n gotoIdleState() {\n runInAction(() => {\n this.executionState = \"idle\"\n })\n this.currentlyExecutingProgramRunnerId = null\n }\n\n async executeProgram(\n wandelscript: string,\n initial_state?: Object,\n activeRobot?: MotionStreamConnection,\n ) {\n this.currentProgram = {\n wandelscript: wandelscript,\n state: ProgramState.NotStarted,\n }\n\n const { currentProgram: openProgram } = this\n if (!openProgram) return\n runInAction(() => {\n this.executionState = \"starting\"\n })\n\n // WOS-1539: Wandelengine parser currently breaks if there are empty lines with indentation\n const trimmedCode = openProgram.wandelscript!.replaceAll(/^\\s*$/gm, \"\")\n\n try {\n const programRunnerRef = await this.nova.api.program.createProgramRun(\n {\n code: trimmedCode,\n initial_state: initial_state,\n default_robot: activeRobot?.wandelscriptIdentifier,\n } as any,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n )\n\n this.log(`Created program runner ${programRunnerRef.id}\"`)\n runInAction(() => {\n this.executionState = \"executing\"\n })\n this.currentlyExecutingProgramRunnerId = programRunnerRef.id\n } catch (error) {\n if (error instanceof AxiosError && error.response && error.request) {\n this.logError(\n `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`,\n )\n } else {\n this.logError(JSON.stringify(error))\n }\n runInAction(() => {\n this.executionState = \"idle\"\n })\n }\n }\n\n async stopProgram() {\n if (!this.currentlyExecutingProgramRunnerId) return\n runInAction(() => {\n this.executionState = \"stopping\"\n })\n\n try {\n await this.nova.api.program.stopProgramRun(\n this.currentlyExecutingProgramRunnerId,\n )\n } catch (err) {\n // Reactivate the stop button so user can try again\n runInAction(() => {\n this.executionState = \"executing\"\n })\n throw err\n }\n }\n\n reset() {\n this.currentProgram = {}\n }\n\n log(message: string) {\n console.log(message)\n this.logs.push({\n timestamp: Date.now(),\n message,\n })\n }\n\n logError(message: string) {\n console.log(message)\n this.logs.push({\n timestamp: Date.now(),\n message,\n level: \"error\",\n })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAc,oCAAd;;;ACQA,mBAA2B;AAC3B,kBAAgD;;;ACNzC,SAAS,aAAa,MAAoB;AAC/C,MAAI;AACF,WAAO,KAAK,MAAM,IAAc;AAAA,EAClC,SAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACPO,SAAS,iBACd,gBACA,gBACA,sBACS;AACT,MAAI,eAAe,WAAW,eAAe,QAAQ;AACnD,WAAO;AAAA,EACT;AAEA,WAAS,aAAa,GAAG,aAAa,eAAe,QAAQ,cAAc;AACzE,QACE,KAAK,IAAI,eAAe,UAAU,IAAK,eAAe,UAAU,CAAE,IAClE,sBACA;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aACd,QACA,QACA,sBACS;AAET,MAAK,WAAW,UAAa,UAAY,UAAU,WAAW,QAAY;AACxE,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,UAAa,WAAW,QAAW;AAChD,WAAO;AAAA,EACT;AAEA,MAAI,eAAe;AACnB,kBAAgB,KAAK,IAAI,OAAO,YAAY,CAAC,IAAI,OAAO,YAAY,CAAC,CAAC;AACtE,kBAAgB,KAAK,IAAI,OAAO,YAAY,CAAC,IAAI,OAAO,YAAY,CAAC,CAAC;AACtE,kBAAgB,KAAK,IAAI,OAAO,YAAY,CAAC,IAAI,OAAO,YAAY,CAAC,CAAC;AACtE,kBAAgB,KAAK,IAAI,OAAO,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,CAAC;AAChE,kBAAgB,KAAK,IAAI,OAAO,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,CAAC;AAChE,kBAAgB,KAAK,IAAI,OAAO,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,CAAC;AAEhE,MAAI,eAAe,sBAAsB;AACvC,WAAO;AAAA,EACT;AAEA,SACE,OAAO,sBAAsB,OAAO,qBACpC,OAAO,QAAQ,OAAO;AAE1B;;;AFvCA,IAAM,yBAAyB;AASxB,IAAM,uBAAN,MAAM,sBAAqB;AAAA,EAwFhC,YACW,MACA,YACA,aACA,oBACA,mBACA,WACA,MACA,0BACA,aACT;AATS;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlBX,2CAAoD;AACpD,wCAAiD;AAEjD;AAAA,2BAA0B;AAiBxB,SAAK,6BAA6B;AAElC,sBAAkB,iBAAiB,WAAW,CAAC,UAAU;AA7H7D;AA8HM,YAAM,uBAAsB,kBAAa,MAAM,IAAI,MAAvB,mBAA0B;AAItD,UAAI,CAAC,qBAAqB;AACxB,cAAM,IAAI;AAAA,UACR,kCAAkC,KAAK,aAAa,KAAK,MAAM,IAAI;AAAA,QACrE;AAAA,MACF;AAGA,UACE,CAAC;AAAA,QACC,KAAK,2BAA2B,eAAe;AAAA,QAC/C,oBAAoB,eAAe;AAAA,QACnC;AAAA,MACF,GACA;AACA,qCAAY,MAAM;AAChB,eAAK,6BAA6B;AAAA,QACpC,CAAC;AAAA,MACH;AAGA,UACE,CAAC;AAAA,QACC,KAAK,2BAA2B;AAAA,QAChC,oBAAoB;AAAA,QACpB;AAAA,MACF,GACA;AACA,qCAAY,MAAM;AAChB,eAAK,2BAA2B,WAC9B,oBAAoB;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,wCAAmB,IAAI;AAAA,EACzB;AAAA,EA3IA,OAAa,QACX,MACA,eACA,aACA;AAAA;AA7BJ;AA8BI,YAAM,CAAC,mBAAmB,YAAY,IAAI,cAAc,MAAM,GAAG;AAIjE,YAAM,aAAa,YAAY,KAAK,CAAC,MAAM,EAAE,eAAe,YAAY;AACxE,YAAM,cAAc,yCAAY,cAAc;AAAA,QAC5C,CAAC,OAAO,GAAG,iBAAiB;AAAA;AAE9B,UAAI,CAAC,cAAc,CAAC,aAAa;AAC/B,cAAM,IAAI;AAAA,UACR,cAAc,YAAY,oBAAoB,aAAa;AAAA,QAC7D;AAAA,MACF;AAEA,YAAM,oBAAoB,KAAK;AAAA,QAC7B,kBAAkB,aAAa;AAAA,MACjC;AAGA,YAAM,eAAe,MAAM,kBAAkB,aAAa;AAC1D,YAAM,sBAAqB,kBAAa,aAAa,IAAI,MAA9B,mBACvB;AAEJ,UAAI,CAAC,oBAAoB;AACvB,cAAM,IAAI;AAAA,UACR,gDAAgD,aAAa,IAAI;AAAA,QACnE;AAAA,MACF;AAEA,cAAQ;AAAA,QACN,oDAAoD,YAAY,YAAY;AAAA;AAAA,QAC5E;AAAA,MACF;AAGA,UAAI,YAAY;AAChB,UAAI;AACF,cAAM,SACJ,MAAM,KAAK,IAAI,iBAAiB,iBAAiB,YAAY;AAE/D,YAAI,OAAQ,aAAY;AAAA,MAC1B,SAAS,KAAK;AACZ,YAAI,eAAe,yBAAY;AAC7B,kBAAQ;AAAA,YACN,YAAY,IAAI,MAAM,2CAA2C,YAAY;AAAA,UAC/E;AAAA,QACF,OAAO;AACL,gBAAM;AAAA,QACR;AAAA,MACF;AAGA,YAAM,EAAE,KAAK,IAAI,MAAM,KAAK,IAAI,iBAAiB,SAAS,aAAa;AAEvE,YAAM,2BACJ,MAAM,KAAK,IAAI,iBAAiB,4BAA4B,aAAa;AAE3E,YAAM,cACJ,MAAM,KAAK,IAAI,iBAAiB,eAAe,aAAa;AAE9D,aAAO,IAAI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAiEA,IAAI,gBAAgB;AAClB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,sBAAsB;AACxB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,yBAAyB;AAC3B,UAAM,MAAM,KAAK,cAAc,MAAM,GAAG,EAAE,CAAC;AAC3C,WAAO,GAAG,KAAK,aAAa,WAAW,KAAK,GAAG,CAAC,IAAI,GAAG;AAAA,EACzD;AAAA;AAAA,EAGA,IAAI,sBAAsB;AACxB,WAAQ,KAAK,kBAAkB,KAAK,KAAM;AAAA,EAC5C;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,mBAAmB,eAAe,OAAO,IAAI,CAAC,GAAG,MAAM;AACjE,aAAO;AAAA,QACL,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,yBAAyB;AAAA,EACvC;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,UAAU;AACR,SAAK,kBAAkB,MAAM;AAC7B,QAAI,KAAK;AACP,WAAK,gCAAgC,MAAM;AAC7C,QAAI,KAAK;AACP,WAAK,6BAA6B,MAAM;AAAA,EAC5C;AAAA,EAEA,mBAAmB,UAAkB;AACnC,SAAK,kBAAkB;AAAA,EACzB;AACF;;;AGvNA,YAAuB;AAKhB,SAAS,YAAY,MAA+B;AACzD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAmBO,SAAS,eAAe,QAAiC;AAC9D,SAAO,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AACtC;;;ACdO,IAAM,mBAAN,MAAM,kBAAiB;AAAA,EAyB5B,YACW,MACA,MACA,eACA,kBACA,MACT;AALS;AACA;AACA;AACA;AACA;AA3BX;AAAA;AAAA,4BAAqD;AACrD,+BAAwE;AACxE,wBAAuC;AA2BrC,SAAK,mBAAmB,KAAK;AAAA,MAC3B,UAAU,IAAI;AAAA,IAChB;AACA,SAAK,iBAAiB,iBAAiB,WAAW,CAAC,OAAqB;AACtE,YAAM,OAAO,aAAa,GAAG,IAAI;AACjC,UAAI,QAAQ,WAAW,MAAM;AAC3B,YAAI,KAAK,KAAK,SAAS;AACrB,eAAK,KAAK,QAAQ,GAAG,IAAI;AAAA,QAC3B,OAAO;AACL,gBAAM,IAAI,MAAM,GAAG,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,iBAAiB,iBAAiB,WAAW,CAAC,OAAqB;AACtE,YAAM,OAAO,aAAa,GAAG,IAAI;AACjC,UAAI,QAAQ,WAAW,MAAM;AAC3B,YAAI,KAAK,KAAK,SAAS;AACrB,eAAK,KAAK,QAAQ,GAAG,IAAI;AAAA,QAC3B,OAAO;AACL,gBAAM,IAAI,MAAM,GAAG,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAjDA,OAAa,KACX,MACA,MACA,eACA,MACA;AAAA;AACA,YAAM,mBACJ,MAAM,KAAK,IAAI,iBAAiB,2BAA2B,aAAa;AAE1E,aAAO,IAAI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAmCA,IAAI,aAAa;AA/EnB;AAgFI,YAAO,UAAK,iBAAiB,kBAAtB,mBAAqC,OAAO;AAAA,EACrD;AAAA,EAEA,IAAI,kBAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEM,OAAO;AAAA;AAvFf;AA2FI,UAAI,CAAC,KAAK,kBAAkB;AAC1B;AAAA,MACF;AAEA,YAAI,UAAK,wBAAL,mBAA0B,kBAAiB,wBAAwB;AACrE,aAAK,iBAAiB,SAAS;AAAA,UAC7B,cAAc;AAAA,UACd,UAAU;AAAA,YACR,QAAQ,MAAM,KAAK,IAAI,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC;AAAA,UACnE;AAAA,QACF,CAAyB;AAAA,MAC3B;AAEA,YAAI,UAAK,wBAAL,mBAA0B,kBAAiB,sBAAsB;AACnE,aAAK,iBAAiB,SAAS;AAAA,UAC7B,cAAc;AAAA,UACd,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,UAClB,aAAa,CAAC,GAAG,GAAG,CAAC;AAAA,QACvB,CAAuB;AAAA,MACzB;AAAA,IACF;AAAA;AAAA,EAEA,UAAU;AACR,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,QAAQ;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKM,mBAAmB,IAQtB;AAAA,+CARsB;AAAA,MACvB;AAAA,MACA;AAAA,IACF,GAKG;AACD,UAAI,CAAC,KAAK,kBAAkB;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,kBAAkB,IAAI,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;AACzD,sBAAgB,KAAK,IAAI;AAEzB,WAAK,iBAAiB,SAAS;AAAA,QAC7B,cAAc;AAAA,QACd,UAAU;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,MACF,CAAyB;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAKM,oBAAoB,IAQvB;AAAA,+CARuB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAIG;AACD,UAAI,CAAC,KAAK,kBAAkB;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,gBAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,oBAAc,YAAY,IAAI,CAAC,IAAI;AAEnC,WAAK,iBAAiB,SAAS;AAAA,QAC7B,cAAc;AAAA,QAEd,aAAa;AAAA,QACb,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,QAClB,4BAA4B;AAAA,MAC9B,CAAuB;AAAA,IACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKM,iBAAiB,IAQpB;AAAA,+CARoB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAIG;AACD,UAAI,CAAC,KAAK,kBAAkB;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,gBAAgB,CAAC,GAAG,GAAG,CAAC;AAC9B,oBAAc,YAAY,IAAI,CAAC,IAAI;AAEnC,WAAK,iBAAiB,SAAS;AAAA,QAC7B,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa,CAAC,GAAG,GAAG,CAAC;AAAA,QACrB,4BAA4B;AAAA,MAC9B,CAAuB;AAAA,IACzB;AAAA;AACF;;;ACzMA,IAAAA,eAAgD;AAChD,IAAAC,SAAuB;AAOvB,IAAMC,0BAAyB;AAE/B,SAAS,qBACP,sBACA,0BACU;AACV,QAAM,wBAAwB,IAAU;AAAA,IACtC,yBAAyB,CAAC;AAAA,IAC1B,yBAAyB,CAAC;AAAA,IAC1B,yBAAyB,CAAC;AAAA,EAC5B;AAEA,QAAM,oBAAoB,IAAU;AAAA,IAClC,qBAAqB,CAAC;AAAA,IACtB,qBAAqB,CAAC;AAAA,IACtB,qBAAqB,CAAC;AAAA,EACxB;AAEA,QAAM,eAAe,sBAAsB,OAAO;AAClD,QAAM,cAAc,sBAAsB,UAAU;AAEpD,MAAI,WAAW,kBAAkB,OAAO;AACxC,MAAI,UAAU,kBAAkB,UAAU;AAG1C,MAAI,QAAQ,IAAI,WAAW,IAAI,GAAG;AAChC,eAAW,CAAC;AACZ,cAAU,QAAQ,eAAe,EAAI;AAAA,EACvC;AAIA,MAAI,kBAAkB,WAAW;AACjC,qBACE,IAAM,KAAK,KAAK,KAAK,OAAO,kBAAkB,KAAK,OAAO,IAAM,KAAK,GAAG;AAE1E,aAAW,eAAe;AAE1B,SAAO,eAAe,QAAQ,eAAe,QAAQ,CAAC;AACxD;AAKO,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EAqDlC,YACW,MACA,YACA,aACA,oBACA,mBACT;AALS;AACA;AACA;AACA;AACA;AAET,SAAK,6BAA6B;AAElC,sBAAkB,iBAAiB,WAAW,CAAC,UAAU;AAvH7D;AAwHM,YAAM,eAAc,kBAAa,MAAM,IAAI,MAAvB,mBAA0B;AAI9C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI;AAAA,UACR,kCAAkC,KAAK,aAAa,KAAK,MAAM,IAAI;AAAA,QACrE;AAAA,MACF;AAGA,UACE,CAAC;AAAA,QACC,KAAK,2BAA2B,eAAe;AAAA,QAC/C,YAAY,eAAe;AAAA,QAC3BA;AAAA,MACF,GACA;AACA,sCAAY,MAAM;AAChB,eAAK,6BAA6B;AAAA,QACpC,CAAC;AAAA,MACH;AAGA,UACE,CAAC;AAAA,QACC,KAAK,2BAA2B;AAAA,QAChC,YAAY;AAAA,QACZA;AAAA,MACF,GACA;AACA,sCAAY,MAAM;AAChB,cAAI,KAAK,2BAA2B,YAAY,QAAW;AACzD,iBAAK,2BAA2B,WAAW,YAAY;AAAA,UACzD,OAAO;AACL,iBAAK,2BAA2B,WAAW;AAAA,cACzC,UAAU,YAAY,SAAU;AAAA,cAChC,aAAa;AAAA,gBACX,YAAY,SAAU;AAAA,gBACtB,KAAK,2BAA2B,SAC7B;AAAA,cACL;AAAA,cACA,KAAK,YAAY,SAAU;AAAA,cAC3B,mBAAmB,YAAY,SAAU;AAAA,YAC3C;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,yCAAmB,IAAI;AAAA,EACzB;AAAA,EAhHA,OAAa,KAAK,MAAkB,eAAuB;AAAA;AA1D7D;AA2DI,YAAM,EAAE,YAAyB,IAC/B,MAAM,KAAK,IAAI,WAAW,gBAAgB;AAE5C,YAAM,CAAC,mBAAmB,YAAY,IAAI,cAAc,MAAM,GAAG;AAIjE,YAAM,aAAa,YAAY,KAAK,CAAC,MAAM,EAAE,eAAe,YAAY;AACxE,YAAM,cAAc,yCAAY,cAAc;AAAA,QAC5C,CAAC,OAAO,GAAG,iBAAiB;AAAA;AAE9B,UAAI,CAAC,cAAc,CAAC,aAAa;AAC/B,cAAM,IAAI;AAAA,UACR,cAAc,YAAY,oBAAoB,aAAa;AAAA,QAC7D;AAAA,MACF;AAEA,YAAM,oBAAoB,KAAK;AAAA,QAC7B,kBAAkB,aAAa;AAAA,MACjC;AAGA,YAAM,eAAe,MAAM,kBAAkB,aAAa;AAC1D,cAAQ,IAAI,qBAAqB,YAAY;AAC7C,YAAM,sBAAqB,kBAAa,aAAa,IAAI,MAA9B,mBACvB;AAEJ,UAAI,CAAC,oBAAoB;AACvB,cAAM,IAAI;AAAA,UACR,gDAAgD,aAAa,IAAI;AAAA,QACnE;AAAA,MACF;AAEA,cAAQ;AAAA,QACN,oDAAoD,YAAY,YAAY;AAAA;AAAA,QAC5E;AAAA,MACF;AAEA,aAAO,IAAI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAoEA,IAAI,gBAAgB;AAClB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,sBAAsB;AACxB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,IAAI,yBAAyB;AAC3B,UAAM,MAAM,KAAK,cAAc,MAAM,GAAG,EAAE,CAAC;AAC3C,WAAO,GAAG,KAAK,aAAa,WAAW,KAAK,GAAG,CAAC,IAAI,GAAG;AAAA,EACzD;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,mBAAmB,eAAe,OAAO,IAAI,CAAC,GAAG,MAAM;AACjE,aAAO;AAAA,QACL,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU;AACR,SAAK,kBAAkB,MAAM;AAAA,EAC/B;AACF;;;ACvMA,gBAsBO;AAGP,IAAAC,gBAAkB;AAwBX,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YACW,QACA,MAIT;AALS;AACA;AAkFX,SAAS,SAAS,KAAK,2BAA2B,mBAAS;AAC3D,SAAS,OAAO,KAAK,2BAA2B,iBAAO;AAEvD,SAAS,cAAc,KAAK,WAAW,wBAAc;AACrD,SAAS,mBAAmB,KAAK,WAAW,4BAAkB;AAE9D,SAAS,aAAa,KAAK,WAAW,uBAAa;AAEnD,SAAS,UAAU,KAAK,WAAW,oBAAU;AAC7C,SAAS,kBAAkB,KAAK,WAAW,4BAAkB;AAE7D,SAAS,gBAAgB,KAAK,WAAW,oCAA0B;AAEnE,SAAS,uBAAuB,KAAK,WAAW,kCAAwB;AACxE,SAAS,qBAAqB,KAAK,WAAW,+BAAqB;AACnE,SAAS,sBAAsB,KAAK,WAAW,gCAAsB;AAErE,SAAS,oBAAoB,KAAK,WAAW,8BAAoB;AAEjE,SAAS,cAAc,KAAK,WAAW,wBAAc;AACrD,SAAS,oBAAoB,KAAK,2BAA2B,wBAAc;AAE3E,SAAS,UAAU,KAAK,WAAW,oBAAU;AAE7C,SAAS,eAAe,KAAK,WAAW,yBAAe;AACvD,SAAS,oBAAoB,KAAK,WAAW,8BAAoB;AACjE,SAAS,mBAAmB,KAAK,WAAW,6BAAmB;AAC/D,SAAS,uBAAuB,KAAK,WAAW,iCAAuB;AAEvE,SAAS,cAAc,KAAK,WAAW,wBAAc;AACrD,SAAS,2BAA2B,KAAK;AAAA,MACvC;AAAA,IACF;AACA,SAAS,uBAAuB,KAAK,WAAW,iCAAuB;AAAA,EA/GpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOK,WACN,gBAKA;AAtEJ;AAuEI,UAAM,YAAY,IAAI;AAAA,MACpB,iCACK,KAAK,OADV;AAAA,QAEE,YAAY,CAAC,SAAiB;AAC5B,iBAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAAA,OACA,UAAK,KAAK,aAAV,YAAsB;AAAA,OACtB,UAAK,KAAK,kBAAV,YAA2B,cAAAC,QAAM,OAAO;AAAA,IAC1C;AAIA,eAAW,OAAO,QAAQ,QAAQ,QAAQ,eAAe,SAAS,CAAE,GAAG;AACrE,UAAI,QAAQ,iBAAiB,OAAO,UAAU,GAAG,MAAM,YAAY;AACjE,cAAM,mBAAmB,UAAU,GAAG;AACtC,kBAAU,GAAG,IAAI,IAAI,SAAgB;AACnC,iBAAO,iBACJ,MAAM,WAAW,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,EACvC,KAAK,CAAC,QAAa,IAAI,IAAI;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,2BACN,gBAKA;AA3GJ;AA4GI,UAAM,YAAY,IAAI;AAAA,MACpB,iCACK,KAAK,OADV;AAAA,QAEE,YAAY,CAAC,SAAiB;AAC5B,iBAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAAA,OACA,UAAK,KAAK,aAAV,YAAsB;AAAA,OACtB,UAAK,KAAK,kBAAV,YAA2B,cAAAA,QAAM,OAAO;AAAA,IAC1C;AAIA,eAAW,OAAO,QAAQ,QAAQ,QAAQ,eAAe,SAAS,CAAE,GAAG;AACrE,UAAI,QAAQ,iBAAiB,OAAO,UAAU,GAAG,MAAM,YAAY;AACjE,cAAM,mBAAmB,UAAU,GAAG;AACtC,kBAAU,GAAG,IAAI,IAAI,SAAgB;AACnC,iBAAO,iBACJ,MAAM,WAAW,IAAI,EACrB,KAAK,CAAC,QAAa,IAAI,IAAI;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAoCF;;;ACvKA,IAAAC,gBAAoC;AACpC,sBAAoB;;;ACHpB,IAAM,gBAAgB;AAGtB,IAAM,iBAAiB;AAAA,EACrB,KAAK;AAAA,IACH,QAAQ,2BAA2B,aAAa;AAAA,IAChD,UAAU;AAAA,EACZ;AAAA,EACA,KAAK;AAAA,IACH,QAAQ,2BAA2B,aAAa;AAAA,IAChD,UAAU;AAAA,EACZ;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ,uBAAuB,aAAa;AAAA,IAC5C,UAAU;AAAA,EACZ;AACF;AAGA,IAAM,iBAAiB,CAAC,gBAAwB;AAC9C,MAAI,YAAY,SAAS,OAAO,aAAa,EAAE,EAAG,QAAO,eAAe;AACxE,MAAI,YAAY,SAAS,OAAO,aAAa,EAAE,EAAG,QAAO,eAAe;AACxE,MAAI,YAAY,SAAS,aAAa,EAAG,QAAO,eAAe;AAC/D,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAOO,IAAM,iBAAiB,CAC5B,gBAC2B;AAnC7B;AAoCE,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,eAAe,WAAW;AAE9C,MAAI,IAAI,IAAI,WAAW,EAAE,WAAW,OAAO,SAAS,QAAQ;AAI1D,WAAO,SAAS,OAAO;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAKA,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,qBAAqB;AAE1D,QAAM,cAAc,IAAI,YAAY;AAAA,IAClC,QAAQ,YAAY;AAAA,IACpB,WAAU,iBAAY,aAAZ,YAAwB;AAAA,IAClC,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,MACnB,UAAU;AAAA,MACV,cAAc,OAAO,SAAS;AAAA,IAChC;AAAA,EACF,CAAC;AAGD,MACE,OAAO,SAAS,OAAO,SAAS,OAAO,KACvC,OAAO,SAAS,OAAO,SAAS,QAAQ,GACxC;AACA,UAAM,EAAE,SAAS,IAAI,MAAM,YAAY,uBAAuB;AAE9D,WAAO,QAAQ;AAAA,MACb,CAAC;AAAA,MACD,SAAS;AAAA,OACT,qCAAU,aAAY,OAAO,SAAS;AAAA,IACxC;AAAA,EACF,OAAO;AAEL,UAAM,YAAY,kBAAkB;AAAA,EACtC;AAGA,QAAM,cAAc,MAAM,YAAY,iBAAiB;AACvD,SAAO;AACT;;;ACzFA,oCAAuD;AAIhD,IAAM,4BAAN,cAAwC,8BAAAC,QAAsB;AAAA,EAKnE,YACE,WACS,OAGL,CAAC,GACL;AACA,YAAQ,IAAI,wBAAwB,SAAS;AAE7C,UAAM,MAAM,KAAK,aAAa,WAAW,QAAW;AAAA,MAClD,aAAa;AAAA,IACf,CAAC;AATQ;AAJX,oBAAW;AAgBT,WAAO,eAAe,MAAM,OAAO;AAAA,MACjC,MAAM;AACJ,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AAEjB,SAAK,iBAAiB,QAAQ,MAAM;AAClC,cAAQ,IAAI,gBAAgB,KAAK,GAAG,SAAS;AAAA,IAC/C,CAAC;AAED,SAAK,iBAAiB,WAAW,CAAC,OAAO;AACvC,UAAI,CAAC,KAAK,sBAAsB;AAC9B,aAAK,uBAAuB;AAAA,MAC9B;AAAA,IACF,CAAC;AAED,SAAK,iBAAiB,SAAS,MAAM;AACnC,cAAQ,IAAI,gBAAgB,KAAK,GAAG,SAAS;AAAA,IAC/C,CAAC;AAED,UAAM,gBAAgB,KAAK;AAC3B,SAAK,YAAY,MAAM;AACrB,UAAI,KAAK,KAAK,MAAM;AAClB,aAAK,KAAK,KAAK,0BAA0B,IAAI;AAAA,MAC/C,OAAO;AACL,sBAAc,MAAM,IAAI;AAAA,MAC1B;AAAA,IACF;AAEA,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,UAAU,WAAmB;AAC3B,SAAK,uBAAuB;AAC5B,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,MAAe;AACtB,QAAI,KAAK,KAAK,MAAM;AAClB,WAAK,KAAK,KAAK,uBAAuB,MAAM,KAAK,UAAU,IAAI,CAAC;AAAA,IAClE,OAAO;AACL,WAAK,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACR,SAAK,MAAM;AACX,SAAK,WAAW;AAChB,QAAI,KAAK,KAAK,WAAW;AACvB,WAAK,KAAK,UAAU;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKM,SAAS;AAAA;AACb,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAI,KAAK,eAAe,UAAU,MAAM;AACtC,kBAAQ;AAAA,QACV,OAAO;AACL,eAAK,iBAAiB,QAAQ,MAAM,QAAQ,CAAC;AAC7C,eAAK,iBAAiB,SAAS,MAAM;AAAA,QACvC;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAKM,SAAS;AAAA;AACb,aAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAI,KAAK,eAAe,UAAU,QAAQ;AACxC,kBAAQ;AAAA,QACV,OAAO;AACL,eAAK,iBAAiB,SAAS,MAAM,QAAQ,CAAC;AAC9C,eAAK,iBAAiB,SAAS,MAAM;AAAA,QACvC;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOM,eAAe;AAAA;AACnB,UAAI,KAAK,sBAAsB;AAC7B,eAAO,KAAK;AAAA,MACd;AAEA,aAAO,IAAI,QAAsB,CAAC,SAAS,WAAW;AACpD,cAAM,YAAY,CAAC,OAAqB;AACtC,eAAK,uBAAuB;AAC5B,eAAK,oBAAoB,WAAW,SAAS;AAC7C,eAAK,oBAAoB,SAAS,OAAO;AACzC,kBAAQ,EAAE;AAAA,QACZ;AAEA,cAAM,UAAU,CAAC,OAAmB;AAClC,eAAK,oBAAoB,WAAW,SAAS;AAC7C,eAAK,oBAAoB,SAAS,OAAO;AACzC,iBAAO,EAAE;AAAA,QACX;AAEA,aAAK,iBAAiB,WAAW,SAAS;AAC1C,aAAK,iBAAiB,SAAS,OAAO;AAAA,MACxC,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMM,cAAc;AAAA;AAClB,aAAO,IAAI,QAAsB,CAAC,SAAS,WAAW;AACpD,cAAM,YAAY,CAAC,OAAqB;AACtC,eAAK,oBAAoB,WAAW,SAAS;AAC7C,eAAK,oBAAoB,SAAS,OAAO;AACzC,kBAAQ,EAAE;AAAA,QACZ;AAEA,cAAM,UAAU,CAAC,OAAmB;AAClC,eAAK,oBAAoB,WAAW,SAAS;AAC7C,eAAK,oBAAoB,SAAS,OAAO;AACzC,iBAAO,EAAE;AAAA,QACX;AAEA,aAAK,iBAAiB,WAAW,SAAS;AAC1C,aAAK,iBAAiB,SAAS,OAAO;AAAA,MACxC,CAAC;AAAA,IACH;AAAA;AACF;;;AC9JA,IAAM,mBAAN,MAAuB;AAAA,EAAvB;AACE,qBAAY,OAAO,WAAW,eAAe,CAAC,CAAC,OAAO;AAAA;AAAA,EAEtD,QAAW,KAAgC;AACzC,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,UAAM,SAAS,OAAO,aAAa,QAAQ,GAAG;AAC9C,QAAI,WAAW,KAAM,QAAO;AAE5B,QAAI;AACF,aAAO,KAAK,MAAM,MAAM;AAAA,IAC1B,SAAS,KAAK;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,QAAQ,KAAa,KAAU;AAC7B,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,WAAO,aAAa,QAAQ,KAAK,KAAK,UAAU,GAAG,CAAC;AAAA,EACtD;AAAA,EAEA,OAAO,KAAa;AAClB,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,WAAO,aAAa,WAAW,GAAG;AAAA,EACpC;AAAA,EAEA,UAAU,KAAa,OAAe;AACpC,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,WAAO,aAAa,QAAQ,KAAK,KAAK;AAAA,EACxC;AAAA,EAEA,UAAU,KAA4B;AACpC,QAAI,CAAC,KAAK,UAAW,QAAO;AAE5B,WAAO,OAAO,aAAa,QAAQ,GAAG;AAAA,EACxC;AACF;AAEO,IAAM,mBAAmB,IAAI,iBAAiB;;;ACrCrD,IAAAC,gBAA2B;AAC3B,mBAA8B;AAOvB,IAAM,mBAAN,MAAuB;AAAA,EAAvB;AACL,SAAS,cAA2C,CAAC;AAAA;AAAA,EAE/C,iBACJ,QACwB;AAAA;AArB5B;AAsBI,YAAM,cAAc;AAAA,QAClB;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,aAAa;AAAA,gBACX;AAAA,kBACE,YAAY;AAAA,kBACZ,YAAY;AAAA,kBACZ,MAAM;AAAA,kBACN,sCAAsC;AAAA,kBACtC,eAAe;AAAA,oBACb;AAAA,sBACE,cAAc;AAAA,sBACd,sBAAsB;AAAA,sBACtB,QAAQ;AAAA,sBACR,uBAAuB;AAAA,oBACzB;AAAA,kBACF;AAAA,kBACA,WAAW;AAAA,kBACX,eAAe;AAAA,gBACjB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,eAAe;AAAA,gBACb,MAAM;AAAA,gBACN,cAAc;AAAA,gBACd,UAAU;AAAA,gBACV,MAAM;AAAA,cACR;AAAA,cACA,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,eAAe;AAAA,gBACb;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,OAAO;AAAA,kBACP,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,4BAA4B;AAAA,gBAC9B;AAAA,cACF;AAAA,cACA,yBAAyB;AAAA,gBACvB;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,gBACA;AAAA,kBACE,OAAO;AAAA,kBACP,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,WAAW;AAAA,gBACb;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,iBAAiB;AAAA,gBACf;AAAA,kBACE,cAAc;AAAA,kBACd,UAAU;AAAA,oBACR,uBAAuB;AAAA,sBACrB;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,aAAa;AAAA,wBACb,aAAa;AAAA,wBACb,WAAW;AAAA,sBACb;AAAA,oBACF;AAAA,oBACA,uBAAuB;AAAA,sBACrB;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,OAAO;AAAA,wBACP,OAAO;AAAA,sBACT;AAAA,oBACF;AAAA,oBACA,2BAA2B,CAAC;AAAA,oBAC5B,qBAAqB,CAAC;AAAA,oBACtB,oBAAoB;AAAA,kBACtB;AAAA,gBACF;AAAA,cACF;AAAA,cACA,cAAc;AAAA,gBACZ;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,UAAU;AAAA,oBACR,UAAU;AAAA,sBACR,kBAAkB;AAAA,wBAChB;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR,EAAE,QAAQ,CAAC,MAAM,OAAO,KAAK,EAAE;AAAA,8BAC/B,EAAE,QAAQ,CAAC,MAAM,OAAO,KAAK,EAAE;AAAA,8BAC/B,EAAE,QAAQ,CAAC,MAAM,MAAM,KAAK,EAAE;AAAA,8BAC9B,EAAE,QAAQ,CAAC,MAAM,MAAM,KAAK,EAAE;AAAA,4BAChC;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,wBACA;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,KAAK;AAAA,8BAC7B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,KAAK;AAAA,8BAC7B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,4BACF;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,wBACA;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,KAAK;AAAA,8BAC7B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,8BAC5B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,4BACF;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,wBACA;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,4BACF;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,wBACA;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,8BAC5B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,8BAC5B;AAAA,4BACF;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,wBACA;AAAA,0BACE,aAAa;AAAA,4BACX,UAAU;AAAA,8BACR;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,8BAC3B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,8BAC5B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,OAAO,KAAK;AAAA,8BAC7B;AAAA,8BACA;AAAA,gCACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,8BAC5B;AAAA,4BACF;AAAA,0BACF;AAAA,0BACA,WAAW;AAAA,4BACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,4BAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,0BAC1B;AAAA,0BACA,IAAI;AAAA,wBACN;AAAA,sBACF;AAAA,oBACF;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,sBAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,kBACA,kBAAkB;AAAA,gBACpB;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,UAAU;AAAA,oBACR,aAAa;AAAA,sBACX,UAAU;AAAA,wBACR;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,wBAC3B;AAAA,sBACF;AAAA,oBACF;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,sBAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,kBACA,kBAAkB;AAAA,gBACpB;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,UAAU;AAAA,oBACR,aAAa;AAAA,sBACX,UAAU;AAAA,wBACR;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,KAAK,IAAI;AAAA,wBACzB;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,KAAK,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,KAAK,KAAK;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,KAAK,KAAK;AAAA,wBAC3B;AAAA,sBACF;AAAA,oBACF;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,sBAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,kBACA,kBAAkB;AAAA,gBACpB;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,UAAU;AAAA,oBACR,aAAa;AAAA,sBACX,UAAU;AAAA,wBACR;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,OAAO,IAAI;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,OAAO,IAAI;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,OAAO,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,OAAO,KAAK;AAAA,wBAC7B;AAAA,sBACF;AAAA,oBACF;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,sBAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,kBACA,kBAAkB;AAAA,gBACpB;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,UAAU;AAAA,oBACR,aAAa;AAAA,sBACX,UAAU;AAAA,wBACR;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,KAAK;AAAA,wBAC5B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,KAAK,KAAK;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,KAAK,KAAK;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,MAAM,IAAI;AAAA,wBAC3B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,MAAM,IAAI;AAAA,wBAC1B;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,KAAK,KAAK,IAAI;AAAA,wBACzB;AAAA,wBACA;AAAA,0BACE,QAAQ,CAAC,MAAM,KAAK,IAAI;AAAA,wBAC1B;AAAA,sBACF;AAAA,oBACF;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,sBAClB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,kBACA,kBAAkB;AAAA,gBACpB;AAAA,cACF;AAAA,cACA,wBAAwB;AAAA,gBACtB;AAAA,kBACE,YAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,QAAQ;AAAA,sBACN,QAAQ;AAAA,oBACV;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,KAAK,KAAK,GAAG;AAAA,sBACxB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,YAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,SAAS;AAAA,sBACP,QAAQ;AAAA,sBACR,iBAAiB;AAAA,oBACnB;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,MAAM,IAAI,GAAG;AAAA,sBACxB,aAAa;AAAA,wBACX;AAAA,wBAAG;AAAA,wBAAqB;AAAA,wBAAG;AAAA,sBAC7B;AAAA,oBACF;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,YAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,QAAQ;AAAA,sBACN,QAAQ;AAAA,oBACV;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,MAAM,IAAI,IAAI;AAAA,sBACzB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,YAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,SAAS;AAAA,sBACP,QAAQ;AAAA,sBACR,iBAAiB;AAAA,oBACnB;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,KAAK,EAAE;AAAA,sBACrB,aAAa;AAAA,wBACX;AAAA,wBAAqB;AAAA,wBAAG;AAAA,wBAAG;AAAA,sBAC7B;AAAA,oBACF;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,YAAY;AAAA,kBACZ,UAAU;AAAA,oBACR,QAAQ;AAAA,sBACN,QAAQ;AAAA,oBACV;AAAA,oBACA,WAAW;AAAA,sBACT,UAAU,CAAC,GAAG,GAAG,GAAG;AAAA,sBACpB,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBAC1B;AAAA,oBACA,IAAI;AAAA,kBACN;AAAA,gBACF;AAAA,cACF;AAAA,cACA,iBAAiB,CAAC;AAAA,YACpB;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,mBAAmB;AAAA,gBACjB;AAAA,kBACE,mBAAmB;AAAA,kBACnB,MAAM;AAAA,kBACN,eAAe;AAAA,kBACf,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,kBAClB,UAAU;AAAA,oBACR,QAAQ,CAAC,GAAG,GAAG,CAAC;AAAA,oBAChB,MAAM;AAAA,kBACR;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,SAAS;AACP,mBAAO;AAAA,cACL,MAAM;AAAA,gBACJ;AAAA,kBACE,IAAI;AAAA,kBACJ,eAAe;AAAA,kBACf,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,kBAClB,UAAU;AAAA,oBACR,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,oBACnB,MAAM;AAAA,kBACR;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,eAAe;AAAA,kBACf,UAAU,CAAC,MAAM,KAAK,GAAG;AAAA,kBACzB,UAAU;AAAA,oBACR,QAAQ;AAAA,sBACN;AAAA,sBAAsB;AAAA,sBACtB;AAAA,sBAAqB;AAAA,oBACvB;AAAA,oBACA,MAAM;AAAA,kBACR;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,WAAS,YAAO,WAAP,mBAAe,kBAAiB;AAC/C,YAAM,OAAO,aAAW,kBAAO,QAAP,mBAAY,MAAM,UAAU,OAA5B,mBAAgC,MAAM,KAAK;AAEnE,iBAAW,WAAW,aAAa;AACjC,cAAMC,SAAqB,mBAAM,QAAQ,IAAI,EAAE,QAAQ,EAAE;AACzD,YAAI,WAAW,QAAQ,UAAUA,QAAO;AACtC,gBAAM,OAAO,QAAQ,OAAO;AAC5B,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,MAAM,KAAK,UAAU,IAAI;AAAA,YACzB,SAAS,CAAC;AAAA,YACV;AAAA,YACA,SAAS;AAAA,cACP,aAAa,OAAO;AAAA,YACtB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI;AAAA,QACR,yCAAyC,MAAM,IAAI,IAAI;AAAA,QACvD;AAAA,QACA;AAAA,MACF;AAAA,IAYF;AAAA;AAAA,EAEA,0BAA0B,QAAmC;AAC3D,SAAK,YAAY,KAAK,MAAM;AAE5B,eAAW,MAAM;AACf,aAAO,cAAc,IAAI,MAAM,MAAM,CAAC;AAEtC,cAAQ,IAAI,oCAAoC,OAAO,GAAG;AAE1D,UAAI,OAAO,IAAI,SAAS,eAAe,GAAG;AACxC,eAAO;AAAA,UACL,IAAI,aAAa,WAAW;AAAA,YAC1B,MAAM,KAAK,UAAU,kBAAkB;AAAA,UACzC,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,OAAO,IAAI,SAAS,aAAa,GAAG;AACtC,eAAO;AAAA,UACL,IAAI,aAAa,WAAW;AAAA,YAC1B,MAAM,KAAK,UAAU;AAAA,cACnB,QAAQ;AAAA,gBACN,cAAc;AAAA,gBACd,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,cAAc;AAAA,kBACd,WAAW;AAAA,kBACX,mBAAmB;AAAA,kBACnB,eAAe;AAAA,oBACb;AAAA,sBACE,cAAc;AAAA,sBACd,YAAY;AAAA,sBACZ,gBAAgB;AAAA,wBACd,QAAQ;AAAA,0BACN;AAAA,0BAAoB;AAAA,0BACpB;AAAA,0BAAoB;AAAA,0BACpB;AAAA,0BAAoB;AAAA,wBACtB;AAAA,sBACF;AAAA,sBACA,gBAAgB;AAAA,wBACd,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,sBAC3B;AAAA,sBACA,aAAa;AAAA,wBACX,UAAU;AAAA,0BACR;AAAA,0BAAmB;AAAA,0BACnB;AAAA,wBACF;AAAA,wBACA,aAAa;AAAA,0BACX,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,UAAU;AAAA,wBACR,UAAU;AAAA,0BACR;AAAA,0BAAmB;AAAA,0BACnB;AAAA,wBACF;AAAA,wBACA,aAAa;AAAA,0BACX,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,wBACnB,KAAK;AAAA,sBACP;AAAA,sBACA,UAAU;AAAA,wBACR,QAAQ;AAAA,0BACN,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,SAAS;AAAA,0BACP,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,OAAO;AAAA,wBACL,OAAO;AAAA,0BACL,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,QAAQ;AAAA,0BACN,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,qBAAqB;AAAA,wBACnB,eAAe;AAAA,0BACb;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,wBACF;AAAA,sBACF;AAAA,sBACA,eAAe;AAAA,wBACb,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,sBAC3B;AAAA,sBACA,iBAAiB;AAAA,oBACnB;AAAA,kBACF;AAAA,kBACA,iBAAiB;AAAA,gBACnB;AAAA,gBACA,gBAAgB;AAAA,cAClB;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,OAAO,IAAI,SAAS,WAAW,GAAG;AACpC,eAAO;AAAA,UACL,IAAI,aAAa,WAAW;AAAA,YAC1B,MAAM,KAAK,UAAU;AAAA,cACnB,QAAQ;AAAA,gBACN,cAAc;AAAA,gBACd,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,cAAc;AAAA,kBACd,WAAW;AAAA,kBACX,mBAAmB;AAAA,kBACnB,eAAe;AAAA,oBACb;AAAA,sBACE,cAAc;AAAA,sBACd,YAAY;AAAA,sBACZ,gBAAgB;AAAA,wBACd,QAAQ;AAAA,0BACN;AAAA,0BAAoB;AAAA,0BACpB;AAAA,0BAAoB;AAAA,0BACpB;AAAA,0BAAoB;AAAA,wBACtB;AAAA,sBACF;AAAA,sBACA,gBAAgB;AAAA,wBACd,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,sBAC3B;AAAA,sBACA,aAAa;AAAA,wBACX,UAAU;AAAA,0BACR;AAAA,0BAAoB;AAAA,0BACpB;AAAA,wBACF;AAAA,wBACA,aAAa;AAAA,0BACX,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,UAAU;AAAA,wBACR,UAAU;AAAA,0BACR;AAAA,0BAAoB;AAAA,0BACpB;AAAA,wBACF;AAAA,wBACA,aAAa;AAAA,0BACX,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,wBACnB,KAAK;AAAA,sBACP;AAAA,sBACA,UAAU;AAAA,wBACR,QAAQ;AAAA,0BACN,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,SAAS;AAAA,0BACP,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,OAAO;AAAA,wBACL,OAAO;AAAA,0BACL,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,QAAQ;AAAA,0BACN,GAAG;AAAA,0BACH,GAAG;AAAA,0BACH,GAAG;AAAA,wBACL;AAAA,wBACA,mBAAmB;AAAA,sBACrB;AAAA,sBACA,qBAAqB;AAAA,wBACnB,eAAe;AAAA,0BACb;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA;AAAA,wBACF;AAAA,sBACF;AAAA,sBACA,eAAe;AAAA,wBACb,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,sBAC3B;AAAA,sBACA,iBAAiB;AAAA,oBACnB;AAAA,kBACF;AAAA,kBACA,iBAAiB;AAAA,gBACnB;AAAA,gBACA,gBAAgB;AAAA,cAClB;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,GAAG,EAAE;AAAA,EACP;AAAA,EAEA,uBAAuB,QAAmC,SAAiB;AACzE,YAAQ,IAAI,uBAAuB,OAAO,GAAG,IAAI,OAAO;AAAA,EAC1D;AACF;AAEA,IAAM,qBAAqB;AAAA,EACzB,QAAQ;AAAA,IACN,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,MACd,QAAQ;AAAA,QACN;AAAA,QAAoB;AAAA,QAAqB;AAAA,QACzC;AAAA,QAAoB;AAAA,QAAoB;AAAA,MAC1C;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAC3B;AAAA,IACA,aAAa;AAAA,MACX,UAAU,CAAC,oBAAoB,oBAAoB,iBAAiB;AAAA,MACpE,aAAa;AAAA,QACX;AAAA,QAAoB;AAAA,QAAqB;AAAA,MAC3C;AAAA,MACA,mBAAmB;AAAA,IACrB;AAAA,IACA,UAAU;AAAA,MACR,UAAU,CAAC,oBAAoB,oBAAoB,iBAAiB;AAAA,MACpE,aAAa;AAAA,QACX;AAAA,QAAoB;AAAA,QAAqB;AAAA,MAC3C;AAAA,MACA,mBAAmB;AAAA,MACnB,KAAK;AAAA,IACP;AAAA,IACA,UAAU;AAAA,MACR,QAAQ,CAAC,GAAG,GAAG,CAAC;AAAA,MAChB,SAAS,CAAC,GAAG,GAAG,CAAC;AAAA,MACjB,mBAAmB;AAAA,IACrB;AAAA,IACA,OAAO;AAAA,MACL,OAAO,CAAC,GAAG,GAAG,CAAC;AAAA,MACf,QAAQ,CAAC,GAAG,GAAG,CAAC;AAAA,MAChB,mBAAmB;AAAA,IACrB;AAAA,IACA,qBAAqB;AAAA,MACnB,eAAe,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1D;AAAA,IACA,eAAe;AAAA,MACb,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAC3B;AAAA,EACF;AACF;;;AJh6BO,IAAM,aAAN,MAAiB;AAAA,EAOtB,YAAY,QAA0B;AAHtC,uBAA6C;AAC7C,uBAA6B;AA1D/B;AA6DI,YAAQ,KAAK,mCAAmC;AAChD,UAAM,UAAS,YAAO,WAAP,YAAiB;AAChC,SAAK,SAAS;AAAA,MACZ;AAAA,OACG;AAEL,SAAK,cACH,OAAO,eACP,iBAAiB,UAAU,mBAAmB,KAC9C;AAEF,QAAI,KAAK,OAAO,gBAAgB,4BAA4B;AAC1D,WAAK,OAAO,IAAI,iBAAiB;AAAA,IACnC;AAGA,UAAM,gBAAgB,cAAAC,QAAM,OAAO;AAAA,MACjC,aAAS,gBAAAC,SAAQ,KAAK,OAAO,aAAa,SAAS;AAAA,MACnD,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAED,kBAAc,aAAa,QAAQ,IAAI,CAAO,YAAY;AACxD,UAAI,CAAC,QAAQ,QAAQ,eAAe;AAClC,YAAI,KAAK,aAAa;AACpB,kBAAQ,QAAQ,gBAAgB,UAAU,KAAK,WAAW;AAAA,QAC5D,WAAW,KAAK,OAAO,YAAY,KAAK,OAAO,UAAU;AACvD,kBAAQ,QAAQ,gBAAgB,SAAS,KAAK,OAAO,WAAW,MAAM,OAAO,QAAQ,CAAC;AAAA,QACxF;AAAA,MACF;AACA,aAAO;AAAA,IACT,EAAC;AAED,QAAI,OAAO,WAAW,aAAa;AACjC,oBAAc,aAAa,SAAS;AAAA,QAClC,CAAC,MAAM;AAAA,QACP,CAAO,UAAU;AAnGzB,cAAAC,KAAA;AAoGU,kBAAI,4BAAa,KAAK,GAAG;AACvB,kBAAIA,MAAA,MAAM,aAAN,gBAAAA,IAAgB,YAAW,KAAK;AAGlC,kBAAI;AACF,sBAAM,KAAK,oBAAoB;AAE/B,oBAAI,MAAM,QAAQ;AAChB,sBAAI,KAAK,aAAa;AACpB,0BAAM,OAAO,QAAQ,gBAAgB,UAAU,KAAK,WAAW;AAAA,kBACjE,OAAO;AACL,2BAAO,MAAM,OAAO,QAAQ;AAAA,kBAC9B;AACA,yBAAO,cAAc,QAAQ,MAAM,MAAM;AAAA,gBAC3C;AAAA,cACF,SAAS,KAAK;AACZ,uBAAO,QAAQ,OAAO,GAAG;AAAA,cAC3B;AAAA,YACF,aAAW,WAAM,aAAN,mBAAgB,YAAW,KAAK;AAEzC,oBAAM,MAAM,MAAM,MAAM,OAAO,SAAS,IAAI;AAC5C,kBAAI,IAAI,WAAW,KAAK;AAEtB,uBAAO,SAAS,OAAO;AAAA,cACzB;AAAA,YACF;AAAA,UACF;AAEA,iBAAO,QAAQ,OAAO,KAAK;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,SAAK,MAAM,IAAI,kBAAkB,QAAQ,iCACpC,SADoC;AAAA,MAEvC,cAAU,gBAAAD,SAAQ,KAAK,OAAO,aAAa,SAAS;AAAA,MACpD,YAAY,CAAC,SAAiB;AAC5B,eAAO,SAAS;AAAA,MAClB;AAAA,MACA,aAAa,kCACP,KAAK,OACJ;AAAA,QACC,SAAS,CAACE,YAAW;AACnB,iBAAO,KAAK,KAAM,iBAAiBA,OAAM;AAAA,QAC3C;AAAA,MACF,IACA,CAAC,IACF,OAAO;AAAA,MAEZ;AAAA,IACF,EAAC;AAAA,EACH;AAAA,EAEM,sBAAqC;AAAA;AACzC,UAAI,KAAK,aAAa;AAEpB;AAAA,MACF;AAEA,WAAK,cAAc,eAAe,KAAK,OAAO,WAAW;AACzD,UAAI;AACF,aAAK,cAAc,MAAM,KAAK;AAC9B,YAAI,KAAK,aAAa;AAEpB,2BAAiB,UAAU,qBAAqB,KAAK,WAAW;AAAA,QAClE,OAAO;AACL,2BAAiB,OAAO,mBAAmB;AAAA,QAC7C;AAAA,MACF,UAAE;AACA,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA;AAAA,EAEA,iBAAiB,MAAsB;AACrC,UAAM,MAAM,IAAI;AAAA,UACd,gBAAAF;AAAA,QACE,KAAK,OAAO;AAAA,QACZ,iBAAiB,KAAK,OAAO,MAAM;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AACA,QAAI,WAAW,IAAI,SAAS,QAAQ,QAAQ,IAAI;AAChD,QAAI,WAAW,IAAI,SAAS,QAAQ,SAAS,KAAK;AAKlD,QAAI,KAAK,aAAa;AACpB,UAAI,aAAa,OAAO,SAAS,KAAK,WAAW;AAAA,IACnD,WAAW,KAAK,OAAO,YAAY,KAAK,OAAO,UAAU;AACvD,UAAI,WAAW,KAAK,OAAO;AAC3B,UAAI,WAAW,KAAK,OAAO;AAAA,IAC7B;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,0BAA0B,MAAc;AACtC,WAAO,IAAI,0BAA0B,KAAK,iBAAiB,IAAI,GAAG;AAAA,MAChE,MAAM,KAAK;AAAA,IACb,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKM,oBAAoB,eAAuB;AAAA;AAC/C,aAAO,MAAM,uBAAuB,KAAK,MAAM,aAAa;AAAA,IAC9D;AAAA;AAAA,EAEM,oBACJ,gBACiC;AAAA;AACjC,YAAM,EAAE,YAAY,IAAI,MAAM,KAAK,IAAI,WAAW,gBAAgB;AAElE,aAAO,QAAQ;AAAA,QACb,eAAe;AAAA,UAAI,CAAC,kBAClB,qBAAqB,QAAQ,MAAM,eAAe,WAAW;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAEM,mBACJ,eAC+B;AAAA;AAC/B,YAAM,eAAe,MAAM,KAAK,oBAAoB,CAAC,aAAa,CAAC;AACnE,aAAO,aAAa,CAAC;AAAA,IACvB;AAAA;AACF;;;AKzOA,IAAAG,gBAA2B;AAC3B,IAAAC,eAAgD;AAYzC,IAAK,eAAL,kBAAKC,kBAAL;AACL,EAAAA,cAAA,gBAAa;AACb,EAAAA,cAAA,aAAU;AACV,EAAAA,cAAA,aAAU;AACV,EAAAA,cAAA,YAAS;AACT,EAAAA,cAAA,eAAY;AALF,SAAAA;AAAA,GAAA;AA4BL,IAAM,yBAAN,MAA6B;AAAA,EASlC,YAAqB,MAAkB;AAAlB;AARrB,0BAAiC,CAAC;AAClC,gBAAgC,CAAC;AAEjC,0BAAiB;AACjB,6CAAoC;AAKlC,yCAAmB,MAAM,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAE/C,SAAK,qBAAqB,KAAK,0BAA0B,iBAAiB;AAE1E,SAAK,mBAAmB,iBAAiB,WAAW,CAAC,OAAO;AAC1D,YAAM,MAAM,aAAa,GAAG,IAAI;AAEhC,UAAI,CAAC,KAAK;AACR,gBAAQ,MAAM,yCAAyC,GAAG,IAAI;AAC9D;AAAA,MACF;AACA,UAAI,IAAI,SAAS,UAAU;AACzB,aAAK,0BAA0B,GAAG;AAAA,MACpC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGM,0BAA0B,KAA0B;AAAA;AArE5D;AAsEI,YAAM,EAAE,OAAO,IAAI;AAInB,UAAI,OAAO,OAAO,KAAK,kCAAmC;AAE1D,UAAI,OAAO,UAAU,uBAAqB;AACxC,YAAI;AACF,gBAAM,cAAc,MAAM,KAAK,KAAK,IAAI,QAAQ,cAAc,OAAO,EAAE;AAIvE,gBAAM,SAAU,YAAoB;AACpC,cAAI,QAAQ;AACV,iBAAK,IAAI,MAAM;AAAA,UACjB;AACA,eAAK;AAAA,YACH,kBAAkB,OAAO,EAAE,uBAAuB,YAAY,KAAK;AAAA,EAAK,YAAY,SAAS;AAAA,UAC/F;AAAA,QACF,SAAS,KAAK;AACZ,eAAK;AAAA,YACH,0CAA0C,OAAO,EAAE,KAAK,GAAG;AAAA,UAC7D;AAAA,QACF;AAEA,aAAK,eAAe,QAAQ;AAE5B,aAAK,cAAc;AAAA,MACrB,WAAW,OAAO,UAAU,yBAAsB;AAChD,YAAI;AACF,gBAAM,cAAc,MAAM,KAAK,KAAK,IAAI,QAAQ,cAAc,OAAO,EAAE;AAEvE,gBAAM,SAAU,YAAoB;AACpC,cAAI,QAAQ;AACV,iBAAK,IAAI,MAAM;AAAA,UACjB;AAEA,eAAK,eAAe,QAAQ;AAC5B,eAAK,IAAI,kBAAkB,OAAO,EAAE,UAAU;AAAA,QAChD,SAAS,KAAK;AACZ,eAAK;AAAA,YACH,0CAA0C,OAAO,EAAE,KAAK,GAAG;AAAA,UAC7D;AAAA,QACF;AAEA,aAAK,cAAc;AAAA,MACrB,WAAW,OAAO,UAAU,6BAAwB;AAClD,YAAI;AACF,gBAAM,cAAc,MAAM,KAAK,KAAK,IAAI,QAAQ,cAAc,OAAO,EAAE;AAEvE,gBAAM,SAAU,YAAoB;AACpC,cAAI,QAAQ;AACV,iBAAK,IAAI,MAAM;AAAA,UACjB;AACA,eAAK;AAAA,YACH,kBAAkB,OAAO,EAAE,8BAA6B,YAAO,mBAAP,mBAAuB,QAAQ,EAAE;AAAA,UAC3F;AAEA,eAAK,eAAe,QAAQ;AAAA,QAC9B,SAAS,KAAK;AACZ,eAAK;AAAA,YACH,0CAA0C,OAAO,EAAE,KAAK,GAAG;AAAA,UAC7D;AAAA,QACF;AAEA,aAAK,cAAc;AAAA,MACrB,WAAW,OAAO,UAAU,yBAAsB;AAChD,aAAK,eAAe,QAAQ;AAC5B,aAAK,IAAI,kBAAkB,OAAO,EAAE,cAAc;AAAA,MACpD,WAAW,OAAO,UAAU,gCAAyB;AACnD,gBAAQ,MAAM,MAAM;AACpB,aAAK;AAAA,UACH,kBAAkB,OAAO,EAAE,8BAA8B,OAAO,KAAK;AAAA,QACvE;AACA,aAAK,eAAe,QAAQ;AAC5B,aAAK,cAAc;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;AAAA,EAGA,gBAAgB;AACd,kCAAY,MAAM;AAChB,WAAK,iBAAiB;AAAA,IACxB,CAAC;AACD,SAAK,oCAAoC;AAAA,EAC3C;AAAA,EAEM,eACJ,cACA,eACA,aACA;AAAA;AACA,WAAK,iBAAiB;AAAA,QACpB;AAAA,QACA,OAAO;AAAA,MACT;AAEA,YAAM,EAAE,gBAAgB,YAAY,IAAI;AACxC,UAAI,CAAC,YAAa;AAClB,oCAAY,MAAM;AAChB,aAAK,iBAAiB;AAAA,MACxB,CAAC;AAGD,YAAM,cAAc,YAAY,aAAc,WAAW,WAAW,EAAE;AAEtE,UAAI;AACF,cAAM,mBAAmB,MAAM,KAAK,KAAK,IAAI,QAAQ;AAAA,UACnD;AAAA,YACE,MAAM;AAAA,YACN;AAAA,YACA,eAAe,2CAAa;AAAA,UAC9B;AAAA,UACA;AAAA,YACE,SAAS;AAAA,cACP,gBAAgB;AAAA,YAClB;AAAA,UACF;AAAA,QACF;AAEA,aAAK,IAAI,0BAA0B,iBAAiB,EAAE,GAAG;AACzD,sCAAY,MAAM;AAChB,eAAK,iBAAiB;AAAA,QACxB,CAAC;AACD,aAAK,oCAAoC,iBAAiB;AAAA,MAC5D,SAAS,OAAO;AACd,YAAI,iBAAiB,4BAAc,MAAM,YAAY,MAAM,SAAS;AAClE,eAAK;AAAA,YACH,GAAG,MAAM,SAAS,MAAM,IAAI,MAAM,SAAS,UAAU,SAAS,MAAM,SAAS,OAAO,GAAG,IAAI,KAAK,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,UAChI;AAAA,QACF,OAAO;AACL,eAAK,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,QACrC;AACA,sCAAY,MAAM;AAChB,eAAK,iBAAiB;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,IACF;AAAA;AAAA,EAEM,cAAc;AAAA;AAClB,UAAI,CAAC,KAAK,kCAAmC;AAC7C,oCAAY,MAAM;AAChB,aAAK,iBAAiB;AAAA,MACxB,CAAC;AAED,UAAI;AACF,cAAM,KAAK,KAAK,IAAI,QAAQ;AAAA,UAC1B,KAAK;AAAA,QACP;AAAA,MACF,SAAS,KAAK;AAEZ,sCAAY,MAAM;AAChB,eAAK,iBAAiB;AAAA,QACxB,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA,EAEA,QAAQ;AACN,SAAK,iBAAiB,CAAC;AAAA,EACzB;AAAA,EAEA,IAAI,SAAiB;AACnB,YAAQ,IAAI,OAAO;AACnB,SAAK,KAAK,KAAK;AAAA,MACb,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,SAAS,SAAiB;AACxB,YAAQ,IAAI,OAAO;AACnB,SAAK,KAAK,KAAK;AAAA,MACb,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;","names":["import_mobx","THREE","MOTION_DELTA_THRESHOLD","import_axios","axios","import_axios","ReconnectingWebSocket","import_axios","match","axios","urlJoin","_a","config","import_axios","import_mobx","ProgramState"]}
1
+ {"version":3,"sources":["../../../src/lib/v2/index.ts","../../../src/lib/v2/ConnectedMotionGroup.ts","../../../src/lib/converters.ts","../../../src/lib/v2/motionStateUpdate.ts","../../../src/lib/v2/vectorUtils.ts","../../../src/lib/v2/JoggerConnection.ts","../../../src/lib/v2/MotionStreamConnection.ts","../../../src/lib/v2/NovaCellAPIClient.ts","../../../src/lib/v2/NovaClient.ts","../../../src/LoginWithAuth0.ts","../../../src/lib/AutoReconnectingWebsocket.ts","../../../src/lib/availableStorage.ts","../../../src/lib/v2/mock/MockNovaInstance.ts","../../../src/lib/v2/ProgramStateConnection.ts"],"sourcesContent":["export * from \"@wandelbots/nova-api/v2\"\nexport * from \"./ConnectedMotionGroup\"\nexport * from \"./JoggerConnection\"\nexport * from \"./MotionStreamConnection\"\nexport * from \"./NovaCellAPIClient\"\nexport * from \"./NovaClient\"\nexport * from \"./ProgramStateConnection\"\n","import type {\n Controller,\n MotionGroupPhysical,\n MotionGroupSpecification,\n MotionGroupState,\n RobotTcp,\n SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nexport type MotionGroupOption = {\n selectionId: string\n} & MotionGroupPhysical\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class ConnectedMotionGroup {\n static async connect(\n nova: NovaClient,\n motionGroupId: string,\n controllers: Controller[],\n ) {\n const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n string,\n string,\n ]\n const controller = controllers.find((c) => c.controller === controllerId)\n const motionGroup = controller?.motion_groups.find(\n (mg) => mg.motion_group === motionGroupId,\n )\n if (!controller || !motionGroup) {\n throw new Error(\n `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n )\n }\n\n const motionStateSocket = nova.openReconnectingWebsocket(\n `/motion-groups/${motionGroupId}/state-stream`,\n )\n\n // Wait for the first message to get the initial state\n const firstMessage = await motionStateSocket.firstMessage()\n const initialMotionState = tryParseJson(firstMessage.data)\n ?.result as MotionGroupState\n\n if (!initialMotionState) {\n throw new Error(\n `Unable to parse initial motion state message ${firstMessage.data}`,\n )\n }\n\n console.log(\n `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n `,\n initialMotionState,\n )\n\n // This is used to determine if the robot is virtual or physical\n let isVirtual = false\n try {\n const opMode =\n await nova.api.virtualRobotMode.getOperationMode(controllerId)\n\n if (opMode) isVirtual = true\n } catch (err) {\n if (err instanceof AxiosError) {\n console.log(\n `Received ${err.status} from getOperationMode, concluding that ${controllerId} is physical`,\n )\n } else {\n throw err\n }\n }\n\n // Find out what TCPs this motion group has (we need it for jogging)\n const { tcps } = await nova.api.motionGroupInfos.listTcps(motionGroupId)\n\n const motionGroupSpecification =\n await nova.api.motionGroupInfos.getMotionGroupSpecification(motionGroupId)\n\n const safetySetup =\n await nova.api.motionGroupInfos.getSafetySetup(motionGroupId)\n\n return new ConnectedMotionGroup(\n nova,\n controller,\n motionGroup,\n initialMotionState,\n motionStateSocket,\n isVirtual,\n tcps!,\n motionGroupSpecification,\n safetySetup,\n )\n }\n\n connectedJoggingCartesianSocket: WebSocket | null = null\n connectedJoggingJointsSocket: WebSocket | null = null\n planData: any | null // tmp\n joggingVelocity: number = 10\n\n // Not mobx-observable as this changes very fast; should be observed\n // using animation frames\n rapidlyChangingMotionState: MotionGroupState\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: Controller,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupState,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n readonly isVirtual: boolean,\n readonly tcps: RobotTcp[],\n readonly motionGroupSpecification: MotionGroupSpecification,\n readonly safetySetup: SafetySetup,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionStateResponse = tryParseJson(event.data)?.result as\n | MotionGroupState\n | undefined\n\n if (!motionStateResponse) {\n throw new Error(\n `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n )\n }\n\n // handle motionState message\n if (\n !jointValuesEqual(\n this.rapidlyChangingMotionState.joint_position.joints,\n motionStateResponse.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState = motionStateResponse\n })\n }\n\n // handle tcpPose message\n if (\n !tcpPoseEqual(\n this.rapidlyChangingMotionState.tcp_pose,\n motionStateResponse.tcp_pose,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState.tcp_pose =\n motionStateResponse.tcp_pose\n })\n }\n })\n makeAutoObservable(this)\n }\n\n get motionGroupId() {\n return this.motionGroup.motion_group\n }\n\n get controllerId() {\n return this.controller.controller\n }\n\n get modelFromController() {\n return this.motionGroup.model_from_controller\n }\n\n get wandelscriptIdentifier() {\n const num = this.motionGroupId.split(\"@\")[0]\n return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n }\n\n /** Jogging velocity in radians for rotation and joint movement */\n get joggingVelocityRads() {\n return (this.joggingVelocity * Math.PI) / 180\n }\n\n get joints() {\n return this.initialMotionState.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n get dhParameters() {\n return this.motionGroupSpecification.dh_parameters\n }\n\n get safetyZones() {\n return this.safetySetup.safety_zones\n }\n\n dispose() {\n this.motionStateSocket.close()\n if (this.connectedJoggingCartesianSocket)\n this.connectedJoggingCartesianSocket.close()\n if (this.connectedJoggingJointsSocket)\n this.connectedJoggingJointsSocket.close()\n }\n\n setJoggingVelocity(velocity: number) {\n this.joggingVelocity = velocity\n }\n}\n","import type { Pose } from \"@wandelbots/nova-api/v1\"\n\n/** Try to parse something as JSON; return undefined if we can't */\nexport function tryParseJson(json: unknown): any {\n try {\n return JSON.parse(json as string)\n } catch {\n return undefined\n }\n}\n\n/** Try to turn something into JSON; return undefined if we can't */\nexport function tryStringifyJson(json: unknown): string | undefined {\n try {\n return JSON.stringify(json)\n } catch {\n return undefined\n }\n}\n\n/**\n * Converts object parameters to query string.\n * e.g. { a: \"1\", b: \"2\" } => \"?a=1&b=2\"\n * {} => \"\"\n */\nexport function makeUrlQueryString(obj: Record<string, string>): string {\n const str = new URLSearchParams(obj).toString()\n return str ? `?${str}` : \"\"\n}\n\n/** Convert radians to degrees */\nexport function radiansToDegrees(radians: number): number {\n return radians * (180 / Math.PI)\n}\n\n/** Convert degrees to radians */\nexport function degreesToRadians(degrees: number): number {\n return degrees * (Math.PI / 180)\n}\n\n/**\n * Convert a Pose object representing a motion group position\n * into a string which represents that pose in Wandelscript.\n */\nexport function poseToWandelscriptString(\n pose: Pick<Pose, \"position\" | \"orientation\">,\n) {\n const position = [pose.position.x, pose.position.y, pose.position.z]\n const orientation = [\n pose.orientation?.x ?? 0,\n pose.orientation?.y ?? 0,\n pose.orientation?.z ?? 0,\n ]\n\n const positionValues = position.map((v) => v.toFixed(1))\n // Rotation needs more precision since it's in radians\n const rotationValues = orientation.map((v) => v.toFixed(4))\n\n return `(${positionValues.concat(rotationValues).join(\", \")})`\n}\n\n/**\n * Check for coordinate system id equivalence, accounting for the \"world\" default\n * on empty/undefined values.\n */\nexport function isSameCoordinateSystem(\n firstCoordSystem: string | undefined,\n secondCoordSystem: string | undefined,\n) {\n if (!firstCoordSystem) firstCoordSystem = \"world\"\n if (!secondCoordSystem) secondCoordSystem = \"world\"\n\n return firstCoordSystem === secondCoordSystem\n}\n","import type { TcpPose } from \"@wandelbots/nova-api/v2\"\n\nexport function jointValuesEqual(\n oldJointValues: number[],\n newJointValues: number[],\n changeDeltaThreshold: number,\n): boolean {\n if (newJointValues.length !== oldJointValues.length) {\n return true\n }\n\n for (let jointIndex = 0; jointIndex < newJointValues.length; jointIndex++) {\n if (\n Math.abs(newJointValues[jointIndex]! - oldJointValues[jointIndex]!) >\n changeDeltaThreshold\n ) {\n return false\n }\n }\n\n return true\n}\n\nexport function tcpPoseEqual(\n oldTcp: TcpPose | undefined,\n newTcp: TcpPose | undefined,\n changeDeltaThreshold: number,\n): boolean {\n // undefined -> defined (+reverse) transition\n if ((oldTcp === undefined && newTcp) || (oldTcp && newTcp === undefined)) {\n return false\n }\n\n // the typechecker cannot resolve states to \"!= undefined\" if \"&&\" is used\n if (oldTcp === undefined || newTcp === undefined) {\n return true\n }\n\n let changedDelta = 0\n changedDelta += Math.abs(oldTcp.orientation[0] - newTcp.orientation[0])\n changedDelta += Math.abs(oldTcp.orientation[1] - newTcp.orientation[1])\n changedDelta += Math.abs(oldTcp.orientation[2] - newTcp.orientation[2])\n changedDelta += Math.abs(oldTcp.position[0] - newTcp.position[0])\n changedDelta += Math.abs(oldTcp.position[1] - newTcp.position[1])\n changedDelta += Math.abs(oldTcp.position[2] - newTcp.position[2])\n\n if (changedDelta > changeDeltaThreshold) {\n return false\n }\n\n return (\n oldTcp.coordinate_system === newTcp.coordinate_system &&\n oldTcp.tcp === newTcp.tcp\n )\n}\n","import * as THREE from \"three\"\n\n// Vector used by api endpoints\nexport type Vector3d = [number, number, number]\n\nexport function axisToIndex(axis: \"x\" | \"y\" | \"z\"): number {\n switch (axis) {\n case \"x\":\n return 0\n case \"y\":\n return 1\n case \"z\":\n return 2\n }\n}\n\nexport function indexToAxis(index: number): \"x\" | \"y\" | \"z\" | null {\n switch (index) {\n case 0:\n return \"x\"\n case 1:\n return \"y\"\n case 2:\n return \"z\"\n default:\n return null\n }\n}\n\nexport function vector3FromArray(vector: Vector3d): THREE.Vector3 {\n return new THREE.Vector3(vector[0], vector[1], vector[2])\n}\n\nexport function vector3ToArray(vector: THREE.Vector3): Vector3d {\n return [vector.x, vector.y, vector.z]\n}\n","import type {\n InitializeJoggingRequest,\n JoggingResponse,\n JointVelocityRequest,\n MotionGroupState,\n TcpVelocityRequest,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { axisToIndex } from \"./vectorUtils\"\n\nexport type JoggerConnectionOpts = {\n /**\n * When an error message is received from the jogging websocket, it\n * will be passed here. If this handler is not provided, the error will\n * instead be thrown as an unhandled error.\n */\n onError?: (err: unknown) => void\n} & Omit<InitializeJoggingRequest, \"message_type\">\n\nexport class JoggerConnection {\n // Currently a separate websocket is needed for each mode, pester API people\n // to merge these for simplicity\n joggingWebsocket: AutoReconnectingWebsocket | null = null\n lastVelocityRequest: JointVelocityRequest | TcpVelocityRequest | null = null\n lastResponse: JoggingResponse | null = null\n\n static async open(\n nova: NovaClient,\n cell: string,\n motionGroupId: string,\n opts: JoggerConnectionOpts,\n ) {\n const motionGroupState =\n await nova.api.motionGroupInfos.getCurrentMotionGroupState(motionGroupId)\n\n return new JoggerConnection(\n nova,\n cell,\n motionGroupId,\n motionGroupState,\n opts,\n )\n }\n\n constructor(\n readonly nova: NovaClient,\n readonly cell: string,\n readonly motionGroupId: string,\n readonly motionGroupState: MotionGroupState,\n readonly opts: JoggerConnectionOpts,\n ) {\n this.joggingWebsocket = nova.openReconnectingWebsocket(\n `/cells/${cell}/execution/jogging`,\n )\n this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n const data = tryParseJson(ev.data) as JoggingResponse\n if (data && \"error\" in data) {\n if (this.opts.onError) {\n this.opts.onError(ev.data)\n } else {\n throw new Error(ev.data)\n }\n }\n })\n\n this.joggingWebsocket.addEventListener(\"message\", (ev: MessageEvent) => {\n const data = tryParseJson(ev.data)\n if (data && \"error\" in data) {\n if (this.opts.onError) {\n this.opts.onError(ev.data)\n } else {\n throw new Error(ev.data)\n }\n }\n })\n }\n\n get jointCount() {\n return this.motionGroupState.joint_current?.joints.length\n }\n\n get activeWebsocket() {\n return this.joggingWebsocket\n }\n\n async stop() {\n // Why not call the stopJogging API endpoint?\n // Because this results in the websocket closing and we\n // would like to keep it open for now.\n if (!this.joggingWebsocket) {\n return\n }\n\n if (this.lastVelocityRequest?.message_type === \"JointVelocityRequest\") {\n this.joggingWebsocket.sendJson({\n message_type: \"JointVelocityRequest\",\n velocity: {\n joints: Array.from(new Array(this.jointCount).keys()).map(() => 0),\n },\n } as JointVelocityRequest)\n }\n\n if (this.lastVelocityRequest?.message_type === \"TcpVelocityRequest\") {\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n rotation: [0, 0, 0],\n translation: [0, 0, 0],\n } as TcpVelocityRequest)\n }\n }\n\n dispose() {\n if (this.joggingWebsocket) {\n this.joggingWebsocket.dispose()\n }\n }\n\n /**\n * Start rotation of a single robot joint at the specified velocity\n */\n async startJointRotation({\n joint,\n velocityRadsPerSec,\n }: {\n /** Index of the joint to rotate */\n joint: number\n /** Speed of the rotation in radians per second */\n velocityRadsPerSec: number\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Joint jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const jointVelocities = new Array(this.jointCount).fill(0)\n jointVelocities[joint] = velocityRadsPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"JointVelocityRequest\",\n velocity: {\n joints: jointVelocities,\n },\n } as JointVelocityRequest)\n }\n\n /**\n * Start the TCP moving along a specified axis at a given velocity\n */\n async startTCPTranslation({\n axis,\n velocityMmPerSec,\n useToolCoordinateSystem,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n velocityMmPerSec: number\n useToolCoordinateSystem: boolean\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const joggingVector = [0, 0, 0]\n joggingVector[axisToIndex(axis)] = velocityMmPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n\n translation: joggingVector,\n rotation: [0, 0, 0],\n use_tool_coordinate_system: useToolCoordinateSystem,\n } as TcpVelocityRequest)\n }\n\n /**\n * Start the TCP rotating around a specified axis at a given velocity\n */\n async startTCPRotation({\n axis,\n velocityRadsPerSec,\n useToolCoordinateSystem,\n }: {\n axis: \"x\" | \"y\" | \"z\"\n velocityRadsPerSec: number\n useToolCoordinateSystem: boolean\n }) {\n if (!this.joggingWebsocket) {\n throw new Error(\n \"Cartesian jogging websocket not connected. Wait for reconnect or open new jogging connection\",\n )\n }\n\n const joggingVector = [0, 0, 0]\n joggingVector[axisToIndex(axis)] = velocityRadsPerSec\n\n this.joggingWebsocket.sendJson({\n message_type: \"TcpVelocityRequest\",\n rotation: joggingVector,\n translation: [0, 0, 0],\n use_tool_coordinate_system: useToolCoordinateSystem,\n } as TcpVelocityRequest)\n }\n}\n","import type {\n Controller,\n MotionGroupPhysical,\n MotionGroupState,\n} from \"@wandelbots/nova-api/v2\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport * as THREE from \"three\"\nimport type { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport { jointValuesEqual, tcpPoseEqual } from \"./motionStateUpdate\"\nimport type { NovaClient } from \"./NovaClient\"\nimport { Vector3d, vector3ToArray } from \"./vectorUtils\"\n\nconst MOTION_DELTA_THRESHOLD = 0.0001\n\nfunction unwrapRotationVector(\n newRotationVectorApi: Vector3d,\n currentRotationVectorApi: Vector3d,\n): Vector3d {\n const currentRotationVector = new THREE.Vector3(\n currentRotationVectorApi[0],\n currentRotationVectorApi[1],\n currentRotationVectorApi[2],\n )\n\n const newRotationVector = new THREE.Vector3(\n newRotationVectorApi[0],\n newRotationVectorApi[1],\n newRotationVectorApi[2],\n )\n\n const currentAngle = currentRotationVector.length()\n const currentAxis = currentRotationVector.normalize()\n\n let newAngle = newRotationVector.length()\n let newAxis = newRotationVector.normalize()\n\n // Align rotation axes\n if (newAxis.dot(currentAxis) < 0) {\n newAngle = -newAngle\n newAxis = newAxis.multiplyScalar(-1.0)\n }\n\n // Shift rotation angle close to previous one to extend domain of rotation angles beyond [0, pi]\n // - this simplifies interpolation and prevents abruptly changing signs of the rotation angles\n let angleDifference = newAngle - currentAngle\n angleDifference -=\n 2.0 * Math.PI * Math.floor((angleDifference + Math.PI) / (2.0 * Math.PI))\n\n newAngle = currentAngle + angleDifference\n\n return vector3ToArray(newAxis.multiplyScalar(newAngle))\n}\n\n/**\n * Store representing the current state of a connected motion group.\n */\nexport class MotionStreamConnection {\n static async open(nova: NovaClient, motionGroupId: string) {\n const { controllers: controllers } =\n await nova.api.controller.listControllers()\n\n const [_motionGroupIndex, controllerId] = motionGroupId.split(\"@\") as [\n string,\n string,\n ]\n const controller = controllers.find((c) => c.controller === controllerId)\n const motionGroup = controller?.motion_groups.find(\n (mg) => mg.motion_group === motionGroupId,\n )\n if (!controller || !motionGroup) {\n throw new Error(\n `Controller ${controllerId} or motion group ${motionGroupId} not found`,\n )\n }\n\n const motionStateSocket = nova.openReconnectingWebsocket(\n `/motion-groups/${motionGroupId}/state-stream`,\n )\n\n // Wait for the first message to get the initial state\n const firstMessage = await motionStateSocket.firstMessage()\n console.log(\"got first message\", firstMessage)\n const initialMotionState = tryParseJson(firstMessage.data)\n ?.result as MotionGroupState\n\n if (!initialMotionState) {\n throw new Error(\n `Unable to parse initial motion state message ${firstMessage.data}`,\n )\n }\n\n console.log(\n `Connected motion state websocket to motion group ${motionGroup.motion_group}. Initial state:\\n `,\n initialMotionState,\n )\n\n return new MotionStreamConnection(\n nova,\n controller,\n motionGroup,\n initialMotionState,\n motionStateSocket,\n )\n }\n\n // Not mobx-observable as this changes very fast; should be observed\n // using animation frames\n rapidlyChangingMotionState: MotionGroupState\n\n constructor(\n readonly nova: NovaClient,\n readonly controller: Controller,\n readonly motionGroup: MotionGroupPhysical,\n readonly initialMotionState: MotionGroupState,\n readonly motionStateSocket: AutoReconnectingWebsocket,\n ) {\n this.rapidlyChangingMotionState = initialMotionState\n\n motionStateSocket.addEventListener(\"message\", (event) => {\n const motionState = tryParseJson(event.data)?.result as\n | MotionGroupState\n | undefined\n\n if (!motionState) {\n throw new Error(\n `Failed to get motion state for ${this.motionGroupId}: ${event.data}`,\n )\n }\n\n // handle motionState message\n if (\n !jointValuesEqual(\n this.rapidlyChangingMotionState.joint_position.joints,\n motionState.joint_position.joints,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n this.rapidlyChangingMotionState = motionState\n })\n }\n\n // handle tcpPose message\n if (\n !tcpPoseEqual(\n this.rapidlyChangingMotionState.tcp_pose,\n motionState.tcp_pose,\n MOTION_DELTA_THRESHOLD,\n )\n ) {\n runInAction(() => {\n if (this.rapidlyChangingMotionState.tcp_pose == undefined) {\n this.rapidlyChangingMotionState.tcp_pose = motionState.tcp_pose\n } else {\n this.rapidlyChangingMotionState.tcp_pose = {\n position: motionState.tcp_pose!.position,\n orientation: unwrapRotationVector(\n motionState.tcp_pose!.orientation as Vector3d,\n this.rapidlyChangingMotionState.tcp_pose!\n .orientation as Vector3d,\n ),\n tcp: motionState.tcp_pose!.tcp,\n coordinate_system: motionState.tcp_pose!.coordinate_system,\n }\n }\n })\n }\n })\n makeAutoObservable(this)\n }\n\n get motionGroupId() {\n return this.motionGroup.motion_group\n }\n\n get controllerId() {\n return this.controller.controller\n }\n\n get modelFromController() {\n return this.motionGroup.model_from_controller\n }\n\n get wandelscriptIdentifier() {\n const num = this.motionGroupId.split(\"@\")[0]\n return `${this.controllerId.replaceAll(\"-\", \"_\")}_${num}`\n }\n\n get joints() {\n return this.initialMotionState.joint_position.joints.map((_, i) => {\n return {\n index: i,\n }\n })\n }\n\n dispose() {\n this.motionStateSocket.close()\n }\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport {\n ApplicationApi,\n CellApi,\n ControllerApi,\n ControllerInputsOutputsApi,\n CoordinateSystemsApi,\n JoggingApi,\n MotionGroupApi,\n MotionGroupInfoApi,\n MotionGroupKinematicsApi,\n ProgramApi,\n ProgramOperatorApi,\n StoreCollisionComponentsApi,\n StoreCollisionScenesApi,\n StoreObjectApi,\n SystemApi,\n TrajectoryExecutionApi,\n TrajectoryPlanningApi,\n VirtualRobotApi,\n VirtualRobotBehaviorApi,\n VirtualRobotModeApi,\n VirtualRobotSetupApi,\n} from \"@wandelbots/nova-api/v2\"\nimport type { BaseAPI } from \"@wandelbots/nova-api/v2/base\"\nimport type { AxiosInstance } from \"axios\"\nimport axios from \"axios\"\n\ntype OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R\n ? (...args: P) => R\n : never\n\ntype UnwrapAxiosResponseReturn<T> = T extends (...a: any) => any\n ? (\n ...a: Parameters<T>\n ) => Promise<Awaited<ReturnType<T>> extends { data: infer D } ? D : never>\n : never\n\nexport type WithCellId<T> = {\n [P in keyof T]: UnwrapAxiosResponseReturn<OmitFirstArg<T[P]>>\n}\n\nexport type WithUnwrappedAxiosResponse<T> = {\n [P in keyof T]: UnwrapAxiosResponseReturn<T[P]>\n}\n\n/**\n * API client providing type-safe access to all the Nova API REST endpoints\n * associated with a specific cell id.\n */\nexport class NovaCellAPIClient {\n constructor(\n readonly cellId: string,\n readonly opts: BaseConfiguration & {\n axiosInstance?: AxiosInstance\n mock?: boolean\n },\n ) {}\n\n /**\n * Some TypeScript sorcery which alters the API class methods so you don't\n * have to pass the cell id to every single one, and de-encapsulates the\n * response data\n */\n private withCellId<T extends BaseAPI>(\n ApiConstructor: new (\n config: BaseConfiguration,\n basePath: string,\n axios: AxiosInstance,\n ) => T,\n ) {\n const apiClient = new ApiConstructor(\n {\n ...this.opts,\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n },\n this.opts.basePath ?? \"\",\n this.opts.axiosInstance ?? axios.create(),\n ) as {\n [key: string | symbol]: any\n }\n\n for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n const originalFunction = apiClient[key]\n apiClient[key] = (...args: any[]) => {\n return originalFunction\n .apply(apiClient, [this.cellId, ...args])\n .then((res: any) => res.data)\n }\n }\n }\n\n return apiClient as WithCellId<T>\n }\n\n /**\n * As withCellId, but only does the response unwrapping\n */\n private withUnwrappedResponsesOnly<T extends BaseAPI>(\n ApiConstructor: new (\n config: BaseConfiguration,\n basePath: string,\n axios: AxiosInstance,\n ) => T,\n ) {\n const apiClient = new ApiConstructor(\n {\n ...this.opts,\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n },\n this.opts.basePath ?? \"\",\n this.opts.axiosInstance ?? axios.create(),\n ) as {\n [key: string | symbol]: any\n }\n\n for (const key of Reflect.ownKeys(Reflect.getPrototypeOf(apiClient)!)) {\n if (key !== \"constructor\" && typeof apiClient[key] === \"function\") {\n const originalFunction = apiClient[key]\n apiClient[key] = (...args: any[]) => {\n return originalFunction\n .apply(apiClient, args)\n .then((res: any) => res.data)\n }\n }\n }\n\n return apiClient as WithUnwrappedAxiosResponse<T>\n }\n\n readonly system = this.withUnwrappedResponsesOnly(SystemApi)\n readonly cell = this.withUnwrappedResponsesOnly(CellApi)\n\n readonly motionGroup = this.withCellId(MotionGroupApi)\n readonly motionGroupInfos = this.withCellId(MotionGroupInfoApi)\n\n readonly controller = this.withCellId(ControllerApi)\n\n readonly program = this.withCellId(ProgramApi)\n readonly programOperator = this.withCellId(ProgramOperatorApi)\n\n readonly controllerIOs = this.withCellId(ControllerInputsOutputsApi)\n\n readonly motionGroupKinematic = this.withCellId(MotionGroupKinematicsApi)\n readonly trajectoryPlanning = this.withCellId(TrajectoryPlanningApi)\n readonly trajectoryExecution = this.withCellId(TrajectoryExecutionApi)\n\n readonly coordinateSystems = this.withCellId(CoordinateSystemsApi)\n\n readonly application = this.withCellId(ApplicationApi)\n readonly applicationGlobal = this.withUnwrappedResponsesOnly(ApplicationApi)\n\n readonly jogging = this.withCellId(JoggingApi)\n\n readonly virtualRobot = this.withCellId(VirtualRobotApi)\n readonly virtualRobotSetup = this.withCellId(VirtualRobotSetupApi)\n readonly virtualRobotMode = this.withCellId(VirtualRobotModeApi)\n readonly virtualRobotBehavior = this.withCellId(VirtualRobotBehaviorApi)\n\n readonly storeObject = this.withCellId(StoreObjectApi)\n readonly storeCollisionComponents = this.withCellId(\n StoreCollisionComponentsApi,\n )\n readonly storeCollisionScenes = this.withCellId(StoreCollisionScenesApi)\n}\n","import type { Configuration as BaseConfiguration } from \"@wandelbots/nova-api/v2\"\nimport type { AxiosRequestConfig } from \"axios\"\nimport axios, { isAxiosError } from \"axios\"\nimport urlJoin from \"url-join\"\nimport { loginWithAuth0 } from \"../../LoginWithAuth0\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { availableStorage } from \"../availableStorage\"\nimport { ConnectedMotionGroup } from \"./ConnectedMotionGroup\"\nimport { MockNovaInstance } from \"./mock/MockNovaInstance\"\nimport { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport { NovaCellAPIClient } from \"./NovaCellAPIClient\"\n\nexport type NovaClientConfig = {\n /**\n * Url of the deployed Nova instance to connect to\n * e.g. https://saeattii.instance.wandelbots.io\n */\n instanceUrl: string | \"https://mock.example.com\"\n\n /**\n * Identifier of the cell on the Nova instance to connect this client to.\n * If omitted, the default identifier \"cell\" is used.\n **/\n cellId?: string\n\n /**\n * Username for basic auth to the Nova instance.\n * @deprecated use accessToken instead\n */\n username?: string\n\n /**\n * Password for basic auth to the Nova instance.\n * @deprecated use accessToken instead\n */\n password?: string\n\n /**\n * Access token for Bearer authentication.\n */\n accessToken?: string\n} & Omit<BaseConfiguration, \"isJsonMime\" | \"basePath\">\n\ntype NovaClientConfigWithDefaults = NovaClientConfig & { cellId: string }\n\n/**\n * EXPERIMENTAL\n *\n * This client provides a starting point to migrate NOVA api v2.\n * As v2 is still in development, this client has to be considered unstable\n *\n * Client for connecting to a Nova instance and controlling robots.\n */\nexport class NovaClient {\n readonly api: NovaCellAPIClient\n readonly config: NovaClientConfigWithDefaults\n readonly mock?: MockNovaInstance\n authPromise: Promise<string | null> | null = null\n accessToken: string | null = null\n\n constructor(config: NovaClientConfig) {\n console.warn(\"Using experimental NOVA v2 client\")\n const cellId = config.cellId ?? \"cell\"\n this.config = {\n cellId,\n ...config,\n }\n this.accessToken =\n config.accessToken ||\n availableStorage.getString(\"wbjs.access_token\") ||\n null\n\n if (this.config.instanceUrl === \"https://mock.example.com\") {\n this.mock = new MockNovaInstance()\n }\n\n // Set up Axios instance with interceptor for token fetching\n const axiosInstance = axios.create({\n baseURL: urlJoin(this.config.instanceUrl, \"/api/v2\"),\n headers: {\n \"X-Client-SDK\": \"Wandelbots-Nova-JS-SDK\",\n \"X-SDK-Version\": \"v2\",\n \"X-Wandelbots-Client\": \"Wandelbots-Nova-JS-SDK\",\n },\n })\n\n axiosInstance.interceptors.request.use(async (request) => {\n if (!request.headers.Authorization) {\n if (this.accessToken) {\n request.headers.Authorization = `Bearer ${this.accessToken}`\n } else if (this.config.username && this.config.password) {\n request.headers.Authorization = `Basic ${btoa(config.username + \":\" + config.password)}`\n }\n }\n return request\n })\n\n if (typeof window !== \"undefined\") {\n axiosInstance.interceptors.response.use(\n (r) => r,\n async (error) => {\n if (isAxiosError(error)) {\n if (error.response?.status === 401) {\n // If we hit a 401, attempt to login the user and retry with\n // a new access token\n try {\n await this.renewAuthentication()\n\n if (error.config) {\n if (this.accessToken) {\n error.config.headers.Authorization = `Bearer ${this.accessToken}`\n } else {\n delete error.config.headers.Authorization\n }\n return axiosInstance.request(error.config)\n }\n } catch (err) {\n return Promise.reject(err)\n }\n } else if (error.response?.status === 503) {\n // Check if the server as a whole is down\n const res = await fetch(window.location.href)\n if (res.status === 503) {\n // Go to 503 page\n window.location.reload()\n }\n }\n }\n\n return Promise.reject(error)\n },\n )\n }\n\n this.api = new NovaCellAPIClient(cellId, {\n ...config,\n basePath: urlJoin(this.config.instanceUrl, \"/api/v1\"),\n isJsonMime: (mime: string) => {\n return mime === \"application/json\"\n },\n baseOptions: {\n ...(this.mock\n ? ({\n adapter: (config) => {\n return this.mock!.handleAPIRequest(config)\n },\n } satisfies AxiosRequestConfig)\n : {}),\n ...config.baseOptions,\n },\n axiosInstance,\n })\n }\n\n async renewAuthentication(): Promise<void> {\n if (this.authPromise) {\n // Don't double up\n return\n }\n\n this.authPromise = loginWithAuth0(this.config.instanceUrl)\n try {\n this.accessToken = await this.authPromise\n if (this.accessToken) {\n // Cache access token so we don't need to log in every refresh\n availableStorage.setString(\"wbjs.access_token\", this.accessToken)\n } else {\n availableStorage.delete(\"wbjs.access_token\")\n }\n } finally {\n this.authPromise = null\n }\n }\n\n makeWebsocketURL(path: string): string {\n const url = new URL(\n urlJoin(\n this.config.instanceUrl,\n `/api/v1/cells/${this.config.cellId}`,\n path,\n ),\n )\n url.protocol = url.protocol.replace(\"http\", \"ws\")\n url.protocol = url.protocol.replace(\"https\", \"wss\")\n\n // If provided, add basic auth credentials to the URL\n // NOTE - basic auth is deprecated on websockets and doesn't work in Safari\n // use tokens instead\n if (this.accessToken) {\n url.searchParams.append(\"token\", this.accessToken)\n } else if (this.config.username && this.config.password) {\n url.username = this.config.username\n url.password = this.config.password\n }\n\n return url.toString()\n }\n\n /**\n * Retrieve an AutoReconnectingWebsocket to the given path on the Nova instance.\n * If you explicitly want to reconnect an existing websocket, call `reconnect`\n * on the returned object.\n */\n openReconnectingWebsocket(path: string) {\n return new AutoReconnectingWebsocket(this.makeWebsocketURL(path), {\n mock: this.mock,\n })\n }\n\n /**\n * Connect to the motion state websocket(s) for a given motion group\n */\n async connectMotionStream(motionGroupId: string) {\n return await MotionStreamConnection.open(this, motionGroupId)\n }\n\n async connectMotionGroups(\n motionGroupIds: string[],\n ): Promise<ConnectedMotionGroup[]> {\n const { controllers } = await this.api.controller.listControllers()\n\n return Promise.all(\n motionGroupIds.map((motionGroupId) =>\n ConnectedMotionGroup.connect(this, motionGroupId, controllers),\n ),\n )\n }\n\n async connectMotionGroup(\n motionGroupId: string,\n ): Promise<ConnectedMotionGroup> {\n const motionGroups = await this.connectMotionGroups([motionGroupId])\n return motionGroups[0]!\n }\n}\n","const DOMAIN_SUFFIX = \"wandelbots.io\"\n\n/** Mapping of stages to Auth0 configurations */\nconst auth0ConfigMap = {\n dev: {\n domain: `https://auth.portal.dev.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_DEV_CLIENT_ID,\n },\n stg: {\n domain: `https://auth.portal.stg.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_STG_CLIENT_ID,\n },\n prod: {\n domain: `https://auth.portal.${DOMAIN_SUFFIX}`,\n clientId: process.env.NOVA_AUTH0_PROD_CLIENT_ID,\n },\n}\n\n/** Determine which Auth0 configuration to use based on instance URL */\nconst getAuth0Config = (instanceUrl: string) => {\n if (instanceUrl.includes(`dev.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.dev\n if (instanceUrl.includes(`stg.${DOMAIN_SUFFIX}`)) return auth0ConfigMap.stg\n if (instanceUrl.includes(DOMAIN_SUFFIX)) return auth0ConfigMap.prod\n throw new Error(\n \"Unsupported instance URL. Cannot determine Auth0 configuration.\",\n )\n}\n\n/**\n * Initializes Auth0 login process using redirect if necessary and retrieves an access token.\n * Returns null when an access token should not be needed to authenticate (i.e. cookie auth\n * when deployed on the instance domain)\n */\nexport const loginWithAuth0 = async (\n instanceUrl: string,\n): Promise<string | null> => {\n if (typeof window === \"undefined\") {\n throw new Error(\n `Access token must be set to use NovaClient when not in a browser environment.`,\n )\n }\n\n const auth0Config = getAuth0Config(instanceUrl)\n\n if (new URL(instanceUrl).origin === window.location.origin) {\n // When deployed on the instance itself, our auth is handled by cookies\n // and no access token is needed-- just need to reload the page and it'll\n // login again / set cookie as needed\n window.location.reload()\n throw new Error(\n \"Failed to reload page to get auth details, please refresh manually\",\n )\n }\n\n // If we're on localhost or another domain, we need to do the full oauth flow\n // Note this will ONLY work for origins which are whitelisted as a redirect_uri\n // in the auth0 config, currently\n const { Auth0Client } = await import(\"@auth0/auth0-spa-js\")\n\n const auth0Client = new Auth0Client({\n domain: auth0Config.domain,\n clientId: auth0Config.clientId ?? \"\",\n useRefreshTokens: false,\n authorizationParams: {\n audience: \"nova-api\",\n redirect_uri: window.location.origin,\n },\n })\n\n // If the URL includes a redirect result, handle it\n if (\n window.location.search.includes(\"code=\") &&\n window.location.search.includes(\"state=\")\n ) {\n const { appState } = await auth0Client.handleRedirectCallback()\n // Return to the URL the user was originally on before the redirect\n window.history.replaceState(\n {},\n document.title,\n appState?.returnTo || window.location.pathname,\n )\n } else {\n // Initiate login with redirect\n await auth0Client.loginWithRedirect()\n }\n\n // Once logged in, retrieve the access token silently\n const accessToken = await auth0Client.getTokenSilently()\n return accessToken\n}\n","import ReconnectingWebSocket, { type ErrorEvent } from \"reconnecting-websocket\"\nimport * as v2 from \"./v2/mock/MockNovaInstance\"\nimport * as v1 from \"./v1/mock/MockNovaInstance\"\n\nexport class AutoReconnectingWebsocket extends ReconnectingWebSocket {\n receivedFirstMessage?: MessageEvent\n targetUrl: string\n disposed = false\n\n constructor(\n targetUrl: string,\n readonly opts: {\n mock?: v1.MockNovaInstance | v2.MockNovaInstance\n onDispose?: () => void\n } = {},\n ) {\n console.log(\"Opening websocket to\", targetUrl)\n\n super(() => this.targetUrl || targetUrl, undefined, {\n startClosed: true,\n })\n\n // Reconnecting websocket doesn't set this properly with startClosed\n Object.defineProperty(this, \"url\", {\n get() {\n return this.targetUrl\n },\n })\n\n this.targetUrl = targetUrl\n\n this.addEventListener(\"open\", () => {\n console.log(`Websocket to ${this.url} opened`)\n })\n\n this.addEventListener(\"message\", (ev) => {\n if (!this.receivedFirstMessage) {\n this.receivedFirstMessage = ev\n }\n })\n\n this.addEventListener(\"close\", () => {\n console.log(`Websocket to ${this.url} closed`)\n })\n\n const origReconnect = this.reconnect\n this.reconnect = () => {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketConnection(this)\n } else {\n origReconnect.apply(this)\n }\n }\n\n this.reconnect()\n }\n\n changeUrl(targetUrl: string) {\n this.receivedFirstMessage = undefined\n this.targetUrl = targetUrl\n this.reconnect()\n }\n\n sendJson(data: unknown) {\n if (this.opts.mock) {\n this.opts.mock.handleWebsocketMessage(this, JSON.stringify(data))\n } else {\n this.send(JSON.stringify(data))\n }\n }\n\n /**\n * Permanently close this websocket and indicate that\n * this object should not be used again.\n **/\n dispose() {\n this.close()\n this.disposed = true\n if (this.opts.onDispose) {\n this.opts.onDispose()\n }\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the OPEN state. */\n async opened() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.OPEN) {\n resolve()\n } else {\n this.addEventListener(\"open\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves once the websocket\n * is in the CLOSED state. */\n async closed() {\n return new Promise<void>((resolve, reject) => {\n if (this.readyState === WebSocket.CLOSED) {\n resolve()\n } else {\n this.addEventListener(\"close\", () => resolve())\n this.addEventListener(\"error\", reject)\n }\n })\n }\n\n /**\n * Returns a promise that resolves when the first message\n * is received from the websocket. Resolves immediately if\n * the first message has already been received.\n */\n async firstMessage() {\n if (this.receivedFirstMessage) {\n return this.receivedFirstMessage\n }\n\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.receivedFirstMessage = ev\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n\n /**\n * Returns a promise that resolves when the next message\n * is received from the websocket.\n */\n async nextMessage() {\n return new Promise<MessageEvent>((resolve, reject) => {\n const onMessage = (ev: MessageEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n resolve(ev)\n }\n\n const onError = (ev: ErrorEvent) => {\n this.removeEventListener(\"message\", onMessage)\n this.removeEventListener(\"error\", onError)\n reject(ev)\n }\n\n this.addEventListener(\"message\", onMessage)\n this.addEventListener(\"error\", onError)\n })\n }\n}\n","/**\n * Safety wrapper around browser localStorage providing context availability\n * checks and JSON parsing\n */\nclass AvailableStorage {\n available = typeof window !== \"undefined\" && !!window.localStorage\n\n getJSON<T>(key: string): Partial<T> | null {\n if (!this.available) return null\n\n const result = window.localStorage.getItem(key)\n if (result === null) return null\n\n try {\n return JSON.parse(result)\n } catch (err) {\n return null\n }\n }\n\n setJSON(key: string, obj: any) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, JSON.stringify(obj))\n }\n\n delete(key: string) {\n if (!this.available) return null\n\n window.localStorage.removeItem(key)\n }\n\n setString(key: string, value: string) {\n if (!this.available) return null\n\n window.localStorage.setItem(key, value)\n }\n\n getString(key: string): string | null {\n if (!this.available) return null\n\n return window.localStorage.getItem(key)\n }\n}\n\nexport const availableStorage = new AvailableStorage()\n","import type {\n ControllersList,\n MotionGroupSpecification,\n MotionGroupState,\n RobotController,\n SafetySetup,\n} from \"@wandelbots/nova-api/v2\"\nimport type { AxiosResponse, InternalAxiosRequestConfig } from \"axios\"\nimport { AxiosError } from \"axios\"\nimport * as pathToRegexp from \"path-to-regexp\"\nimport type { AutoReconnectingWebsocket } from \"../../AutoReconnectingWebsocket\"\n\n/**\n * EXPERIMENTAL\n * Ultra-simplified mock Nova server for testing stuff\n */\nexport class MockNovaInstance {\n readonly connections: AutoReconnectingWebsocket[] = []\n\n async handleAPIRequest(\n config: InternalAxiosRequestConfig,\n ): Promise<AxiosResponse> {\n const apiHandlers = [\n {\n method: \"GET\",\n path: \"/cells/:cellId/controllers\",\n handle() {\n return {\n controllers: [\n {\n controller: \"mock-ur5e\",\n model_name: \"UniversalRobots::Controller\",\n host: \"mock-ur5e\",\n allow_software_install_on_controller: true,\n motion_groups: [\n {\n motion_group: \"0@mock-ur5e\",\n name_from_controller: \"UR5e\",\n active: false,\n model_from_controller: \"UniversalRobots_UR5e\",\n },\n ],\n has_error: false,\n error_details: \"\",\n },\n ],\n } satisfies ControllersList\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/controllers/:controllerId\",\n handle() {\n return {\n configuration: {\n kind: \"VirtualController\",\n manufacturer: \"universalrobots\",\n position: \"[0,-1.571,-1.571,-1.571,1.571,-1.571,0]\",\n type: \"universalrobots-ur5e\",\n },\n name: \"mock-ur5\",\n } satisfies RobotController\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/specification\",\n handle() {\n return {\n dh_parameters: [\n {\n alpha: 1.5707963267948966,\n theta: 0,\n a: 0,\n d: 162.25,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: -425,\n d: 0,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: -392.2,\n d: 0,\n reverse_rotation_direction: false,\n },\n {\n alpha: 1.5707963267948966,\n theta: 0,\n a: 0,\n d: 133.3,\n reverse_rotation_direction: false,\n },\n {\n alpha: -1.5707963267948966,\n theta: 0,\n a: 0,\n d: 99.7,\n reverse_rotation_direction: false,\n },\n {\n alpha: 0,\n theta: 0,\n a: 0,\n d: 99.6,\n reverse_rotation_direction: false,\n },\n ],\n mechanical_joint_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n lower_limit: -6.335545063018799,\n upper_limit: 6.335545063018799,\n unlimited: false,\n },\n ],\n } satisfies MotionGroupSpecification\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/safety-setup\",\n handle() {\n return {\n safety_settings: [\n {\n safety_state: \"SAFETY_NORMAL\",\n settings: {\n joint_position_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n lower_limit: -2.96705961227417,\n upper_limit: 2.96705961227417,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n lower_limit: -1.7453292608261108,\n upper_limit: 2.7925267219543457,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n lower_limit: -3.3161256313323975,\n upper_limit: 0.40142571926116943,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n lower_limit: -3.4906585216522217,\n upper_limit: 3.4906585216522217,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n lower_limit: -2.4434609413146973,\n upper_limit: 2.4434609413146973,\n unlimited: false,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n lower_limit: -4.71238899230957,\n upper_limit: 4.71238899230957,\n unlimited: false,\n },\n ],\n joint_velocity_limits: [\n {\n joint: \"JOINTNAME_AXIS_1\",\n limit: 3.1415927410125732,\n },\n {\n joint: \"JOINTNAME_AXIS_2\",\n limit: 3.1415927410125732,\n },\n {\n joint: \"JOINTNAME_AXIS_3\",\n limit: 3.4906585216522217,\n },\n {\n joint: \"JOINTNAME_AXIS_4\",\n limit: 6.108652591705322,\n },\n {\n joint: \"JOINTNAME_AXIS_5\",\n limit: 6.108652591705322,\n },\n {\n joint: \"JOINTNAME_AXIS_6\",\n limit: 6.981317043304443,\n },\n ],\n joint_acceleration_limits: [],\n joint_torque_limits: [],\n tcp_velocity_limit: 1800,\n },\n },\n ],\n safety_zones: [\n {\n id: 1,\n priority: 0,\n geometry: {\n compound: {\n child_geometries: [\n {\n convex_hull: {\n vertices: [\n { vertex: [-800, -1330, -1820] },\n { vertex: [1650, -1330, -1820] },\n { vertex: [1650, 1330, -1820] },\n { vertex: [-800, 1330, -1820] },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [-800, -1330, -1820],\n },\n {\n vertex: [1650, -1330, -1820],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [-800, -1330, -1820],\n },\n {\n vertex: [-800, 1330, -1820],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, -1330, 1500],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [-800, 1330, 1500],\n },\n {\n vertex: [-800, 1330, -1820],\n },\n {\n vertex: [1650, 1330, -1820],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, 1500],\n },\n {\n vertex: [1650, -1330, 1500],\n },\n {\n vertex: [1650, -1330, -1820],\n },\n {\n vertex: [1650, 1330, -1820],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"box\",\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Cell workzone\",\n },\n motion_group_uid: 1,\n },\n {\n id: 2,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, -1850],\n },\n {\n vertex: [865, 1330, -1850],\n },\n {\n vertex: [865, -720, -1850],\n },\n {\n vertex: [1650, -720, -1850],\n },\n {\n vertex: [1650, 1330, -920],\n },\n {\n vertex: [865, 1330, -920],\n },\n {\n vertex: [865, -720, -920],\n },\n {\n vertex: [1650, -720, -920],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Transport\",\n },\n motion_group_uid: 1,\n },\n {\n id: 3,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, 1330, -600],\n },\n {\n vertex: [865, 1330, -600],\n },\n {\n vertex: [865, 430, -600],\n },\n {\n vertex: [1650, 430, -600],\n },\n {\n vertex: [1650, 1330, -1250],\n },\n {\n vertex: [865, 1330, -1250],\n },\n {\n vertex: [865, 430, -1250],\n },\n {\n vertex: [1650, 430, -1250],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Tunel\",\n },\n motion_group_uid: 1,\n },\n {\n id: 4,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [1650, -760, -440],\n },\n {\n vertex: [900, -760, -440],\n },\n {\n vertex: [900, -1330, -440],\n },\n {\n vertex: [1650, -1330, -440],\n },\n {\n vertex: [1650, -760, -1800],\n },\n {\n vertex: [900, -760, -1800],\n },\n {\n vertex: [900, -1330, -1800],\n },\n {\n vertex: [1650, -1330, -1800],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Fanuc controller\",\n },\n motion_group_uid: 1,\n },\n {\n id: 6,\n priority: 0,\n geometry: {\n convex_hull: {\n vertices: [\n {\n vertex: [-200, -200, -1900],\n },\n {\n vertex: [200, -200, -1900],\n },\n {\n vertex: [200, 200, -1900],\n },\n {\n vertex: [-200, 200, -1900],\n },\n {\n vertex: [-200, -200, -350],\n },\n {\n vertex: [200, -200, -350],\n },\n {\n vertex: [200, 200, -350],\n },\n {\n vertex: [-200, 200, -350],\n },\n ],\n },\n init_pose: {\n position: [0, 0, 0],\n orientation: [0, 0, 0, 1],\n },\n id: \"Robot base\",\n },\n motion_group_uid: 1,\n },\n ],\n robot_model_geometries: [\n {\n link_index: 1,\n geometry: {\n sphere: {\n radius: 270,\n },\n init_pose: {\n position: [-70, -70, -50],\n orientation: [0, 0, 0, 1],\n },\n id: \"link1_sphere\",\n },\n },\n {\n link_index: 2,\n geometry: {\n capsule: {\n radius: 160,\n cylinder_height: 800,\n },\n init_pose: {\n position: [-450, 40, 170],\n orientation: [\n 0, -0.7071067811865475, 0, 0.7071067811865476,\n ],\n },\n id: \"link2_capsule\",\n },\n },\n {\n link_index: 3,\n geometry: {\n sphere: {\n radius: 270,\n },\n init_pose: {\n position: [-110, 10, -100],\n orientation: [0, 0, 0, 1],\n },\n id: \"link3_sphere\",\n },\n },\n {\n link_index: 4,\n geometry: {\n capsule: {\n radius: 110,\n cylinder_height: 600,\n },\n init_pose: {\n position: [0, 300, 40],\n orientation: [\n -0.7071067811865475, 0, 0, 0.7071067811865476,\n ],\n },\n id: \"link4_capsule\",\n },\n },\n {\n link_index: 5,\n geometry: {\n sphere: {\n radius: 75,\n },\n init_pose: {\n position: [0, 0, -50],\n orientation: [0, 0, 0, 1],\n },\n id: \"link5_sphere\",\n },\n },\n ],\n tool_geometries: [],\n } satisfies SafetySetup\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/coordinate-systems\",\n handle() {\n return {\n coordinatesystems: [\n {\n coordinate_system: \"\",\n name: \"world\",\n reference_uid: \"\",\n position: [0, 0, 0],\n rotation: {\n angles: [0, 0, 0],\n type: \"ROTATION_VECTOR\",\n },\n },\n ],\n } //satisfies CoordinateSystems\n },\n },\n {\n method: \"GET\",\n path: \"/cells/:cellId/motion-groups/:motionGroupId/tcps\",\n handle() {\n return {\n tcps: [\n {\n id: \"Flange\",\n readable_name: \"Default-Flange\",\n position: [0, 0, 0],\n rotation: {\n angles: [0, 0, 0, 0],\n type: \"ROTATION_VECTOR\",\n },\n },\n {\n id: \"complex-tcp-position\",\n readable_name: \"Complex TCP Position\",\n position: [-200, 300, 150],\n rotation: {\n angles: [\n -0.12139440409113832, -0.06356210998212003,\n -0.2023240068185639, 0,\n ],\n type: \"ROTATION_VECTOR\",\n },\n },\n ],\n }\n },\n },\n ]\n\n const method = config.method?.toUpperCase() || \"GET\"\n const path = \"/cells\" + config.url?.split(\"/cells\")[1]?.split(\"?\")[0]\n\n for (const handler of apiHandlers) {\n const match = pathToRegexp.match(handler.path)(path || \"\")\n if (method === handler.method && match) {\n const json = handler.handle()\n return {\n status: 200,\n statusText: \"Success\",\n data: JSON.stringify(json),\n headers: {},\n config,\n request: {\n responseURL: config.url,\n },\n }\n }\n }\n\n throw new AxiosError(\n `No mock handler matched this request: ${method} ${path}`,\n \"404\",\n config,\n )\n\n // return {\n // status: 404,\n // statusText: \"Not Found\",\n // data: \"\",\n // headers: {},\n // config,\n // request: {\n // responseURL: config.url,\n // },\n // }\n }\n\n handleWebsocketConnection(socket: AutoReconnectingWebsocket) {\n this.connections.push(socket)\n\n setTimeout(() => {\n socket.dispatchEvent(new Event(\"open\"))\n\n console.log(\"Websocket connection opened from\", socket.url)\n\n if (socket.url.includes(\"/state-stream\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify(defaultMotionState),\n }),\n )\n }\n\n if (socket.url.includes(\"/move-joint\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify({\n result: {\n motion_group: \"0@ur\",\n state: {\n controller: \"ur\",\n operation_mode: \"OPERATION_MODE_AUTO\",\n safety_state: \"SAFETY_STATE_NORMAL\",\n timestamp: \"2024-09-18T12:48:26.096266444Z\",\n velocity_override: 100,\n motion_groups: [\n {\n motion_group: \"0@ur\",\n controller: \"ur\",\n joint_position: {\n joints: [\n 1.3492152690887451, -1.5659207105636597,\n 1.6653711795806885, -1.0991662740707397,\n -1.829018235206604, 1.264623761177063,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [\n 6.437331889439328, -628.4123774830913,\n 577.0569957147832,\n ],\n orientation: {\n x: -1.683333649797158,\n y: -1.9783363827298732,\n z: -0.4928031860165713,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [\n 6.437331889439328, -628.4123774830913,\n 577.0569957147832,\n ],\n orientation: {\n x: -1.683333649797158,\n y: -1.9783363827298732,\n z: -0.4928031860165713,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n angular: {\n x: -0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n force: {\n force: {\n x: 0,\n y: 0,\n z: 0,\n },\n moment: {\n x: 0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [\n false,\n false,\n false,\n false,\n false,\n false,\n ],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"671259\",\n },\n ],\n sequence_number: \"671259\",\n },\n movement_state: \"MOVEMENT_STATE_MOVING\",\n },\n }),\n }),\n )\n }\n\n if (socket.url.includes(\"/move-tcp\")) {\n socket.dispatchEvent(\n new MessageEvent(\"message\", {\n data: JSON.stringify({\n result: {\n motion_group: \"0@ur\",\n state: {\n controller: \"ur\",\n operation_mode: \"OPERATION_MODE_AUTO\",\n safety_state: \"SAFETY_STATE_NORMAL\",\n timestamp: \"2024-09-18T12:43:12.188335774Z\",\n velocity_override: 100,\n motion_groups: [\n {\n motion_group: \"0@ur\",\n controller: \"ur\",\n joint_position: {\n joints: [\n 1.3352527618408203, -1.5659207105636597,\n 1.6653711795806885, -1.110615611076355,\n -1.829018235206604, 1.264623761177063,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [\n -2.763015284002938, -630.2151479701106,\n 577.524509114342,\n ],\n orientation: {\n x: -1.704794877102097,\n y: -1.9722372952861567,\n z: -0.4852079204210754,\n },\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [\n -2.763015284002938, -630.2151479701106,\n 577.524509114342,\n ],\n orientation: {\n x: -1.704794877102097,\n y: -1.9722372952861567,\n z: -0.4852079204210754,\n },\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: {\n x: 0,\n y: 0,\n z: 0,\n },\n angular: {\n x: -0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n force: {\n force: {\n x: 0,\n y: 0,\n z: 0,\n },\n moment: {\n x: 0,\n y: 0,\n z: 0,\n },\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [\n false,\n false,\n false,\n false,\n false,\n false,\n ],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n sequence_number: \"627897\",\n },\n ],\n sequence_number: \"627897\",\n },\n movement_state: \"MOVEMENT_STATE_MOVING\",\n },\n }),\n }),\n )\n }\n }, 10)\n }\n\n handleWebsocketMessage(socket: AutoReconnectingWebsocket, message: string) {\n console.log(`Received message on ${socket.url}`, message)\n }\n}\n\nconst defaultMotionState = {\n result: {\n motion_group: \"0@universalrobots-ur5e\",\n controller: \"universalrobots-ur5e\",\n joint_position: {\n joints: [\n 1.1699999570846558, -1.5700000524520874, 1.3600000143051147,\n 1.0299999713897705, 1.2899999618530273, 1.2799999713897705,\n ],\n },\n joint_velocity: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n flange_pose: {\n position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n orientation: [\n 1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n ],\n coordinate_system: \"\",\n },\n tcp_pose: {\n position: [1.3300010259703043, -409.2680714682808, 531.0203477065281],\n orientation: [\n 1.7564919306270736, -1.7542521568325058, 0.7326972590614671,\n ],\n coordinate_system: \"\",\n tcp: \"Flange\",\n },\n velocity: {\n linear: [0, 0, 0],\n angular: [0, 0, 0],\n coordinate_system: \"\",\n },\n force: {\n force: [0, 0, 0],\n moment: [0, 0, 0],\n coordinate_system: \"\",\n },\n joint_limit_reached: {\n limit_reached: [false, false, false, false, false, false],\n },\n joint_current: {\n joints: [0, 0, 0, 0, 0, 0],\n },\n } satisfies MotionGroupState,\n}\n","import { AxiosError } from \"axios\"\nimport { makeAutoObservable, runInAction } from \"mobx\"\nimport { AutoReconnectingWebsocket } from \"../AutoReconnectingWebsocket\"\nimport { tryParseJson } from \"../converters\"\nimport type { MotionStreamConnection } from \"./MotionStreamConnection\"\nimport type { NovaClient } from \"./NovaClient\"\n\nexport type ProgramRunnerLogEntry = {\n timestamp: number\n message: string\n level?: \"warn\" | \"error\"\n}\n\nexport enum ProgramState {\n NotStarted = \"not started\",\n Running = \"running\",\n Stopped = \"stopped\",\n Failed = \"failed\",\n Completed = \"completed\",\n}\n\nexport type CurrentProgram = {\n id?: string\n wandelscript?: string\n state?: ProgramState\n}\n\ntype ProgramStateMessage = {\n type: string\n runner: {\n id: string\n state: ProgramState\n start_time?: number | null\n execution_time?: number | null\n }\n}\n\n/**\n * Interface for running Wandelscript programs on the Nova instance and\n * tracking their progress and output\n */\nexport class ProgramStateConnection {\n currentProgram: CurrentProgram = {}\n logs: ProgramRunnerLogEntry[] = []\n\n executionState = \"idle\" as \"idle\" | \"starting\" | \"executing\" | \"stopping\"\n currentlyExecutingProgramRunnerId = null as string | null\n\n programStateSocket: AutoReconnectingWebsocket\n\n constructor(readonly nova: NovaClient) {\n makeAutoObservable(this, {}, { autoBind: true })\n\n this.programStateSocket = nova.openReconnectingWebsocket(`/programs/state`)\n\n this.programStateSocket.addEventListener(\"message\", (ev) => {\n const msg = tryParseJson(ev.data)\n\n if (!msg) {\n console.error(\"Failed to parse program state message\", ev.data)\n return\n }\n if (msg.type === \"update\") {\n this.handleProgramStateMessage(msg)\n }\n })\n }\n\n /** Handle a program state update from the backend */\n async handleProgramStateMessage(msg: ProgramStateMessage) {\n const { runner } = msg\n\n // Ignoring other programs for now\n // TODO - show if execution state is busy from another source\n if (runner.id !== this.currentlyExecutingProgramRunnerId) return\n\n if (runner.state === ProgramState.Failed) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n // TODO - wandelengine should send print statements in real time over\n // websocket as well, rather than at the end\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n this.logError(\n `Program runner ${runner.id} failed with error: ${runnerState.error}\\n${runnerState.traceback}`,\n )\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.currentProgram.state = ProgramState.Failed\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Stopped) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n\n this.currentProgram.state = ProgramState.Stopped\n this.log(`Program runner ${runner.id} stopped`)\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Completed) {\n try {\n const runnerState = await this.nova.api.program.getProgramRun(runner.id)\n\n const stdout = (runnerState as any).stdout\n if (stdout) {\n this.log(stdout)\n }\n this.log(\n `Program runner ${runner.id} finished successfully in ${runner.execution_time?.toFixed(2)} seconds`,\n )\n\n this.currentProgram.state = ProgramState.Completed\n } catch (err) {\n this.logError(\n `Failed to retrieve results for program ${runner.id}: ${err}`,\n )\n }\n\n this.gotoIdleState()\n } else if (runner.state === ProgramState.Running) {\n this.currentProgram.state = ProgramState.Running\n this.log(`Program runner ${runner.id} now running`)\n } else if (runner.state !== ProgramState.NotStarted) {\n console.error(runner)\n this.logError(\n `Program runner ${runner.id} entered unexpected state: ${runner.state}`,\n )\n this.currentProgram.state = ProgramState.NotStarted\n this.gotoIdleState()\n }\n }\n\n /** Call when a program is no longer executing */\n gotoIdleState() {\n runInAction(() => {\n this.executionState = \"idle\"\n })\n this.currentlyExecutingProgramRunnerId = null\n }\n\n async executeProgram(\n wandelscript: string,\n initial_state?: Object,\n activeRobot?: MotionStreamConnection,\n ) {\n this.currentProgram = {\n wandelscript: wandelscript,\n state: ProgramState.NotStarted,\n }\n\n const { currentProgram: openProgram } = this\n if (!openProgram) return\n runInAction(() => {\n this.executionState = \"starting\"\n })\n\n // WOS-1539: Wandelengine parser currently breaks if there are empty lines with indentation\n const trimmedCode = openProgram.wandelscript!.replaceAll(/^\\s*$/gm, \"\")\n\n try {\n const programRunnerRef = await this.nova.api.program.createProgramRun(\n {\n code: trimmedCode,\n initial_state: initial_state,\n default_robot: activeRobot?.wandelscriptIdentifier,\n } as any,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n )\n\n this.log(`Created program runner ${programRunnerRef.id}\"`)\n runInAction(() => {\n this.executionState = \"executing\"\n })\n this.currentlyExecutingProgramRunnerId = programRunnerRef.id\n } catch (error) {\n if (error instanceof AxiosError && error.response && error.request) {\n this.logError(\n `${error.response.status} ${error.response.statusText} from ${error.response.config.url} ${JSON.stringify(error.response.data)}`,\n )\n } else {\n this.logError(JSON.stringify(error))\n }\n runInAction(() => {\n this.executionState = \"idle\"\n })\n }\n }\n\n async stopProgram() {\n if (!this.currentlyExecutingProgramRunnerId) return\n runInAction(() => {\n this.executionState = \"stopping\"\n })\n\n try {\n await this.nova.api.program.stopProgramRun(\n this.currentlyExecutingProgramRunnerId,\n )\n } catch (err) {\n // Reactivate the stop button so user can try again\n runInAction(() => {\n this.executionState = \"executing\"\n })\n throw err\n }\n }\n\n reset() {\n this.currentProgram = {}\n }\n\n log(message: string) {\n console.log(message)\n this.logs.push({\n timestamp: Date.now(),\n message,\n })\n }\n\n logError(message: string) {\n console.log(message)\n this.logs.push({\n timestamp: Date.now(),\n message,\n level: \"error\",\n })\n }\n}\n"],"mappings":"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","names":["import_mobx","THREE","MOTION_DELTA_THRESHOLD","import_axios","axios","import_axios","ReconnectingWebSocket","import_axios","match","axios","urlJoin","_a","config","import_axios","import_mobx","ProgramState"]}