国产精品久久久久久久久久久久久久_国产肉体ⅹxxx137大胆_国产精品mv_国产日韩中文字幕_国产福利一区二区三区在线视频_中文字幕www_久草最新_日韩av第一页在线播放_青青草在线视频网站_少妇淫片aaaaa毛片叫床爽_成人精品在线视频_超碰97免费观看_毛片一级视频_他掀开裙子把舌头伸进去添视频_天堂一区二区三区在线_黑人日比视频_一区在线看_一区日本_亚洲中文字幕无码中文字_国产一级视频免费看

selenium從入門到應(yīng)用 - 5,頁(yè)面對(duì)象設(shè)計(jì)模式下

系統(tǒng) 3031 0

本系列所有代碼?https://github.com/zhangting85/simpleWebtest

本文將介紹一個(gè)Java+TestNG+Maven+Selenium的web自動(dòng)化測(cè)試腳本環(huán)境下selenium頁(yè)面對(duì)象設(shè)計(jì)下的頁(yè)面模塊的寫(xiě)法,并提供全部代碼。

?

在一個(gè)頁(yè)面上,有的時(shí)候,會(huì)有一些需要重復(fù)利用的模塊。

比如,一個(gè)電子商務(wù)網(wǎng)站上,經(jīng)常會(huì)在頁(yè)面最頂上有一個(gè)搜索框。這個(gè)搜索框在幾乎所有頁(yè)面上都會(huì)出現(xiàn)。可以隨時(shí)用它搜索一些商品。

這里,有人用繼承,寫(xiě)一個(gè)父類,父類提供了這個(gè)搜索框的一些功能封裝。然后所有頁(yè)面類都繼承這個(gè)父類。

這樣寫(xiě)一開(kāi)始是沒(méi)問(wèn)題的。但是當(dāng)這類重用模塊增加了,變動(dòng)了,會(huì)造成整個(gè)測(cè)試代碼邏輯結(jié)構(gòu)亂成一團(tuán)。所以不推薦。

?

這里介紹一下我的寫(xiě)法:

把這些重復(fù)利用的部分作為頁(yè)面模塊。然后我對(duì)京東的首頁(yè)、搜索結(jié)果頁(yè)建立了頁(yè)面對(duì)象模型:

代碼如下:

?

首頁(yè)

        
           1
        
        
          /**
        
        
           2
        
        
           *京東首頁(yè)


        
        
           3
        
        
          */
        
        
           4
        
        
          public
        
        
          class
        
         JDHomepage 
        
          extends
        
        
           Page {


        
        
           5
        
        
          /**
        
        
           6
        
        
           *URL常量,很少用到,一般在起始頁(yè)用,有時(shí)放到配置文件里去統(tǒng)一管理


        
        
           7
        
        
          */
        
        
           8
        
        
          private
        
        
          static
        
        
          final
        
         String URL="http://www.jd.com"
        
          ;


        
        
           9
        
        
          10
        
        
          /**
        
        
          11
        
        
           *可供重用的頁(yè)面模塊,作為成員對(duì)象在顯示這個(gè)模塊的頁(yè)面中保存。


        
        
          12
        
        
           *這里用了組合的寫(xiě)法(composite),注意不要濫用繼承。


        
        
          13
        
        
          */
        
        
          14
        
        
          public
        
         SearchHeaderModule searchHeader=
        
          new
        
        
           SearchHeaderModule();


        
        
          15
        
        
          16
        
        
          /**
        
        
          17
        
        
           * 只有homepage之類的起始頁(yè)才必要有這個(gè)init方法用來(lái)打開(kāi)URL。


        
        
          18
        
        
           * return this 表示執(zhí)行完畢之后頁(yè)面仍舊在本頁(yè)。


        
        
          19
        
        
           * 如果留在本頁(yè),并有頁(yè)面刷新,就要return new JDHomepage


        
        
          20
        
        
           * 如果沒(méi)有頁(yè)面刷新等頁(yè)面改變,就return this


        
        
          21
        
        
           * 如果跳轉(zhuǎn)到其他頁(yè)面,就return new xxxPage


        
        
          22
        
        
           * 這樣寫(xiě)的好處,是每個(gè)方法的return語(yǔ)句上明確了頁(yè)面跳轉(zhuǎn)的預(yù)期結(jié)果


        
        
          23
        
        
           * Only the start page of a test case should has this init method


        
        
          24
        
        
           * 
        
        
          @return
        
        
           return this means no page refresh and stay on this page after this method


        
        
          25
        
        
           * return new JDHomepage means stay on this page and has a page refresh


        
        
          26
        
        
           * return new xxxPage means page redirects after this method


        
        
          27
        
        
          */
        
        
          28
        
        
          public
        
        
           JDHomepage init(){


        
        
          29
        
        
              DriverManager.driver.get(URL);


        
        
          30
        
        
          return
        
        
          this
        
        
          ;


        
        
          31
        
        
          }


        
        
          32
        
        
          33
        
        
          34
        
        
          35
        
         }
      
