MDA-ZZ

MDA(Model Driven Architecture)是OMG定义的一种软件开发框架,它支持软件设计的可视化、存储和交换。MDA通过分离平台无关模型(PIM)和平台相关模型(PSM),实现了轻便性、互操作性和可重用性,有助于提高软件开发效率。

   MDA(Model Driven Architecture)是模型驱动架构,它是由OMG定义的一个软件开发框架。它是一种基于UML以及其他工业标准的框架,支持软件设计和模型的可视化、存储和交换。和UML相比,MDA能够创建出机器可读和高度抽象的模型,这些模型独立于实现技术,以标准化的方式储存。MDA把建模语言用作一种编程语言而不仅仅是设计语言。MDA的关键之处是模型在软件开发中扮演了非常重要的角色。

      MDA源自于众所周知的把系统操作的规范从系统利用底层平台能力的方式细节中分离出来的思想,MDA提供了一种途径(通过相关的工具)来规范化一个平台独立的系统、规范化平台、为系统选择一个特定的实现平台,并且把系统规范转换到特定的实现平台。MDA的三个主要目标是:通过架构性的分离来实现轻便性、互操作性和可重用性。

     模型驱动架构(MDA)是OMG组织近年来一直热炒的一个新的技术体系,同时也是众多搞软件模型研究人员的一个新热点。MDA(模型驱动)核心的思路是希望通过对商业模型(比如企业信息化或建筑领域的解决方案)的领域研究。进而提炼出一个相对核心的领域模型,同时抽象出一个PIM(平台无关模型)。之后根据不同的开发平台(例如.net或J2EE),应用平台(windows或unix)形成相应的 PSM(平台相关模型)。依照相应的工具,例如 ArcStyler可以完整地生成相应的代码和软件系统。当然这里只是罗列出一个大致的思路和方法。

      1 MDA理论还处在一个探索期,很多理论和方法并不成熟,当然无从谈起有成熟的工具,从目前的趋势而言,从理论到实际的工具都离OMG组织所提出的预想有较大距离,至少还需要数年的努力才能成型 。

      2目前无论是国外的开源组织还是国内的一些组织对MDA都只是处在一个草创阶段,很多人所谓的应用MDA 其实都只是在MDA的体系中作一个最初的探索和尝试。例如 ORM就是在一定层次上实现MDA 在数据库应用方面的探索,但也只是解决了一个实体模型映射的问题。前几天一个面试人员用 ArcStyler4.X 做了一个银行POS系统的应用模型,生成了一点还需要修改的框架代码。就告诉我说他已经掌握了 MDA,斯等水准真是让我汗颜!佩服!

      3 MDA的第一个热点可能是桥接器,而在MDA领域中,映射是个很重要的点,而转换和交互都只是在这个点上的延伸 。

      4 目前而言,最有可能在MDA体系中得以实现的语言是 JAVA,尽管我很讨厌JAVA的一些愚蠢方法。

      5 MDA的核心是PIM,因为他是最抽象和协同性最高的。同时就当前形势而言,PIM也是一个瓶颈!同时就目前的 UML2.0(从OMG那里得到最新的)而言,还不足以作为建立整个MDA体系的语言。同时对于MOF中的一些定义似乎还有提升的必要。因为对于整个体系而言,MOF应该更多的作为一个标准,只有在标准成熟的前提下,才有可能产生正确的映射规则。

      6 等到MDA风光无限的那天,会使一部分程序员失业,但不会是全部,起码MDA工具要有人做,因为一个MDA工具不足以应付所有的领域。这就好比没有一个财务系统能适应所有的企业一样。因为各个领域的标准化不同。

一、MDA(模型驱动架构)背景

       MDA目前在以下领域得到了应用:

      *银行业
      *保险业
      *公共企业(特别在金融管理领域)
      *嵌入式系统
      *后勤保障系统

      您将会看到,MDA确在其中起到了作用。

      MDA的流程
      MDA的实现主要集中在以下3个步骤:

      1 首先,您用UML对您的应用领域进行高度抽象的建模,这个模型和实现它的技术(或者底层技术)完全没有关系。这个模型我们称之为平台无关模型(PIM)。

      2 然后,PIM将被转换为一个或多个平台相关模型(PSM)。这个翻译的过程一般是自动实现的。PSM将用一个特定的实现技术来描述您的系统。它将用到这种技术所提供的种种架构,比如EJB, 数据库模型,COM组件等等。

      3 最后,PSM将被翻译成源代码。因为每个PSM已经完全依靠某种特定的技术,这个步骤一般是比较简单的。

      MDA流程中最难的一步,是从PIM生成一个PSM。它要求您对您要应用的基础技术具有丰富且巩固的知识,另一方面,源模型(PIM)必须具备自动生成PSM所要求的足够信息量。

      通过模板生成:MDA-light?!

     在MDA的实际应用当中,一个较容易的实现是通过模板(我们称之为MDA-light)。这样,平台相关模型这一步可以说是被跳过了,您可以直接从高度抽象的PIM生成源代码。您将继续在MDA-light的基础上进行真正意义的编程:您必须在源代码,而不是UML,编写细致的应用逻辑。

      使用MDA的前提

      * 业界(甚至是整个世界)一个被广泛接受的事实是:只有变化是永恒的。技术永远在革新。这在中间件领域尤其明显,当然还有数据库技术,操作系统,甚至是编程语言都经常变化。这些技术明显比应用领域的基本概念要变化的快。

      * 如果您在某一特定的应用领域工作,在这个领域中的项目都具有一定的相似性。整个应用程序族或者不同的项目都属于同一个应用领域,那么,MDA或者生成流程将特别适合于您

      MDA的优点

      * 您对建模的投资将更加持久的有效--远长于您目前实现它所应用的技术。这将更有利于保护您的投资。
      * 您具有了技术上的灵活性。
      * 您将不再受技术或应用所具有的不同变化周期的影响--在MDA的帮助下,您可以中立的保持两方面的多样性。

      MDA的缺点

      * MDA意味着更多的"组装"而不是"开发"--在为一个应用建立PIM的时候,您基本上没有技术上的周旋空间。这对于今天的很多开发人员来说,还是难以想象的。
      * 软件开发的创造性在一定程度上减弱了。开发人员常常觉得,就一种新技术展开争论,在技术的前沿工作,是十分吸引人的。可是在MDA流程下,大量的工作是建立模型,这和具体的技术相距甚远,但符合OMG的建议。
      * 潜在的不成熟性。UML2.0还在幼年时代。MDA工具出现的时间也相对很短。这里还隐藏了很多风险。

      MDA流程和生成开发中有待解决的问题

      * 数据和应用程序的移植:目前在商业领域经常需要面对的问题是,大量的数据和应用程序如何向新的,MDA为基础的系统中移植。纯粹的MDA流程将把数据模型和数据库表结构看成是技术细节。它们不应该对平台无关模型(PIM)层产生任何影响--那么,您的MDA工具或生成器也负责生成数据库脚本吗?
      * 软件维护:编制不同的发行版本,补丁或者升级,是对目前正在运行的程序进行维护的重要组成部分。MDA怎么处理这些问题呢?每次进行一次全新的安装?
      * 投资报酬率(Return-on-Investment):从什么样的环境和系统开始计算?从应用MDA的第二个项目?还是从第五个开始?
      * 购买软件架构还是自主开发?
      * 生成器和相关工具造成了对其生产商的依赖--这种对生产商的依赖是我们以往一直极力避免的。
      * 企业应用整合(EAI):高度的抽象,听起来不错--但是对于已经在运转的应用系统,怎么得到这种抽象呢?
       您可以看到--潜在很多实际问题(其回答都具有重要的意义)。这些问题正是我们创立openMDA的原因:在很多项目当中,某些以上的问题已经得到了实验性的回答,您(和我们)都将从中获益!

