微信扫一扫,关注公众号

  • 科技行者

  • 算力行者

见证连接与计算的「力量」

首页 训练AI理解世界,到底缺了什么数据

训练AI理解世界,到底缺了什么数据

2026-08-26 15:39
分享至:
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-
2026-08-26 15:39 科技行者

你有没有想过一个问题:让AI看懂一段行走视频,需要给它看什么?

答案好像很简单,给它看视频就行了。可事情没那么简单。当一个摄像头在世界里移动时,画面里的每一个像素变化,背后可能有完全不同的原因。可能是摄像机自己在转头,也可能是画面里有个东西自己在动,还可能只是灯光变了。这三种情况在RGB画面上看起来几乎一样,全是像素在挪动,但对于一个想要真正理解这个世界的AI模型来说,这是三件完全不同的事。

这就是这篇论文要解决的核心矛盾。研究者们发现,现有的合成数据集要么信息不够全,要么虽然信息全但不能反复观察同一段旅程。于是他们造了一个叫WorldRover的数据引擎,专门解决这个问题。

视频里缺失的另一半信息

先说说现实世界的数据有多难搞。

真实拍摄的视频量非常大,谷歌、Meta这些巨头手里有海量的街景和监控视频。但这些视频有个致命问题:相机的位置、场景的深度、画面里物体前后帧的对应关系,这些统统要靠算法事后估计出来。

估计就会有误差。相机轨迹会漂移,遮挡会让追踪算法找不到对应点,专业设备虽然精确但只能在有限场景里用。这就好比你想知道一个人昨天走了什么路线,但没有GPS记录,只能靠他事后回忆和路边监控拼凑,拼出来的路线肯定是模糊且不完整的。

那用游戏引擎渲染合成数据不就行了?渲染引擎天生就知道每个像素的深度、每个物体的真实位置,这些信息不需要估计,直接从引擎内部读出来就行。但问题是,现有的合成数据集大多是为单一任务定制的。

有的数据集专门做深度估计的基准测试,标注很细但场景数量有限。有的是给强化学习智能体用的仿真器,追求实时低延迟,但不会给你完整的几何信息。还有的是程序化生成场景,场景数量能刷得很高,但场景本身缺乏艺术家精心设计的细节和真实感。

更关键的是,这些数据集里几乎没有一个能让你反复观察同一段旅程的不同版本。比如说,你想知道换个视角看同一条街会有什么不同,或者想知道同一个场景在白天和夜晚看起来差多少,这些数据集给不了你成对的对比样本。

这就好比你想研究"下雨对交通影响"这个课题,但手头只有下雨天的照片和晴天的照片,这两批照片来自完全不同的街道、不同的时间、甚至不同的车流量。你没法把变量控制住,只能看到一堆混杂在一起的因素。如果不能做到"同一条路、同一批车、只是天气变了"的对照实验,你永远说不清楚下雨到底造成了多大的影响。这正是WorldRover想要解决的问题:让同一段探索轨迹,可以在保持路线、场景、时间完全一致的前提下,被反复"重新观察"。

WorldRover-Engine:把一次探索存成可复用的轨迹

WorldRover的核心设计理念其实特别简单:一次探索,不应该只对应一个渲染死的视频文件,而应该是一条可以在世界坐标系里保存、复用的轨迹。

> Unreal Engine(虚幻引擎):一款广泛用于游戏开发和电影特效制作的3D图形引擎,以高度真实的光照和材质渲染著称,简称UE。

这句话听起来抽象,但拆开看很好懂。传统的渲染工作流程是:设计好一条路线,架好摄像机,渲染出一段视频,这段视频就是最终产品,改不了了。而WorldRover-Engine反过来做:先把路线当成一份可以反复读取的"剧本",剧本本身不依赖任何具体的摄像机角度或者天气设定,需要什么样的呈现方式,再去按需渲染。

这就好比拍电影时,导演不是直接把演员的走位和台词录成一条不可逆的视频,而是先把整场戏的调度写成分镜脚本。有了这份脚本之后,你可以让摄影师用第一视角跟拍主角,也可以架个固定机位拍全景,甚至可以把布景换成雨天重新拍一遍,演员的走位和台词完全不用变。如果没有这份可复用的脚本,每次想换个角度看同一场戏,就得重新请演员走一遍,走位很可能就对不上了,画面里的信息也就没法直接拿来做对比。

具体到工程实现上,WorldRover-Engine分成两个阶段。第一阶段在Windows编辑器上跑一次性的场景准备工作,包括把美术资源处理成可以无界面加载的格式、烘焙导航网格、配置光照和天气这些"场景风格"。第二阶段在Linux多GPU主机上跑正式的内容生成,包括渲染、后处理和打包发布,这个阶段是无界面的,可以并行跑很多批次。

> 导航网格(NavMesh):游戏引擎里预先计算好的一张"可行走区域地图",标记出场景里哪些地方角色可以走,哪些地方是障碍物,供路径规划算法使用。

两边通过一个"版本化的磁盘交接点"衔接起来,好处是场景准备好之后,后续想生成多少条轨迹、渲染成什么风格,完全不需要再打开一次编辑器,直接批量跑就行。这个设计决策的价值在于把"一次性的手工准备"和"可重复的自动化生产"彻底分开了。如果两者混在一起,每次想多生成一条数据,都得重新走一遍完整的场景加载和光照烘焙流程,效率会被拖得很低。

三种轨迹生成策略:自动化、覆盖率和可控性的三方博弈

路线是怎么生成的?论文里给出了三种办法,各有取舍。

第一种叫NavMesh规划器,基于前面提到的导航网格。一个虚拟智能体从场景里随机找一个可到达的点出发,朝着采样出来的目标点走,偶尔改变一下朝向。因为走的是预先烘焙好的可行走表面,路线通常是高效且连贯的,能覆盖场景里大部分区域。代价是每个场景都需要提前烘焙导航网格,这一步需要针对每个场景单独调试。

第二种叫反应式探索器,不需要预先计算导航网格,靠一圈短距离的射线检测来实时避开障碍物,并且倾向于往最近没去过的方向走。它的好处是完全不依赖场景准备,坏处是这种"走一步看一步"的局部决策容易让智能体走进死胡同、反复折返,或者在某个角落里打转出不来。

第三种是人工录制,操作员亲自在场景里走一遍,把摄像机路径录下来。这种方式能精确得到你想要的特定路线和视角,代价是纯靠人力,没法批量生产。

三种方式凑在一起,恰好形成了自动化程度、场景覆盖广度和路线可控性之间的三角权衡。这让我想起城市规划里选公交线路的逻辑:有的线路是算法根据客流数据自动优化出来的,跑得快、覆盖广,但可能不经过某些冷门但确实有需求的角落;有的线路是靠居民投诉和实地调研一段段拼出来的,能精准满足特定需求,但费时费力覆盖不了全城。如果只用一种策略生成所有路线,数据集要么会缺失覆盖率,要么会丢失路线的多样性和真实感,两难之下,干脆三种策略都留着,按需搭配着用。

论文里的统计数据也印证了这种权衡:在最终发布的6003条序列里,NavMesh规划器生成了3662条,反应式探索器生成了1996条,人工录制的有345条。规划路线的中位时长是115秒,人工录制的是105秒,反应式探索的最短,只有81秒,这也侧面说明反应式策略确实更容易提前"卡住"或者结束。

一条轨迹,三种观察视角

WorldRover-Engine最有意思的设计之一,是同一条轨迹可以从三种完全不同的视角重新观察:第一视角、第三视角和360度全景视角。

第一视角很好理解,摄像机就是探索者本身,眼睛高度,视线方向跟着行进方向走,俯仰角和横滚角锁死,只有朝向平滑地跟随移动方向变化,读起来就像一个人走路时头部自然的转动,而不是机械的规划轨迹。这种模式最贴近人的第一视角视频和具身导航场景。

第三视角就复杂一些了。一个动画角色沿着记录好的轨迹在世界坐标系里行走,一个跟随摄像机保持在角色身后偏上方的位置。这里有个巧妙之处:跟随摄像机的朝向不是简单复制角色的朝向,而是由一个缓慢变化的环绕目标驱动的,这样即便角色走了个急转弯,画面视角也不会跟着猛地一甩,只有在长时间的方向变化里才会缓慢跟随。这就带来一个结果,角色的运动方向可以是朝向摄像机、背向摄像机,或者横穿画面。角色和摄像机的轨迹是两条独立的路径,虽然摄像机路径是从角色路径衍生出来的。

这个设计的价值在于,它天然地把"角色自己的运动"和"摄像机的运动"区分开了。这对于训练那些需要区分刚性相机运动和非刚性物体形变的模型非常关键。想象一下,如果你在看一段第三人称游戏录像,画面里角色和背景同时在动,你的大脑其实一直在做一件事,就是分辨"是我在操作视角转动,还是角色自己在跑"。如果没有这种分离的标注数据,模型很难学会做同样的区分,它很可能会把摄像机平移误判成物体在移动。

第三视角还配了一套明确的控制语义,用WASD控制角色相对摄像机的移动方向,用L和R控制摄像机绕静止角色旋转。这套控制体系其实就是把"探索轨迹"转换成了游戏里常见的操作指令流,为后续训练交互式模型提供了直接可用的控制信号。

360度全景视角则解决了另一个问题:怎么让一段视频覆盖摄像机周围的所有方向,而不只是前方的视野。技术实现上有个细节值得展开讲讲。研究者没有直接用虚幻引擎自带的全景渲染功能,原因是那个功能在图像累积阶段会把场景颜色"硬截断",在关闭色调映射的渲染模式下,画面里最亮的十分之一区域会被压缩成同一个数值,之后再也没法恢复出真实的高光细节。

> 色调映射(tone mapping):把渲染引擎里数值范围很宽的原始光照数据(比如太阳直射的极亮和阴影里的极暗),压缩映射到显示屏能呈现的有限亮度范围内的处理过程。

于是研究者改用了一个更麻烦但更靠谱的办法:单独渲染六张普通视角的立方体贴图,这样能完整保留高动态范围的光照信息,再在服务器端把这六张图拼接成一张全景图。拼接过程包括重投影、余弦加权羽化融合边缘,以及基于余弦纬度加权的对数亮度统计来估计曝光量,最后用局部细节压缩算法把动态范围收窄到可显示的范围。这个过程听起来繁琐,但换来的好处是全景图里保留了完整的高光和阴影层次,不会因为过曝而丢失场景细节。这就像拍一张逆光的风景照,如果直接按自动曝光拍,天空往往会变成一片死白,但如果先拍出保留全部光照信息的原始文件,再手动调整曝光和对比度,就能同时看清亮部的云彩纹理和暗部的地面细节。

场景的"素颜"版本:白模渲染

WorldRover还有一个很巧妙的功能,叫白模渲染。简单说,就是把整个场景的材质全部替换成一种中性的白色材质,只保留几何形状和光影关系,颜色、纹理、贴花、发光效果统统去掉。

这个功能是干什么用的?论文里提到,这是"由粗到精"生成模型的训练输入。这类模型的任务是:给它一个只有几何结构没有细节纹理的粗糙场景,让它自己"脑补"出逼真的材质和光照效果。要训练这样的模型,你需要成对的数据,一份是白模的粗糙版本,一份是带纹理的最终成品,并且两者的几何结构、相机运动必须完全一致。

技术实现上有个细节挺有意思。研究者一开始尝试逐个替换场景组件的材质,结果发现这种做法会漏掉一些东西,比如地形上的草地、关卡实例化物体和远景建筑代理模型。后来他们改用引擎自带的"默认材质显示标志",这个标志能一次性覆盖建筑、地形及其程序化生成的草地和植被、实例化网格、层级细节代理模型、样条几何体比如铁轨,以及运行时才加载进来的建筑。

这就好比给一栋正在装修的房子拍两张照片,一张是刚砌完毛坯墙、还没刷漆没铺地板的样子,另一张是软装完工之后的样子。如果拍照的时候不小心挪动了机位,或者两次拍摄之间房子的结构本身发生了变化,这两张照片就没法拿来做"从毛坯到精装"的对比训练素材了。白模渲染的关键就在于,它用的是同一套关卡序列和摄像机配置,唯一变化的只有材质的显示方式,这就保证了两个版本之间除了外观,其他一切都严格一致。

数据里到底装了什么:深度、光流和长程点追踪

说完了怎么拍,再来说说拍出来的每一帧画面里到底藏着多少信息。

先说RGB视频本身。第一视角和第三视角的视频分辨率是1280乘720,全景视频则是4096乘2048的等距柱状投影格式,用GPU的硬件编码器编码成H.264格式,这样做的好处是能腾出CPU资源去做别的后处理工作。

> 等距柱状投影:一种把球面全景图像展开成矩形平面图像的方式,类似世界地图上常见的墨卡托投影,纬度线和经度线都变成直线。

深度信息是从渲染引擎的深度层直接读出来的,单位是米,表示每个像素到摄像机中心的实际距离。这和用算法从图像里估计出来的深度完全不同,它不受纹理和传感器噪声的干扰,是绝对精确的真值。为了压缩存储空间,深度值被限制在0.1米到200米的范围内,并用对数方式量化成16位数据,这样近处的精度更高,远处的精度相对粗糙一些,这个设计其实符合人眼和大多数视觉任务对距离感知的实际需求,近处的微小差异更重要,远处差个几米往往无关紧要。

光流数据只在第三视角的子集里提供。这里同样是从引擎内部直接读取运动矢量缓冲区,而不是靠算法去比对两帧图像估计出来的。每个像素记录的是它在相邻两帧之间的屏幕空间位移量。这个设计避免了传统光流估计算法常见的误差来源,比如纹理缺失区域的匹配失败。

> 光流:描述视频中每个像素点在相邻帧之间移动方向和距离的一种运动场表示,常用于视频动作识别和运动补偿。

最值得展开讲的是长程点追踪功能,这是整个数据集里技术含量最高的部分之一。传统的点追踪方法通常靠图像特征匹配来跟踪一个点在视频里的位置,但这种方法一旦遇到遮挡,追踪就会中断或者出错,因为它没法"看穿"挡住视线的物体去猜测被遮挡点应该在哪里。

WorldRover的做法完全不同。它在某一帧上选定一批查询像素点,利用当时渲染出来的深度信息和摄像机参数,把这些2D像素点反投影成3D世界坐标系里的点。之后在后续每一帧里,这些3D点会被重新投影回图像平面,得到的像素序列就是这条轨迹。因为整个过程靠的是几何投影而不是图像特征匹配,它完全不会因为长时间跟踪而产生"漂移"误差,追踪精度只取决于渲染深度和摄像机姿态的准确性。

更关键的是遮挡处理。当一个点被别的物体挡住时,传统方法会直接放弃这个点,或者干脆报错。但WorldRover的做法是:位置信息照样无条件记录下来,只是额外附加一个"是否可见"的标记位。这意味着即便一个点被完全挡住看不见了,数据集里依然会诚实地告诉你,这个点此刻在图像里"应该"出现的位置在哪里。论文里举了个很形象的例子:某一帧里一堵墙把整个角色完全遮住了,摄像机压根看不到人,但对应的点追踪数据依然精确地记录着那些点的"隐藏位置",只是可见性标记全部设为不可见。

这个设计其实回应了一个很根本的问题:可见性和有没有定义位置,是两件不同的事。如果把这两者混为一谈,直接删掉被遮挡时的位置信息,那模型在训练时就永远学不会"这个东西暂时看不见,但它没有消失,还在那儿"这种物体恒常性的概念。这就好比小孩子玩捉迷藏,一个物体被遮挡挡住的时候不代表它凭空消失了,它只是暂时看不见而已,这是每个正常发育的孩子都会在某个阶段学会的认知能力,叫做客体永久性。如果一套训练数据从根源上就抹去了这种"看不见但依然存在"的信息,模型学到的可能只是一种脆弱的、遇到遮挡就崩溃的伪装理解,而不是真正对世界连续性的把握。

除了几何真值追踪,数据集还额外提供了摄像机轨迹、角色轨迹和一套从运动数据里反推出来的动作信号流。这套动作信号并不是记录操作者当时按了哪个键,而是通过分析相邻帧之间的速度差,分解成前进、侧移、转向、垂直四个方向上的量化数值。这种做法的好处是即便某条轨迹是靠算法自动生成的,而不是人工用手柄录制的,依然能得到一套结构一致的动作标注。

场景、外观和角色的多样性堆叠

数据的丰富程度不只体现在标注类型上,也体现在场景本身的多样性上。

WorldRover-Engine的资源库里有超过30个虚幻引擎场景,涵盖城市、历史建筑、恐怖题材、工业风、室内空间、奇幻风格、赛博朋克、山地、街道和村镇十个类别,规模从一间公寓到一整座城区都有。这些场景都是商业授权的、由专业美术团队精心搭建的成品资源,本身就带着完整的材质细节和场景陈设,不是程序化随机生成的空壳子。

场景之外,还有两个维度的"外观状态"可以独立切换:光照状态包括白天、黎明、傍晚、日落和夜晚五种,天气状态包括晴朗、阴天、雾天和雪天四种。这里有个技术细节特别值得一提:光照效果是渲染时实时计算出来的,而不是提前烘焙进一张固定的光照贴图里。这意味着换一个光照状态重新渲染,间接光照、色彩渗透、阴影的软硬程度都会跟着物理规律真实地变化,而不是简单地对画面做一次色调滤镜叠加。

每种光照状态还配了各自校准好的固定曝光值,渲染过程中不会有自动曝光去干扰它。这就保证了夜晚场景真的是暗的,不会被自动曝光算法强行拉亮到一个"看得清但不真实"的中间灰度。这个细节说起来简单,但如果换成自动曝光,你会发现所有的夜景视频看起来都莫名其妙地比真实夜晚亮很多,因为算法总想把整体亮度往中间灰靠拢,这恰恰破坏了"夜晚应该是暗的"这个最基本的物理常识。

角色资源库同样丰富,超过70个可动画角色,既有人形角色也有动物和奇幻生物。不同的身体结构决定了完全不同的运动方式:双足角色原地转身,四足动物和鸟类则是沿着弧线转弯。论文里特别强调,这种角色形态和步态的多样性,对于训练那些需要理解动态形变主体的4D重建模型来说,重要程度不亚于场景本身的多样性。

把场景、光照天气状态、材质版本、角色种类和路线生成策略这几个维度乘起来,理论上能组合出的数据量是极其庞大的。这也是这篇论文标题里"可扩展"三个字的真正含义:场景准备工作只需要做一次,后续想要多少种组合,全靠渲染算力堆出来,不需要再靠人工一帧一帧去标注。

最终交出的成绩单:WorldRover-10M

说了这么多设计思路,最后来看看实际产出的数据规模。

|数据类别|场景数|序列数|帧数|时长|数据量|

|---|---|---|---|---|---|

|第一视角|23|2,910|10.8M|100.5小时|5.9TB|

|第三视角|7|1,885|8.3M|76.5小时|4.4TB|

|360度全景|15|1,208|2.8M|25.8小时|8.4TB|

|**总计**|**32**|**6,003**|**21.9M**|**202.7小时**|**18.7TB**|

WorldRover-10M这个名字,取自它1080万帧的第一视角数据规模,但实际上算上第三视角和全景视角,整个数据集提供了2190万帧渲染画面,覆盖32个不同环境,总时长超过200小时,数据总量接近18.7TB。

按场景类型分类,城市题材占比最大,达到2128条序列,其次是城镇和年代场景,1668条,室内场景639条,历史与奇幻题材633条,赛博朋克题材603条。所有序列的路径长度中位数是122米,速度参数分三档取值,分别是每秒1.0米、1.2米和1.5米,对应人类走路、快走和小跑三种不同的步行节奏。

每一份发布出去的数据在正式对外公开前,都要经过两道审查。第一道是格式审查,检查编码后的视频和每一路标注数据是否完整存在、能否正常解码、长度是否一致。第二道是质量审查,专门抓那些"格式上没问题,但内容有毛病"的情况,比如曝光校准失误导致画面过暗、摄像机意外穿模进了场景几何体里、路线在同一片区域反复打转、渲染画质出现明显瑕疵。任何一道审查没通过的序列都会被直接剔除,不会流入最终发布的数据集。

三个应用方向和三条尚未解决的问题

这套数据到底能拿来干什么?论文里提了三个具体的应用方向。

第一是交互式世界模型的训练,也就是那种能根据用户输入的操作指令,实时生成对应画面变化的AI模型。WorldRover提供的RGB画面、渲染出来的精确摄像机轨迹,以及从轨迹反推出来的动作信号,正好省去了另外训练一个姿态估计模型的麻烦。第三视角数据里角色和摄像机运动的分离,加上第一视角和全景视角在同一时刻的匹配观察,为这类模型提供了摄像机视野之外的参考画面。