View Code

在首頁(yè)里我其實(shí)沒(méi)有封裝什么業(yè)務(wù)邏輯,正常來(lái)說(shuō)如果實(shí)際去實(shí)現(xiàn)整個(gè)京東的測(cè)試用例,那么首頁(yè)這個(gè)類會(huì)變得比較龐大的。

這里我用下面這段代碼創(chuàng)建了SearchHeader這個(gè)頁(yè)面模塊

      
        public
      
       SearchHeaderModule searchHeader=
      
        new
      
       SearchHeaderModule();
    

作為一個(gè)成員對(duì)象。這個(gè)對(duì)象的實(shí)例會(huì)在JDHomepage的構(gòu)造方法被調(diào)用前先被jvm調(diào)用。

所以,每個(gè)Homepage的實(shí)例都會(huì)包含一個(gè)SearchHeader,然后我們只使用時(shí)如下調(diào)用即可:

      home.init().searchHeader.search("巧克力");
    

home是一個(gè)JDHomepage類的實(shí)例,init方法是去打開(kāi)這個(gè)page的URL,我只在首頁(yè)等起始頁(yè)上寫(xiě)init方法。

search是searchHeader提供的方法,這樣直接連點(diǎn)調(diào)用即可。

?

SearchHeader的實(shí)現(xiàn):

        
           1
        
        
          package
        
        
           simplewebtest.core.page.module.sample.jd;


        
        
           2
        
        
           3
        
        
          import
        
        
           org.openqa.selenium.WebElement;


        
        
           4
        
        
          import
        
        
           org.openqa.selenium.support.FindBy;


        
        
           5
        
        
           6
        
        
          import
        
        
           simplewebtest.core.Page;


        
        
           7
        
        
          import
        
        
           simplewebtest.core.page.sample.jd.JDItemlistPage;


        
        
           8
        
        
           9
        
        
          10
        
        
          /**
        
        
          11
        
        
           * 頁(yè)面模塊。此處表示京東各頁(yè)面上方共享的搜索條


        
        
          12
        
        
           * 他本身也可以看做是一個(gè)頁(yè)面


        
        
          13
        
        
           * 并以組合(composite)的形式嵌入外部網(wǎng)頁(yè),注意不要濫用繼承


        
        
          14
        
        
           * this page module is composite to the outer page


        
        
          15
        
        
          */
        
        
          16
        
        
          public
        
        
          class
        
         SearchHeaderModule 
        
          extends
        
        
           Page {


        
        
          17
        
        
          18
        
        
          /**
        
        
          19
        
        
               * PageFactory的寫(xiě)法,用標(biāo)簽來(lái)定義web elment的查找 define how to find a webelment by


        
        
          20
        
        
               * annotation


        
        
          21
        
        
          */
        
        
          22
        
             @FindBy(id = "key"
        
          )


        
        
          23
        
        
              WebElement searchInput;


        
        
          24
        
        
          25
        
             @FindBy(xpath = "http://input[@value='搜索']"
        
          )


        
        
          26
        
        
              WebElement searchButton;


        
        
          27
        
        
          28
        
        
          /**
        
        
          29
        
        
               * 搜索一個(gè)關(guān)鍵字,先輸入文字,再按搜索按鈕 search a keyword


        
        
          30
        
        
               * 


        
        
          31
        
        
               * 
        
        
          @param
        
        
           keyword


        
        
          32
        
        
               *            :搜索關(guān)鍵字


        
        
          33
        
        
               * 
        
        
          @return
        
        
           返回一個(gè)JDItemlistPage


        
        
          34
        
        
          */
        
        
          35
        
        
          public
        
        
           JDItemlistPage search(String keyword) {


        
        
          36
        
        
                  searchInput.sendKeys(keyword);


        
        
          37
        
        
                  searchButton.click();


        
        
          38
        
        
          return
        
        
          new
        
        
           JDItemlistPage();


        
        
          39
        
        
              }


        
        
          40
        
         }
      
View Code

這個(gè)SearchHader就是一個(gè)普通的頁(yè)面對(duì)象。

注意所有的頁(yè)面對(duì)象里的封裝方法我都讓他返回類似 new JDItemlistPage()之類的頁(yè)面對(duì)象。

