# Lasvsim OpenAPI SDK for Python
千行仿真平台(Lasvsim)的 Python SDK。提供了一种简单直观的方式来控制和获取自动驾驶场景的仿真。
## 安装
您可以直接从PyPI安装该软件包:
```bash
pip install lasvsim-openapi
```
## 快速开始
以下是 SDK 使用的简单示例:
```python
import os
from lasvsim_openapi.client import Client
from lasvsim_openapi.http_client import HttpConfig
from lasvsim_openapi.simulator import SimulatorConfig
# 接口地址
endpoint = os.getenv("QX_ENDPOINT") # 线上环境地址: https://qianxing-api.risenlighten.com
# 授权token
token = os.getenv("QX_TOKEN") # 登录仿真平台后访问https://qianxing.risenlighten.com/#/usecenter/personalCenter, 点击最下面按钮复制token
# 登录仿真平台, 选择想要进行联合仿真的任务及剧本
task_id = 0 # 替换为你的任务ID
record_id = 0 # 替换为你的剧本ID
# 1. 初始化客户端
cli = Client(HttpConfig(
endpoint=endpoint, # 接口地址
token=token, # 授权token
))
# 2. 拷贝剧本, 返回的结构中new_record_id字段就是新创建的剧本ID
# 仿真结束后可到该剧本下查看结果详情
new_record = cli.process_task.copy_record(task_id, record_id)
print("拷贝剧本成功")
# 3. 通过拷贝的场景Id、Version和SimRecordId初始化仿真器
simulator = cli.init_simulator_from_config({
"scen_id": new_record.scen_id,
"scen_ver": new_record.scen_ver,
"sim_record_id": new_record.sim_record_id,
})
print("初始化仿真器成功")
try:
# 获取测试车辆列表
test_vehicle_list = simulator.get_test_vehicle_id_list()
print("测试车辆ID列表:", test_vehicle_list)
# 使测试车辆环形行驶
for i in range(50):
# 设置方向盘转角10度, 纵向加速度0.05
ste_wheel = 10.0
lon_acc = 0.05
# 设置车辆的控制信息
simulator.set_vehicle_control_info(test_vehicle_list.list[0], ste_wheel, lon_acc)
# 执行仿真器步骤
step_res = simulator.step()
print(f"第 {i} 步结果: {step_res}")
# 可在此处继续调用其他接口, 查看联合仿真文档: https://www.risenlighten.com/#/union
# 仿真结束后, 到千行仿真平台对应的taskId/recordId下查看联合仿真结果详情
print(f"https://qianxing.risenlighten.com/#/configuration/circleTask?id={task_id}")
# 如想直接查看本次联合仿真的回放视频, 可访问下面网址:
print(f"https://qianxing.risenlighten.com/#/sampleRoad/cartest/?id={task_id}&record_id={new_record.new_record_id}&sim_record_id={new_record.sim_record_id}")
finally:
# 停止仿真器, 释放服务器资源
simulator.stop()
```
## 可用API
### 仿真器API
#### 仿真控制
- `init_simulator_from_config(sim_config)`: 从配置初始化仿真器
- `init_simulator_from_sim(simulation_id, addr)`: 从现有仿真初始化仿真器
- `step()`: 仿真前进一步
- `stop()`: 停止仿真
- `reset(reset_traffic_flow)`: 重置仿真器到初始状态,可选择是否重置交通流
#### 车辆API
- `get_vehicle_id_list()`: 获取所有车辆ID
- `get_test_vehicle_id_list()`: 获取测试车辆ID
- `get_vehicle_base_info(id_list)`: 获取车辆基本信息
- `get_vehicle_position(id_list)`: 获取车辆位置
- `get_vehicle_moving_info(id_list)`: 获取车辆运动信息
- `get_vehicle_control_info(id_list)`: 获取车辆控制参数
- `get_vehicle_perception_info(vehicle_id)`: 获取车辆感知信息
- `get_vehicle_reference_lines(vehicle_id)`: 获取可用参考线
- `get_vehicle_planning_info(vehicle_id)`: 获取车辆规划信息
- `get_vehicle_navigation_info(vehicle_id)`: 获取车辆导航信息
- `get_vehicle_collision_status(vehicle_id)`: 检查车辆碰撞状态
- `get_vehicle_target_speed(vehicle_id)`: 获取车辆目标速度
- `set_vehicle_position(vehicle_id, point, phi)`: 设置车辆位置和航向角
- `set_vehicle_control_info(vehicle_id, ste_wheel, lon_acc)`: 设置车辆控制参数
- `set_vehicle_planning_info(vehicle_id, planning_path)`: 设置车辆规划路径
- `set_vehicle_moving_info(vehicle_id, u, v, w, u_acc, v_acc, w_acc)`: 设置车辆运动参数
- `set_vehicle_base_info(vehicle_id, base_info)`: 设置车辆基本信息
#### 交通流API
- `get_traffic_flow_info()`: 获取交通流信息
- `get_traffic_flow_vehicle_info(vehicle_id)`: 获取交通流车辆信息
- `get_traffic_flow_vehicle_list()`: 获取交通流车辆列表
- `get_traffic_flow_vehicle_position(vehicle_id)`: 获取交通流车辆位置
- `get_traffic_flow_vehicle_moving_info(vehicle_id)`: 获取交通流车辆运动信息
- `get_traffic_flow_vehicle_control_info(vehicle_id)`: 获取交通流车辆控制信息
#### 场景API
- `get_scene_info()`: 获取场景信息
- `get_scene_objects()`: 获取场景物体列表
- `get_scene_object_info(object_id)`: 获取场景物体信息
- `get_scene_object_position(object_id)`: 获取场景物体位置
- `get_scene_object_moving_info(object_id)`: 获取场景物体运动信息
- `get_scene_object_control_info(object_id)`: 获取场景物体控制信息
#### 路网API
- `get_lane_info(lane_id)`: 获取车道信息
- `get_lane_list()`: 获取车道列表
- `get_lane_center_line(lane_id)`: 获取车道中心线
- `get_lane_boundary(lane_id)`: 获取车道边界
- `get_lane_width(lane_id)`: 获取车道宽度
- `get_lane_speed_limit(lane_id)`: 获取车道限速
- `get_lane_type(lane_id)`: 获取车道类型
- `get_lane_direction(lane_id)`: 获取车道方向
- `get_lane_predecessor(lane_id)`: 获取前序车道
- `get_lane_successor(lane_id)`: 获取后继车道
#### 路口API
- `get_junction_info(junction_id)`: 获取路口信息
- `get_junction_list()`: 获取路口列表
- `get_junction_center_point(junction_id)`: 获取路口中心点
- `get_junction_boundary(junction_id)`: 获取路口边界
- `get_junction_type(junction_id)`: 获取路口类型
- `get_junction_direction(junction_id)`: 获取路口方向
- `get_junction_predecessor(junction_id)`: 获取前序路口
- `get_junction_successor(junction_id)`: 获取后继路口
- `get_movement_list(junction_id)`: 获取移动列表
Raw data
{
"_id": null,
"home_page": "https://github.com/rl-lasvsim/openapi-sdk-python",
"name": "lasvsim-openapi",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.0",
"maintainer_email": null,
"keywords": "Qianxing, Lasvsim, \u81ea\u52a8\u9a7e\u9a76, OpenAPI, Simulation, Autonomous Driving",
"author": "Zhihong Luo",
"author_email": "luozhihong@risenlighten.com",
"download_url": "https://files.pythonhosted.org/packages/98/1c/5502528fc73ea9c54a6911b619f96efe4fd4b77586ea341284c0b0046bad/lasvsim-openapi-0.1.11.tar.gz",
"platform": null,
"description": "# Lasvsim OpenAPI SDK for Python\n\n\u5343\u884c\u4eff\u771f\u5e73\u53f0\uff08Lasvsim\uff09\u7684 Python SDK\u3002\u63d0\u4f9b\u4e86\u4e00\u79cd\u7b80\u5355\u76f4\u89c2\u7684\u65b9\u5f0f\u6765\u63a7\u5236\u548c\u83b7\u53d6\u81ea\u52a8\u9a7e\u9a76\u573a\u666f\u7684\u4eff\u771f\u3002\n\n## \u5b89\u88c5\n\n\u60a8\u53ef\u4ee5\u76f4\u63a5\u4ecePyPI\u5b89\u88c5\u8be5\u8f6f\u4ef6\u5305\uff1a\n\n```bash\npip install lasvsim-openapi\n```\n\n## \u5feb\u901f\u5f00\u59cb\n\n\u4ee5\u4e0b\u662f SDK \u4f7f\u7528\u7684\u7b80\u5355\u793a\u4f8b\uff1a\n\n```python\nimport os\n\nfrom lasvsim_openapi.client import Client\nfrom lasvsim_openapi.http_client import HttpConfig\nfrom lasvsim_openapi.simulator import SimulatorConfig\n\n# \u63a5\u53e3\u5730\u5740\nendpoint = os.getenv(\"QX_ENDPOINT\") # \u7ebf\u4e0a\u73af\u5883\u5730\u5740: https://qianxing-api.risenlighten.com\n# \u6388\u6743token\ntoken = os.getenv(\"QX_TOKEN\") # \u767b\u5f55\u4eff\u771f\u5e73\u53f0\u540e\u8bbf\u95eehttps://qianxing.risenlighten.com/#/usecenter/personalCenter, \u70b9\u51fb\u6700\u4e0b\u9762\u6309\u94ae\u590d\u5236token\n\n# \u767b\u5f55\u4eff\u771f\u5e73\u53f0, \u9009\u62e9\u60f3\u8981\u8fdb\u884c\u8054\u5408\u4eff\u771f\u7684\u4efb\u52a1\u53ca\u5267\u672c\ntask_id = 0 # \u66ff\u6362\u4e3a\u4f60\u7684\u4efb\u52a1ID\nrecord_id = 0 # \u66ff\u6362\u4e3a\u4f60\u7684\u5267\u672cID\n\n# 1. \u521d\u59cb\u5316\u5ba2\u6237\u7aef\ncli = Client(HttpConfig(\n endpoint=endpoint, # \u63a5\u53e3\u5730\u5740\n token=token, # \u6388\u6743token\n))\n\n# 2. \u62f7\u8d1d\u5267\u672c, \u8fd4\u56de\u7684\u7ed3\u6784\u4e2dnew_record_id\u5b57\u6bb5\u5c31\u662f\u65b0\u521b\u5efa\u7684\u5267\u672cID\n# \u4eff\u771f\u7ed3\u675f\u540e\u53ef\u5230\u8be5\u5267\u672c\u4e0b\u67e5\u770b\u7ed3\u679c\u8be6\u60c5\nnew_record = cli.process_task.copy_record(task_id, record_id)\nprint(\"\u62f7\u8d1d\u5267\u672c\u6210\u529f\")\n\n# 3. \u901a\u8fc7\u62f7\u8d1d\u7684\u573a\u666fId\u3001Version\u548cSimRecordId\u521d\u59cb\u5316\u4eff\u771f\u5668\nsimulator = cli.init_simulator_from_config({\n \"scen_id\": new_record.scen_id,\n \"scen_ver\": new_record.scen_ver,\n \"sim_record_id\": new_record.sim_record_id,\n})\nprint(\"\u521d\u59cb\u5316\u4eff\u771f\u5668\u6210\u529f\")\n\ntry:\n # \u83b7\u53d6\u6d4b\u8bd5\u8f66\u8f86\u5217\u8868\n test_vehicle_list = simulator.get_test_vehicle_id_list()\n print(\"\u6d4b\u8bd5\u8f66\u8f86ID\u5217\u8868:\", test_vehicle_list)\n\n # \u4f7f\u6d4b\u8bd5\u8f66\u8f86\u73af\u5f62\u884c\u9a76\n for i in range(50):\n # \u8bbe\u7f6e\u65b9\u5411\u76d8\u8f6c\u89d210\u5ea6, \u7eb5\u5411\u52a0\u901f\u5ea60.05\n ste_wheel = 10.0\n lon_acc = 0.05\n # \u8bbe\u7f6e\u8f66\u8f86\u7684\u63a7\u5236\u4fe1\u606f\n simulator.set_vehicle_control_info(test_vehicle_list.list[0], ste_wheel, lon_acc)\n\n # \u6267\u884c\u4eff\u771f\u5668\u6b65\u9aa4\n step_res = simulator.step()\n print(f\"\u7b2c {i} \u6b65\u7ed3\u679c: {step_res}\")\n\n # \u53ef\u5728\u6b64\u5904\u7ee7\u7eed\u8c03\u7528\u5176\u4ed6\u63a5\u53e3, \u67e5\u770b\u8054\u5408\u4eff\u771f\u6587\u6863: https://www.risenlighten.com/#/union\n\n # \u4eff\u771f\u7ed3\u675f\u540e, \u5230\u5343\u884c\u4eff\u771f\u5e73\u53f0\u5bf9\u5e94\u7684taskId/recordId\u4e0b\u67e5\u770b\u8054\u5408\u4eff\u771f\u7ed3\u679c\u8be6\u60c5\n print(f\"https://qianxing.risenlighten.com/#/configuration/circleTask?id={task_id}\")\n\n # \u5982\u60f3\u76f4\u63a5\u67e5\u770b\u672c\u6b21\u8054\u5408\u4eff\u771f\u7684\u56de\u653e\u89c6\u9891, \u53ef\u8bbf\u95ee\u4e0b\u9762\u7f51\u5740\uff1a\n print(f\"https://qianxing.risenlighten.com/#/sampleRoad/cartest/?id={task_id}&record_id={new_record.new_record_id}&sim_record_id={new_record.sim_record_id}\")\n\nfinally:\n # \u505c\u6b62\u4eff\u771f\u5668, \u91ca\u653e\u670d\u52a1\u5668\u8d44\u6e90\n simulator.stop()\n```\n\n## \u53ef\u7528API\n\n### \u4eff\u771f\u5668API\n\n#### \u4eff\u771f\u63a7\u5236\n- `init_simulator_from_config(sim_config)`: \u4ece\u914d\u7f6e\u521d\u59cb\u5316\u4eff\u771f\u5668\n- `init_simulator_from_sim(simulation_id, addr)`: \u4ece\u73b0\u6709\u4eff\u771f\u521d\u59cb\u5316\u4eff\u771f\u5668\n- `step()`: \u4eff\u771f\u524d\u8fdb\u4e00\u6b65\n- `stop()`: \u505c\u6b62\u4eff\u771f\n- `reset(reset_traffic_flow)`: \u91cd\u7f6e\u4eff\u771f\u5668\u5230\u521d\u59cb\u72b6\u6001\uff0c\u53ef\u9009\u62e9\u662f\u5426\u91cd\u7f6e\u4ea4\u901a\u6d41\n\n#### \u8f66\u8f86API\n- `get_vehicle_id_list()`: \u83b7\u53d6\u6240\u6709\u8f66\u8f86ID\n- `get_test_vehicle_id_list()`: \u83b7\u53d6\u6d4b\u8bd5\u8f66\u8f86ID\n- `get_vehicle_base_info(id_list)`: \u83b7\u53d6\u8f66\u8f86\u57fa\u672c\u4fe1\u606f\n- `get_vehicle_position(id_list)`: \u83b7\u53d6\u8f66\u8f86\u4f4d\u7f6e\n- `get_vehicle_moving_info(id_list)`: \u83b7\u53d6\u8f66\u8f86\u8fd0\u52a8\u4fe1\u606f\n- `get_vehicle_control_info(id_list)`: \u83b7\u53d6\u8f66\u8f86\u63a7\u5236\u53c2\u6570\n- `get_vehicle_perception_info(vehicle_id)`: \u83b7\u53d6\u8f66\u8f86\u611f\u77e5\u4fe1\u606f\n- `get_vehicle_reference_lines(vehicle_id)`: \u83b7\u53d6\u53ef\u7528\u53c2\u8003\u7ebf\n- `get_vehicle_planning_info(vehicle_id)`: \u83b7\u53d6\u8f66\u8f86\u89c4\u5212\u4fe1\u606f\n- `get_vehicle_navigation_info(vehicle_id)`: \u83b7\u53d6\u8f66\u8f86\u5bfc\u822a\u4fe1\u606f\n- `get_vehicle_collision_status(vehicle_id)`: \u68c0\u67e5\u8f66\u8f86\u78b0\u649e\u72b6\u6001\n- `get_vehicle_target_speed(vehicle_id)`: \u83b7\u53d6\u8f66\u8f86\u76ee\u6807\u901f\u5ea6\n- `set_vehicle_position(vehicle_id, point, phi)`: \u8bbe\u7f6e\u8f66\u8f86\u4f4d\u7f6e\u548c\u822a\u5411\u89d2\n- `set_vehicle_control_info(vehicle_id, ste_wheel, lon_acc)`: \u8bbe\u7f6e\u8f66\u8f86\u63a7\u5236\u53c2\u6570\n- `set_vehicle_planning_info(vehicle_id, planning_path)`: \u8bbe\u7f6e\u8f66\u8f86\u89c4\u5212\u8def\u5f84\n- `set_vehicle_moving_info(vehicle_id, u, v, w, u_acc, v_acc, w_acc)`: \u8bbe\u7f6e\u8f66\u8f86\u8fd0\u52a8\u53c2\u6570\n- `set_vehicle_base_info(vehicle_id, base_info)`: \u8bbe\u7f6e\u8f66\u8f86\u57fa\u672c\u4fe1\u606f\n\n#### \u4ea4\u901a\u6d41API\n- `get_traffic_flow_info()`: \u83b7\u53d6\u4ea4\u901a\u6d41\u4fe1\u606f\n- `get_traffic_flow_vehicle_info(vehicle_id)`: \u83b7\u53d6\u4ea4\u901a\u6d41\u8f66\u8f86\u4fe1\u606f\n- `get_traffic_flow_vehicle_list()`: \u83b7\u53d6\u4ea4\u901a\u6d41\u8f66\u8f86\u5217\u8868\n- `get_traffic_flow_vehicle_position(vehicle_id)`: \u83b7\u53d6\u4ea4\u901a\u6d41\u8f66\u8f86\u4f4d\u7f6e\n- `get_traffic_flow_vehicle_moving_info(vehicle_id)`: \u83b7\u53d6\u4ea4\u901a\u6d41\u8f66\u8f86\u8fd0\u52a8\u4fe1\u606f\n- `get_traffic_flow_vehicle_control_info(vehicle_id)`: \u83b7\u53d6\u4ea4\u901a\u6d41\u8f66\u8f86\u63a7\u5236\u4fe1\u606f\n\n#### \u573a\u666fAPI\n- `get_scene_info()`: \u83b7\u53d6\u573a\u666f\u4fe1\u606f\n- `get_scene_objects()`: \u83b7\u53d6\u573a\u666f\u7269\u4f53\u5217\u8868\n- `get_scene_object_info(object_id)`: \u83b7\u53d6\u573a\u666f\u7269\u4f53\u4fe1\u606f\n- `get_scene_object_position(object_id)`: \u83b7\u53d6\u573a\u666f\u7269\u4f53\u4f4d\u7f6e\n- `get_scene_object_moving_info(object_id)`: \u83b7\u53d6\u573a\u666f\u7269\u4f53\u8fd0\u52a8\u4fe1\u606f\n- `get_scene_object_control_info(object_id)`: \u83b7\u53d6\u573a\u666f\u7269\u4f53\u63a7\u5236\u4fe1\u606f\n\n#### \u8def\u7f51API\n- `get_lane_info(lane_id)`: \u83b7\u53d6\u8f66\u9053\u4fe1\u606f\n- `get_lane_list()`: \u83b7\u53d6\u8f66\u9053\u5217\u8868\n- `get_lane_center_line(lane_id)`: \u83b7\u53d6\u8f66\u9053\u4e2d\u5fc3\u7ebf\n- `get_lane_boundary(lane_id)`: \u83b7\u53d6\u8f66\u9053\u8fb9\u754c\n- `get_lane_width(lane_id)`: \u83b7\u53d6\u8f66\u9053\u5bbd\u5ea6\n- `get_lane_speed_limit(lane_id)`: \u83b7\u53d6\u8f66\u9053\u9650\u901f\n- `get_lane_type(lane_id)`: \u83b7\u53d6\u8f66\u9053\u7c7b\u578b\n- `get_lane_direction(lane_id)`: \u83b7\u53d6\u8f66\u9053\u65b9\u5411\n- `get_lane_predecessor(lane_id)`: \u83b7\u53d6\u524d\u5e8f\u8f66\u9053\n- `get_lane_successor(lane_id)`: \u83b7\u53d6\u540e\u7ee7\u8f66\u9053\n\n#### \u8def\u53e3API\n- `get_junction_info(junction_id)`: \u83b7\u53d6\u8def\u53e3\u4fe1\u606f\n- `get_junction_list()`: \u83b7\u53d6\u8def\u53e3\u5217\u8868\n- `get_junction_center_point(junction_id)`: \u83b7\u53d6\u8def\u53e3\u4e2d\u5fc3\u70b9\n- `get_junction_boundary(junction_id)`: \u83b7\u53d6\u8def\u53e3\u8fb9\u754c\n- `get_junction_type(junction_id)`: \u83b7\u53d6\u8def\u53e3\u7c7b\u578b\n- `get_junction_direction(junction_id)`: \u83b7\u53d6\u8def\u53e3\u65b9\u5411\n- `get_junction_predecessor(junction_id)`: \u83b7\u53d6\u524d\u5e8f\u8def\u53e3\n- `get_junction_successor(junction_id)`: \u83b7\u53d6\u540e\u7ee7\u8def\u53e3\n- `get_movement_list(junction_id)`: \u83b7\u53d6\u79fb\u52a8\u5217\u8868\n",
"bugtrack_url": null,
"license": null,
"summary": "Lasvsim OpenAPI SDK for Python - A client library for accessing Lasvsim's simulation platform",
"version": "0.1.11",
"project_urls": {
"Bug Reports": "https://github.com/rl-lasvsim/openapi-sdk-python/issues",
"Homepage": "https://github.com/rl-lasvsim/openapi-sdk-python",
"Source": "https://github.com/rl-lasvsim/openapi-sdk-python"
},
"split_keywords": [
"qianxing",
" lasvsim",
" \u81ea\u52a8\u9a7e\u9a76",
" openapi",
" simulation",
" autonomous driving"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9dfd51ba118a8d81168474ba0b947b0a7ab1b471283dc648525f180771f26cb7",
"md5": "2a92a6fb89af17791692b36c66e4e0b7",
"sha256": "1fd6e86a54ac4949979f711ffa23da856229217532798feceff76dc4dbd85d1e"
},
"downloads": -1,
"filename": "lasvsim_openapi-0.1.11-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2a92a6fb89af17791692b36c66e4e0b7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.0",
"size": 48971,
"upload_time": "2025-01-14T12:03:39",
"upload_time_iso_8601": "2025-01-14T12:03:39.597137Z",
"url": "https://files.pythonhosted.org/packages/9d/fd/51ba118a8d81168474ba0b947b0a7ab1b471283dc648525f180771f26cb7/lasvsim_openapi-0.1.11-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "981c5502528fc73ea9c54a6911b619f96efe4fd4b77586ea341284c0b0046bad",
"md5": "4c64d7bab43d2cfeda9c3cff7196d0fd",
"sha256": "6d893c584d021169569730a0bb11bb99eb34e7fbf55c9b3b2f9c273f392e9a93"
},
"downloads": -1,
"filename": "lasvsim-openapi-0.1.11.tar.gz",
"has_sig": false,
"md5_digest": "4c64d7bab43d2cfeda9c3cff7196d0fd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.0",
"size": 24949,
"upload_time": "2025-01-14T12:03:42",
"upload_time_iso_8601": "2025-01-14T12:03:42.767248Z",
"url": "https://files.pythonhosted.org/packages/98/1c/5502528fc73ea9c54a6911b619f96efe4fd4b77586ea341284c0b0046bad/lasvsim-openapi-0.1.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-14 12:03:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rl-lasvsim",
"github_project": "openapi-sdk-python",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "requests",
"specs": [
[
"===",
"2.28.2"
]
]
}
],
"lcname": "lasvsim-openapi"
}