二、MDA的软件开发周期

      在MDA中软件开发过程是由软件系统的建模行为驱动的。下面是MDA的软件开发周期:

 


      MDA生命周期和传统生命周期没有大的不同,主要的区别在于开发过程创建的工件,包括PIM(Platform Independent Model,平台无关模型)、PSM(Platform specific Model,平台相关模型)和代码。PIM是具有高抽象层次、独立任何实现技术的模型。PIM被转换为一个或多个PSM。PSM是为某种特定实现技术量身定做。例如,EJB PSM是用EJB结构表达的系统模型。开发的最后一步是把每个PSM变化为代码, PSM同应用技术密切相关。传统的开发过程从模型到模型的变换,或者从模型到代码的变换是手工完成的。但是MDA的变换都是由工具自动完成的。从PIM到PSM,再从PSM到代码都可以由工具实现。PIM, PSM,和Code 模型被作为软件开发生命周期中的设计工件,在传统的开发方式中是文档和图表。重要的是,它们代表了对系统不同层次的抽象,从不同的视角来看待我们的系统,将高层次的PIM 转换到PSM 的能力提升了抽象的层次。能够使得开发人员更加清晰地了解系统的整个架构,而不会被具体的实现技术所“污染”,同时对于复杂系统,也减少了开发人员的工作量。

      MDA的出现,为提高软件开发效率,增强软件的可移植性、协同工作能力和可维护性,以及文档编制的便利性指明了解决之道。MDA被面向对象技术界预言为未来两年里最重要的方法学。当今建模的主要问题在于,对于很多企业来说它只是纸面上的练习。这就造成了模型和代码不同步的问题,代码会被不断修改,而模型不会被更新,这样模型就失去了意义。弥补建模和开发之间的鸿沟的关键就在于将建模变为开发的一个必不可少的部分。MDA 是模型驱动开发的框架,MDA 的愿景是定义一种描述和创建系统的新的途径。MDA 使得UML 的用途走得更远,而不仅仅是美丽的图画。很多专家预言MDA 有可能会带领我们进入软件开发的另一个黄金时代。

 

三、MDA框架

      MDA 将软件系统的模型分离为平台无关模型PIM 和特定平台模型PSM,同时又能通过转换规则将它们统一起来,以这样的方式试图去摆脱需求变更所带来的困境。平台无关模型PIM 是对系统高层次的抽象,其中不包括任何与实现技术相关的信息;特定平台模型PSM是特定平台相关的模型。在MDA 框架中,首先使用平台无关的建模语言来搭建平台无关的模型PIM,然后根据特定平台和实现语言的映射规则,将PIM 转换以生成平台相关的模型PSM,最终生成应用程序代码和测试框架。

      MDA框架的“建筑材料”包括:高层次模型;一种或多种标准、精确定义的语言,用来编写高层次模型;如何把PIM变换到PSM的定义;编写这些定义的语言,这种语言能够被变换工具执行;能够执行变换定义的工具;能够执行PSM到代码的变换工具。

 

 

      上图是MDA的框架,它的主要元素有模型、PIM、PSM、语言、变换、变换定义、以及变换工具。MDA 是一个开放的,中立于软件供应商的架构,它广阔地支持不同的应用领域和技术平台,能够成为应用领域和具体技术平台之间的杠杆。在MDA 开发途径中,PIM 代表对需求的建模,PSM 代表应用具体技术后的模型,这使得MDA 成为需求和技术之间的杠杆;它们各自的改变都可以是相互独立的,不会造成商业逻辑和实现技术的紧密藕合,同时MDA 又可以通过转换来弥补它们之间的鸿沟,从而保护我们的投资。MDA 开发途径使得我们的系统能够灵活地被实现、集成、维护和测试,系统的轻便性、互操作性和可重用性都是可以长期保持的,能够应对未来的变化。

四、MDA的现状

      MDA 还处在一个发展的过程中,MDA还在不断的演进。虽然MDA正朝气蓬勃地走来,但是人们也能看出它所存在的问题。MDA最大的好处就是业务模型的持久价值,但是付出的代价是增加了抽象层,而目前看来,层之间的转换并不是我们所期待的那样顺畅,至少,从PIM到PSM,从PSM到代码,这个实现的过程要远比从3GL生成机器代码来得困难。在建模技术方面,UML正在暴露其固有的缺陷,它需要扩展更多的机制来支持精确建模和分析模型,虽然目前OCL为精确建模提供了一定的支持,但是这种支持距离可执行模型的理想还很遥远。回顾MDA的历史,我们可以看出UML的巨大成功为MDA的产生奠定了坚实的基础,同时也感觉到:在由软件工艺到软件工程的漫漫长路中,MDA只不过是向前迈进了一小步,但却给整个软件业掀起了一场波澜,它在模型定义、开发过程等诸多方面都将对未来IT技术产生深远的影响。

      目前在MDA开发工具市场上的情形是:由于从PIM 到PSM转换方法的标准化尚未完成,IBM、Borland等大型厂商大都持谨慎态度,虽然也纷纷在他们的开发工具中提供部分的MDA功能,但并没有完全遵循OMG定义的MDA规范。虽然如此,IBM除了在Rational中增加MDA功能之外,在开源项目Eclipse中,也提出了EMF(Eclipse Modeling Framework)这一创新的MDA代码生成系统项目,由此可见IBM对MDA这一发展中的技术的重视程度。Borland公司宣称他们也在关注MDA技术,并且准备在Together中配置基于MDA的模型自动生成功能。相对于业界大厂的冷静和矜持,一些中小厂商反而特别活跃,像Interactive Objects公司著名的ArcStyler、Compuware公司著名的OptimalJ,还有开放源码的AndroMDA等遵循OMG标准规范的MDA工具已在一些项目中得到了广泛的运用,并取得了显著的成效。