這樣我們?cè)趖est case里可以連點(diǎn)。比如

      home.init().searchHeader.search("巧克力").getProduct(1).getText();
    

至于連點(diǎn)造成調(diào)試?yán)щy?不,由于我們有事件監(jiān)聽(tīng)和自動(dòng)log功能,調(diào)試不會(huì)很困難。

并且我通常是先寫(xiě)線性代碼再重構(gòu)成頁(yè)面對(duì)象,寫(xiě)成這種的都是已經(jīng)執(zhí)行通過(guò)的代碼。

另外,我們不是每次都需要返回新的頁(yè)面對(duì)象實(shí)例,因?yàn)橛袝r(shí)比做一個(gè)操作,頁(yè)面不會(huì)跳轉(zhuǎn)也不會(huì)變動(dòng)。這時(shí),return this;返回當(dāng)前頁(yè)的實(shí)例就行了。

?

JDItemlistPage

        
           1
        
        
          package
        
        
           simplewebtest.core.page.sample.jd;


        
        
           2
        
        
           3
        
        
          import
        
        
           java.util.List;


        
        
           4
        
        
           5
        
        
          import
        
        
           org.openqa.selenium.By;


        
        
           6
        
        
          import
        
        
           org.openqa.selenium.WebElement;


        
        
           7
        
        
          import
        
        
           org.openqa.selenium.support.FindBy;


        
        
           8
        
        
           9
        
        
          import
        
        
           simplewebtest.core.Page;


        
        
          10
        
        
          /**
        
        
          11
        
        
           *京東搜索商品結(jié)果頁(yè)


        
        
          12
        
        
          */
        
        
          13
        
        
          public
        
        
          class
        
         JDItemlistPage 
        
          extends
        
        
           Page {


        
        
          14
        
        
          15
        
        
          16
        
        
          /**
        
        
          17
        
        
               *先找所有商品的父親節(jié)點(diǎn)plist


        
        
          18
        
        
          */
        
        
          19
        
             @FindBy(id = "plist"
        
          )


        
        
          20
        
        
          public
        
        
           WebElement productList;


        
        
          21
        
        
          22
        
        
          /**
        
        
          23
        
        
               *直接找第一個(gè)商品,XPATH表達(dá)式過(guò)長(zhǎng),無(wú)法閱讀。(你會(huì)看得頭疼嗎?我會(huì)。。。)


        
        
          24
        
        
               *注意這個(gè)xpath是由firepath自動(dòng)生成的,冗余過(guò)度。如果你要用xpath,一定要會(huì)自己寫(xiě)


        
        
          25
        
        
               *插件太傻,別依賴他。


        
        
          26
        
        
          */
        
        
          27
        
             @FindBy(xpath = ".//*[@id='plist']/ul/li[1]/div/div[2]/a"
        
          )


        
        
          28
        
        
          public
        
        
           WebElement firstproduct;


        
        
          29
        
        
          30
        
        
          /**
        
        
          31
        
        
               *預(yù)先定位所有product


        
        
          32
        
        
               *get all products, suggested to use this way


        
        
          33
        
        
          */
        
        
          34
        
             @FindBy(xpath = ".//*[@id='plist']//li"
        
          )


        
        
          35
        
        
          public
        
         List<WebElement>
        
           products;


        
        
          36
        
        
          37
        
        
          /**
        
        
          38
        
        
               *先找父親plist,讓父親來(lái)找兒子,這種寫(xiě)法也是可以的,但是也不是特別好(這一定不是強(qiáng)迫癥)


        
        
          39
        
        
               *但是這個(gè)方法只能找第一個(gè)商品,想找第二個(gè)商品要再寫(xiě)一個(gè)方法。不推薦。     


        
        
          40
        
        
          */
        
        
          41
        
        
          public
        
        
           String getFirstProductName() {


        
        
          42
        
        
          return
        
         productList.findElement(By.xpath("http://div[@class='p-name'][1]//a"
        
          )).getText();


        
        
          43
        
        
              }


        
        
          44
        
        
          45
        
        
          /**
        
        
          46
        
        
               *先找父親plist,讓父親來(lái)找兒子,但是加了一個(gè)傳入?yún)?shù)告訴父親要找第幾個(gè)兒子,也就是第幾個(gè)商品。(圣斗士嗎,這么多兒子)


        
        
          47
        
        
               *這樣我寫(xiě)一次可以找到這個(gè)頁(yè)面上任意一個(gè)商品了,京東的網(wǎng)頁(yè)設(shè)計(jì)特別適合自動(dòng)化,可能你要測(cè)的網(wǎng)站不是這么工整。


        
        
          48
        
        
               *這里的重點(diǎn)是:Xpath表達(dá)式是一個(gè)字符串,你可以隨意拼接。所以傳入?yún)?shù)number可以插進(jìn)去。


        
        
          49
        
        
               *suggested


        
        
          50
        
        
          */
        
        
          51
        
        
          public
        
         String getProductNameByIndexMethodOne(
        
          int
        
        
           number) {


        
        
          52
        
        
          return
        
         productList.findElement(By.xpath("http://div[@class='p-name']["+number+"]//a"
        
          )).getText();


        
        
          53
        
        
              }


        
        
          54
        
        
          55
        
        
          /**
        
        
          56
        
        
               *一次性找出所有product,然后取第幾個(gè),我喜歡從1開(kāi)始所以number-1,僅個(gè)人喜好。


        
        
          57
        
        
               *接著對(duì)找到的product執(zhí)行g(shù)etProductNameOf方法來(lái)獲取名字


        
        
          58
        
        
               *suggested


        
        
          59
        
        
          */
        
        
          60
        
        
          public
        
         String getProductNameByIndexMethodTwo(
        
          int
        
        
           number) {    


        
        
          61
        
        
          return
        
         getProductNameOf(products.get(number-1
        
          ));


        
        
          62
        
        
              }


        
        
          63
        
        
          64
        
        
          private
        
        
           String getProductNameOf(WebElement product)


        
        
          65
        
        
              {


        
        
          66
        
        
          return
        
         product.findElement(By.className("p-name"
        
          )).getText();


        
        
          67
        
        
          68
        
        
              }


        
        
          69
        
        
          70
        
        
          71
        
         }
      
