插件式软件和实现方法、计算机设备和可读存储介质与流程

文档序号:33621636发布日期:2023-03-25 12:14阅读:46来源:国知局
插件式软件和实现方法、计算机设备和可读存储介质与流程

1.本技术属于计算机技术领域,具体涉及一种插件式软件和实现方法、计算机设备和可读存储介质。


背景技术:

2.相关技术中,采用启动时安装插件,并且,在插件在安装时,主功能和附加功能未做拆分,全部插件均进行安装,造成大型软件普遍存在安装包体过大的问题。
3.相关技术中,插件在加载时,均是采用启动时加载全部插件到内存的方式,占用内存情况严重,降低了用户体验。并且,相关技术中心的插件结构复杂,一般插件结构需要设置多层,例如,需要引入服务层、交互层、物理层等,复杂的结构加大了插件开发难度,也增加了耦合性。


技术实现要素:

4.本技术实施例的目的是提供一种插件式软件和实现方法、计算机设备和可读存储介质,能够解决在启动时安装插件,安装全部插件,导致安装包过大,降低用户体验的问题。
5.第一方面,本技术实施例提供了一种插件式软件实现方法,包括基于开始安装主程序的指令,显示插件模块中的多个插件;基于选取待安装插件的指令,构建插件管理模块,通过服务端下载待安装插件;安装主程序模块、插件管理模块和待安装插件;基于启动主程序的指令,运行主程序模块,加载插件管理模块,显示目标插件;基于启动目标插件的指令,调用目标插件。
6.第二方面,本技术实施例提供了一种插件式软件,包括主程序模块、插件管理模块和插件模块,主程序模块用于加载插件管理模块,显示目标插件,发送调用目标插件通知或释放目标插件通知至插件管理模块;插件管理模块用于在接收到调用目标插件通知的情况下,在插件模块中查找目标插件,加载目标插件,返回插件的对象指针至插件管理模块,将插件的对象指针返回至主程序模块;在接收到释放目标插件通知的情况下,释放目标插件;插件模块包括多个插件。
7.第三方面,本技术实施例提供了一种计算机设备,该计算机设备包括处理器和存储器,存储器存储可在处理器上运行的程序或指令,程序或指令被处理器执行时实现如第一方面的插件式软件实现方法的步骤。
8.第四方面,本技术实施例提供了一种可读存储介质,可读存储介质上存储程序或指令,程序或指令被处理器执行时实现如第一方面的插件式软件实现方法的步骤。
9.本技术采用安装时选装插件的形式,即在安装软件的时候可以选择安装或不安装某些插件,用户自由度高,由于无需安装所有插件,在一定程度上可以减小软件安装包的体积,进而提升用户体验。
附图说明
10.图1示出了本技术实施例提供的插件式软件实现方法的流程示意图之一;
11.图2示出了本技术实施例提供的插件式软件实现方法的流程示意图之二;
12.图3示出了本技术实施例提供的插件式软件实现方法的流程示意图之三;
13.图4示出了本技术实施例提供的插件式软件实现方法的流程示意图之四;
14.图5示出了本技术实施例提供的插件式软件的结构框图之一;
15.图6示出了本技术实施例的插件式软件层次示意图;
16.图7示出了本技术实施例的插件内存占用示意图;
17.图8示出了本技术实施例提供的插件结构框图;
18.图9示出了本技术实施例提供的计算机设备的结构框图;
19.图10示出了本技术实施例提供的插件之间接口调用示意图;
20.图11示出了本技术实施例提供的插件式软件安装流程示意图。
21.其中,图5至图10中附图标记与部件名称之间的对应关系为:
22.100:插件式软件;110:主程序模块;120:插件管理模块;130:插件模块;140:插件;142:资源区;144:组态转换区;146:通信区;148:代码区;300:主程序层;302:插件管理层;304:插件层;306:插件a;308:插件b;310:插件c;312:插件接口类;314:插件管理类;316:主窗体;1000:计算机设备;1002:处理器;1004:存储器。
具体实施方式
23.下面将结合本技术实施例中的附图,对本技术实施例中的技术方案进行清楚地描述,显然,所描述的实施例是本技术一部分实施例,而不是全部的实施例。基于本技术中的实施例,本领域普通技术人员获得的所有其他实施例,都属于本技术保护的范围。
24.本技术的说明书和权利要求书中的术语“第一”、“第二”等是用于区别类似的对象,而不用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便本技术的实施例能够以除了在这里图示或描述的那些以外的顺序实施,且“第一”、“第二”等所区分的对象通常为一类,并不限定对象的个数,例如第一对象可以是一个,也可以是多个。此外,说明书以及权利要求中“和/或”表示所连接对象的至少其中之一,字符“/”,一般表示前后关联对象是一种“或”的关系。
25.下面结合附图1至图11,通过具体的实施例及其应用场景对本技术实施例提供的插件式软件和实现方法、计算机设备和可读存储介质进行详细地说明。
26.在本技术实施例提供了一种插件式软件实现方法,图1示出了本技术实施例提供的插件式软件实现方法的流程示意图之一,如图1所示,插件式软件实现方法包括:
27.步骤s102,基于开始安装主程序的指令,显示插件模块中的多个插件。
28.步骤s104,基于选取待安装插件的指令,构建插件管理模块,通过服务端下载待安装插件。
29.步骤s106,安装主程序模块、插件管理模块和待安装插件。
30.步骤s108,基于启动主程序的指令,运行主程序模块,加载插件管理模块,显示目标插件。
31.步骤s110,基于启动目标插件的指令,调用目标插件。
32.相关技术中,大型软件通常具有主功能和很多附加功能,因为对主功能和附加功能没有进行拆分,会导致软件安装包体过大的问题。
33.具体地,本实施例在安装时,首先开始安装主程序模块时,在安装主程序模块时,显示插件模块中的多个插件,显示的方式可以为弹出插件选择模块,可选地,插件选择模块可以为插件选择框,其中设有勾选输入框,便于用户进行插件的选取。在插件选择框中勾选相应需要安装的插件,选取结束并进行确认后,构建插件管理模块,从服务端下载相应的插件,下载完成后执行安装流程,安装主程序模块、插件管理模块和待安装插件,直至安装成功。
34.进一步地,本实施例中可以设定主程序模块运行时默认加载插件管理模块,渲染主程序模块的主窗口。在主程序模块运行时,插件管理模块默认也是加载后运行状态,值得说明的是,即使在当前状态下,没有调用任意一个插件,在主程序模块运行时也加载插件管理模块。在主程序模块运行时,需要对主程序模块的主窗口进行渲染,主程序模块可以设有渲染库。本实施例中,通过默认加载插件管理模块,可以在主程序模块需要调用插件或者释放插件时,及时发送通知至插件管理模块,更快进行响应。
35.本实施例采用安装时选装插件的形式,对主功能和附加功能进行拆分,即在安装软件的时候可以选择安装或不安装某些插件,用户自由度高,由于无需安装所有插件,在一定程度上可以减小软件安装包的体积,进而提升用户体验。
36.举例而言地,如图11所示,安装步骤可以包括:
37.步骤s502,开始安装。
38.开始安装主程序时,弹出插件选择框。
39.步骤s504,勾选插件。
40.在插件选择框中勾选相应的插件。根据勾选的插件,更新插件配置表。
41.步骤s506,下载插件。
42.安装程序从服务端下载勾选的相应的插件。
43.步骤s508,判断是否下载完成。
44.如果下载完成,进入步骤s510,否则返回步骤s506,继续下载插件。
45.步骤s510,安装插件。
46.插件下载完成后,进行安装。
47.步骤s512,判断是否安装成功。
48.如果安装成功,进入步骤s514,否则,返回步骤s502,重新进行安装,直至安装成功。
49.步骤s514,安装成功。
50.再次举例而言地,本实施例中,还可以先建立插件配置表,插件配置表记录了安装插件的自身信息,插件数量及插件所属的功能类别(插件式软件根据实现功能不同,可以划分为多个功能类别,每个插件对应有具体的功能类别),自身信息包括插件存储路径、资源数量(即依赖的资源库)等。然后再根据用户选择插件自动更新插件配置表信息。在插件式软件启动时加载插件配置表,根据插件配置表信息在菜单栏创建插件关联按钮。通过点击插件关联按钮,开始执行插件初始化及加载操作。通过上述操作可以简化操作,通过插件关联按钮实现加载等操作,提升用户体验。
51.在本技术的一些实施例中,图2示出了本技术实施例提供的插件式软件实现方法的流程示意图之二,如图2所示,调用目标插件,具体包括:
52.步骤s202,通过主程序模块发送调用目标插件通知至插件管理模块。
53.步骤s204,插件管理模块在插件模块中查找目标插件,加载目标插件,返回目标插件的对象指针至插件管理模块。
54.步骤s206,插件管理模块将目标插件的对象指针返回至主程序模块。
55.具体地,主程序模块用于管理插件管理模块,负责整个软件框架的运行,主程序模块与插件管理模块之间可以进行通信,分别发送与接收相关信息,在主程序模块需要调用目标插件时,主程序模块发送调用目标插件通知至插件管理模块,在收到上述通知后,插件管理块进行相应动作,在插件模块中查找目标插件,并且进行加载。
56.本实施例中,只通过主程序模块、插件管理模块和插件模块,即可实现插件运行,结构简单,降低了开发难度,并且插件均在同一进程中通信与交互,可以提高插件运行效率。
57.在本技术的一些实施例中,图3示出了本技术实施例提供的插件式软件实现方法的流程示意图之三,如图3所示,插件式软件实现方法,还包括:
58.步骤s302,基于关闭目标插件的指令,通过主程序模块发送释放目标插件通知至插件管理模块。
59.步骤s304,插件管理模块释放目标插件。
60.具体地,当插件式软件中有至少一个目标插件在运行时,在需要关闭目标插件时,主程序模块发送释放目标插件通知,在收到上述通知后,插件管理器进行相应动作,释放插件。插件模块中包括至少一个插件,插件处于动态加载与动态释放的过程中,在插件管理模块的控制下,需要调用时进行加载,关闭时进行释放,值得说明的是,当插件模块中有多个插件时,每个插件均可以独立加载或释放,不影响其余插件的运行。在本实施例中,插件可以动态加载和释放,插件运行时加载到内存,不用时释放内存,节省内存空间。
61.在本技术的一些实施例中,图4示出了本技术实施例提供的插件式软件实现方法的流程示意图之四,如图4所示,插件式软件实现方法,还包括:
62.步骤s402,主程序模块发送第一信息至插件管理模块,插件管理模块释放全部插件;
63.步骤s404,插件管理模块发送第二信息至主程序模块,主程序模块释放插件管理模块;
64.步骤s406,主程序自我释放。
65.进一步地,本实施例说明了在软件进程的生命周期结束时,主程序模块、插件管理模块、插件的运行情况。在软件生命周期结束时,主程序模块的生命周期、插件管理模块的生命周期与其同步,主程序模块发送第一信息至插件管理模块,插件管理模块收到第一消息后,对插件的生命周期进行控制,控制全部插件释放,进而结束所有插件的生命周期。在插件全部释放后,插件管理模块发送第二信息至主程序模块,主程序模块结束插件管理模块的生命周期,在插件管理模块的生命周期结束后,主城模块结束自己的生命周期。本实施例详细给出了在软件进程的生命周期结束时,如何控制主程序模块、插件管理模块、插件的生命周期的具体步骤,便于插件式软件可以实现正常运行。
66.在本技术的一些实施例中,插件式软件实现方法,还包括:
67.将插件继承至插件接口类,设定插件接口类与插件管理模块的插件管理类通过继承多态的方式进行通信。
68.可以理解的是,接口继承是出自设计模式中的一个概念。接口继承,又称子类型化。描述了一个对象什么时候能够被用来替代另一个对象。
69.具体地,插件管理模块对应有插件管理类,插件继承至插件接口类,插件管理类与插件接口类之间有相互通信方法,通过继承多态的方式,在插件管理模块加载插件时,可以区分调用的具体插件名称。本实施例中插件管理类与插件接口类通过继承多态的方式进行通信,可以对调用插件的具体类别进行区分判断,以使得插件管理模块可以加载到正确的插件。
70.进一步地,如图10所示,插件a306、插件b308和插件c310均继承至插件接口类312,插件接口类312与插件管理类314之间通过继承多态的方式通信,可以区分调用者是插件a306、插件b308或插件c310。
71.在本技术的一些实施例中,插件式软件实现方法,还包括:
72.在第一插件与第二插件需要通信的情况下,第一插件发送第三信息至插件管理模块,插件管理模块在接收到第三信息后,对第三信息进行处理后得到第四信息,将第四信息发送至第二插件,第二插件对第四信息进行处理后得到第五信息,将第五信息发送至插件管理模块,插件管理模块将第五信息发送至第一插件。
73.具体地,在第一插件、第二插件需要进行通信时,第一插件发出第三信息给插件管理类,插件管理类进行处理后,得到第四信息,再将第四信息转给第二插件,第二插件进行处理,得到第五信息,再将第五信息反馈给插件管理类,插件管理类再将第五信息转发给第一插件,通过上述过程,完成第一插件与第二插件的一轮相互通信。本实施例采用上述方式,可以保证第一插件与第二插件之间的相互独立性。
74.进一步地,如图10所示,插件a306和插件b308需要通信时,插件a306发出信息至插件管理类314,插件管理类314处理后转给插件b308,插件b308把处理后的消息反馈给插件管理类314,插件管理类314再转发给插件a306,完成一轮相互通信,可保证插件a306与插件b308的相互独立性。
75.在本技术实施例提供一种插件式软件,图5示出了本技术实施例提供的插件式软件的结构框图之一,如图5所示,插件式软件100包括主程序模块110、插件管理模块120和插件模块130。
76.主程序模块110用于加载插件管理模块,显示目标插件,发送调用目标插件通知或释放目标插件通知至插件管理模块120;插件管理模块120用于在接收到调用目标插件通知的情况下,在插件模块130中查找目标插件,加载目标插件,返回目标插件的对象指针至插件管理模块120,将目标插件的对象指针返回至主程序模块110;在接收到释放目标插件通知的情况下,释放目标插件;插件模块130包括多个插件140。
77.可以理解的是,主程序也称为主函数,是程序开始运行的地方,软件框架(software framework),通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。插件(plug-in,又称addin、add-in、addon或add-on)是一种遵循一定规范的应用程序接口编写
出来的程序。对象指针为指向类的成员的指针,用来容纳对象地址的指针,指向的是一个对象。
78.具体地,主程序模块110用于管理插件管理模块120,负责整个软件框架的运行,主程序模块110与插件管理模块120之间可以进行通信,分别发送与接收相关信息,在主程序模块110需要调用目标插件时,主程序模块110发送调用目标插件通知至插件管理模块120,在收到上述通知后,插件管理模块120进行相应动作,在插件模块130中查找目标插件,并且进行加载。当插件式软件中有至少一个目标插件在运行时,在需要关闭目标插件时,主程序模块110发送释放目标插件通知,在收到上述通知后,插件管理模块120进行相应动作,释放目标插件。插件模块130中包括至少一个插件,插件处于动态加载与动态释放的过程中,在插件管理模块120的控制下,需要调用时进行加载,关闭时进行释放,值得说明的是,当插件模块130中有多个插件时,每个插件均可以独立加载或释放,不影响其余插件的运行。本实施例中,只通过主程序模块110、插件管理模块120和插件模块130,即可实现插件运行,结构简单,降低了开发难度,并且插件均在同一进程中通信与交互,可以提高插件运行效率。在本实施例中,插件可以动态加载和释放,插件运行时加载到内存,不用时释放内存,节省内存空间。
79.相关技术中,插件式软件的结构一般采用多层,引入服务层,交互层,物理层等,加大了插件开发难度,增加了耦合性。可选地,如图6所示,本实施例设有三层,分别为主程序层300、插件管理层302和插件层304。其中,主程序层300对应主程序模块110,插件管理层302对应插件管理模块120,插件层304对应插件模块130(插件模块130包括插件a306、插件b308、
……
插件y和插件z等),主程序层300负责整个软件框架的运行,管理插件管理层302。在主程序模块110需要调用插件a306时(即主程序需要插件a306),主程序层300通知插件管理层302,在插件管理层302收到调用指令后,在插件层304查找插件a306,在查找到插件a306后,加载插件a306,插件a306激活后加载插件a306自身的资源,完成初始化,申请内存等相关操作(即初始化插件a306,并加载到内存中),在插件a306加载完毕后,返回插件a306的对象指针(即返回插件a306指向内存数据的指针)至插件管理模块120,插件管理模块120在接收到插件a306的对象指针后,将插件的对象指针返回至主程序模块110(即创建并返回插件a306对象指针)。在主程序模块110不需要插件a306时,主程序层300通知插件管理层302,在插件管理层302收到释放指令后,释放插件a306的自身资源,并释放插件a306占用的内存空间。本实施例中的插件式结构,只设有主程序层300、插件管理层302和插件层304,没有冗余复杂的层次,进而可维护性高,稳定性高。
80.相关技术中,插件加载是启动时加载全部插件到内存,不支持动态加载释放。可选地,本实施例中插件为窗体式插件,插件运行内存占用情况为,主程序事件触发插件a的插件窗体时,插件管理模块120加载插件a到内存中运行并与主程序模块110交互,插件a关闭时,插件管理模块120释放插件a占用的内存,对于其他插件处理过程相同,本实施例对插件的加载流程进行了优化,采用上述动态加载和释放插件,可以节省程序运行内存。插件为主程序中独立性较高的窗体模块,在没有插件运行时,不影响主程序运行,在插件出现异常时,也不影响主程序正常运行。
81.进一步地,主程序事件触发插件a306的窗体时,插件管理模块120加载插件a306到内存中,运行并与主程序交互,插件a306关闭时,插件管理模块120释放插件a306占用的内
存。同理,插件b308插件亦如此,节省程序运行内存。举例而言,如图7所示,插件使用前内存占用包括插件管理模块120和主窗体316(即主程序的窗体),在插件a306和插件b308使用中,内存占用包括插件管理模块120、主窗体316、插件a306和插件b308,当关闭插件a306后,内存占用包括插件管理模块120、主窗体316和插件b308,当关闭插件b308后,内存占用包括插件管理模块120和主窗体316。
82.值得说明的是,本实施例中的插件采用窗体式插件,其本身有插件类的属性,可以解决窗口式多进程框架中,进程间通信效率低的问题。
83.值得说明的是,多个插件可以同时运行,在多个插件运行的同时,也可以继续进行插件的加载,在任一插件需要终止时,可以将插件直接释放,其不会影响其他插件的运行,进而完成插件的动态加载和动态释放。
84.本技术实施例提供的插件式软件100可以实现上述插件式软件实现方法实施例的各个过程,且能达到相同的技术效果,为避免重复,这里不再赘述。
85.在本技术的一些实施例中,主程序模块110的生命周期、插件管理模块120的生命周期和软件进程的生命周期一致,插件管理模块120控制插件140的生命周期。
86.可以理解的是,软件进程的生命周期可以包括进程创建、进程运行、进程等待、进程唤醒和进程结束,主程序模块110的生命周期和插件管理模块120的生命周期与软件进行的生命周期一致。进一步地,插件140的生命周期通过插件管理模块120进行控制。本实施例设定了软件进行生命周期、主程序模块110生命周期、插件管理模块120生命周期、插件140生命周期之间的关系,以使得插件式软件可以正常运行。
87.在本技术的一些实施例中,图8示出了本技术实施例提供的插件结构框图,如图8所示,插件140包括资源区142、组态转换区144、通信区146和代码区148。资源区142用于提供插件140加载时所需图片资源、文件资源和/或库资源。组态转换区144用于切换插件140的组态。通信区146用于与父窗体交互。代码区148用于处理业务逻辑。
88.具体地,插件140为窗体式插件,自带窗体渲染资源,因为具有插件类的属性,可以解决窗口式多进程框架中进程间通信效率低的问题。插件140设有资源区142,用于提供插件140所需资源,举例而言,资源区142用于加载插件140所需的图片资源,文件资源以及库资源等,用于运行时窗口的渲染,特效的渲染等。插件窗口渲染所需的动态库资源(例如:基于qt框架的ide,所需qtcore.dll等)可与主程序复用同一套渲染库,节省资源空间。
89.具体地,通信区146用于与父窗体交互,父窗体为空时候不影响插件运行。代码区148用于实现插件内部功能,即处理插件140的业务逻辑。
90.进一步地,还可以设有属性转换图标,通过点击属性转换图标实现组态转换区在插件态和独立态之间切换。
91.在本技术的一些实施例中,插件的组态包括插件态和独立态,在组态转换区为插件态的情况下,传入父窗体句柄;在组态转换区为独立态的情况下,父窗体句柄设置为空,插件编译为独立进程。
92.相关技术中的,插件并不能脱离主程序而单独运行,若主程序框架较为复杂时候调试难度大,可复用性不高。
93.具体地,组态转换区144可切换为插件态与独立态,插件态时需传入父窗体句柄。独立态时父窗体句柄为空,插件140可编译成独立的进程,单独运行,即插件140可以脱离主
程序,通过增加main函数的方式独立运行,进而使得插件具有高复用性及高度独立性。由于插件140可以在独立态与插件态中进行切换,插件140具有独立性较高的特性,本实施例应用于多人协作开发的场景时,每个开发人员只需关注自己负责的插件140,无需关注主程序的实现方式,进而使得多人协作开发效率更高,并且,还可以提高插件140的可复用性。
94.可选地,如图9所示,本技术实施例还提供一种计算机设备1000,计算机设备1000包括处理器1002和存储器1004,存储器1004上存储有可在处理器1002上运行的程序或指令,该程序或指令被处理器1002执行时实现上述方法实施例的各个步骤,且能达到相同的技术效果,为避免重复,这里不再赘述。
95.本技术实施例还提供一种可读存储介质,可读存储介质上存储有程序或指令,该程序或指令被处理器执行时实现上述插件式软件实现方法实施例的各个过程,且能达到相同的技术效果,为避免重复,这里不再赘述。
96.其中,处理器为上述实施例中的计算机设备中的处理器。可读存储介质,包括计算机可读存储介质,如计算机只读存储器rom、随机存取存储器ram、磁碟或者光盘等。
97.本技术实施例另提供了一种芯片,芯片包括处理器和通信接口,通信接口和处理器耦合,处理器用于运行程序或指令,实现上述插件式软件实现方法实施例的各个过程,且能达到相同的技术效果,为避免重复,这里不再赘述。
98.应理解,本技术实施例提到的芯片还可以称为系统级芯片、系统芯片、芯片系统或片上系统芯片等。
99.本技术实施例提供一种计算机程序产品,该程序产品被存储在存储介质中,该程序产品被至少一个处理器执行以实现如上述插件式软件实现方法实施例的各个过程,且能达到相同的技术效果,为避免重复,这里不再赘述。
100.需要说明的是,在本文中,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者装置不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者装置所固有的要素。在没有更多限制的情况下,由语句“包括一个
……”
限定的要素,并不排除在包括该要素的过程、方法、物品或者装置中还存在另外的相同要素。此外,需要指出的是,本技术实施方式中的方法和装置的范围不限按示出或讨论的顺序来执行功能,还可包括根据所涉及的功能按基本同时的方式或按相反的顺序来执行功能,例如,可以按不同于所描述的次序来执行所描述的方法,并且还可以添加、省去、或组合各种步骤。另外,参照某些示例所描述的特征可在其他示例中被组合。
101.通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到上述实施例方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本技术的技术方案本质上或者说对现有技术做出贡献的部分可以以计算机软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端(可以是手机,计算机,服务器,或者网络设备等)执行本技术各个实施例的方法。
102.上面结合附图对本技术的实施例进行了描述,但是本技术并不局限于上述的具体实施方式,上述的具体实施方式仅仅是示意性的,而不是限制性的,本领域的普通技术人员在本技术的启示下,在不脱离本技术宗旨和权利要求所保护的范围情况下,还可做出很多
形式,均属于本技术的保护之内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1