五、MDA的相关标准

      为了实现MDA这一宏大构想,OMG制定了一系列的标准:

      UML:UML被MDA用来描述各种模型。它并不是为MDA而生,但是作为目前最为风行的建模语言,UML已经占据了全球建模语言领域90%的市场份额,成为了建模语言事实上的标准,因此OMG将它作为MDA技术的基础是自然而然的明智选择。它是MDA的基础,也是MDA最有力的武器。

      MOF:MOF(Meta Object Facility 元对象机制)是比UML更高层次的抽象,它的目的是为了描述UML的扩展或者其它未来可能出现的类UML的建模语言。虽然MOF也不是为MDA而生的,但是我们可以体味到OMG的工程师们良苦的用心和长远的目光。

      XMI:XMI(XML-based metadata Interchange)是基于XML的元数据交换。它通过标准化的XML文档格式和DTDs(Document Type Definitions)为各种模型定义了一种基于XML的数据交换格式。这使得作为最终产品的模型可以在各种不同的工具中传递,这一点是非常重要的,它保证了MDA不会在打破了一种束缚之后再被加上一层新的束缚。

      CWM:CWM(Common Warehouse Metamodel 公共仓库元模型)提供了一种数据格式变换的手段,在任意级别的模型上都可以使用CWM来描述两种数据模型之间的映射规则,比如将数据实体从关系数据库变换为XML格式。在MOF的框架下,CWM使得通用的数据模型变换引擎成为可能。

      在OMG的蓝图中,UML、MOF、XMI、CWM等一系列标准分别解决了MDA的模型建立、模型扩展、模型交换、模型变换这几个方面的问题。OMG试图通过标准化的定义,扩大MDA的应用范围。同时通过这样一个可扩展的建模语言环境,IT厂商可以自由实现自己的建模语言,以及语言到可执行代码的映射,然而不管怎么样,都必须处于OMG的标准化框架之下。

 

 