View Code

這個(gè)頁(yè)面就是一個(gè)標(biāo)準(zhǔn)的頁(yè)面對(duì)象了

為了擴(kuò)展一下,我增加了一些內(nèi)容,比如尋找第一個(gè)商品的四種方法:

              JDHomepage home = 
      
        new
      
      
         JDHomepage();

        

        
      
      
        //
      
      
        結(jié)果頁(yè)面the expected result page 
      
      

        JDItemlistPage resultPage=home.init().searchHeader.search("巧克力"
      
        );

        
      
      
        //
      
      
        actual result: 用四種方法找出第一個(gè)商品名字,作為實(shí)際結(jié)果.(回字有五種寫(xiě)法:P)
      
      
            

        String product_1
      
      = resultPage.firstproduct.getText();
      
        //
      
      
        不推薦,但偶爾有適用場(chǎng)景
      
      

        String product_2= resultPage.getFirstProductName();
      
        //
      
      
        不推薦,但偶爾有適用場(chǎng)景
      
      

        String product_3= resultPage.getProductNameByIndexMethodOne(1);
      
        //
      
      
        推薦寫(xiě)法,但你方法名字不要這么長(zhǎng)
      
      

        String product_4= resultPage.getProductNameByIndexMethodTwo(1);
      
        //
      
      
        推薦寫(xiě)法,但你方法名字不要這么長(zhǎng)
      
    

?

如上代碼中,(和JDItemlistPage的代碼結(jié)合起來(lái)看)

方法1直接用PageObject.WebElement來(lái)獲取商品,缺點(diǎn)是每個(gè)商品我都要定義一個(gè)WebElement

方法2先找到product list,再用一句寫(xiě)死的Xpath來(lái)尋找第一個(gè)商品,缺點(diǎn)是個(gè)商品我都要寫(xiě)一段寫(xiě)死的Xpath

方法3先找到product list,再通過(guò)傳入?yún)?shù)來(lái)組合一段可用的Xpath,優(yōu)點(diǎn)是我只要寫(xiě)一次Xpath

方法4先找到所有product:

      @FindBy(xpath = ".//*[@id='plist']//li"
      
        )

    
      
      
        public
      
       List<WebElement> products;
    

然后再蔥存放WebElement的List里取第一個(gè)元素。我同樣要寫(xiě)一次By.className定位。

?

對(duì)于尋找商品這樣的例子來(lái)說(shuō),推薦用方法3或4。對(duì)于一般的頁(yè)面元素推薦用方法1。對(duì)于一些其他特殊的場(chǎng)景,看情況使用方法2。

另外,JDItemListPage里也可以像首頁(yè)一樣加入一個(gè)SearchHeader的定義,這里沒(méi)加只是因?yàn)槟壳拔矣玫降膖est case里沒(méi)有這個(gè)需要。

?

selenium從入門到應(yīng)用 - 5,頁(yè)面對(duì)象設(shè)計(jì)模式下的頁(yè)面模塊


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |