整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Rust學(xué)習(xí)筆記(四十四)Cargo發(fā)布crate和工作空間(Workspace)

          用pub use導(dǎo)出方便使用的公共API

          問題:crate的程序結(jié)構(gòu)在開發(fā)時(shí)對于開發(fā)者很合理,但是對它的使用者不夠方便。例如:開發(fā)者會把程序結(jié)構(gòu)分為很多層,使用者想找到這種深層結(jié)構(gòu)中的某個(gè)類型費(fèi)時(shí)費(fèi)力。例: 有這么一個(gè)類型,開發(fā)者這樣定義my_crate::some_module::another_module::UsefulType,用戶用的時(shí)候希望是my_crate::UsefulType 解決方法:

          • 不需要重新組織內(nèi)部代碼的結(jié)構(gòu)
          • 使用pub use可以重新導(dǎo)出,創(chuàng)建一個(gè)與內(nèi)部私有結(jié)構(gòu)不同的對外公共結(jié)構(gòu)

          例:

          // src/lib.rs
          //! # Art
          //!
          //! A library for modeling artistic concepts.
          
          pub mod kinds {
              /// The primary colors according to the RYB color model.
              pub enum PrimaryColor {
                  Red,
                  Yellow,
                  Blue,
              }
          
              /// The secondary colors according to the RYB color model.
              pub enum SecondaryColor {
                  Orange,
                  Green,
                  Purple,
              }
          }
          
          pub mod utils {
              use crate::kinds::*;
          
              /// Combines two primary colors in equal amounts to create
              /// a secondary color.
              pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
                  SecondaryColor::Green
              }
          }
          
          // src/main.rs
          use art::kinds::PrimaryColor;
          use art::utils::mix;
          
          fn main() {
              let red = PrimaryColor::Red;
              let yellow = PrimaryColor::Yellow;
              mix(red, yellow);
          }
          

          可以看到,PrimaryColor和mix分別在不同的模塊里。使用起來不是很友好。使用cargo doc --open生成并查看文檔:

          文檔看起來也比較麻煩,需要點(diǎn)kinds和utils才能查看里的內(nèi)容。

          下面利用pub use進(jìn)行修改

          // src/lib.rs
          //! # Art
          //!
          //! A library for modeling artistic concepts.
          
          pub use self::kinds::PrimaryColor;
          pub use self::kinds::SecondaryColor;
          pub use self::utils::mix;
          
          pub mod kinds {
              /// The primary colors according to the RYB color model.
              pub enum PrimaryColor {
                  Red,
                  Yellow,
                  Blue,
              }
          
              /// The secondary colors according to the RYB color model.
              pub enum SecondaryColor {
                  Orange,
                  Green,
                  Purple,
              }
          }
          
          pub mod utils {
              use crate::kinds::*;
          
              /// Combines two primary colors in equal amounts to create
              /// a secondary color.
              pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor {
                  SecondaryColor::Green
              }
          }
          
          // src/main.rs
          use art::PrimaryColor;
          use art::mix;
          
          fn main() {
              let red = PrimaryColor::Red;
              let yellow = PrimaryColor::Yellow;
              mix(red, yellow);
          }
          

          查看文檔:

          可以看到,使用和查看文檔都比較方便。

          創(chuàng)建并設(shè)置crates.io賬號

          發(fā)布crate前,需要在crates.io創(chuàng)建賬號并獲得API token。

          • 首先進(jìn)入crates.io,點(diǎn)擊右上角的Log in with Github。
          • 登陸后進(jìn)入賬號設(shè)置頁面,新建一個(gè)API token
          • 運(yùn)行cargo login 自己的API token命令,會將API token存儲在本地~/.cargo/credentials
          • 如果token被泄露,可以去創(chuàng)建token的地方將其刪除,防止別人冒用。
          • 綁定自己的郵箱,否則無法發(fā)布

          在Cargo.toml文件里填寫一些信息:

          [package]
          name = "art"#必須是在crates.io里唯一的
          description = "a demo for publish crate."#簡介,會出現(xiàn)在crate搜索數(shù)據(jù)中
          license = "MIT"#提供開源許可標(biāo)識,可在http://spdx.org/licenses/查看,可以指定多個(gè),用OR隔開
          version = "0.1.0"#版本號
          author = "demo"#作者
          edition = "2021"
          
          # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
          
          [dependencies]
          

          使用cargo publish發(fā)布。 crate一旦發(fā)布,就是永久性的:該版本無法覆蓋,代碼無法刪除。目的是讓依賴該版本的項(xiàng)目可以一直使用。如果想發(fā)布新版本,只需要修改Cargo.toml中的version,然后重新發(fā)布即可。版本語義參考http://semver.org/

          使用cargo yank從crates.io撤回版本

          我們不可以刪除crate之前的版本,但是可以使用cargo yank防止其他項(xiàng)目把它作為新的依賴,換句話說就是防止新的項(xiàng)目依賴該版本。已經(jīng)存在的項(xiàng)目可繼續(xù)將其作為依賴(并可下載)。 yank意味著:

          • 所有已經(jīng)產(chǎn)生Cargo.lock文件的項(xiàng)目都不會中斷
          • 但是任何將來生成的Cargo.lock文件都不會使用已經(jīng)yank的版本

          撤回命令:cargo yank --vers 1.0.1 取消撤回:cargo yank --vers 1.0.1 --undo

          Cargo工作空間

          Cargo工作空間:幫助管理多個(gè)相互關(guān)聯(lián)且需要協(xié)同開發(fā)的crate,它是一套共享同一個(gè)Cargo.lock和輸出文件夾(target)的包。

          創(chuàng)建工作空間

          有多種方式創(chuàng)建工作空間,例如創(chuàng)建含有1個(gè)二進(jìn)制crate和2個(gè)library(庫) crate的工作空間:

          • 二進(jìn)制crate中main函數(shù)依賴于其它兩個(gè)library
          • 其中一個(gè)庫crate提供add_one函數(shù)
          • 另一個(gè)庫提供add_two函數(shù)

          首先創(chuàng)建一個(gè)空文件夾,然后在里面新建Cargo.toml文件:

          [workspace]
          
          members = [
              "adder",
              "add-one",
              "add-two",
          ]
          

          然后分別執(zhí)行cargo new adder,cargo new add-one --lib,cargo new add-two --lib來創(chuàng)建一個(gè)二進(jìn)制crate和兩個(gè)庫crate。

          //add-one/src/lib.rs
          pub fn add_one(x: i32) -> i32 {
              x + 1
          }
          
          //add-two/src/lib.rs
          pub fn add_two(x: i32) -> i32 {
              x + 2
          }
          
          //adder/src/main.rs
          use add_one;
          use add_two;
          fn main() {
              let num = 10;
          
              println!(
                  "Hello, world! {} + 1 = {} {} + 2 = {}",
                  num,
                  add_one::add_one(num),
                  num,
                  add_two::add_two(num),
              );
          }
          
          }
          

          使用cargo run -p adder運(yùn)行workspace中的二進(jìn)制crate,同理,cargo test命令也可以用-p指定要運(yùn)行哪個(gè)crate的測試。

          在工作空間中依賴外部crate

          工作空間只有一個(gè)Cargo.lock文件,在工作空間頂層目錄。它能保證工作空間內(nèi)所有crate使用的依賴版本都相同。例如我們在Cargo.toml 和 add-one/Cargo.toml 中都增加 rand crate,則 Cargo 會將其都解析為同一版本并記錄到唯一的 Cargo.lock 中。使得工作空間中的所有 crate 都使用相同的依賴意味著其中的 crate 都是相互兼容的。例:

          #adder/Cargo.toml
          [package]
          name = "adder"
          version = "0.1.0"
          edition = "2021"
          
          # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
          
          [dependencies]
          add-one = {path = "../add-one"}
          add-two = {path = "../add-two"}
          rand = "0.3.14"
          
          #add-one/Cargo.toml
          [package]
          name = "add-one"
          version = "0.1.0"
          edition = "2021"
          
          # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
          
          [dependencies]
          rand = "0.3.13"
          

          adder和add_one的Cargo.toml分別填寫依賴rand的0.3.14和0.3.13,可以從下面看出我這里Cargo.lock文件里這兩個(gè)工crate的依賴都被解析到了0.3.23這同一個(gè)版本上。

          # This file is automatically @generated by Cargo.
          # It is not intended for manual editing.
          version = 3
          
          [[package]]
          name = "add-one"
          version = "0.1.0"
          dependencies = [
           "rand 0.3.23",
          ]
          
          [[package]]
          name = "add-two"
          version = "0.1.0"
          
          [[package]]
          name = "adder"
          version = "0.1.0"
          dependencies = [
           "add-one",
           "add-two",
           "rand 0.3.23",
          ]
          

          如果你選擇向 crates.io發(fā)布工作空間中的 crate,每一個(gè)工作空間中的 crate 需要單獨(dú)發(fā)布。cargo publish 命令并沒有 --all 或者 -p 參數(shù),所以必須進(jìn)入每一個(gè) crate 的目錄并運(yùn)行 cargo publish 來發(fā)布工作空間中的每一個(gè) crate。

          從crates.io安裝二進(jìn)制crate

          命令:cargo install 來源:https://crates.io 限制:只能安裝具有二進(jìn)制目標(biāo)(binary target)的crate 二進(jìn)制目標(biāo):是一個(gè)可運(yùn)行程序,由src/main.rs或其它被指定為二進(jìn)制文件的crate生成。 通常README里有關(guān)于crate的描述:

          • 是否擁有庫目標(biāo)(library target)
          • 是否擁有二進(jìn)制目標(biāo)(binary target)
          • 擁有二者

          cargo install安裝的二進(jìn)制文件存放在根目錄的bin文件夾。如果你是用rustup安裝的Rust,沒有任何自定義配置,那么二進(jìn)制存放的目錄是HOME/.cargo/bin,要確保該目錄在環(huán)境變量HOME/.cargo/bin,要確保該目錄在環(huán)境變量PATH中,不然安裝的二進(jìn)制文件無法直接運(yùn)行。例:

          > cargo install test_bin
              Updating `sjtu` index
            Downloaded test_bin v0.3.0 (registry `sjtu`)
            Downloaded 1 crate (7.3 KB) in 1.04s
            Installing test_bin v0.3.0
             Compiling test_bin v0.3.0
              Finished release [optimized] target(s) in 2.05s
            Installing C:\Users\Chris\.cargo\bin\test_bin.exe
             Installed package `test_bin v0.3.0` (executable `test_bin.exe`)
          > test_bin
          Output from my CLI app!
          

          我們安裝了test_bin這個(gè)binary crate,然后就可以直接用test_bin來運(yùn)行這個(gè)可執(zhí)行程序。

          使用自定義命令擴(kuò)展cargo

          cargo被設(shè)計(jì)成可以使用子命令來擴(kuò)展,并且無需修改cargo本身。例如$PATH中的某個(gè)二進(jìn)制是cargo-something,那么我們就可以像子命令一樣運(yùn)行它:cargo something,這樣看起來something像cargo的子命令一樣。 而且這樣的自定義命令可以通過cargo --list列出來。 優(yōu)點(diǎn):可使用cargo install來安裝擴(kuò)展,像內(nèi)置工具一樣來運(yùn)行。

          . 自定義積木

          雖然Blockly定義了許多標(biāo)準(zhǔn)積木,但大多數(shù)應(yīng)用程序需要定義和實(shí)現(xiàn)至少一些域相關(guān)積木,這也是Scartch3.0 Blocks使用Blockly的原因,可擴(kuò)展性強(qiáng)。積木由三個(gè)部分組成:積木定義對象:定義積木的外觀和行為,包括文本,顏色,字段和連接。添加積木到Toolbox:工具箱XML中對積木類型的引用,因此用戶可以將其添加到工作區(qū)。添加積木代碼:生成此積木的代碼字符串。它是用JavaScript編寫的,即使目標(biāo)語言不是JavaScript,甚至是用于Android端的Blockly。

          積木定義

          用于Web加載的Blockly通過腳本文件加載積木。在“blocks/”目錄中包含幾個(gè)標(biāo)準(zhǔn)積木的示例。假設(shè)您的積木不適合現(xiàn)有分類,需要?jiǎng)?chuàng)建一個(gè)新的JavaScript文件。這個(gè)新的JavaScript文件需要包含在編輯器HTML文件的script標(biāo)簽列表中。

          注意:大多數(shù)積木都可以使用Blockly Developer Tools定義,而不是手動創(chuàng)建下面的代碼。

          典型的積木定義如下所示,Json語言版本:

          Blockly.Blocks['string_length'] = {
            init: function() {
              this.jsonInit({
                "message0": 'length of %1',
                "args0": [
                  {
                    "type": "input_value",
                    "name": "VALUE",
                    "check": "String"
                  }
                ],
                "output": "Number",
                "colour": 160,
                "tooltip": "Returns number of letters in the provided text.",
                "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
              });
            }
          };
          

          此處添加了一個(gè)名為VALUE的的積木,輸入一個(gè)字符串(String)參數(shù),輸出為數(shù)字(Number),積木顯示內(nèi)容為length of。

          將積木添加到Toolbox

          定義后,使用類型名稱將積木引用到工具箱:

          <xml id="toolbox" style="display: none">
              <category name="Text">
                  <block type="string_length"></block>
              </category>
          ...
          </xml>
          

          添加積木對應(yīng)的代碼

          最后,要將積木轉(zhuǎn)換為代碼,請將積木與生成器函數(shù)配對。每個(gè)積木都對應(yīng)有生成器函數(shù),多個(gè)積木形成積木組,多個(gè)生成器函數(shù),形成代碼片段,片段就可以執(zhí)行。生成器特定于所需的輸出語言,但標(biāo)準(zhǔn)生成器通常采用以下格式:

          Blockly.JavaScript['text_length'] = function(block) {
          // String or array length.
              var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
              Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
              return [argument0 + '.length', Blockly.JavaScript.ORDER_MEMBER];
          }
          

          Blockly可以將積木導(dǎo)出為許多編程語言,包括這些流行的選項(xiàng):JavaScript、Python、PHP、Lua、Dart

          4. Events

          工作區(qū)上的每個(gè)更改都會觸發(fā)一個(gè)事件。這些事件完整地描述了每個(gè)變化的前后狀態(tài)。

          監(jiān)聽事件

          工作區(qū)具有可用于偵聽事件流的addChangeListener方法和removeChangeListener方法。以下示例檢測用戶何時(shí)創(chuàng)建其第一條評論,然后停止監(jiān)聽。

          function onFirstComment(event) {
            if (event.type == Blockly.Events.CHANGE &&
                event.element == 'comment' &&
                !event.oldValue && event.newValue) {
              alert('Congratulations on creating your first comment!')
              workspace.removeChangeListener(onFirstComment);
            }
          }
          workspace.addChangeListener(onFirstComment);
          

          積木也可以定義onchange函數(shù),只要積木的工作空間發(fā)生更改,就會調(diào)用該函數(shù)。

          事件類型

          名稱類型描述type串積木事件、變量事件workspaceId串作區(qū)的UUID。可以找到工作區(qū)Blockly.Workspace.getById(event.workspaceId)blockId串積木的UUID。該積木可以找到workspace.getBlockById(event.blockId)group串組的UUID。某些事件是不可分割的組的一部分,例如在堆棧中插入語句

          積木創(chuàng)建事件( Blockly.Events.BLOCK_CREATE)積木刪除事件( Blockly.Events.BLOCK_DELETE)積木變更事件( Blockly.Events.BLOCK_DCHANGE)積木移動事件( Blockly.Events.BLOCK_MOVE)變量創(chuàng)建事件( Blockly.Events.VAR_CREATE)變量刪除事件( Blockly.Events.VAR_DELETE)變量重命名事件(Blockly.Events.VAR_RENAME)UI事件(lockly.Events.UI):例如滾動,縮放,拖動氣泡等事件。

          5. 代碼編輯器

          生成代碼

          第一步是導(dǎo)入相關(guān)語言的生成器。 Blockly包括以下生成器:javascript_compressed.jspython_compressed.jsphp_compressed.jslua_compressed.jsdart_compressed.js應(yīng)該在blockly_compressed.js之后包含代碼生成器。例如,以下是包含的JavaScript生成器:

          <script src="blockly_compressed.js"></script>
          <script src="javascript_compressed.js"></script>
          

          通過此調(diào)用,用戶的塊可以隨時(shí)從您的應(yīng)用程序?qū)С龅酱a:var code = Blockly.JavaScript.workspaceToCode(workspace);在前面兩行中用Python, PHP, Lua或Dart替換JavaScript以切換生成的語法。

          實(shí)時(shí)生成

          通過向Blockly的change事件添加一個(gè)監(jiān)聽器來實(shí)時(shí)生成和顯示代碼:

          論在WebStorm 中做什么,都是在項(xiàng)目的上下文中執(zhí)行的。WebStorm 中的項(xiàng)目是一個(gè)文件夾,其中包含您編輯的源代碼、您使用的庫和工具(例如,在node_modules子文件夾中)以及各種應(yīng)用程序配置文件(例如,package.json或.eslintrc)。

          WebStorm已更新至V2022.1,歡迎下載WebStorm最新版本試用:

          點(diǎn)擊獲WebStorm官方正式版

          在 WebStorm 中打開一個(gè)文件夾后,.idea子文件夾將添加到其中 WebStorm 存儲其內(nèi)部配置設(shè)置,例如項(xiàng)目代碼樣式或版本控制系統(tǒng)。

          .idea目錄中的所有設(shè)置文件都應(yīng)置于版本控制之下,除了workspace.xml,它存儲您的本地首選項(xiàng)。workspace.xml文件應(yīng)被VCS標(biāo)記為忽略。

          WebStorm 不支持直接編輯遠(yuǎn)程主機(jī)上的文件。因此,要在 WebStorm 中使用遠(yuǎn)程源,需要下載它們,打開存儲它們的文件夾,并將它們安排在 WebStorm 項(xiàng)目中,如從現(xiàn)有本地源創(chuàng)建項(xiàng)目中所述。要使本地和遠(yuǎn)程源保持同步,請使用“部署選項(xiàng)”對話框中的“將更改的文件自動上載到默認(rèn)服務(wù)器”列表配置自動上載。

          在項(xiàng)目之間切換

          如果您同時(shí)打開了多個(gè)項(xiàng)目,您可以使用以下選項(xiàng)在它們之間切換:

          • 切換到下一個(gè)項(xiàng)目窗口:(Ctrl+Alt+]窗口|下一個(gè)項(xiàng)目窗口)
          • 切換到上一個(gè)項(xiàng)目窗口:(Ctrl+Alt+[窗口|上一個(gè)項(xiàng)目窗口)
          • 或者,打開窗口菜單并選擇要切換到的項(xiàng)目。

          重命名項(xiàng)目

          1. 右鍵單擊項(xiàng)目的根文件夾并選擇Refactor | 從上下文菜單重命名Shift+F6或按。
          2. 在打開的對話框中,選擇重命名策略。
          3. 如果項(xiàng)目名稱與其根文件夾的名稱相同,請選擇Rename directory。
          4. 如果項(xiàng)目名稱與其根文件夾的名稱不同,請選擇Rename project。
            或者,選擇文件 | 從主菜單重命名項(xiàng)目并在打開的對話框中輸入項(xiàng)目的新名稱。
            如果您的應(yīng)用程序部署到遠(yuǎn)程服務(wù)器并且項(xiàng)目根文件夾映射到服務(wù)器根目錄,也請選擇此選項(xiàng)。
          5. 當(dāng)然,您可以重命名根文件夾并相應(yīng)地更新服務(wù)器配置中的映射。

          將項(xiàng)目移動到另一個(gè)位置

          1. 在Project工具窗口Alt+1中,右鍵單擊項(xiàng)目的根目錄并選擇Refactor | 移動目錄( F6)。
          2. 在打開的對話框中,為項(xiàng)目指定一個(gè)新位置,然后單擊Refactor。

          更改項(xiàng)目的默認(rèn)位置

          在 WebStorm 中,您可以為項(xiàng)目指定默認(rèn)父文件夾。當(dāng)您打開項(xiàng)目時(shí),WebStorm 將從該文件夾開始。每次創(chuàng)建新項(xiàng)目時(shí)也會建議使用此默認(rèn)位置。

          1. 打開設(shè)置/首選項(xiàng)對話框 ( Ctrl+Alt+S) 并轉(zhuǎn)到外觀和行為 | 系統(tǒng)設(shè)置。
          2. 在默認(rèn)目錄字段中,指定要存儲項(xiàng)目的文件夾的路徑。
          3. 下次創(chuàng)建項(xiàng)目時(shí),WebStorm 會建議指定目錄作為新項(xiàng)目的父目錄。

          通過 VCS 共享項(xiàng)目設(shè)置

          根據(jù)您的選擇處理配置文件。修改項(xiàng)目設(shè)置并創(chuàng)建新的配置文件后,IDE 會在屏幕底部顯示一條通知,提示您選擇如何處理此項(xiàng)目中的配置文件:

          • 查看文件:查看已創(chuàng)建配置文件的列表并選擇要置于版本控制之下的配置文件。之后,選定的文件將被安排添加到 VCS。
          • Always Add:靜默計(jì)劃在.idea目錄中創(chuàng)建的所有配置文件以添加到 VCS(僅適用于當(dāng)前項(xiàng)目)。
          • 不要再問:永遠(yuǎn)不要安排配置文件添加到 VCS;在您手動將它們添加到 VCS 之前,它們將具有未版本化狀態(tài)(僅適用于當(dāng)前項(xiàng)目)。

          如果您在未選擇任何選項(xiàng)的情況下關(guān)閉通知,則在創(chuàng)建新配置文件后它將再次出現(xiàn)。即使您重新啟動 IDE,新文件也將進(jìn)入該列表,直到您選擇其中一個(gè)選項(xiàng)。

          不可共享的配置文件列表

          前端開發(fā)工具WebStorm 識別配置文件并將它們自動添加到忽略文件列表中。但是,如果您手動共享項(xiàng)目,我們建議您避免將這些文件和文件夾置于版本控制之下:

          • .idea/workspace.xml
          • .idea/usage.statistics.xml
          • .idea/字典文件夾
          • .idea/架子文件夾

          將全局設(shè)置復(fù)制到項(xiàng)目級別

          全局 (IDE) 設(shè)置與項(xiàng)目分開存儲。這就是為什么這些設(shè)置不會通過版本控制與項(xiàng)目一起共享。

          但是,可以將某些設(shè)置復(fù)制到項(xiàng)目級別。例如,您可以創(chuàng)建檢查配置文件的副本,從代碼完成和自動導(dǎo)入中排除的類和包的列表。如果這樣做,IDE 會在.idea目錄中創(chuàng)建相應(yīng)的配置文件,您可以通過 VCS 與項(xiàng)目一起共享這些配置文件。

          以上就是有關(guān)WebStorm項(xiàng)目的介紹,更多關(guān)于WebStorm價(jià)格信息可進(jìn)入慧都官網(wǎng)查看。

          WebStorm是一個(gè)針對JavaScript和相關(guān)技術(shù)的集成開發(fā)環(huán)境。像其他JetBrains IDE一樣,它使你的開發(fā)體驗(yàn)更加愉快,使日常工作自動化,并幫助你輕松處理復(fù)雜的任務(wù)。


          主站蜘蛛池模板: 亚洲电影一区二区| 亚洲一区二区三区91| AV怡红院一区二区三区| 日本精品一区二区三区视频| 国产精品一区二区久久乐下载| 国产精品一区二区三区高清在线| 一区二区视频在线免费观看| 伦理一区二区三区| 无码人妻精品一区二区三区久久久| 夜夜高潮夜夜爽夜夜爱爱一区| 综合无码一区二区三区| 亚洲av成人一区二区三区观看在线 | 亚洲高清日韩精品第一区| 精品国产一区二区三区久| 熟女大屁股白浆一区二区| 无码国产精品一区二区免费虚拟VR| 精品不卡一区中文字幕| 日韩精品无码一区二区中文字幕| 国产大秀视频一区二区三区| 精品一区二区三区四区| 精品国产免费观看一区| 久久久久久人妻一区精品| 精品日韩一区二区| 91video国产一区| 变态拳头交视频一区二区| 波多野结衣AV一区二区三区中文| 韩国福利一区二区三区高清视频| 亚洲综合一区国产精品| 久久免费精品一区二区| 日韩动漫av在线播放一区| 97一区二区三区四区久久 | 亚洲国产精品自在线一区二区| 国产成人一区二区三区高清| 无码人妻精品一区二区三| 国产不卡视频一区二区三区| 国产精品视频一区国模私拍| 激情内射亚洲一区二区三区| 国精品无码A区一区二区| 日韩精品一区二区三区中文版| 亚洲丰满熟女一区二区v| 国产一区二区在线视频|