<section data-v-5e8a711c="" id="promotion" data-tea-expose="create_module_show" data-tea-std_component_name="promotion" class="index_container_sy5k3 card-container--normal" data-tea-adgroup-module="promotion" data-tea-std_module_name="Promotion app" elementtiming="element-timing"><div data-v-5e8a711c="" id="promotion-title" data-testid="card-container-index-3fM7A9" data-tea-click="" tabindex="-1" class="index_header_fTgs7" elementtiming="element-timing"><!----><div data-v-5e8a711c="" class="card-title index_title_s6TqN" elementtiming="element-timing"><span data-v-5e8a711c="" elementtiming="element-timing"> 应用 </span><!----><!----><!----><!----></div><!----></div><!----><div data-v-5e8a711c="" elementtiming="element-timing"><div data-v-5e8a711c="" class="card-cont index_bodyWrapper_NHYq8 card-container__body-wrapper--normal" elementtiming="element-timing"><div data-v-5e8a711c="" class="index_body_WGzeD" elementtiming="element-timing"><div data-v-5e8a711c="" elementtiming="element-timing"><div class="vi-form-item inline-item" elementtiming="element-timing"><!----><div class="vi-form-item__content" elementtiming="element-timing"><div class="appListSelect d-flex" elementtiming="element-timing"><div class="ttam-promotion-app-select" data-testid="spc-promotion-index-umPn3A" elementtiming="element-timing"><div data-tea="create_adgroup_ad_detail_app" class="ttam-promotion-app-select__wrap" elementtiming="element-timing"><div class="ttam-dropdown-panel__wrap" elementtiming="element-timing"><div class="ttam-dropdown-panel__reference" elementtiming="element-timing"><div data-testid="dropdown-panel-index-uYWYQh" elementtiming="element-timing"><div data-testid="input-input-qJLqaS" class="vi-input vi-input--prefix vi-input--suffix" elementtiming="element-timing" style="width: 480px;"><!----><input type="text" autocomplete="off" data-testid="app-promotion-app-j45A6Y" readonly="readonly" placeholder="选择应用" class="vi-input__inner" elementtiming="element-timing"><span class="vi-input__prefix" elementtiming="element-timing"><img class-name="ttam-promotion-app-select__prefix-icon" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTRweCIgaGVpZ2h0PSIxNHB4IiB2aWV3Qm94PSIwIDAgMTQgMTQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU1LjIgKDc4MTgxKSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5Hcm91cDwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSJwYWdlIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iZ3JvdXAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDAwMDAwLCAwLjAwMDAwMCkiIGZpbGw9IiNDMUMxQzEiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0zLjMwMjAwNzg4LDYuNjA0MDE1NjMgQzEuNDc5MDUyNSw2LjYwMjM1NDY5IDAuMDAxNjU0Mjk4OCw1LjEyNDk2OTkyIDIuODQyMTcwOTRlLTE0LDMuMzAyMDAxIEMwLjAwMTY2NTM1MDY1LDEuNDc5MDI1MjkgMS40NzkwNjYxOSwwLjAwMTY0MDc1ODE4IDMuMzAyMDIxNDQsMS4zMTE0MzQyM2UtMDcgQzUuMTI0OTc2NTQsMC4wMDE2NTQwMzM0NiA2LjYwMjM3NDc0LDEuNDc5MDM4OTYgNi42MDQwMjkwNCwzLjMwMjAwNzg4IEw2LjYwNDAyOTA0LDYuNjA0MDE1NjMgTDMuMzAyMDA3ODgsNi42MDQwMTU2MyBaIE01LjIwNDAyOTYyLDMuMzAzMjc4MzQgQzUuMjAzMDc2MDgsMi4yNTI1MjExNiA0LjM1MTUwNTQzLDEuNDAwOTUyODcgMy4zMDMyODEyNywxLjM5OTk5OTU2IEMyLjI1MjUzNDM2LDEuNDAwOTQ1MjIgMS40MDA5NTkzMiwyLjI1MjUxMDA2IDEuMzk5OTk5NDIsMy4zMDA3MTAwOSBDMS40MDA5NTI5Nyw0LjM1MTQ4NjEyIDIuMjUyNTIzMiw1LjIwMzA1ODg0IDMuMzAyMDA3NzUsNS4yMDQwMTU2MyBMNS4yMDQwMjk2Miw1LjIwNDAxNTYzIEw1LjIwNDAyOTYyLDMuMzAzMjc4MzQgWiIgaWQ9Iui3r+W+hCI+PC9wYXRoPgogICAgICAgICAgICA8cGF0aCBkPSJNMTAuNjcwMDIyMyw2LjYwNTAwNjc5IEw3LjM2ODAxNDU2LDYuNjA1MDA2NzkgTDcuMzY4MDE0NTYsMy4zMDIwMDEgQzcuMzY5Njc5OTIsMS40NzkwMjUxNiA4Ljg0NzA4MDc2LDAuMDAxNjQwNjI3MDUgMTAuNjcwMDM2LDAgQzEyLjQ5Mjk5MTEsMC4wMDE2NTM5MDIzMiAxMy45NzAzODkzLDEuNDc5MDM4ODMgMTMuOTcyMDQzNiwzLjMwMjAwNzc1IEMxMy45NzAzNzgzLDUuMTI0OTgzNDQgMTIuNDkyOTc3NCw2LjYwMjM2Nzk3IDEwLjY3MDAyMjIsNi42MDQwMDg1OSBMMTAuNjcwMDIyMyw2LjYwNTAwNjc5IFogTTEwLjY2ODc2MjIsNS4yMDQwMDkxNiBDMTEuNzE5NTA5Miw1LjIwMzA2MzUxIDEyLjU3MTA4NDMsNC4zNTE0OTg2NyAxMi41NzIwNDQyLDMuMzAzMjk4NjQgQzEyLjU3MTA5MDYsMi4yNTI1MjI4NCAxMS43MTk1MjE4LDEuNDAwOTUyNzQgMTAuNjcxMjk1OCwxLjM5OTk5OTQzIEM5LjYyMDU0ODkyLDEuNDAwOTQ1MDkgOC43Njg5NzM4OSwyLjI1MjUwOTkzIDguNzY4MDE0NTYsMy4zMDE5ODA0IEw4Ljc2ODAxNDU2LDUuMjA1MDA2NzkgTDkuNTYwMjU4NDksNS4yMDUwMDY3OSBMMTAuNjY4NzYyMiw1LjIwNDAwOTE2IFoiIGlkPSLot6/lvoQiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggZD0iTTMuMzAyMDA3ODgsMTMuOTQyMDI0NCBDMS40NzkwNTI1LDEzLjk0MDM2MzUgMC4wMDE2NTQyOTg4LDEyLjQ2Mjk3ODcgMi44NDIxNzA5NGUtMTQsMTAuNjQwMDA5OCBDMC4wMDE2NjUzNTA2NSw4LjgxNzAzNDA2IDEuNDc5MDY2MTksNy4zMzk2NDk1MiAzLjMwMjAyMTQ0LDcuMzM4MDA4OSBDNS4xMjQ5NzY1NCw3LjMzOTY2MjggNi42MDIzNzQ3NCw4LjgxNzA0NzczIDYuNjA0MDI5MDQsMTAuNjQwMDE2NiBMNi42MDQwMjkwNCwxMy45NDIwMjQ0IEwzLjMwMjAwNzg4LDEzLjk0MjAyNDQgWiBNNS4yMDQwMjk2MiwxMC42NDEyODcxIEM1LjIwMzA3NjA4LDkuNTkwNTI5OTMgNC4zNTE1MDU0Myw4LjczODk2MTYzIDMuMzAzMjgxMjcsOC43MzgwMDgzMyBDMi4yNTI1MzQzNiw4LjczODk1Mzk4IDEuNDAwOTU5MzIsOS41OTA1MTg4MyAxLjM5OTk5OTQyLDEwLjYzODcxODkgQzEuNDAwOTUyOTcsMTEuNjg5NDk0OSAyLjI1MjUyMzIsMTIuNTQxMDY3NiAzLjMwMjAwNzc1LDEyLjU0MjAyNDQgTDUuMjA0MDI5NjIsMTIuNTQyMDI0NCBMNS4yMDQwMjk2MiwxMC42NDEyODcxIFoiIGlkPSLot6/lvoQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMuMzAyMDE1LCAxMC42NDAwMTcpIHNjYWxlKDEsIC0xKSB0cmFuc2xhdGUoLTMuMzAyMDE1LCAtMTAuNjQwMDE3KSAiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggZD0iTTEwLjY3MDAyMjMsMTMuOTQzMDE1NiBMNy4zNjgwMTQ1NiwxMy45NDMwMTU2IEw3LjM2ODAxNDU2LDEwLjY0MDAwOTggQzcuMzY5Njc5OTIsOC44MTcwMzM5MiA4Ljg0NzA4MDc2LDcuMzM5NjQ5MzkgMTAuNjcwMDM2LDcuMzM4MDA4NzcgQzEyLjQ5Mjk5MTEsNy4zMzk2NjI2NyAxMy45NzAzODkzLDguODE3MDQ3NiAxMy45NzIwNDM2LDEwLjY0MDAxNjUgQzEzLjk3MDM3ODMsMTIuNDYyOTkyMiAxMi40OTI5Nzc0LDEzLjk0MDM3NjcgMTAuNjcwMDIyMiwxMy45NDIwMTc0IEwxMC42NzAwMjIzLDEzLjk0MzAxNTYgWiBNMTAuNjY4NzYyMiwxMi41NDIwMTc5IEMxMS43MTk1MDkyLDEyLjU0MTA3MjMgMTIuNTcxMDg0MywxMS42ODk1MDc0IDEyLjU3MjA0NDIsMTAuNjQxMzA3NCBDMTIuNTcxMDkwNiw5LjU5MDUzMTYxIDExLjcxOTUyMTgsOC43Mzg5NjE1IDEwLjY3MTI5NTgsOC43MzgwMDgyIEM5LjYyMDU0ODkyLDguNzM4OTUzODUgOC43Njg5NzM4OSw5LjU5MDUxODcgOC43NjgwMTQ1NiwxMC42Mzk5ODkyIEw4Ljc2ODAxNDU2LDEyLjU0MzAxNTYgTDkuNTYwMjU4NDksMTIuNTQzMDE1NiBMMTAuNjY4NzYyMiwxMi41NDIwMTc5IFoiIGlkPSLot6/lvoQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwLjY3MDAyOSwgMTAuNjQwNTEyKSBzY2FsZSgxLCAtMSkgdHJhbnNsYXRlKC0xMC42NzAwMjksIC0xMC42NDA1MTIpICI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==" elementtiming="element-timing"><!----></span><span class="vi-input__suffix" elementtiming="element-timing"><span class="vi-input__suffix-inner" elementtiming="element-timing"><i class="vi-input__icon vi-icon-arrow-down" elementtiming="element-timing"></i></span><!----></span><!----></div></div><div class="ttam-dropdown-panel__content" elementtiming="element-timing" style="top: 100%; margin-top: 5px; display: none;"><div scrollable="" data-testid="app-promotion-app-virtual-list-nxvwvD" keep="40" data-tea-expose="create_module_app_select_list_show" class="ttam-promotion-app-select__content" elementtiming="element-timing"><div role="group" class="" elementtiming="element-timing" style="padding: 0px;"><div role="listitem" class="" elementtiming="element-timing"><span effect="light" elementtiming="element-timing"><div data-testid="popover-main-5Uvc3C" role="tooltip" id="vi-popover-9903" aria-hidden="true" class="vi-popover vi-popper" elementtiming="element-timing" tabindex="0" style="max-width: none; display: none;"><!----><div class="ttam-promotion-app-item__hover-content" elementtiming="element-timing"><!----></div></div><div data-testid="app-promotion-app-item-7091913528453398529" class="ttam-promotion-app-item__item vi-popover__reference" elementtiming="element-timing" aria-describedby="vi-popover-9903" tabindex="0"><div class="vi-image ttam-promotion-app-item__item-img" elementtiming="element-timing"><img src="https://p16-tiktok-ads-sg.tiktokcdn.com/app-market-data-sg/0cc427effc59035fb28ae88331ec525e~tplv-n82rq3yc7r-compress.image" data-testid="component-app-item-kPYHjY" class="vi-image__inner" elementtiming="element-timing"><!----></div><div class="ttam-promotion-app-item__item-content" elementtiming="element-timing"><div dir="auto" class="ttam-promotion-app-item__item-title" elementtiming="element-timing"> iScanner - QRCode Barcode Scan </div><div dir="auto" class="ttam-promotion-app-item__item-desc" elementtiming="element-timing"> ID:com.i.scanner </div></div><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTRweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgMTQgMTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU0LjEgKDc2NDkwKSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5BbmRyb2lkPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9ImNyZWF0ZS1wcm9jZXNzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iQWQtRGV0YWlscy1jaG9vc2V3ZWJzaXRlL0FwcCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTg0MS4wMDAwMDAsIC0xODIxLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0iZ3JvdXAtY295cC01IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1Ni4wMDAwMDAsIDE0OTEuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iNi5yYWRpby8xLm5vcm1hbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjM2LjAwMDAwMCwgOTIuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9IjgubGlzdC8xLmZpcnN0LWxldmVsLW5vcm1hbC1jb3B5IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODguMDAwMDAwLCAxMjQuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSI1LmNoZWNrYm94LzEubm9ybWFs5aSN5Yi2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMi4wMDAwMDAsIDEwMS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSJhbmRyb2lkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDguMDAwMDAwLCAxMy4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cmVjdCBpZD0icmVjdCIgeD0iMCIgeT0iMCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48L3JlY3Q+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuNDE1MjAxMDYsNC45NTc0OTg4OSBDMS45MTA2MDMxMiw0Ljk1NzQ5ODg5IDEuNSw1LjM5NTI1ODc4IDEuNSw1LjkzNjcwMDAzIEwxLjUsOS43NTYyMjAxIEMxLjUsMTAuMjk3MDIwNyAxLjkwOTk4NTY0LDEwLjczNDc4MDYgMi40MTUyMDEwNiwxMC43MzQ3ODA2IEMyLjkyMDQxNjQ5LDEwLjczNDc4MDYgMy4zMzEwMjExMSwxMC4yOTcwMjA3IDMuMzMxMDIxMTEsOS43NTU1Nzk0OCBMMy4zMzEwMjExMSw1LjkzNjA1OTQxIEMzLjMzMTAyMTExLDUuMzk2NTM4NDcgMi45MjE2NTQ0NSw0Ljk1ODEzNzk2IDIuNDE1ODIwMDUsNC45NTgxMzc5NiBMMi40MTUyMDEwNiw0Ljk1NzQ5ODg5IFogTTEzLjQ1OTQ1NzgsNC45NTc0OTg4OSBDMTIuOTUzNjIzNCw0Ljk1NzQ5ODg5IDEyLjU0MzYzNzcsNS4zOTUyNTg3OCAxMi41NDM2Mzc3LDUuOTM2MDU5NDEgTDEyLjU0MzYzNzcsOS43NTU1Nzk0OCBDMTIuNTQzNjM3NywxMC4yOTYzODAxIDEyLjk1NDI0MDksMTAuNzM0MTQgMTMuNDU4ODM4OCwxMC43MzQxNCBDMTMuOTY0NjczMiwxMC43MzQxNCAxNC4zNzQ2NTg5LDEwLjI5NjM4MDEgMTQuMzc0NjU4OSw5Ljc1NDkzODg1IEwxNC4zNzQ2NTg5LDUuOTM2MDU5NDEgQzE0LjM3NDY1ODksNS4zOTY1Mzg0NyAxMy45NjQ2NzMyLDQuOTU4MTM3OTYgMTMuNDU5NDU3OCw0Ljk1ODEzNzk2IEwxMy40NTk0NTc4LDQuOTU3NDk4ODkgWiBNMy44ODIwMDk1NywxMS45NjgwNjk2IEMzLjg4MjAwOTU3LDEyLjM4MzQyOTQgNC4yMDE3MTEyNiwxMi43MTg3OTA3IDQuNTk1NjE4NDUsMTIuNzE4NzkwNyBMNS40MTEyNTk4NywxMi43MTg3OTA3IEw1LjQxMTI1OTg3LDE0Ljg0NDg3MTMgQzUuNDExMjU5ODcsMTUuMzg1MDMxMyA1LjgyMTI0NTUyLDE1LjgyMjc5MjggNi4zMjY0NjA5NCwxNS44MjI3OTI4IEM2LjgzMTY3NjM2LDE1LjgyMjc5MjggNy4yNDE2NjIsMTUuMzg1NjcyIDcuMjQxNjYyLDE0Ljg0NDg3MTMgTDcuMjQxNjYyLDEyLjcxODc5MDcgTDguNjY2NDA2ODQsMTIuNzE4NzkwNyBMOC42NjY0MDY4NCwxNC44NDQ4NzEzIEM4LjY2NjQwNjg0LDE1LjM4NTAzMTMgOS4wNzcwMDk5NiwxNS44MjI3OTI4IDkuNTgxNjA3OSwxNS44MjI3OTI4IEMxMC4wODc0NDIzLDE1LjgyMjc5MjggMTAuNDk2ODA5LDE1LjM4NTY3MiAxMC40OTY4MDksMTQuODQ0ODcxMyBMMTAuNDk2ODA5LDEyLjcxODc5MDcgTDExLjMxMzA2OTQsMTIuNzE4NzkwNyBDMTEuNzA2MzU5MSwxMi43MTg3OTA3IDEyLjAyNjY3ODMsMTIuMzgzNDMxIDEyLjAyNjY3ODMsMTEuOTY4MDY5NiBMMTIuMDI2Njc4Myw0Ljk4NzU3NzA1IEwzLjg3OTUzMzY0LDQuOTg3NTc3MDUgTDMuODc5NTMzNjQsMTEuOTY4MDY5NiBMMy44ODIwMDcxNiwxMS45NjgwNjk2IEwzLjg4MjAwOTU3LDExLjk2ODA2OTYgWiBNOS44Njg1NDEyNCwxLjM2OTY1MDk3IEwxMC42MjExMDgzLDAuMjIzNDA5MDA5IEMxMC42NjU2MzE2LDAuMTU0OTI4OTI5IDEwLjY1NDUwMDgsMC4wNjUzMjkxMzc3IDEwLjU5NjM3MzEsMC4wMjMwODg0NjM2IEMxMC41MzgyNDU1LC0wLjAxOTE1MTU4NTYgMTAuNDU0MTQ1OSwwLjAwMjYwODQzOTc0IDEwLjQxMDI0MDQsMC4wNjk4MDg1MTc5IEw5LjYyNzk5MDg3LDEuMjYzNDA5OTEgTDkuNjI3OTkwNzYsMS4yNjM0MDk4NiBDOS4wOTAwMzExNCwxLjA0MjE2NTg2IDguNTE2MjE3MzEsMC45MjkyMTEwMzcgNy45MzczMzY4NywwLjkzMDYwOTQ3NiBDNy4zMzQ0MTcyNSwwLjkzMDYwOTQ3NiA2Ljc2MjQxNjU4LDEuMDQ5MDA5NjEgNi4yNDczMDE5NywxLjI2Mjc2OTI0IEw1LjQ2NTY2OTg4LDAuMDY3ODg4MTU5MyBDNS40MjA1MjgyMSwwLjAwMDY4ODA4MTEwMiA1LjMzNzA0NzAzLC0wLjAyMDQzMTk0MzUgNS4yNzgzMDA3MSwwLjAyMTgwODEwNTcgQzUuMjE5NTU0NywwLjA2NDY4ODE1NTYgNS4yMDkwNDIyNSwwLjE1MzY0ODI1OSA1LjI1MzU2NTU1LDAuMjIyMTI4NjUxIEw2LjAwNTUxNTEzLDEuMzcwOTI5OTkgQzQuODA5NTcwNTYsMS45NTY1MzA2NyAzLjk2OTgxNTk3LDMuMDY3NTcyNTkgMy44NjM0NTY1OCw0LjM2NTQ5NTk3IEwxMi4wMDk5ODIyLDQuMzY1NDk1OTcgQzExLjkwMjM4NDMsMy4wNjgyMTQ3OCAxMS4wNjMyNDMyLDEuOTU1ODk5NDIgOS44NjczMDQ2OCwxLjM3MDkyOTk5IEw5Ljg2NzkyMzA2LDEuMzcwOTI5OTkgTDkuODY3OTIzMDYsMS4zNzAyODk5OSBMOS44Njg1NDEyNCwxLjM2OTY1MDk3IFogTTYuMjE4ODY2NiwzLjE4MDg1NjIgTDYuMjE4ODY2NTksMy4xODA4NTYyIEM1Ljk2ODA4NzksMy4xNzg3NDM0MyA1Ljc2NjM1Mzc5LDIuOTY2ODA0MzkgNS43NjgwNjg4MywyLjcwNzI1NTY1IEM1Ljc2ODA2ODgzLDIuNDQ1NDk1OTcgNS45Njk2NjEwMiwyLjIzMzAxNDQ3IDYuMjE4ODY2NTksMi4yMzMwMTQ0NyBDNi40Njc0NTQ2OCwyLjIzMzAxNDQ3IDYuNjY5MDQ2ODcsMi40NDU0OTQ0MSA2LjY2OTA0Njg3LDIuNzA3MjU1NjUgQzYuNjY5MDQ2ODcsMi45Njk2NTU5NSA2LjQ2NzQ1NDY4LDMuMTgxNDk2ODMgNi4yMTg4NjY1OSwzLjE4MTQ5NjgzIEw2LjIxODg2NjU5LDMuMTgwODU2ODMgTDYuMjE4ODY2NiwzLjE4MDg1NjIgWiBNOS43MTE0NzA1MywzLjE4MDg1NjIgTDkuNzExNDcwNTQsMy4xODA4NTYyIEM5LjQ2MDQ1Nzg0LDMuMTc5MDk0OTMgOS4yNTgzNTIzNSwyLjk2NzA2Njg5IDkuMjYwMDUzNzksMi43MDcyNzc1MiBDOS4yNjAwNTM4NCwyLjcwNzI3MDI3IDkuMjYwMDUzODksMi43MDcyNjMwMSA5LjI2MDA1Mzk0LDIuNzA3MjU1NzYgQzkuMjYwMDUzOTQsMi40NDU0OTYwOCA5LjQ2Mjg4MjU4LDIuMjMzMDE0NTggOS43MTE0NzA2OCwyLjIzMzAxNDU4IEM5Ljk2MDA1ODc3LDIuMjMzMDE0NTggMTAuMTYxNjUxLDIuNDQ1NDk0NTEgMTAuMTYxNjUxLDIuNzA3MjU1NzYgQzEwLjE2MTY1MSwyLjk2OTY1NjA2IDkuOTYwMDU4NzcsMy4xODE0OTY5MyA5LjcxMTQ3MDY4LDMuMTgxNDk2OTMgTDkuNzExNDcwNjgsMy4xODA4NTY5MyBMOS43MTE0NzA1MywzLjE4MDg1NjIgWiIgaWQ9IuW9oueKtiIgZmlsbD0iIzhBQ0UwMCI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" alt="Android" class="ttam-promotion-app-item__item-icon" elementtiming="element-timing"></div></span></div><div role="listitem" class="" elementtiming="element-timing"><span effect="light" elementtiming="element-timing"><div data-testid="popover-main-5Uvc3C" role="tooltip" id="vi-popover-8836" aria-hidden="true" class="vi-popover vi-popper" elementtiming="element-timing" tabindex="0" style="max-width: none; display: none;"><!----><div class="ttam-promotion-app-item__hover-content" elementtiming="element-timing"><!----></div></div><div data-testid="app-promotion-app-item-7337238951184400385" class="ttam-promotion-app-item__item vi-popover__reference" elementtiming="element-timing" aria-describedby="vi-popover-8836" tabindex="0"><div class="vi-image ttam-promotion-app-item__item-img" elementtiming="element-timing"><img src="https://p16-tiktok-ads-sg.tiktokcdn.com/app-market-data-sg/702294e7636c74434ccf0b000e3d1d99~tplv-n82rq3yc7r-compress.image" data-testid="component-app-item-kPYHjY" class="vi-image__inner" elementtiming="element-timing"><!----></div><div class="ttam-promotion-app-item__item-content" elementtiming="element-timing"><div dir="auto" class="ttam-promotion-app-item__item-title" elementtiming="element-timing"> Prankster-Funny Prank Sounds </div><div dir="auto" class="ttam-promotion-app-item__item-desc" elementtiming="element-timing"> ID:com.voice.prankster </div></div><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTRweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgMTQgMTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU0LjEgKDc2NDkwKSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5BbmRyb2lkPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9ImNyZWF0ZS1wcm9jZXNzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iQWQtRGV0YWlscy1jaG9vc2V3ZWJzaXRlL0FwcCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTg0MS4wMDAwMDAsIC0xODIxLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0iZ3JvdXAtY295cC01IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1Ni4wMDAwMDAsIDE0OTEuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iNi5yYWRpby8xLm5vcm1hbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjM2LjAwMDAwMCwgOTIuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9IjgubGlzdC8xLmZpcnN0LWxldmVsLW5vcm1hbC1jb3B5IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxODguMDAwMDAwLCAxMjQuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSI1LmNoZWNrYm94LzEubm9ybWFs5aSN5Yi2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMi4wMDAwMDAsIDEwMS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnIGlkPSJhbmRyb2lkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDguMDAwMDAwLCAxMy4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cmVjdCBpZD0icmVjdCIgeD0iMCIgeT0iMCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48L3JlY3Q+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuNDE1MjAxMDYsNC45NTc0OTg4OSBDMS45MTA2MDMxMiw0Ljk1NzQ5ODg5IDEuNSw1LjM5NTI1ODc4IDEuNSw1LjkzNjcwMDAzIEwxLjUsOS43NTYyMjAxIEMxLjUsMTAuMjk3MDIwNyAxLjkwOTk4NTY0LDEwLjczNDc4MDYgMi40MTUyMDEwNiwxMC43MzQ3ODA2IEMyLjkyMDQxNjQ5LDEwLjczNDc4MDYgMy4zMzEwMjExMSwxMC4yOTcwMjA3IDMuMzMxMDIxMTEsOS43NTU1Nzk0OCBMMy4zMzEwMjExMSw1LjkzNjA1OTQxIEMzLjMzMTAyMTExLDUuMzk2NTM4NDcgMi45MjE2NTQ0NSw0Ljk1ODEzNzk2IDIuNDE1ODIwMDUsNC45NTgxMzc5NiBMMi40MTUyMDEwNiw0Ljk1NzQ5ODg5IFogTTEzLjQ1OTQ1NzgsNC45NTc0OTg4OSBDMTIuOTUzNjIzNCw0Ljk1NzQ5ODg5IDEyLjU0MzYzNzcsNS4zOTUyNTg3OCAxMi41NDM2Mzc3LDUuOTM2MDU5NDEgTDEyLjU0MzYzNzcsOS43NTU1Nzk0OCBDMTIuNTQzNjM3NywxMC4yOTYzODAxIDEyLjk1NDI0MDksMTAuNzM0MTQgMTMuNDU4ODM4OCwxMC43MzQxNCBDMTMuOTY0NjczMiwxMC43MzQxNCAxNC4zNzQ2NTg5LDEwLjI5NjM4MDEgMTQuMzc0NjU4OSw5Ljc1NDkzODg1IEwxNC4zNzQ2NTg5LDUuOTM2MDU5NDEgQzE0LjM3NDY1ODksNS4zOTY1Mzg0NyAxMy45NjQ2NzMyLDQuOTU4MTM3OTYgMTMuNDU5NDU3OCw0Ljk1ODEzNzk2IEwxMy40NTk0NTc4LDQuOTU3NDk4ODkgWiBNMy44ODIwMDk1NywxMS45NjgwNjk2IEMzLjg4MjAwOTU3LDEyLjM4MzQyOTQgNC4yMDE3MTEyNiwxMi43MTg3OTA3IDQuNTk1NjE4NDUsMTIuNzE4NzkwNyBMNS40MTEyNTk4NywxMi43MTg3OTA3IEw1LjQxMTI1OTg3LDE0Ljg0NDg3MTMgQzUuNDExMjU5ODcsMTUuMzg1MDMxMyA1LjgyMTI0NTUyLDE1LjgyMjc5MjggNi4zMjY0NjA5NCwxNS44MjI3OTI4IEM2LjgzMTY3NjM2LDE1LjgyMjc5MjggNy4yNDE2NjIsMTUuMzg1NjcyIDcuMjQxNjYyLDE0Ljg0NDg3MTMgTDcuMjQxNjYyLDEyLjcxODc5MDcgTDguNjY2NDA2ODQsMTIuNzE4NzkwNyBMOC42NjY0MDY4NCwxNC44NDQ4NzEzIEM4LjY2NjQwNjg0LDE1LjM4NTAzMTMgOS4wNzcwMDk5NiwxNS44MjI3OTI4IDkuNTgxNjA3OSwxNS44MjI3OTI4IEMxMC4wODc0NDIzLDE1LjgyMjc5MjggMTAuNDk2ODA5LDE1LjM4NTY3MiAxMC40OTY4MDksMTQuODQ0ODcxMyBMMTAuNDk2ODA5LDEyLjcxODc5MDcgTDExLjMxMzA2OTQsMTIuNzE4NzkwNyBDMTEuNzA2MzU5MSwxMi43MTg3OTA3IDEyLjAyNjY3ODMsMTIuMzgzNDMxIDEyLjAyNjY3ODMsMTEuOTY4MDY5NiBMMTIuMDI2Njc4Myw0Ljk4NzU3NzA1IEwzLjg3OTUzMzY0LDQuOTg3NTc3MDUgTDMuODc5NTMzNjQsMTEuOTY4MDY5NiBMMy44ODIwMDcxNiwxMS45NjgwNjk2IEwzLjg4MjAwOTU3LDExLjk2ODA2OTYgWiBNOS44Njg1NDEyNCwxLjM2OTY1MDk3IEwxMC42MjExMDgzLDAuMjIzNDA5MDA5IEMxMC42NjU2MzE2LDAuMTU0OTI4OTI5IDEwLjY1NDUwMDgsMC4wNjUzMjkxMzc3IDEwLjU5NjM3MzEsMC4wMjMwODg0NjM2IEMxMC41MzgyNDU1LC0wLjAxOTE1MTU4NTYgMTAuNDU0MTQ1OSwwLjAwMjYwODQzOTc0IDEwLjQxMDI0MDQsMC4wNjk4MDg1MTc5IEw5LjYyNzk5MDg3LDEuMjYzNDA5OTEgTDkuNjI3OTkwNzYsMS4yNjM0MDk4NiBDOS4wOTAwMzExNCwxLjA0MjE2NTg2IDguNTE2MjE3MzEsMC45MjkyMTEwMzcgNy45MzczMzY4NywwLjkzMDYwOTQ3NiBDNy4zMzQ0MTcyNSwwLjkzMDYwOTQ3NiA2Ljc2MjQxNjU4LDEuMDQ5MDA5NjEgNi4yNDczMDE5NywxLjI2Mjc2OTI0IEw1LjQ2NTY2OTg4LDAuMDY3ODg4MTU5MyBDNS40MjA1MjgyMSwwLjAwMDY4ODA4MTEwMiA1LjMzNzA0NzAzLC0wLjAyMDQzMTk0MzUgNS4yNzgzMDA3MSwwLjAyMTgwODEwNTcgQzUuMjE5NTU0NywwLjA2NDY4ODE1NTYgNS4yMDkwNDIyNSwwLjE1MzY0ODI1OSA1LjI1MzU2NTU1LDAuMjIyMTI4NjUxIEw2LjAwNTUxNTEzLDEuMzcwOTI5OTkgQzQuODA5NTcwNTYsMS45NTY1MzA2NyAzLjk2OTgxNTk3LDMuMDY3NTcyNTkgMy44NjM0NTY1OCw0LjM2NTQ5NTk3IEwxMi4wMDk5ODIyLDQuMzY1NDk1OTcgQzExLjkwMjM4NDMsMy4wNjgyMTQ3OCAxMS4wNjMyNDMyLDEuOTU1ODk5NDIgOS44NjczMDQ2OCwxLjM3MDkyOTk5IEw5Ljg2NzkyMzA2LDEuMzcwOTI5OTkgTDkuODY3OTIzMDYsMS4zNzAyODk5OSBMOS44Njg1NDEyNCwxLjM2OTY1MDk3IFogTTYuMjE4ODY2NiwzLjE4MDg1NjIgTDYuMjE4ODY2NTksMy4xODA4NTYyIEM1Ljk2ODA4NzksMy4xNzg3NDM0MyA1Ljc2NjM1Mzc5LDIuOTY2ODA0MzkgNS43NjgwNjg4MywyLjcwNzI1NTY1IEM1Ljc2ODA2ODgzLDIuNDQ1NDk1OTcgNS45Njk2NjEwMiwyLjIzMzAxNDQ3IDYuMjE4ODY2NTksMi4yMzMwMTQ0NyBDNi40Njc0NTQ2OCwyLjIzMzAxNDQ3IDYuNjY5MDQ2ODcsMi40NDU0OTQ0MSA2LjY2OTA0Njg3LDIuNzA3MjU1NjUgQzYuNjY5MDQ2ODcsMi45Njk2NTU5NSA2LjQ2NzQ1NDY4LDMuMTgxNDk2ODMgNi4yMTg4NjY1OSwzLjE4MTQ5NjgzIEw2LjIxODg2NjU5LDMuMTgwODU2ODMgTDYuMjE4ODY2NiwzLjE4MDg1NjIgWiBNOS43MTE0NzA1MywzLjE4MDg1NjIgTDkuNzExNDcwNTQsMy4xODA4NTYyIEM5LjQ2MDQ1Nzg0LDMuMTc5MDk0OTMgOS4yNTgzNTIzNSwyLjk2NzA2Njg5IDkuMjYwMDUzNzksMi43MDcyNzc1MiBDOS4yNjAwNTM4NCwyLjcwNzI3MDI3IDkuMjYwMDUzODksMi43MDcyNjMwMSA5LjI2MDA1Mzk0LDIuNzA3MjU1NzYgQzkuMjYwMDUzOTQsMi40NDU0OTYwOCA5LjQ2Mjg4MjU4LDIuMjMzMDE0NTggOS43MTE0NzA2OCwyLjIzMzAxNDU4IEM5Ljk2MDA1ODc3LDIuMjMzMDE0NTggMTAuMTYxNjUxLDIuNDQ1NDk0NTEgMTAuMTYxNjUxLDIuNzA3MjU1NzYgQzEwLjE2MTY1MSwyLjk2OTY1NjA2IDkuOTYwMDU4NzcsMy4xODE0OTY5MyA5LjcxMTQ3MDY4LDMuMTgxNDk2OTMgTDkuNzExNDcwNjgsMy4xODA4NTY5MyBMOS43MTE0NzA1MywzLjE4MDg1NjIgWiIgaWQ9IuW9oueKtiIgZmlsbD0iIzhBQ0UwMCI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" alt="Android" class="ttam-promotion-app-item__item-icon" elementtiming="element-timing"></div></span></div></div><div elementtiming="element-timing" style="width: 100%; height: 0px;"></div></div><div class="ttam-select-list-operator" data-testid="app-promotion-app-sWhsXx" elementtiming="element-timing"><div elementtiming="element-timing"><button data-testid="select-list-operator-index-unwgjY" type="button" class="vi-button vi-byted-button vi-button--text ttam-select-list-operator__btn" data-tea="common_select_list_operator_add_app_select" data-tea-from="" elementtiming="element-timing"><!----><i class="vi-icon2-add-small" elementtiming="element-timing"></i><span elementtiming="element-timing"> 新建 </span></button></div><div class="ttam-select-list-operator__right" elementtiming="element-timing"><span elementtiming="element-timing"></span><button data-testid="select-list-operator-index-fyLLsP" type="button" class="vi-button vi-byted-button vi-button--text ttam-select-list-operator__btn ttam-select-list-operator__btn--right" data-tea="common_select_list_operator_refresh_app_select" elementtiming="element-timing"><!----><i class="vi-icon2-refresh" elementtiming="element-timing"></i><span elementtiming="element-timing"> 刷新 </span></button></div></div></div></div></div></div></div></div><!----><!----></div></div><!----></div></div></div></div></section>
最新发布
09-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值