第二是动态4D场景重建,也就是从视频里重建出随时间变化的三维场景结构。密集光流和长程点追踪提供的短程和长程对应关系,包括三维位置、二维投影和遮挡时的可见性标记,配合独立记录的摄像机和角色轨迹,能帮助模型学会区分摄像机自己的运动和场景里物体的真实运动。

第三是生成式渲染,也就是那种"由粗到精"的图像生成模型。白模和带纹理版本的成对数据提供了逐帧对齐的结构化控制信号,环境变化的成对数据则提供了几何和运动完全固定、只有外观发生变化的对照样本。

不过论文的作者们也很坦诚地列出了三个现存的局限。

第一个局限是,目前每条第三视角序列里只有一个独立运动并且被完整标注轨迹的角色,场景里其他会动的元素并没有被单独控制或标注。而且跟随摄像机的位置是固定在角色身后几米的地方,路线规划本身并不保证这个位置一定能顺利通过,在比较拥挤的场景里,摄像机有时会意外撞进场景几何体,遇到这种情况整条序列只能被直接丢弃。研究者提出的解决思路是让场景里能同时容纳多个被追踪的角色,并让跟随摄像机具备感知遮挡、自动避让的能力。

第二个局限是,因为用的是动态全局光照加上艺术家搭建的场景资源,整套渲染流程并不模拟真实摄像头会有的传感器噪声、卷帘快门效应和镜头畸变,这些真实世界拍摄时必然存在的瑕疵,在合成数据里是完全缺失的。

第三个局限也是最直白的一个:这篇论文只讲清楚了这套数据生产流水线是怎么造出来的,但完全没有汇报任何下游任务上的实际训练效果。换句话说,这套数据到底好不好用,能带来多大提升,论文本身没有给出答案,作者说下一步的工作就是拿这批数据去训练模型,在标准的评测基准上验证效果。

写在后面

读完这篇论文,最让我意外的一点是那个"点追踪不因遮挡而中断"的设计。大多数做视频理解的数据集,遇到遮挡要么直接放弃标注,要么用某种插值凑合一下,但WorldRover选择了一个更彻底的立场:既然渲染引擎本来就知道那个点在三维空间里的真实位置,为什么不老老实实把它记下来,只是标记成"当前不可见"就好了。这其实是把一个工程上的技术细节,做成了一个认知层面的价值判断,就是"看不见"和"不存在"必须被严格区分开。

另一个值得琢磨的地方是白模渲染那段提到的技术弯路。研究者一开始想逐个组件去替换材质,结果漏掉了草地、实例化物体这些容易被忽视的角落,后来才改用引擎自带的显示标志一次性解决。这种从"看起来能用"到"发现遗漏之后推翻重来"的过程,其实是做工程系统时最真实也最容易被论文省略的部分,这篇论文难得地把这个细节写了出来。

这套数据能不能真正推动交互式世界模型往前走一步,论文自己也没给出答案。如果哪天有团队拿它训练出一个明显更懂遮挡、更能分清相机运动和物体运动的模型,那才是检验这套数据引擎真正价值的时刻。

Q&A

Q1:WorldRover是什么?

A:WorldRover是一套基于虚幻引擎打造的合成视频数据生成系统,核心能力是让同一段探索轨迹能被反复渲染成第一视角、第三视角、360度全景等不同观察方式,并附带深度、光流、点追踪等丰富标注信息。

Q2:WorldRover-10M数据集有多大规模?

A:包含6003条序列,来自32个不同虚幻引擎环境,总计2190万帧渲染画面,视频总时长202.7小时,数据总量约18.7TB,其中第一视角部分有1080万帧。

Q3:WorldRover的点追踪功能有什么特别之处?

A:它采用几何投影而非图像匹配来生成追踪轨迹,因此不会产生漂移误差,并且即便一个点被遮挡挡住看不见,依然会记录它此刻应该出现的图像位置,只是标记为不可见,这种设计保留了遮挡期间的完整监督信号。

分享至
0赞

好文章,需要你的鼓励

推荐文章
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-