From 38cb9c4097637a7a52cb9f521e39fac70659a466 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 16:34:53 +0700
Subject: [PATCH 1/7] feat: add extractSubstr to match strs; add js errors

---
 .github/workflows/test.yaml                |   48 +-
 .prettierrc                                |   10 +
 packages/apis/package.json                 |   55 +-
 packages/apis/src/extract_substrs.rs       |  162 ++-
 packages/apis/src/wasm.rs                  |  120 +-
 packages/apis/tests/airbnb_eml.ts          | 1146 ++++++++++++++++++++
 packages/apis/tests/extract_substr.test.ts |  180 +++
 packages/circom/package.json               |   78 +-
 8 files changed, 1654 insertions(+), 145 deletions(-)
 create mode 100644 .prettierrc
 create mode 100644 packages/apis/tests/airbnb_eml.ts
 create mode 100644 packages/apis/tests/extract_substr.test.ts

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index e56399f..3e8866e 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -3,28 +3,26 @@ name: Test
 on: [push]
 
 jobs:
-  build:
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout code
-        uses: actions/checkout@v2
-      - name: Setup Node.js
-        uses: actions/setup-node@v3
-        with:
-          node-version: 18
-      - name: Setup Rust
-        uses: actions-rs/toolchain@v1
-        with:
-          toolchain: stable
-          override: true
-          components: rustfmt, clippy
-      - name: Install wasm-pack
-        run: cargo install wasm-pack
-      - name: Download circom v2.1.9 (Linux)
-        run: wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/local/bin/circom && chmod +x /usr/local/bin/circom
-      - name: Install yarn
-        run: npm install -g yarn
-      - name: Install dependencies
-        run: yarn install  --immutable
-      - name: Run tests
-        run: yarn test
+    build:
+        runs-on: ubuntu-latest
+        steps:
+            - name: Checkout code
+              uses: actions/checkout@v2
+            - name: Setup Bun
+              uses: oven-sh/setup-bun@v1
+              with:
+                  bun-version: latest
+            - name: Setup Rust
+              uses: actions-rs/toolchain@v1
+              with:
+                  toolchain: stable
+                  override: true
+                  components: rustfmt, clippy
+            - name: Install wasm-pack
+              run: cargo install wasm-pack
+            - name: Download circom v2.1.9 (Linux)
+              run: wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/local/bin/circom && chmod +x /usr/local/bin/circom
+            - name: Install dependencies
+              run: bun install
+            - name: Run tests
+              run: bun test
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..a7ab234
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+    "tabWidth": 4,
+    "useTabs": false,
+    "semi": true,
+    "singleQuote": true,
+    "endOfLine": "lf",
+    "trailingComma": "none",
+    "bracketSpacing": true,
+    "arrowParens": "avoid"
+}
diff --git a/packages/apis/package.json b/packages/apis/package.json
index 9526418..19ee320 100644
--- a/packages/apis/package.json
+++ b/packages/apis/package.json
@@ -1,26 +1,31 @@
 {
-  "name": "@zk-email/zk-regex-apis",
-  "version": "2.2.0",
-  "description": "apis compatible with [zk-regex](https://github.com/zkemail/zk-regex/tree/main).",
-  "contributors": [
-    "Javier Su <javier.su.weijie@gmail.com>",
-    "Kata Choi <kata.choi@gmail.com>",
-    "Sora Suegami <suegamisora@gmail.com>",
-    "Yush G <aayushg@mit.edu>",
-    "Aditya Bisht <adityabisht64@gmail.com>"
-  ],
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/zkemail/zk-regex.git"
-  },
-  "scripts": {
-    "build": "wasm-pack build --target nodejs --out-dir ./pkg/",
-    "build-debug": "npm run build --",
-    "build-release": "npm run build --",
-    "install": "npm run build-debug",
-    "install-release": "npm run build-release",
-    "test": "cargo test && wasm-pack test --node",
-    "upload-binary": "wasm-pack publish -t nodejs"
-  },
-  "license": "MIT"
-}
\ No newline at end of file
+    "name": "@zk-email/zk-regex-apis",
+    "version": "2.2.0",
+    "description": "apis compatible with [zk-regex](https://github.com/zkemail/zk-regex/tree/main).",
+    "contributors": [
+        "Javier Su <javier.su.weijie@gmail.com>",
+        "Kata Choi <kata.choi@gmail.com>",
+        "Sora Suegami <suegamisora@gmail.com>",
+        "Yush G <aayushg@mit.edu>",
+        "Aditya Bisht <adityabisht64@gmail.com>"
+    ],
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/zkemail/zk-regex.git"
+    },
+    "scripts": {
+        "build": "wasm-pack build --target nodejs --out-dir ./pkg/",
+        "build-debug": "npm run build --",
+        "build-release": "npm run build --",
+        "install": "npm run build-debug",
+        "install-release": "npm run build-release",
+        "test": "cargo test && wasm-pack test --node",
+        "test-js": "jest",
+        "upload-binary": "wasm-pack publish -t nodejs"
+    },
+    "license": "MIT",
+    "devDependencies": {
+        "@types/jest": "^29.5.13",
+        "jest": "^29.7.0"
+    }
+}
diff --git a/packages/apis/src/extract_substrs.rs b/packages/apis/src/extract_substrs.rs
index 18e1a92..b805f8c 100644
--- a/packages/apis/src/extract_substrs.rs
+++ b/packages/apis/src/extract_substrs.rs
@@ -22,9 +22,9 @@ pub struct RegexPartConfig {
 pub enum ExtractSubstrssError {
     // #[error("The max length is {} but the input length is {}",.0,.1)]
     // InvalidInputLen(usize, usize),
-    #[error("Substring of the entire regex {} is not found in {}",.0,.1)]
-    SubstringOfEntireNotFound(Regex, String),
-    #[error("Substring of {} is not found in {}",.0,.1)]
+    #[error("Substring of the entire regex {} is not found given input_str",.0)]
+    SubstringOfEntireNotFound(Regex),
+    #[error("Substring of {} is not found in given input_str",.0)]
     SubstringNotFound(Regex, String),
     #[error(transparent)]
     RegexError(#[from] fancy_regex::Error),
@@ -33,6 +33,7 @@ pub enum ExtractSubstrssError {
 pub fn extract_substr_idxes(
     input_str: &str,
     regex_config: &DecomposedRegexConfig,
+    reveal_private: bool,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     // Construct the full regex pattern with groups for each part
     let mut entire_regex_str = String::new();
@@ -47,24 +48,14 @@ pub fn extract_substr_idxes(
     // Find the match for the entire regex
     let entire_captures = entire_regex
         .captures(input_str)
-        .map_err(|_| {
-            ExtractSubstrssError::SubstringOfEntireNotFound(
-                entire_regex.clone(),
-                input_str.to_string(),
-            )
-        })?
-        .ok_or_else(|| {
-            ExtractSubstrssError::SubstringOfEntireNotFound(
-                entire_regex.clone(),
-                input_str.to_string(),
-            )
-        })?;
+        .map_err(|_| ExtractSubstrssError::SubstringOfEntireNotFound(entire_regex.clone()))?
+        .ok_or_else(|| ExtractSubstrssError::SubstringOfEntireNotFound(entire_regex.clone()))?;
 
     let mut public_idxes = vec![];
 
     // Iterate over each part to extract the relevant indices
     for (i, part) in regex_config.parts.iter().enumerate() {
-        if part.is_public {
+        if part.is_public || reveal_private {
             if let Some(matched) = entire_captures.get(i + 1) {
                 // Capture group indices are 1-based
                 public_idxes.push((matched.start(), matched.end()));
@@ -75,18 +66,41 @@ pub fn extract_substr_idxes(
     Ok(public_idxes)
 }
 
+pub fn extract_substr(
+    input_str: &str,
+    regex_config: &DecomposedRegexConfig,
+    reveal_private: bool,
+) -> Result<Vec<String>, ExtractSubstrssError> {
+    let substr_idxes = extract_substr_idxes(input_str, regex_config, reveal_private)?;
+
+    let result: Vec<String> = substr_idxes
+        .iter()
+        .map(|&(start, end)| input_str[start..end].to_string())
+        .collect();
+
+    Ok(result)
+}
+
 pub fn extract_email_addr_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/email_addr.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_email_domain_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/email_domain.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 // pub fn extract_email_addr_with_name_idxes(
@@ -100,52 +114,84 @@ pub fn extract_from_all_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/from_all.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_from_addr_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/from_addr.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_to_all_idxes(input_str: &str) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/to_all.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_to_addr_idxes(input_str: &str) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/to_addr.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_subject_all_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/subject_all.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_body_hash_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/body_hash.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_timestamp_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/timestamp.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 pub fn extract_message_id_idxes(
     input_str: &str,
 ) -> Result<Vec<(usize, usize)>, ExtractSubstrssError> {
     let regex_config = include_str!("./decomposed_defs/message_id.json");
-    extract_substr_idxes(input_str, &serde_json::from_str(regex_config).unwrap())
+    extract_substr_idxes(
+        input_str,
+        &serde_json::from_str(regex_config).unwrap(),
+        false,
+    )
 }
 
 #[cfg(test)]
@@ -215,7 +261,7 @@ mod test {
             ],
         };
         let input_str = "sepolia+ACCOUNTKEY.0xabc123@sendeth.org";
-        let idxes = extract_substr_idxes(input_str, &code_regex).unwrap();
+        let idxes = extract_substr_idxes(input_str, &code_regex, false).unwrap();
         assert_eq!(idxes, vec![(21, 27)]);
     }
 
@@ -260,7 +306,7 @@ mod test {
             ],
         };
         let input_str = "azb";
-        let idxes = extract_substr_idxes(input_str, &code_regex).unwrap();
+        let idxes = extract_substr_idxes(input_str, &code_regex, false).unwrap();
         assert_eq!(idxes, vec![(1, 2)]);
     }
 
@@ -279,7 +325,65 @@ mod test {
             ],
         };
         let input_str = "b";
-        let idxes = extract_substr_idxes(input_str, &code_regex).unwrap();
+        let idxes = extract_substr_idxes(input_str, &code_regex, false).unwrap();
         assert_eq!(idxes, vec![(0, 0)]);
     }
+
+    #[test]
+    fn extract_str_hide_private() {
+        let code_regex = DecomposedRegexConfig {
+            parts: vec![
+                RegexPartConfig {
+                    is_public: true,
+                    regex_def: "Hello ".to_string(),
+                },
+                RegexPartConfig {
+                    is_public: false,
+                    regex_def: "guys!".to_string(),
+                },
+            ],
+        };
+        let input_str = "some email: Hello guys! Best, ZK Email";
+        let strs = extract_substr(input_str, &code_regex, false).unwrap();
+        assert_eq!(strs, vec!["Hello ".to_string()]);
+    }
+
+    #[test]
+    fn extract_str_show_private() {
+        let code_regex = DecomposedRegexConfig {
+            parts: vec![
+                RegexPartConfig {
+                    is_public: true,
+                    regex_def: "Hello ".to_string(),
+                },
+                RegexPartConfig {
+                    is_public: false,
+                    regex_def: "guys!".to_string(),
+                },
+            ],
+        };
+        let input_str = "some email: Hello guys! Best, ZK Email";
+        let strs = extract_substr(input_str, &code_regex, true).unwrap();
+        assert_eq!(strs, vec!["Hello ".to_string(), "guys!".to_string()]);
+    }
+
+    #[test]
+    fn extract_str_empty_vec_all_private() {
+        let code_regex = DecomposedRegexConfig {
+            parts: vec![
+                RegexPartConfig {
+                    is_public: false,
+                    regex_def: "Hello ".to_string(),
+                },
+                RegexPartConfig {
+                    is_public: false,
+                    regex_def: "guys!".to_string(),
+                },
+            ],
+        };
+        let input_str = "some email: Hello guys! Best, ZK Email";
+        let strs = extract_substr(input_str, &code_regex, false).unwrap();
+        let empty_vec: Vec<String> = Vec::new();
+        assert_eq!(strs, empty_vec);
+    }
 }
diff --git a/packages/apis/src/wasm.rs b/packages/apis/src/wasm.rs
index 9e5b0ff..1fceda6 100644
--- a/packages/apis/src/wasm.rs
+++ b/packages/apis/src/wasm.rs
@@ -1,6 +1,7 @@
 use crate::extract_substrs::*;
 use crate::*;
 use js_sys::Array;
+use serde_json::Value;
 use wasm_bindgen::prelude::*;
 
 #[wasm_bindgen]
@@ -18,33 +19,67 @@ pub fn padString(str: &str, paddedBytesSize: usize) -> Array {
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractSubstrIdxes(inputStr: &str, regexConfig: JsValue) -> Array {
-    let regex_config_str = regexConfig.as_string().unwrap();
-    let regex_config: DecomposedRegexConfig = serde_json::from_str(&regex_config_str).unwrap();
-    let public_idxes = extract_substrs::extract_substr_idxes(inputStr, &regex_config).unwrap();
-    let arr = Array::new_with_length(public_idxes.len() as u32);
-    for (i, idx) in public_idxes.iter().enumerate() {
+pub fn extractSubstrIdxes(
+    inputStr: &str,
+    regexConfig: JsValue,
+    reveal_private: bool,
+) -> Result<Array, JsValue> {
+    let regex_config = parse_js_regex_config(regexConfig)?;
+
+    let idxes = extract_substrs::extract_substr_idxes(inputStr, &regex_config, reveal_private)
+        .map_err(|e| {
+            println!("e: {:?}", e);
+            let error_msg = format!("Failed to extract indxes: {}", e);
+            JsValue::from_str(&error_msg)
+        })?;
+
+    let arr = Array::new_with_length(idxes.len() as u32);
+    for (i, idx) in idxes.iter().enumerate() {
         let js_arr = Array::new_with_length(2);
         js_arr.set(0, JsValue::from(idx.0 as u32));
         js_arr.set(1, JsValue::from(idx.1 as u32));
         arr.set(i as u32, JsValue::from(js_arr));
     }
 
-    arr
+    Ok(arr)
+}
+
+#[wasm_bindgen]
+#[allow(non_snake_case)]
+pub fn extractSubstr(
+    inputStr: &str,
+    regexConfig: JsValue,
+    reveal_private: bool,
+) -> Result<Array, JsValue> {
+    let regex_config = parse_js_regex_config(regexConfig)?;
+
+    let result_strs = extract_substrs::extract_substr(inputStr, &regex_config, reveal_private)
+        .map_err(|e| {
+            println!("e: {:?}", e);
+            let error_msg = format!("Failed to extract strings: {}", e);
+            JsValue::from_str(&error_msg)
+        })?;
+
+    let js_array = Array::new_with_length(result_strs.len() as u32);
+    for (i, s) in result_strs.into_iter().enumerate() {
+        js_array.set(i as u32, JsValue::from_str(&s));
+    }
+
+    Ok(js_array)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractEmailAddrIdxes(inputStr: &str) -> Array {
+pub fn extractEmailAddrIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/email_addr.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractEmailDomainIdxes(inputStr: &str) -> Array {
+pub fn extractEmailDomainIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/email_domain.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 // #[wasm_bindgen]
@@ -56,56 +91,87 @@ pub fn extractEmailDomainIdxes(inputStr: &str) -> Array {
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractFromAllIdxes(inputStr: &str) -> Array {
+pub fn extractFromAllIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/from_all.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractFromAddrIdxes(inputStr: &str) -> Array {
+pub fn extractFromAddrIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/from_addr.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractToAllIdxes(inputStr: &str) -> Array {
+pub fn extractToAllIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/to_all.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractToAddrIdxes(inputStr: &str) -> Array {
+pub fn extractToAddrIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/to_addr.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractSubjectAllIdxes(inputStr: &str) -> Array {
+pub fn extractSubjectAllIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/subject_all.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractBodyHashIdxes(inputStr: &str) -> Array {
+pub fn extractBodyHashIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/body_hash.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractTimestampIdxes(inputStr: &str) -> Array {
+pub fn extractTimestampIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/timestamp.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
 }
 
 #[wasm_bindgen]
 #[allow(non_snake_case)]
-pub fn extractMessageIdIdxes(inputStr: &str) -> Array {
+pub fn extractMessageIdIdxes(inputStr: &str) -> Result<Array, JsValue> {
     let regex_config = include_str!("./decomposed_defs/message_id.json");
-    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config))
+    extractSubstrIdxes(inputStr, JsValue::from_str(regex_config), false)
+}
+
+// Accepts regexConfig either as string or js object
+fn parse_js_regex_config(regex_config: JsValue) -> Result<DecomposedRegexConfig, JsValue> {
+    // Checks if regexConfig is passed as string or object
+    // As string
+    let parsed_config: DecomposedRegexConfig = if regex_config.is_string() {
+        let config_str = regex_config.as_string().unwrap();
+        serde_json::from_str(&config_str).map_err(|e| {
+            let error_msg = format!("Failed to parse JSON string: {}", e);
+            JsValue::from_str(&error_msg)
+        })?
+    // As object
+    } else {
+        serde_wasm_bindgen::from_value(regex_config).map_err(|e| {
+            let error_msg = simplify_error(&e);
+            JsValue::from_str(&error_msg)
+        })?
+    };
+
+    Ok(parsed_config)
+}
+
+fn simplify_error(e: &serde_wasm_bindgen::Error) -> String {
+    let error_string = e.to_string();
+    if let Some(json_error) = serde_json::from_str::<Value>(&error_string).ok() {
+        if let Some(message) = json_error["message"].as_str() {
+            return message.to_string();
+        }
+    }
+    error_string
 }
diff --git a/packages/apis/tests/airbnb_eml.ts b/packages/apis/tests/airbnb_eml.ts
new file mode 100644
index 0000000..64e68bd
--- /dev/null
+++ b/packages/apis/tests/airbnb_eml.ts
@@ -0,0 +1,1146 @@
+export default `Delivered-To: dimitridumonet@gmail.com
+Received: by 2002:a0c:fecd:0:b0:6c3:6081:347f with SMTP id z13csp81193qvs;
+        Thu, 10 Oct 2024 16:19:45 -0700 (PDT)
+X-Google-Smtp-Source: AGHT+IEd0XrzNnTswxWNTmEZgIArn+BlrkDF1vp1CyMewhYGmJAj19KVofiC8WRBHgTjYX7aQ6Cc
+X-Received: by 2002:a05:6214:3b86:b0:6cb:e662:c59a with SMTP id 6a1803df08f44-6cbeff36cf0mr10369186d6.11.1728602385043;
+        Thu, 10 Oct 2024 16:19:45 -0700 (PDT)
+ARC-Seal: i=1; a=rsa-sha256; t=1728602385; cv=none;
+        d=google.com; s=arc-20240605;
+        b=E0qFuaOfdPQc+Ld1vLPYWAZYD+jbI5AzUeQ/wL7UcJv1SSr0Pl4Ku+LBuzDOG+Gai+
+         Pfn9ZHwXjMEFk/nZJw9RiXP3/c8y+0oi5dx4ojupMriS3WzsGB3r/T5+tLz7HDiMP8Zk
+         f7zRkqEeCIY0OUJU/QMfxAdRmCUmE9TsqnKJ7e+Pf4Y1sIHwo0eoEGz0afHsizoaPOTJ
+         KtUB0VYLLC/JmaPnpUZcD/biZRQgCsaL0XPLBvIK/URHnZniPM/hgB/9nQ24lJVX9/ZP
+         tRT8yxnlmHDcfiauoSzVmBwC9Gh6+JFXoNC0mOkK1t7/RhPlSpPVj1RzhJHEwH+JPTn4
+         EkvQ==
+ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605;
+        h=to:priority:importance:bimi-selector:reply-to:subject:message-id
+         :mime-version:from:date:dkim-signature:dkim-signature;
+        bh=qRjFxOyp02fNtl8fsqa9P9TfXf+KOCimKHiS6d8XZa8=;
+        fh=wfDbold4LZmvpOGNo2jQk0a98jfSD+kr9vmhclYezSA=;
+        b=ghyFgwCF/FyqVXrbUiiuPSa3Zu4yHwcLH6VIB/duhMOfiI3VTyV4QIduL41MfNnbg+
+         gMe5x1JrkHdevne5zP1JRtR6cUPiyW2Rah6tXNsmxRPOJr2oqgq3SAorXRkLTX3VRoe9
+         wv51uWUNGaVmfSS6mLmtmADlISwaV8Q47cusyUOnowVtvcAO3BtNnfMNUsR/eblplWiH
+         VkuRbS61kqnnh8jL8Xj4LUj4lYvfhUPvwY6gGv2MET6OZu5+mdsr69RJ42mOIezZuDqy
+         ZntooVCjbBCmRMKC3GzYq/tCJGtA5/EtGnd3PdZI+A0P/Z+WnTpH+HZZmgy0+XG/U38m
+         GeWw==;
+        dara=google.com
+ARC-Authentication-Results: i=1; mx.google.com;
+       dkim=pass header.i=@email.airbnb.com header.s=s20150428 header.b=i5GLT4zT;
+       dkim=pass header.i=@sendgrid.info header.s=smtpapi header.b=D3G4ED+y;
+       spf=pass (google.com: domain of bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com designates 50.31.32.157 as permitted sender) smtp.mailfrom="bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com";
+       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=airbnb.com
+Return-Path: <bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com>
+Received: from o11.email.airbnb.com (o11.email.airbnb.com. [50.31.32.157])
+        by mx.google.com with ESMTPS id 6a1803df08f44-6cbe85e049asi24990216d6.161.2024.10.10.16.19.44
+        for <dimitridumonet@gmail.com>
+        (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);
+        Thu, 10 Oct 2024 16:19:45 -0700 (PDT)
+Received-SPF: pass (google.com: domain of bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com designates 50.31.32.157 as permitted sender) client-ip=50.31.32.157;
+Authentication-Results: mx.google.com;
+       dkim=pass header.i=@email.airbnb.com header.s=s20150428 header.b=i5GLT4zT;
+       dkim=pass header.i=@sendgrid.info header.s=smtpapi header.b=D3G4ED+y;
+       spf=pass (google.com: domain of bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com designates 50.31.32.157 as permitted sender) smtp.mailfrom="bounces+168748-181c-dimitridumonet=gmail.com@email.airbnb.com";
+       dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=airbnb.com
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=email.airbnb.com;
+	h=content-type:from:mime-version:subject:reply-to:x-feedback-id:to:cc:
+	content-type:from:subject:to;
+	s=s20150428; bh=qRjFxOyp02fNtl8fsqa9P9TfXf+KOCimKHiS6d8XZa8=;
+	b=i5GLT4zTtTTSt901iUHFaQ9de9Ai4d01FdDK4MVZ3NsL7h8mN7IBr2iIpmv6AM0Q2Cok
+	3hGxRysyIAF7fQ3qR1/drVCuzh0v5AQPu2tf3hbPv/+BCHLiD4sVt9iPY3FBbo/UnFNEqz
+	0UjR4IfLboxLkdHv5/cSmEovnKoj0RX5k=
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sendgrid.info;
+	h=content-type:from:mime-version:subject:reply-to:x-feedback-id:to:cc:
+	content-type:from:subject:to;
+	s=smtpapi; bh=qRjFxOyp02fNtl8fsqa9P9TfXf+KOCimKHiS6d8XZa8=;
+	b=D3G4ED+yMdDJd90YTuhqvFdCDTfCU/cjAxBmB2MdDA9YquweURwttkoHraS02sYUznUK
+	pg15OmQzP4WbAB2PRJAtSNF28FrZJOxs68ss7tEVAcF9YqHaYj6F5j/sMCZunhnr1aBJfY
+	MMr8i8FPie9OlpKFcCG4y4VX0DtjHzBQ8=
+Received: by recvd-fdb77b5cb-l2cqh with SMTP id recvd-fdb77b5cb-l2cqh-1-67086110-34
+	2024-10-10 23:19:44.63636295 +0000 UTC m=+2438527.951122372
+Received: from MTY4NzQ4 (unknown)
+	by geopod-ismtpd-20 (SG) with HTTP
+	id ozjDOM3PS6WltaTtjuJFaA
+	Thu, 10 Oct 2024 23:19:44.626 +0000 (UTC)
+Content-Type: multipart/alternative; boundary=49a8ec9b277e6a96e7373b3e4727df74d25ab6158dd0a8fb1221118a1304
+Date: Thu, 10 Oct 2024 23:19:44 +0000 (UTC)
+From: Airbnb <express@airbnb.com>
+Mime-Version: 1.0
+Message-ID: <ozjDOM3PS6WltaTtjuJFaA@geopod-ismtpd-20>
+Subject: RE: Reservation at Luxurious 5B/3BA home Nob Hill! for 22 September
+ 2024 - 22 October 2024
+Reply-To: "Isabella (Airbnb)"
+	<4of5lutm2rzokajdtd2j25ek6whsg045r01d@reply.airbnb.com>
+X-Priority: 1
+X-Category: message
+X-Strategy: push_and_email_and_web_push
+X-rpcampaign: airbnb20241010152328760092722452715530303223890373903
+X-Locale: en-GB
+X-Message-Package-UUID: 7e892d74-33f4-ebf8-ef9a-cba7f9c2c579
+BIMI-Selector: v=BIMI1; s=belov2;
+X-User-ID: 467606067
+X-MSMail-Priority: High
+Return-Path: express@airbnb.com
+Importance: high
+Priority: Urgent
+X-Template: homes_messaging/new_message
+X-Feedback-ID: 168748:SG
+X-SG-EID:
+ =?us-ascii?Q?u001=2E373TPjtMqGbzwgRnUiLO4aQplIiW+Q7azdMrDCU1iICBGcf7GI8fS8Yas?=
+ =?us-ascii?Q?=2FrvZ5srvc=2FUg+Y3QtuuZu8t9IoQj8U67X=2Ftferm?=
+ =?us-ascii?Q?GqR0cRkWsdIQdo0l4Ezae3j01oY06yQrm91GBfs?=
+ =?us-ascii?Q?5cx=2FNZOz3bvJt7R7OpkA=2FGLSMdeFwqzm9dhpSx8?=
+ =?us-ascii?Q?YqLodw=2FoFKqS178kFLThUhL1OMuR7EJqMudXl81?=
+ =?us-ascii?Q?Z1ab7TzKTs=2F1Ok7Pkf8CSI=3D?=
+X-SG-ID:
+ =?us-ascii?Q?u001=2ESdBcvi+Evd=2FbQef8eZF3BqZ9cHLZlaQH8LGBOs0K2+F024wgXfxgfZf8o?=
+ =?us-ascii?Q?wozgZzIDr0SWjqkz0Hzl15He+3JiV4qiZ3NftmN?=
+ =?us-ascii?Q?AQKXfQpNpidNvJalNic6JYjllxfNAmK52O3GlhD?=
+ =?us-ascii?Q?FOjjI2YBmc2SQ5GYtyJGmycybZOQvvNcazI85yt?=
+ =?us-ascii?Q?mPQq+Hz8fniF9EjPeVlfxQ0CoVMew0o+IUL9q46?=
+ =?us-ascii?Q?+hi7Q+9jQAOPMZV=2FIZ4e3JazWnV58Av2FlUBtP0?=
+ =?us-ascii?Q?yA=2F5kfOMtemfJB+3OWwPtttyQF8gCtEFp3cmd6m?=
+ =?us-ascii?Q?39i+4FRprLKQypcH6HFCAg0WHbhyiK=2Fa+8ZWE5i?=
+ =?us-ascii?Q?OTyPI3ajl5gFGwtrbgYnMTHOAERzqQMstiK3=2F=2F0?=
+ =?us-ascii?Q?EpJEOMxvs8rkjoxbWnvEWjQMiJSyk+=2F2q6FDbow?=
+ =?us-ascii?Q?s=2FGRpDmfjJeaiTN0jI8QLdDkHCWdfuPY5jnt8Xv?=
+ =?us-ascii?Q?pX8cfwsbZpmoZflQ8PrIjcd=2FkxK7Gf4e5krU4Md?=
+ =?us-ascii?Q?nzRx3=2FxRRYLEzocKrzMv=2FP1hpAC+RN7GKeKaosl?=
+ =?us-ascii?Q?PD7zzN0jSqkzXnN1CKlcNYEygz0tPE=3D?=
+To: dimitridumonet@gmail.com
+X-Entity-ID: u001.xNm+654l4yZx3FKLl1hq6g==
+
+--49a8ec9b277e6a96e7373b3e4727df74d25ab6158dd0a8fb1221118a1304
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/plain; charset=iso-8859-1
+Mime-Version: 1.0
+
+%opentrack%
+
+https://www.airbnb.co.uk/?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&=
+euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579
+
+RE: RESERVATION AT LUXURIOUS 5B/3BA HOME NOB HILL! FOR 22
+SEPTEMBER 2024 - 22 OCTOBER 2024
+
+For your protection and safety, always communicate through
+Airbnb
+[https://www.airbnb.co.uk/help/article/209?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5n=
+L25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579].
+
+   Isabella
+  =20
+   Hello guys! I need to let you know that the owner has
+   scheduled a FaceTime tour with a long term group this
+   Saturday at 1:30pm.
+   I apologize for the inconvenience and
+   Thank you for the cooperation.
+
+Reply
+[https://www.airbnb.co.uk/messaging/thread/1919382305?thread_type=3Dhome_bo=
+oking&c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&euid=3D7e892d74-33f4=
+-ebf8-ef9a-cba7f9c2c579]
+
+Respond to Isabella by replying directly to this email.
+
+https://www.airbnb.co.uk/rooms/1193537369002070065?c=3D.pi80.pkaG9tZXNfbWVz=
+c2FnaW5nL25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579
+
+RESERVATION DETAILS
+
+Luxurious 5B/3BA home Nob Hill!
+
+Rental unit - Entire home/flat hosted by Isabella
+
+GUESTS
+
+10 guests
+
+   CHECK-IN            CHECKOUT
+                   =20
+Sunday              Tuesday
+                   =20
+22 September 2024   22 October 2024
+
+   https://www.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL=
+25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&url=3Dhttps%3A%=
+2F%2Fwww.facebook.com%2Fairbnb   https://www.airbnb.co.uk/external_link?c=
+=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-e=
+f9a-cba7f9c2c579&url=3Dhttps%3A%2F%2Fwww.instagram.com%2Fairbnb   https://w=
+ww.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzY=
+Wdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&url=3Dhttps%3A%2F%2Ftwitter=
+.com%2FAirbnb
+
+Airbnb Ireland UC
+
+8 Hanover Quay
+
+Dublin 2, Ireland
+
+Get the Airbnb app
+
+https://www.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25l=
+d19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&url=3Dhttps%3A%2F%=
+2Fairbnb.sng.link%2FA6f9up%2Fdvs6%3F_smtype%3D3%26pcid%3D.pi80.pkaG9tZXNfbW=
+Vzc2FnaW5nL25ld19tZXNzYWdl   https://www.airbnb.co.uk/external_link?c=3D.pi=
+80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cb=
+a7f9c2c579&url=3Dhttps%3A%2F%2Fairbnb.sng.link%2FA6f9up%2Fqh0lc%3Fid%3Dcom.=
+airbnb.android%26pcid%3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl  =20
+
+Update your email preferences
+[https://www.airbnb.co.uk/account-settings/notifications?c=3D.pi80.pkaG9tZX=
+NfbWVzc2FnaW5nL25ld19tZXNzYWdl&euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579]
+to choose which emails you get or unsubscribe
+[https://www.airbnb.co.uk/account-settings/email-unsubscribe?email_type=3Df=
+alse&mac=3DQJmdxe1CU5PXPvaEGjcsQ6TT5b4%3D&token=]
+from this type of email.
+
+=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0
+--49a8ec9b277e6a96e7373b3e4727df74d25ab6158dd0a8fb1221118a1304
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset=iso-8859-1
+Mime-Version: 1.0
+
+<html lang=3D"en"><head><meta http-equiv=3D"Content-Type" content=3D"text/h=
+tml; charset=3Dutf-8"><meta name=3D"viewport" content=3D"width=3Ddevice-wid=
+th, initial-scale=3D1"><style type=3D"text/css">
+@font-face {
+  font-family: Cereal;
+  src: url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/font=
+s/Airbnb_Cereal-Book-9a1c9cca9bb3d65fefa2aa487617805e.woff2") format("woff2=
+"), url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/fonts/A=
+irbnb_Cereal-Book-aa38e86e3f98554f9f7053d7b713b4db.woff") format('woff');
+  font-weight: normal;
+  font-style: normal;
+  font-display: swap;}
+@font-face {
+  font-family: Cereal;
+  src: url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/font=
+s/Airbnb_Cereal-Medium-50fc004b3082375f12ff0cfb67bf8e56.woff2") format("wof=
+f2"), url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/fonts=
+/Airbnb_Cereal-Medium-4bc8dafd2e0fd8914bf4d5edce9acd24.woff") format('woff'=
+);
+  font-weight: 500;
+  font-style: normal;
+  font-display: swap;}
+@font-face {
+  font-family: Cereal;
+  src: url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/font=
+s/Airbnb_Cereal-Bold-bdfb98485e7836ba31b456f65cded088.woff2") format("woff2=
+"), url("https://a0.muscache.com/airbnb/static/airbnb-dls-web/build/fonts/A=
+irbnb_Cereal-Bold-a188841af78481a25b7bb2316a5f5716.woff") format('woff');
+  font-weight: 700;
+  font-style: normal;
+  font-display: swap;}
+</style><div><!--[if (mso)|(IE)]>
+<style type=3D"text/css">
+h1, h2, h3, h4, h5, h6, a, p, li, div, span {
+  font-family: Cereal, Helvetica Neue, Helvetica, sans-serif !important;
+}
+
+a {
+  color: #222222 !important;
+}
+
+h1, h2, h3, h4, h5, h6, a, p, li, div, span {
+  color: #222222 !important;
+}
+
+.outlook-row-container {
+  padding-bottom: 24px !important;
+  padding-left: 48px !important;
+  padding-right: 48px !important;
+  padding-top: 24px !important;
+}
+
+a.base-button {
+  border: 1px solid #222222 !important;
+  color: #222222 !important;
+  display: inline-block !important;
+  font-size: 18px !important;
+  font-weight: bold !important;
+  padding-top: 16px !important;
+}
+
+a.embedded-button {
+  border: 1px solid #222222 !important;
+  color: #222222 !important;
+  display: inline-block !important;
+  font-size: 18px !important;
+  font-weight: bold !important;
+  padding-top: 8px !important;
+}
+
+div#brand-header {
+  padding-bottom: 24px !important;
+  padding-top: 48px !important;
+}
+
+.outlook-only {
+  display: block !important;
+}
+
+.non-outlook-only {
+  background-color: red;
+  display: none !important;
+  height: 0 !important;
+  max-height: 0px !important;
+  mso-hide: all !important;
+  overflow: hidden !important;
+  padding-bottom: 0 !important;
+  width: 0 !important;
+}
+</style>
+<![endif]--></div><style type=3D"text/css">
+@media only screen and (max-width: 560px) {
+  table .height_12_10 {
+    height: 10px !important;
+  }
+
+  table .height_18_16 {
+    height: 16px !important;
+  }
+
+  table .height_32_24 {
+    height: 24px !important;
+  }
+
+  table .height_48_24 {
+    height: 24px !important;
+  }
+
+  table .height_64_48 {
+    height: 48px !important;
+  }
+
+  table .bottom_0_1 {
+    padding-bottom: 8px !important;
+  }
+
+  table .bottom_1_1 {
+    padding-bottom: 8px !important;
+  }
+
+  table .bottom_1_0 {
+    padding-bottom: 0px !important;
+  }
+
+  table .bottom_3_2 {
+    padding-bottom: 16px !important;
+  }
+
+  table .bottom_3_3 {
+    padding-bottom: 24px !important;
+  }
+
+  table .bottom_4_2 {
+    padding-bottom: 16px !important;
+  }
+
+  table .bottom_4_3 {
+    padding-bottom: 24px !important;
+  }
+
+  table .bottom_5_3 {
+    padding-bottom: 24px !important;
+  }
+
+  table .bottom_6_4 {
+    padding-bottom: 32px !important;
+  }
+
+  table .left_0-5_0-25 {
+    padding-left: 2px !important;
+  }
+
+  table .left_1-25_1-5 {
+    padding-left: 12px !important;
+  }
+
+  table .left_2_0 {
+    padding-left: 0px !important;
+  }
+
+  table .left_2_1-5 {
+    padding-left: 12px !important;
+  }
+
+  table .left_3_2 {
+    padding-left: 16px !important;
+  }
+
+  table .left_6_2 {
+    padding-left: 16px !important;
+  }
+
+  table .left_6_3 {
+    padding-left: 24px !important;
+  }
+
+  table .left_9_6 {
+    padding-left: 48px !important;
+  }
+
+  table .right_0-5_0-25 {
+    padding-right: 2px !important;
+  }
+
+  table .right_1_0 {
+    padding-right: 0px !important;
+  }
+
+  table .right_1-25_1-5 {
+    padding-right: 12px !important;
+  }
+
+  table .right_2_0 {
+    padding-right: 0px !important;
+  }
+
+  table .right_3_2 {
+    padding-right: 16px !important;
+  }
+
+  table .right_6_2 {
+    padding-right: 16px !important;
+  }
+
+  table .right_6_3 {
+    padding-right: 24px !important;
+  }
+
+  table .right_9_6 {
+    padding-right: 48px !important;
+  }
+
+  table .top_0-5_1 {
+    padding-top: 8px !important;
+  }
+
+  table .top_0-75_0-5 {
+    padding-top: 4px !important;
+  }
+
+  table .top_0_3 {
+    padding-top: 24px !important;
+  }
+
+  table .top_1_0 {
+    padding-top: 0px !important;
+  }
+
+  table .top_1_0-5 {
+    padding-top: 4px !important;
+  }
+
+  table .top_1-25_0-5 {
+    padding-top: 4px !important;
+  }
+
+  table .top_1-5_0-5 {
+    padding-top: 4px !important;
+  }
+
+  table .top_1-5_1 {
+    padding-top: 8px !important;
+  }
+
+  table .top_1-5_1-5 {
+    padding-top: 12px !important;
+  }
+
+  table .top_1-75_0-5 {
+    padding-top: 4px !important;
+  }
+
+  table .top_1-75_1-25 {
+    padding-top: 10px !important;
+  }
+
+  table .top_2_1 {
+    padding-top: 8px !important;
+  }
+
+  table .top_2_1-25 {
+    padding-top: 10px !important;
+  }
+
+  table .top_2-25_1-5 {
+    padding-top: 12px;
+  }
+
+  table .top_2_3 {
+    padding-top: 24px !important;
+  }
+
+  table .top_3_1 {
+    padding-top: 8px !important;
+  }
+
+  table .top_3_2 {
+    padding-top: 16px !important;
+  }
+
+  table .top_3_3 {
+    padding-top: 24px !important;
+  }
+
+  table .top_4_2 {
+    padding-top: 16px !important;
+  }
+
+  table .top_4_3 {
+    padding-top: 24px !important;
+  }
+
+  table .top_6_4 {
+    padding-top: 32px !important;
+  }
+
+  table .width_12_10 {
+    width: 10px !important;
+  }
+
+  table .width_18_16 {
+    width: 16px !important;
+  }
+
+  table .width_20_24 {
+    width: 24px !important;
+  }
+
+  table .width_28_20 {
+    width: 20px !important;
+  }
+
+  table .width_32_24 {
+    width: 24px !important;
+  }
+
+  table .width_46_30 {
+    width: 30.67px;
+  }
+
+  table .width_48_24 {
+    width: 24px !important;
+  }
+
+  table .width_64_48 {
+    width: 48px !important;
+  }
+
+  table .width_64_48 {
+    width: 48px !important;
+  }
+
+  table .hide_small {
+    display: block !important;
+  }
+
+  table .hide_large {
+    display: none !important;
+  }
+
+  table a.base-button {
+    display: block !important;
+    font-size: 16px !important;
+    line-height: 20px !important;
+    padding: 14px 24px !important;
+    font-weight: 500 !important;
+  }
+
+  table a.embedded-button {
+    display: block !important;
+    font-size: 14px !important;
+    line-height: 18px !important;
+    padding: 8px 14px !important;
+  }
+
+  table div.base-button-container {
+    display: block !important;
+    width: 100% !important;
+  }
+
+  table div.base-button-container,
+table div.base-button-no-resize {
+    font-size: 16px !important;
+    line-height: 20px !important;
+  }
+
+  table .brand-header {
+    padding-bottom: 0px !important;
+    padding-top: 32px !important;
+  }
+
+  table a.header-nav {
+    font-size: 12px !important;
+  }
+
+  table div.full-width {
+    width: 100% !important;
+  }
+
+  table div.normal-container {
+    border: none !important;
+    border-radius: unset !important;
+    overflow: visible !important;
+  }
+
+  table div.header-middle {
+    background-color: transparent !important;
+    border: none !important;
+  }
+
+  table div.header-bottom {
+    border: none !important;
+  }
+
+  table div.hero-container-top-style {
+    margin-top: 0px !important;
+    border: none !important;
+    border-radius: unset !important;
+    overflow: visible !important;
+  }
+
+  table div.hero-container-bottom-style {
+    margin-bottom: 0px !important;
+    border-radius: 0px !important;
+  }
+
+  table .heading1 {
+    font-size: 24px !important;
+    line-height: 28px !important;
+  }
+
+  table .heading2 {
+    font-size: 18px !important;
+    line-height: 22px !important;
+  }
+
+  table .heading3 {
+    font-size: 16px !important;
+    line-height: 20px !important;
+  }
+
+  table .heading4 {
+    font-size: 14px !important;
+    line-height: 18px !important;
+  }
+
+  table h1.super1 {
+    font-size: 32px !important;
+    line-height: 36px !important;
+  }
+
+  table h1.super2,
+table h2.super2 {
+    font-size: 32px !important;
+    line-height: 36px !important;
+  }
+
+  table p.heading-level-2-3 {
+    font-size: 16px !important;
+    line-height: 20px !important;
+  }
+
+  table p.heading-32-24 {
+    font-size: 24px !important;
+    line-height: 28px !important;
+  }
+
+  table p.medium {
+    font-size: 16px !important;
+    line-height: 22px !important;
+  }
+
+  table a.regular,
+table p.regular,
+table div.regular {
+    font-size: 14px !important;
+    line-height: 20px !important;
+  }
+
+  table a.small,
+table p.small,
+table div.small {
+    font-size: 12px !important;
+    line-height: 18px !important;
+  }
+
+  table p.ui-large,
+table div.ui-large {
+    font-size: 14px !important;
+    line-height: 18px !important;
+  }
+
+  table p.ui-medium,
+table div.ui-medium {
+    font-size: 12px !important;
+    line-height: 16px !important;
+  }
+
+  table p.ui-small,
+table div.ui-small {
+    font-size: 10px !important;
+    line-height: 12px !important;
+  }
+
+  table p.ui-xlarge,
+table div.ui-xlarge {
+    font-size: 14px !important;
+    line-height: 18px !important;
+  }
+
+  table p.ui-xxlarge,
+table div.ui-xxlarge {
+    font-size: 22px !important;
+    line-height: 26px !important;
+  }
+
+  table a.x-small,
+table p.x-small,
+table div.x-small {
+    font-size: 12px !important;
+    line-height: 18px !important;
+  }
+
+  table td.cell-padding-bottom {
+    padding-bottom: 24px !important;
+  }
+
+  table td.height_715_546 {
+    height: 546px !important;
+  }
+
+  table.mobile-view,
+table .mobile-view {
+    display: table !important;
+  }
+
+  div.mobile-view-block,
+div .mobile-view-block {
+    display: block !important;
+  }
+
+  table.desktop-view,
+table .desktop-view {
+    display: none !important;
+  }
+
+  table.desktop-view-for-mobile-default,
+table .desktop-view-for-mobile-default {
+    display: none !important;
+  }
+}
+@media only screen and (min-width: 561px) {
+  table.desktop-view-for-mobile-default,
+table .desktop-view-for-mobile-default {
+    display: table !important;
+  }
+
+  table.mobile-view-for-mobile-default,
+table .mobile-view-for-mobile-default {
+    display: none;
+  }
+}
+</style></head><body style=3D"margin:0 auto!important;padding:0" id=3D"body=
+"><div style=3D"color:transparent;display:none !important;font-size:0px;hei=
+ght:0;opacity:0;width:0"><img src=3D"http://email.airbnbmail.com/wf/open?up=
+n=3Du001.Vf3ZgdAp00A3QHN2nFhKrXHWQkDjrh16-2FjWMP7Hvyx7LbdpEiaAyyUEa8Gi1g16a=
+yyWindWxbL9mAGp82TklRR7x0BiPrhosSH-2FZvPEL1-2BVlaajMdo6DwoH7sUwGbXZQKS3HH2S=
+BDfspaAY6KoVd7dbb-2BH-2FywR4sAzOhXk0uHD9O3o4lugtJLm1xHEdfMEjpS0uS3l-2BL6Srm=
+Ohbyfr2uRlxRFTLb9jFAwQ1-2Fe96onsvwAlCj96RKxJE509H1yOg9ATIGwk1pvad5TGIuDCPiL=
+lMBaNu1oozAIJ4SXVSD0VKwcO6lO819pAMaEyq6rvozA3S1x8OUbSYUz9T30Ch4DyiQI1Pbg7fe=
+DgkHLRoNb6QHVUg5YWDQk6Ts62BZ5VfvOrLAKImCC-2B-2FAJjaeE3-2F4Q2wnEN2hUS81mZBxC=
+l45LzAJOPVFgCtRbEyb2oQFU1sSACKmS0POdFvJqgbLox5x1OiTCkVAgGNfflVgBHYYWZ2h8oIS=
+K-2Fa8kqrBVsfPwALle9mPbtxX3hwLa6rCjbKvf7lHaAwE0WKAogpbgUkJshnGfTazeYiSKpe3J=
+xdhFA3qshB-2FVB0O23dVCnq-2Fwh5NwtqorYaMTIsZDBHFVhXVTwQE0K5dpViGFBottXS-2BmO=
+SPQLMfxi9S7L09JdewpaFI-2FxaNg-2FXJZFuYyN7GJFaOM2zH86Hg70Hxt-2Bn6C3tWf3m7NB-=
+2F398TYnmymoFWBexYJDGVXpw40t-2BjxX-2BLywbXbxeQ-3D" alt=3D"" width=3D"1" hei=
+ght=3D"1" border=3D"0" style=3D"height:1px !important;width:1px !important;=
+border-width:0 !important;margin-top:0 !important;margin-bottom:0 !importan=
+t;margin-right:0 !important;margin-left:0 !important;padding-top:0 !importa=
+nt;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !i=
+mportant;"/></div><div id=3D"app"><div dir=3D"ltr"><table cellpadding=3D"0"=
+ class=3D"_1vaxv5w" style=3D"max-width: 640px; border-collapse: collapse !i=
+mportant; border-spacing: 0px !important; color: #222222 !important; displa=
+y: table !important; font-family: Cereal, Helvetica Neue, Helvetica, sans-s=
+erif !important; margin-left: auto !important; margin-right: auto !importan=
+t; padding: 0px !important; position: relative !important; vertical-align: =
+top !important; width: 100% !important;" role=3D"presentation" width=3D"100=
+% !important" valign=3D"top !important"><tbody><tr class=3D"_16pg94n" style=
+=3D"margin: 0px !important;"><td class><div class=3D"normal-container" styl=
+e=3D"border: 1px solid #DDDDDD; border-radius: 12px; overflow: hidden;"><ta=
+ble cellpadding=3D"0" class style=3D"border-collapse:collapse;border-spacin=
+g:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=
+=3D"margin: 0px !important;"><td class=3D"outlook-row-container left_6_2 ri=
+ght_6_2" style=3D"padding-left: 48px; padding-right: 48px;"><table cellpadd=
+ing=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;width:10=
+0%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0p=
+x !important;"><td class=3D"brand-header" style=3D"padding-bottom: 24px; pa=
+dding-top: 48px;"><a target=3D"_self" rel=3D"noreferrer" data-eon-role=3D"l=
+ink" data-eon-prop=3D"href" href=3D"https://www.airbnb.co.uk/?c=3D.pi80.pka=
+G9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a-cba7=
+f9c2c579" class=3D"regular underline display-block" style=3D"font-family: C=
+ereal, Helvetica Neue, Helvetica; font-size: 18px; line-height: 28px; heigh=
+t: 40px; width: 104px; font-weight: 800; color: #222222; display: block !im=
+portant; text-decoration: underline !important;"><img data-eon-role=3D"imag=
+e" data-eon-prop=3D"src" alt=3D"Airbnb" src=3D"https://a0.muscache.com/pict=
+ures/a6939621-d67c-4265-9762-55449eb5882c.jpg" style=3D"height: 40px; width=
+: 104px; border: 0 !important;" width=3D"104" height=3D"40"></a></td></tr><=
+/tbody></table></td></tr></tbody></table><table cellpadding=3D"0" class sty=
+le=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"present=
+ation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td =
+class=3D"outlook-row-container left_6_2 right_6_2 top_3_3" style=3D"padding=
+-left: 48px; padding-right: 48px; padding-top: 24px;"><div><h1 class=3D"hea=
+ding1" style=3D"font-size: 32px; line-height: 36px; color: #222222; font-fa=
+mily: Cereal, Helvetica Neue, Helvetica, sans-serif; font-weight: 800; marg=
+in: 0;">RE: Reservation at Luxurious 5B/3BA home Nob Hill! for 22 September=
+ 2024 - 22 October 2024</h1></div></td></tr></tbody></table><table cellpadd=
+ing=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;width:10=
+0%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0p=
+x !important;"><td class=3D"outlook-row-container left_6_2 right_6_2 top_3_=
+3" style=3D"padding-left: 48px; padding-right: 48px; padding-top: 24px;"><p=
+ class=3D"regular" style=3D"font-size: 18px; line-height: 28px; font-family=
+: Cereal, Helvetica Neue, Helvetica, sans-serif; margin: 0 !important;">For=
+ your protection and safety, <a target=3D"_self" rel=3D"noreferrer" data-eo=
+n-role=3D"link" data-eon-prop=3D"href" href=3D"https://www.airbnb.co.uk/hel=
+p/article/209?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&amp;euid=3D7=
+e892d74-33f4-ebf8-ef9a-cba7f9c2c579" class=3D"regular underline" style=3D"f=
+ont-family: Cereal, Helvetica Neue, Helvetica; font-size: 18px; line-height=
+: 28px; font-weight: 800; color: #222222; text-decoration: underline !impor=
+tant;">always communicate through Airbnb</a>.</p></td></tr></tbody></table>=
+<table cellpadding=3D"0" class style=3D"border-collapse:collapse;border-spa=
+cing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" styl=
+e=3D"margin: 0px !important;"><td style=3D"padding-left: 48px; padding-righ=
+t: 48px; padding-bottom: 24px; padding-top: 24px;" class=3D"outlook-row-con=
+tainer left_6_2 right_6_2"><div class=3D"_18j460n" style=3D"border-width: 1=
+px !important; border-style: solid !important; border-color: #DDDDDD !impor=
+tant; border-radius: 12px !important;"><table cellpadding=3D"0" class style=
+=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"presentat=
+ion"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td cl=
+ass=3D"left_3_2 right_3_2" style=3D"padding-left: 24px; padding-right: 24px=
+;"><table cellpadding=3D"0" class style=3D"border-collapse:collapse;border-=
+spacing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" s=
+tyle=3D"margin: 0px !important;"><td valign=3D"top" class=3D"height_64_48 w=
+idth_64_48 bottom_3_2 right_3_2 top_3_3" style=3D"height: 64px; padding-bot=
+tom: 24px; padding-right: 24px; padding-top: 24px; width: 64px;" width=3D"6=
+4" height=3D"64"><img style=3D"height: 64px; width: 64px; border-radius: 50=
+%; border: 0 !important;" alt=3D"Isabella" class=3D"height_64_48 width_64_4=
+8" src=3D"https://a0.muscache.com/im/pictures/user/0d4ce48f-7f97-4b4f-aa27-=
+8f4c513e0263.jpg?aki_policy=3Dprofile_medium" width=3D"64" height=3D"64"></=
+td><td class=3D"top_3_3" style=3D"padding-top: 24px;"><table cellpadding=3D=
+"0" class style=3D"border-collapse:collapse;border-spacing:0;width:100%" ro=
+le=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !imp=
+ortant;"><td class><div><p class=3D"heading-level-2-3" style=3D"font-size: =
+22px; line-height: 26px; color: #222222; font-family: Cereal, Helvetica Neu=
+e, Helvetica, sans-serif; font-weight: 800; margin: 0 !important;">Isabella=
+</p></div></td></tr></tbody></table><table cellpadding=3D"0" class style=3D=
+"border-collapse:collapse;border-spacing:0;width:100%" role=3D"presentation=
+"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td class=
+=3D"bottom_3_3 top_3_1" style=3D"padding-bottom: 24px; padding-top: 24px;">=
+<div class=3D"regular" style=3D"font-size: 18px; line-height: 28px; margin:=
+ 0;"><p class=3D"regular" style=3D"font-size: 18px; line-height: 28px; font=
+-family: Cereal, Helvetica Neue, Helvetica, sans-serif; margin: 0 !importan=
+t;">Hello guys! I need to let you know that the owner has scheduled a FaceT=
+ime tour with a long term group this Saturday at 1:30pm.<br>I apologize for=
+ the inconvenience and<br>Thank you for the cooperation.</p></div></td></tr=
+></tbody></table></td></tr></tbody></table></td></tr></tbody></table></div>=
+</td></tr></tbody></table><table cellpadding=3D"0" class style=3D"border-co=
+llapse:collapse;border-spacing:0;width:100%" role=3D"presentation"><tbody><=
+tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td style=3D"paddin=
+g-left: 48px; padding-right: 48px; padding-bottom: 24px;" class=3D"outlook-=
+row-container left_6_2 right_6_2"><table cellpadding=3D"0" class=3D"_1cap30=
+x" style=3D"border-collapse: collapse !important; width: 100% !important;" =
+role=3D"presentation" width=3D"100% !important"><tbody><tr><td class=3D"_12=
+to336" style=3D"text-align: center !important;" align=3D"center !important"=
+><div class=3D"base-button-container full-width" style=3D"display: inline-b=
+lock; font-size: 18px; line-height: 24px; background: linear-gradient(90deg=
+, #E61E4D 1.83%, #E31C5F 50.07%, #D70466 96.34%); background-color: #FF385C=
+; border-radius: 8px; font-family: Cereal, Helvetica Neue, Helvetica, sans-=
+serif; font-weight: 500; text-align: center; width: 100% !important;"><a cl=
+ass=3D"base-button " style=3D"font-family: Cereal, Helvetica Neue, Helvetic=
+a; font-size: 18px; line-height: 24px; font-weight: 500; display: block; pa=
+dding: 14px 0px; color: #FFFFFF; text-align: center; text-decoration: none;=
+" data-eon-role=3D"button" data-eon-prop=3D"href" href=3D"https://www.airbn=
+b.co.uk/messaging/thread/1919382305?thread_type=3Dhome_booking&amp;c=3D.pi8=
+0.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a=
+-cba7f9c2c579"><span class=3D"_vz5kef" style=3D"color: #FFFFFF !important;"=
+>Reply</span></a></div></td></tr></tbody></table></td></tr></tbody></table>=
+<table cellpadding=3D"0" class style=3D"border-collapse:collapse;border-spa=
+cing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" styl=
+e=3D"margin: 0px !important;"><td class=3D"outlook-row-container bottom_3_2=
+ left_6_2 right_6_2" style=3D"padding-bottom: 24px; padding-left: 48px; pad=
+ding-right: 48px;"><p aria-hidden=3D"false" class=3D"ui-small" style=3D"fon=
+t-size: 12px; line-height: 16px; font-family: Cereal, Helvetica Neue, Helve=
+tica, sans-serif; margin: 0 !important;">Respond to Isabella by replying di=
+rectly to this email.</p></td></tr></tbody></table><table cellpadding=3D"0"=
+ class style=3D"border-collapse:collapse;border-spacing:0;width:100%" role=
+=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !impor=
+tant;"><td class=3D"outlook-row-container left_6_2 right_6_2" style=3D"padd=
+ing-left: 48px; padding-right: 48px;"><a target=3D"_self" rel=3D"noreferrer=
+" aria-label=3D"Go to listing details" data-eon-role=3D"link" data-eon-prop=
+=3D"href" href=3D"https://www.airbnb.co.uk/rooms/1193537369002070065?c=3D.p=
+i80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef=
+9a-cba7f9c2c579" class style=3D"font-family: Cereal, Helvetica Neue, Helvet=
+ica; font-weight: 800; color: #222222;"><div class=3D"non-outlook-only"><ta=
+ble cellpadding=3D"0" class=3D"non-outlook-only" style=3D"border-collapse:c=
+ollapse;border-spacing:0;width:100%;max-height:none;mso-hide:all" role=3D"p=
+resentation"><tbody><tr><td background=3D"https://a0.muscache.com/im/pictur=
+es/hosting/Hosting-U3RheVN1cHBseUxpc3Rpbmc6MTE5MzUzNzM2OTAwMjA3MDA2NQ%3D%3D=
+/original/f395baea-883b-4326-b172-f91b49714ddc.jpeg" class=3D"_4dhvbds" dat=
+a-eon-prop=3D"imageUrl" data-eon-role=3D"image" aria-label=3D"Luxurious 5B/=
+3BA home Nob Hill!" role=3D"img" style=3D"padding-bottom: 56.2%; background=
+-position: center; background-color: #F1F1F1; background-repeat: no-repeat =
+!important; background-size: cover !important; height: 0px !important; max-=
+height: 0px !important; overflow: hidden !important; width: 100% !important=
+; border-radius: 12px !important;" width=3D"100% !important" height=3D"0 !i=
+mportant" bgcolor=3D"#F1F1F1"></td></tr></tbody></table></div><table cellpa=
+dding=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;width:=
+100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: =
+0px !important;"><td class=3D"outlook-only" style=3D"display: none;"><img a=
+lt=3D"Luxurious 5B/3BA home Nob Hill!" src=3D"https://a0.muscache.com/im/pi=
+ctures/hosting/Hosting-U3RheVN1cHBseUxpc3Rpbmc6MTE5MzUzNzM2OTAwMjA3MDA2NQ%3=
+D%3D/original/f395baea-883b-4326-b172-f91b49714ddc.jpeg" style=3D"border: 0=
+ !important;"></td></tr></tbody></table></a></td></tr></tbody></table><div =
+class=3D"_6z3til" style=3D"overflow-wrap: break-word !important;"><table ce=
+llpadding=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;wi=
+dth:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"marg=
+in: 0px !important;"><td style=3D"padding-left: 48px; padding-right: 48px; =
+padding-top: 24px;" class=3D"outlook-row-container left_6_2 right_6_2"></td=
+></tr></tbody></table><table cellpadding=3D"0" class style=3D"border-collap=
+se:collapse;border-spacing:0;width:100%" role=3D"presentation"><tbody><tr c=
+lass=3D"_16pg94n" style=3D"margin: 0px !important;"><td style=3D"padding-to=
+p:24px" class><table cellpadding=3D"0" class style=3D"border-collapse:colla=
+pse;border-spacing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"=
+_16pg94n" style=3D"margin: 0px !important;"><td style=3D"padding-left: 48px=
+; padding-right: 48px; padding-bottom: 8px;" class=3D"outlook-row-container=
+ left_6_2 right_6_2"><div><h2 class=3D"heading2" style=3D"font-size: 22px; =
+line-height: 26px; color: #222222; font-family: Cereal, Helvetica Neue, Hel=
+vetica, sans-serif; font-weight: 800; margin: 0;">Reservation details</h2><=
+/div></td></tr></tbody></table><table cellpadding=3D"0" class style=3D"bord=
+er-collapse:collapse;border-spacing:0;width:100%" role=3D"presentation"><tb=
+ody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td class=3D"o=
+utlook-row-container left_6_2 right_6_2" style=3D"padding-left: 48px; paddi=
+ng-right: 48px;"><p aria-hidden=3D"false" class=3D"ui-xlarge" style=3D"font=
+-size: 18px; line-height: 24px; font-family: Cereal, Helvetica Neue, Helvet=
+ica, sans-serif; margin: 0 !important;">Luxurious 5B/3BA home Nob Hill!</p>=
+<p aria-hidden=3D"false" class=3D"ui-xlarge" style=3D"font-size: 18px; line=
+-height: 24px; font-family: Cereal, Helvetica Neue, Helvetica, sans-serif; =
+margin: 0 !important;">Rental unit - Entire home/flat hosted by Isabella</p=
+></td></tr></tbody></table><table cellpadding=3D"0" class style=3D"border-c=
+ollapse:collapse;border-spacing:0;width:100%" role=3D"presentation"><tbody>=
+<tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td style=3D"paddi=
+ng-left: 48px; padding-right: 48px; padding-bottom: 16px; padding-top: 24px=
+;" class=3D"outlook-row-container left_6_2 right_6_2"><div><h3 class=3D"hea=
+ding3" style=3D"font-size: 18px; line-height: 22px; color: #222222; font-fa=
+mily: Cereal, Helvetica Neue, Helvetica, sans-serif; font-weight: 800; marg=
+in: 0;">Guests</h3></div><p aria-hidden=3D"false" class=3D"ui-xlarge" style=
+=3D"font-size: 18px; line-height: 24px; font-family: Cereal, Helvetica Neue=
+, Helvetica, sans-serif; margin: 0 !important;">10 guests</p></td></tr></tb=
+ody></table></td></tr></tbody></table><table cellpadding=3D"0" class style=
+=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"presentat=
+ion"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td st=
+yle=3D"padding-left: 48px; padding-right: 48px; padding-bottom: 24px;" clas=
+s=3D"outlook-row-container left_6_2 right_6_2"><table cellpadding=3D"0" cla=
+ss style=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"p=
+resentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;=
+"><td class><div class=3D"top_3_2" style=3D"padding-top: 24px;"><table cell=
+padding=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;widt=
+h:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin=
+: 0px !important;"><td style=3D"overflow:hidden" class><table cellpadding=
+=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;width:100%;=
+table-layout:fixed" role=3D"presentation"><tbody><tr class=3D"_16pg94n" sty=
+le=3D"margin: 0px !important;"><td valign=3D"top" width=3D"50%" class=3D"ce=
+ll-left" style=3D"padding-right: 8px;"><div class=3D"_1mnp9e4" style=3D"bor=
+der-width: 1px !important; border-style: solid !important; border-color: #D=
+DDDDD !important; border-radius: 8px !important;"><div class=3D"_8jmbbt" st=
+yle=3D"border-bottom: 1px solid #DDDDDD !important; padding: 16px !importan=
+t; padding-top: 12px !important; padding-bottom: 12px !important;"><table c=
+ellpadding=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;w=
+idth:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"mar=
+gin: 0px !important;"><td style=3D"height: 12px; width: 12px; padding-right=
+: 8px;" class=3D"width_12_10 height_12_10" width=3D"12" height=3D"12"><img =
+alt class=3D"width_12_10 height_12_10" src=3D"https://a0.muscache.com/pictu=
+res/44da4fa6-f192-46ed-a7af-f55174c286f1.jpg" style=3D"height: 12px; width:=
+ 12px; border: 0 !important;" width=3D"12" height=3D"12"></td><td class><h3=
+ class=3D"_16pg94n" style=3D"margin: 0px !important;"><p aria-hidden=3D"fal=
+se" class=3D"ui-small" style=3D"font-size: 12px; line-height: 16px; font-we=
+ight: 800; font-family: Cereal, Helvetica Neue, Helvetica, sans-serif; marg=
+in: 0 !important;">Check-In</p></h3></td></tr></tbody></table></div><div cl=
+ass=3D"_1x0fg6n" style=3D"padding: 16px !important;"><div><p class=3D"headi=
+ng-level-2-3" style=3D"font-size: 22px; line-height: 26px; color: #222222; =
+font-family: Cereal, Helvetica Neue, Helvetica, sans-serif; font-weight: 80=
+0; margin: 0 !important;">Sunday</p></div><table cellpadding=3D"0" class st=
+yle=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"presen=
+tation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td=
+ style=3D"padding-top:8px" class><p aria-hidden=3D"false" class=3D"ui-xlarg=
+e" style=3D"font-size: 18px; line-height: 24px; font-family: Cereal, Helvet=
+ica Neue, Helvetica, sans-serif; margin: 0 !important;">22 September 2024</=
+p></td></tr></tbody></table></div></div></td><td valign=3D"top" width=3D"50=
+%" class=3D"cell-right" style=3D"padding-left: 8px;"><div class=3D"_1mnp9e4=
+" style=3D"border-width: 1px !important; border-style: solid !important; bo=
+rder-color: #DDDDDD !important; border-radius: 8px !important;"><div class=
+=3D"_8jmbbt" style=3D"border-bottom: 1px solid #DDDDDD !important; padding:=
+ 16px !important; padding-top: 12px !important; padding-bottom: 12px !impor=
+tant;"><table cellpadding=3D"0" class style=3D"border-collapse:collapse;bor=
+der-spacing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94=
+n" style=3D"margin: 0px !important;"><td style=3D"height: 12px; width: 12px=
+; padding-right: 8px;" class=3D"width_12_10 height_12_10" width=3D"12" heig=
+ht=3D"12"><img alt class=3D"width_12_10 height_12_10" src=3D"https://a0.mus=
+cache.com/pictures/1167b82c-affb-4cbc-bfdc-efaa1542492f.jpg" style=3D"heigh=
+t: 12px; width: 12px; border: 0 !important;" width=3D"12" height=3D"12"></t=
+d><td class><h3 class=3D"_16pg94n" style=3D"margin: 0px !important;"><p ari=
+a-hidden=3D"false" class=3D"ui-small" style=3D"font-size: 12px; line-height=
+: 16px; font-weight: 800; font-family: Cereal, Helvetica Neue, Helvetica, s=
+ans-serif; margin: 0 !important;">Checkout</p></h3></td></tr></tbody></tabl=
+e></div><div class=3D"_1x0fg6n" style=3D"padding: 16px !important;"><div><p=
+ class=3D"heading-level-2-3" style=3D"font-size: 22px; line-height: 26px; c=
+olor: #222222; font-family: Cereal, Helvetica Neue, Helvetica, sans-serif; =
+font-weight: 800; margin: 0 !important;">Tuesday</p></div><table cellpaddin=
+g=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;width:100%=
+" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px =
+!important;"><td style=3D"padding-top:8px" class><p aria-hidden=3D"false" c=
+lass=3D"ui-xlarge" style=3D"font-size: 18px; line-height: 24px; font-family=
+: Cereal, Helvetica Neue, Helvetica, sans-serif; margin: 0 !important;">22 =
+October 2024</p></td></tr></tbody></table></div></div></td></tr></tbody></t=
+able></td></tr></tbody></table></div></td></tr></tbody></table></td></tr></=
+tbody></table></div><table cellpadding=3D"0" class style=3D"border-collapse=
+:collapse;border-spacing:0;width:100%" role=3D"presentation"><tbody><tr cla=
+ss=3D"_16pg94n" style=3D"margin: 0px !important;"><td style=3D"padding-left=
+: 48px; padding-right: 48px; padding-top: 8px;" class=3D"outlook-row-contai=
+ner left_6_2 right_6_2"><table width=3D"100%" role=3D"presentation"><tbody>=
+<tr><td class=3D"_1rd2b9oa" style=3D"padding: 0px !important; border-top: 1=
+px solid #DDDDDD !important;" width=3D"100%" role=3D"separator"></td></tr><=
+/tbody></table></td></tr></tbody></table><table cellpadding=3D"0" class sty=
+le=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"present=
+ation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td =
+class><table cellpadding=3D"0" class style=3D"border-collapse:collapse;bord=
+er-spacing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n=
+" style=3D"margin: 0px !important;"><td class=3D"outlook-row-container left=
+_6_2 right_6_2" style=3D"padding-left: 48px; padding-right: 48px;"><table c=
+ellpadding=3D"0" class style=3D"border-collapse:collapse;border-spacing:0;w=
+idth:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"mar=
+gin: 0px !important;"><td class=3D"bottom_4_3 top_4_3" style=3D"padding-bot=
+tom: 32px; padding-top: 32px;"><table cellpadding=3D"0" class style=3D"bord=
+er-collapse:collapse;border-spacing:0;width:100%" role=3D"presentation"><tb=
+ody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td align=3D"l=
+eft" width=3D"100%" class><img data-eon-role=3D"image" data-eon-prop=3D"src=
+" alt=3D"Airbnb" src=3D"https://a0.muscache.com/pictures/d5e805e2-dfa8-4a7d=
+-b06f-c5910be9a725.jpg" style=3D"height: 32px; width: 32px; border: 0 !impo=
+rtant;" width=3D"32" height=3D"32"></td><td class><table cellpadding=3D"0" =
+class style=3D"border-collapse:collapse;border-spacing:0;width:100%" role=
+=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !impor=
+tant;"><td class=3D"left_1-25_1-5" style=3D"padding-left: 10px;"><a target=
+=3D"_self" rel=3D"noreferrer" data-eon-role=3D"link" data-eon-prop=3D"href"=
+ href=3D"https://www.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2F=
+naW5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&amp;u=
+rl=3Dhttps%3A%2F%2Fwww.facebook.com%2Fairbnb" class=3D"regular underline" s=
+tyle=3D"font-family: Cereal, Helvetica Neue, Helvetica; font-size: 18px; li=
+ne-height: 28px; font-weight: 800; color: #222222; text-decoration: underli=
+ne !important;"><img alt=3D"Facebook" src=3D"https://a0.muscache.com/pictur=
+es/f6cf515c-976d-4a6a-a7be-1843301d6b14.jpg" class=3D"width_20_24" style=3D=
+"width: 20px; border: 0 !important;" width=3D"20"></a></td><td class=3D"lef=
+t_1-25_1-5" style=3D"padding-left: 10px;"><a target=3D"_self" rel=3D"norefe=
+rrer" data-eon-role=3D"link" data-eon-prop=3D"href" href=3D"https://www.air=
+bnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&am=
+p;euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&amp;url=3Dhttps%3A%2F%2Fwww.i=
+nstagram.com%2Fairbnb" class=3D"regular underline" style=3D"font-family: Ce=
+real, Helvetica Neue, Helvetica; font-size: 18px; line-height: 28px; font-w=
+eight: 800; color: #222222; text-decoration: underline !important;"><img al=
+t=3D"Instagram" src=3D"https://a0.muscache.com/im/pictures/mediaverse/canva=
+s-email/original/d98da6f9-52e5-47f8-9f15-134acfbf5e4b.png" class=3D"width_2=
+0_24" style=3D"width: 20px; border: 0 !important;" width=3D"20"></a></td><t=
+d class=3D"left_1-25_1-5" style=3D"padding-left: 10px;"><a target=3D"_self"=
+ rel=3D"noreferrer" data-eon-role=3D"link" data-eon-prop=3D"href" href=3D"h=
+ttps://www.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld=
+19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&amp;url=3Dhttps=
+%3A%2F%2Ftwitter.com%2FAirbnb" class=3D"regular underline" style=3D"font-fa=
+mily: Cereal, Helvetica Neue, Helvetica; font-size: 18px; line-height: 28px=
+; font-weight: 800; color: #222222; text-decoration: underline !important;"=
+><img alt=3D"Twitter" src=3D"https://a0.muscache.com/im/pictures/mediaverse=
+/canvas-email/original/126739e6-d2c8-47eb-82d5-c26299302f2f.png" class=3D"w=
+idth_20_24" style=3D"width: 20px; border: 0 !important;" width=3D"20"></a><=
+/td></tr></tbody></table></td></tr></tbody></table><table cellpadding=3D"0"=
+ class style=3D"border-collapse:collapse;border-spacing:0;width:100%" role=
+=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !impor=
+tant;"><td style=3D"padding-top:24px" class><table cellpadding=3D"0" class =
+style=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"pres=
+entation"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><=
+td class><p class=3D"_jmqnks" style=3D"color: #222222 !important; font-fami=
+ly: Cereal, Helvetica Neue, Helvetica, sans-serif !important; font-size: 14=
+px !important; font-weight: 400 !important; line-height: 18px !important; m=
+argin: 0px !important;">Airbnb Ireland UC</p></td></tr></tbody></table><tab=
+le cellpadding=3D"0" class style=3D"border-collapse:collapse;border-spacing=
+:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=3D=
+"margin: 0px !important;"><td class><p class=3D"_jmqnks" style=3D"color: #2=
+22222 !important; font-family: Cereal, Helvetica Neue, Helvetica, sans-seri=
+f !important; font-size: 14px !important; font-weight: 400 !important; line=
+-height: 18px !important; margin: 0px !important;">8 Hanover Quay</p></td><=
+/tr></tbody></table><table cellpadding=3D"0" class style=3D"border-collapse=
+:collapse;border-spacing:0;width:100%" role=3D"presentation"><tbody><tr cla=
+ss=3D"_16pg94n" style=3D"margin: 0px !important;"><td class><p class=3D"_jm=
+qnks" style=3D"color: #222222 !important; font-family: Cereal, Helvetica Ne=
+ue, Helvetica, sans-serif !important; font-size: 14px !important; font-weig=
+ht: 400 !important; line-height: 18px !important; margin: 0px !important;">=
+Dublin 2, Ireland</p></td></tr></tbody></table></td></tr></tbody></table><t=
+able cellpadding=3D"0" class style=3D"border-collapse:collapse;border-spaci=
+ng:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n" style=
+=3D"margin: 0px !important;"><td class=3D"top_4_3" style=3D"padding-top: 32=
+px;"><table cellpadding=3D"0" class style=3D"border-collapse:collapse;borde=
+r-spacing:0;width:100%" role=3D"presentation"><tbody><tr class=3D"_16pg94n"=
+ style=3D"margin: 0px !important;"><td class><p class=3D"_1mzs5sdg" style=
+=3D"color: #222222 !important; font-family: Cereal, Helvetica Neue, Helveti=
+ca, sans-serif !important; font-size: 14px !important; line-height: 18px !i=
+mportant; margin: 0px !important; font-weight: 800 !important;">Get the Air=
+bnb app</p></td></tr></tbody></table><table cellpadding=3D"0" class style=
+=3D"border-collapse:collapse;border-spacing:0;width:100%" role=3D"presentat=
+ion"><tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td st=
+yle=3D"padding-top:16px" class><table cellpadding=3D"0" class style=3D"bord=
+er-collapse:collapse;border-spacing:0;width:100%" role=3D"presentation"><tb=
+ody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td style=3D"p=
+adding-left:0px" class><a target=3D"_blank" rel=3D"noreferrer" aria-label=
+=3D"App Store" data-eon-role=3D"link" data-eon-prop=3D"href" href=3D"https:=
+//www.airbnb.co.uk/external_link?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZX=
+NzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579&amp;url=3Dhttps%3A%2=
+F%2Fairbnb.sng.link%2FA6f9up%2Fdvs6%3F_smtype%3D3%26pcid%3D.pi80.pkaG9tZXNf=
+bWVzc2FnaW5nL25ld19tZXNzYWdl" class=3D"regular underline" style=3D"font-fam=
+ily: Cereal, Helvetica Neue, Helvetica; font-size: 18px; line-height: 28px;=
+ font-weight: 800; color: #222222; text-decoration: underline !important;">=
+<img alt=3D"App Store" height=3D"40" src=3D"https://a0.muscache.com/picture=
+s/b34eaece-11bc-425b-956a-ee0fb1ab1501.jpg" width=3D"119.66" style=3D"borde=
+r: 0 !important;"></a></td><td style=3D"padding-left:12px" class><a target=
+=3D"_blank" rel=3D"noreferrer" aria-label=3D"Google Play" data-eon-role=3D"=
+link" data-eon-prop=3D"href" href=3D"https://www.airbnb.co.uk/external_link=
+?c=3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-=
+ebf8-ef9a-cba7f9c2c579&amp;url=3Dhttps%3A%2F%2Fairbnb.sng.link%2FA6f9up%2Fq=
+h0lc%3Fid%3Dcom.airbnb.android%26pcid%3D.pi80.pkaG9tZXNfbWVzc2FnaW5nL25ld19=
+tZXNzYWdl" class=3D"regular underline" style=3D"font-family: Cereal, Helvet=
+ica Neue, Helvetica; font-size: 18px; line-height: 28px; font-weight: 800; =
+color: #222222; text-decoration: underline !important;"><img alt=3D"Google =
+Play" height=3D"40" src=3D"https://a0.muscache.com/pictures/8c1b684f-e6ed-4=
+21d-9308-aa782c378d6e.jpg" width=3D"130" style=3D"border: 0 !important;"></=
+a></td><td width=3D"50%" class></td></tr></tbody></table></td></tr></tbody>=
+</table></td></tr></tbody></table><table cellpadding=3D"0" class style=3D"b=
+order-collapse:collapse;border-spacing:0;width:100%" role=3D"presentation">=
+<tbody><tr class=3D"_16pg94n" style=3D"margin: 0px !important;"><td class=
+=3D"top_4_3" style=3D"padding-top: 32px;"><div class=3D"small" style=3D"fon=
+t-size: 14px; line-height: 20px; margin: 0;"><p class=3D"small" style=3D"fo=
+nt-size: 14px; line-height: 20px; font-family: Cereal, Helvetica Neue, Helv=
+etica, sans-serif; margin: 0 !important;">Update your <a href=3D"https://ww=
+w.airbnb.co.uk/account-settings/notifications?c=3D.pi80.pkaG9tZXNfbWVzc2Fna=
+W5nL25ld19tZXNzYWdl&amp;euid=3D7e892d74-33f4-ebf8-ef9a-cba7f9c2c579" style=
+=3D"font-family: Cereal, Helvetica Neue, Helvetica; font-weight: 500; color=
+: #222222 !important;">email preferences</a> to choose which emails you get=
+ or <a href=3D"https://www.airbnb.co.uk/account-settings/email-unsubscribe?=
+email_type=3Dfalse&amp;mac=3DQJmdxe1CU5PXPvaEGjcsQ6TT5b4%3D&amp;token=" s=
+tyle=3D"font-family: Cereal, Helvetica Neue, Helvetica; font-weight: 500; c=
+olor: #222222 !important;">unsubscribe</a> from this type of email.</p></di=
+v></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></t=
+able></td></tr></tbody></table></div></td></tr></tbody></table></div></div>=
+<div style=3D"color:white;display:none !important;font:15px courier;line-he=
+ight:0;white-space:nowrap">=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
+=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0</di=
+v></body></html>
+--49a8ec9b277e6a96e7373b3e4727df74d25ab6158dd0a8fb1221118a1304--
+`;
diff --git a/packages/apis/tests/extract_substr.test.ts b/packages/apis/tests/extract_substr.test.ts
new file mode 100644
index 0000000..028d1e1
--- /dev/null
+++ b/packages/apis/tests/extract_substr.test.ts
@@ -0,0 +1,180 @@
+import init, { extractSubstrIdxes, extractSubstr } from '../pkg/zk_regex_apis';
+import airbnbEml from './airbnb_eml';
+
+console.time('wasm init');
+init()
+    .then(() => {
+        console.timeEnd('wasm init');
+    })
+    .catch(console.error);
+
+describe('Extract substr test suite', async () => {
+    // Wait for wasm to init
+    await new Promise(r => setTimeout(r, 300));
+
+    test('Should extract indicies from object input', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: true,
+                    regex_def: 'Hello'
+                }
+            ]
+        };
+        const result = extractSubstrIdxes(airbnbEml, parts, false);
+        expect(result.length).toBe(1);
+        expect(result[0].length).toBe(2);
+    });
+
+    test('Should extract indicies from object input, hide private', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: true,
+                    regex_def: 'Hello '
+                },
+                {
+                    is_public: false,
+                    regex_def: 'guys!'
+                }
+            ]
+        };
+        const result = extractSubstrIdxes(airbnbEml, parts, false);
+        expect(result.length).toBe(1);
+        expect(result[0].length).toBe(2);
+    });
+
+    test('Should extract indicies from object input, reveal private', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: true,
+                    regex_def: 'Hello '
+                },
+                {
+                    is_public: false,
+                    regex_def: 'guys!'
+                }
+            ]
+        };
+        const result = extractSubstrIdxes(airbnbEml, parts, true);
+        expect(result.length).toBe(2);
+        expect(result[0].length).toBe(2);
+        expect(result[1].length).toBe(2);
+    });
+
+    test('Should extract indicies from stringified input', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: false,
+                    regex_def: 'Hello'
+                }
+            ]
+        };
+        const result = extractSubstrIdxes(
+            airbnbEml,
+            JSON.stringify(parts),
+            true
+        );
+        expect(result.length).toBe(1);
+        expect(result[0].length).toBe(2);
+    });
+
+    test('Should throw helpful js error on wrong object input', () => {
+        const parts = {
+            wrong: 'input'
+        };
+        try {
+            extractSubstrIdxes(airbnbEml, parts, false);
+        } catch (err) {
+            expect(err).toBe('Error: missing field `parts`');
+            return;
+        }
+        throw new Error('Did not catch wrong input');
+    });
+
+    test('Should throw helpful js error on wrong stringified input', () => {
+        const parts = {
+            wrong: 'input'
+        };
+        try {
+            extractSubstrIdxes(airbnbEml, JSON.stringify(parts), false);
+        } catch (err) {
+            const includesErr = err.includes(
+                'Failed to parse JSON string: missing field `parts`'
+            );
+            expect(includesErr).toBe(true);
+            return;
+        }
+        throw new Error('Did not catch wrong input');
+    });
+
+    test('Should throw helpful js error on wrong object input 2', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: false
+                }
+            ]
+        };
+        try {
+            extractSubstrIdxes(airbnbEml, parts, false);
+        } catch (err) {
+            expect(err).toBe('Error: missing field `regex_def`');
+            return;
+        }
+        throw new Error('Did not catch wrong input');
+    });
+
+    test('Should throw helpful js error on no found result', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: true,
+                    regex_def: 'Hello'
+                },
+                {
+                    is_public: false,
+                    regex_def: 'yall!'
+                }
+            ]
+        };
+        try {
+            extractSubstrIdxes(airbnbEml, parts, false);
+        } catch (err) {
+            const includes = err.includes(
+                'Failed to extract indxes: Substring of the entire regex (Hello)(yall!) is not found given input_str'
+            );
+            expect(includes).toBe(true);
+            return;
+        }
+        throw new Error('Did not throw an error');
+    });
+
+    test('extractSubstr should return actual matched string', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: true,
+                    regex_def: 'Hello'
+                }
+            ]
+        };
+        const strs = extractSubstr(airbnbEml, parts, false);
+        expect(strs[0]).toBe('Hello');
+    });
+
+    test('extractSubstr should return an empty array on all private fields', () => {
+        const parts = {
+            parts: [
+                {
+                    is_public: false,
+                    regex_def: 'Hello'
+                }
+            ]
+        };
+        const strs = extractSubstr(airbnbEml, parts, false);
+        expect(strs.length).toBe(0);
+    });
+});
diff --git a/packages/circom/package.json b/packages/circom/package.json
index d9996b1..6aa364f 100644
--- a/packages/circom/package.json
+++ b/packages/circom/package.json
@@ -1,40 +1,40 @@
 {
-  "name": "@zk-email/zk-regex-circom",
-  "version": "2.2.0",
-  "license": "MIT",
-  "description": "regex verification circuits in circom for common regexes, generated with the compiler in [zk-regex](https://github.com/zkemail/zk-regex/tree/main).",
-  "contributors": [
-    "Javier Su <javier.su.weijie@gmail.com>",
-    "Kata Choi <kata.choi@gmail.com>",
-    "Sora Suegami <suegamisora@gmail.com>",
-    "Yush G <aayushg@mit.edu>",
-    "Aditya Bisht <adityabisht64@gmail.com>"
-  ],
-  "scripts": {
-    "test": "jest",
-    "install": "echo",
-    "build": "echo",
-    "upload-binary": "echo"
-  },
-  "dependencies": {
-    "commander": "^11.0.0",
-    "snarkjs": "^0.7.0"
-  },
-  "devDependencies": {
-    "@types/jest": "^29.5.4",
-    "chai": "^4.3.7",
-    "circom_tester": "^0.0.20",
-    "circomlib": "^2.0.5",
-    "circomlibjs": "^0.1.2",
-    "ffjavascript": "^0.2.59",
-    "jest": "^29.5.0",
-    "mocha": "^10.2.0"
-  },
-  "babel": {
-    "presets": [
-      [
-        "@babel/preset-env"
-      ]
-    ]
-  }
-}
\ No newline at end of file
+    "name": "@zk-email/zk-regex-circom",
+    "version": "2.2.0",
+    "license": "MIT",
+    "description": "regex verification circuits in circom for common regexes, generated with the compiler in [zk-regex](https://github.com/zkemail/zk-regex/tree/main).",
+    "contributors": [
+        "Javier Su <javier.su.weijie@gmail.com>",
+        "Kata Choi <kata.choi@gmail.com>",
+        "Sora Suegami <suegamisora@gmail.com>",
+        "Yush G <aayushg@mit.edu>",
+        "Aditya Bisht <adityabisht64@gmail.com>"
+    ],
+    "scripts": {
+        "test": "jest tests/email_domain.test.js",
+        "install": "echo",
+        "build": "echo",
+        "upload-binary": "echo"
+    },
+    "dependencies": {
+        "commander": "^11.0.0",
+        "snarkjs": "^0.7.0"
+    },
+    "devDependencies": {
+        "@types/jest": "^29.5.4",
+        "chai": "^4.3.7",
+        "circom_tester": "^0.0.20",
+        "circomlib": "^2.0.5",
+        "circomlibjs": "^0.1.2",
+        "ffjavascript": "^0.2.59",
+        "jest": "^29.5.0",
+        "mocha": "^10.2.0"
+    },
+    "babel": {
+        "presets": [
+            [
+                "@babel/preset-env"
+            ]
+        ]
+    }
+}

From fc072a693037de4650e3c708d585da5fdc12d1cd Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 16:54:09 +0700
Subject: [PATCH 2/7] fix: no need to init wasm

---
 packages/apis/tests/extract_substr.test.ts | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/packages/apis/tests/extract_substr.test.ts b/packages/apis/tests/extract_substr.test.ts
index 028d1e1..6aec6ce 100644
--- a/packages/apis/tests/extract_substr.test.ts
+++ b/packages/apis/tests/extract_substr.test.ts
@@ -1,17 +1,7 @@
-import init, { extractSubstrIdxes, extractSubstr } from '../pkg/zk_regex_apis';
+import { extractSubstrIdxes, extractSubstr } from '../pkg/zk_regex_apis';
 import airbnbEml from './airbnb_eml';
 
-console.time('wasm init');
-init()
-    .then(() => {
-        console.timeEnd('wasm init');
-    })
-    .catch(console.error);
-
 describe('Extract substr test suite', async () => {
-    // Wait for wasm to init
-    await new Promise(r => setTimeout(r, 300));
-
     test('Should extract indicies from object input', () => {
         const parts = {
             parts: [

From 13cf3bb62861f480761e7831925f1d3dd5e71363 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 18:59:51 +0700
Subject: [PATCH 3/7] fix: fix tests

---
 .github/workflows/test.yaml                   |  41 ++++++-
 package.json                                  | 108 +++++++++---------
 packages/apis/package.json                    |   2 +-
 ..._substr.test.ts => extract_substr.test.js} |   0
 packages/circom/package.json                  |   2 +-
 packages/compiler/package.json                |  50 ++++----
 6 files changed, 116 insertions(+), 87 deletions(-)
 rename packages/apis/tests/{extract_substr.test.ts => extract_substr.test.js} (100%)

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 3e8866e..f0ec741 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -1,4 +1,4 @@
-name: Test
+name: Build and Test
 
 on: [push]
 
@@ -8,10 +8,10 @@ jobs:
         steps:
             - name: Checkout code
               uses: actions/checkout@v2
-            - name: Setup Bun
-              uses: oven-sh/setup-bun@v1
+            - name: Setup Node.js
+              uses: actions/setup-node@v3
               with:
-                  bun-version: latest
+                  node-version: 18
             - name: Setup Rust
               uses: actions-rs/toolchain@v1
               with:
@@ -22,7 +22,36 @@ jobs:
               run: cargo install wasm-pack
             - name: Download circom v2.1.9 (Linux)
               run: wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/local/bin/circom && chmod +x /usr/local/bin/circom
+            - name: Install yarn
+              run: npm install -g yarn
             - name: Install dependencies
-              run: bun install
+              run: yarn install --immutable
+            - name: Install bun
+              uses: oven-sh/setup-bun@v1
+              with:
+                  bun-version: latest
+            - name: Cache build artifacts
+              uses: actions/cache@v2
+              with:
+                  path: |
+                      ./*
+                  key: ${{ runner.os }}-build-${{ github.sha }}
+
+    test:
+        needs: build
+        runs-on: ubuntu-latest
+        steps:
+            - name: Restore cached build artifacts
+              uses: actions/cache@v2
+              with:
+                  path: |
+                      ./*
+                  key: ${{ runner.os }}-build-${{ github.sha }}
+            - name: Setup Node.js
+              uses: actions/setup-node@v3
+              with:
+                  node-version: 18
+            - name: Install yarn
+              run: npm install -g yarn
             - name: Run tests
-              run: bun test
+              run: yarn test
diff --git a/package.json b/package.json
index 83e1f03..fd966ef 100644
--- a/package.json
+++ b/package.json
@@ -1,55 +1,55 @@
 {
-  "name": "@zk-email/zk-regex",
-  "version": "2.1.1",
-  "private": true,
-  "description": "zk regex circuit for content attestation",
-  "main": "pkg/zk_regex_compiler_bg.wasm",
-  "workspaces": [
-    "packages/*"
-  ],
-  "contributors": [
-    "Sora Suegami <suegamisora@gmail.com>",
-    "Yush G <aayushg@mit.edu>",
-    "Javier Su <javier.su.weijie@gmail.com>",
-    "Kata Choi <kata.choi@gmail.com>",
-    "Aditya Bisht <adityabisht64@gmail.com>"
-  ],
-  "scripts": {
-    "install": "yarn workspaces -pt run install",
-    "build": "yarn workspaces -pt run build",
-    "postinstall": "cargo install --path ./packages/compiler",
-    "test": "yarn workspaces -pt run test",
-    "upload-binary": "yarn workspaces -pt run upload-binary"
-  },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/zk-email-verify/zk-regex.git"
-  },
-  "keywords": [
-    "circom",
-    "circuit",
-    "regex",
-    "zk",
-    "attestation"
-  ],
-  "license": "MIT",
-  "bugs": {
-    "url": "https://github.com/zk-email-verify/zk-regex/issues"
-  },
-  "homepage": "https://github.com/zk-email-verify/zk-regex#readme",
-  "devDependencies": {
-    "@babel/core": "^7.22.5",
-    "@babel/plugin-transform-modules-commonjs": "^7.22.15",
-    "@babel/preset-env": "^7.22.2",
-    "@babel/preset-react": "^7.22.0",
-    "@types/jest": "^29.5.4",
-    "babel-jest": "^29.5.0",
-    "babel-preset-jest": "^29.5.0",
-    "jest": "^29.5.0",
-    "prettier": "^3.0.0",
-    "prettier-plugin-solidity": "^1.1.3"
-  },
-  "engines": {
-    "yarn": "^1.22.0"
-  }
-}
\ No newline at end of file
+    "name": "@zk-email/zk-regex",
+    "version": "2.1.1",
+    "private": true,
+    "description": "zk regex circuit for content attestation",
+    "main": "pkg/zk_regex_compiler_bg.wasm",
+    "workspaces": [
+        "packages/*"
+    ],
+    "contributors": [
+        "Sora Suegami <suegamisora@gmail.com>",
+        "Yush G <aayushg@mit.edu>",
+        "Javier Su <javier.su.weijie@gmail.com>",
+        "Kata Choi <kata.choi@gmail.com>",
+        "Aditya Bisht <adityabisht64@gmail.com>"
+    ],
+    "scripts": {
+        "install": "yarn workspaces -pt run install",
+        "build": "yarn workspaces -pt run build",
+        "postinstall": "cargo install --path ./packages/compiler",
+        "test": "yarn workspaces -pt run test",
+        "upload-binary": "yarn workspaces -pt run upload-binary"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/zk-email-verify/zk-regex.git"
+    },
+    "keywords": [
+        "circom",
+        "circuit",
+        "regex",
+        "zk",
+        "attestation"
+    ],
+    "license": "MIT",
+    "bugs": {
+        "url": "https://github.com/zk-email-verify/zk-regex/issues"
+    },
+    "homepage": "https://github.com/zk-email-verify/zk-regex#readme",
+    "devDependencies": {
+        "@babel/core": "^7.22.5",
+        "@babel/plugin-transform-modules-commonjs": "^7.22.15",
+        "@babel/preset-env": "^7.22.2",
+        "@babel/preset-react": "^7.22.0",
+        "@types/jest": "^29.5.4",
+        "babel-jest": "^29.5.0",
+        "babel-preset-jest": "^29.5.0",
+        "jest": "^29.5.0",
+        "prettier": "^3.0.0",
+        "prettier-plugin-solidity": "^1.1.3"
+    },
+    "engines": {
+        "yarn": "^1.22.0"
+    }
+}
diff --git a/packages/apis/package.json b/packages/apis/package.json
index 19ee320..21e355b 100644
--- a/packages/apis/package.json
+++ b/packages/apis/package.json
@@ -19,7 +19,7 @@
         "build-release": "npm run build --",
         "install": "npm run build-debug",
         "install-release": "npm run build-release",
-        "test": "cargo test && wasm-pack test --node",
+        "test": "cargo test && wasm-pack test --node && bun test",
         "test-js": "jest",
         "upload-binary": "wasm-pack publish -t nodejs"
     },
diff --git a/packages/apis/tests/extract_substr.test.ts b/packages/apis/tests/extract_substr.test.js
similarity index 100%
rename from packages/apis/tests/extract_substr.test.ts
rename to packages/apis/tests/extract_substr.test.js
diff --git a/packages/circom/package.json b/packages/circom/package.json
index 6aa364f..e3cd071 100644
--- a/packages/circom/package.json
+++ b/packages/circom/package.json
@@ -11,7 +11,7 @@
         "Aditya Bisht <adityabisht64@gmail.com>"
     ],
     "scripts": {
-        "test": "jest tests/email_domain.test.js",
+        "test": "jest",
         "install": "echo",
         "build": "echo",
         "upload-binary": "echo"
diff --git a/packages/compiler/package.json b/packages/compiler/package.json
index f8cce51..fbbb023 100644
--- a/packages/compiler/package.json
+++ b/packages/compiler/package.json
@@ -1,26 +1,26 @@
 {
-  "name": "@zk-email/zk-regex-compiler",
-  "version": "2.2.0",
-  "description": "A compiler to generate a regex verification circuit in circom from a user-defined regex. Please check [zk-regex](https://github.com/zkemail/zk-regex/tree/main) for the detail.",
-  "contributors": [
-    "Javier Su <javier.su.weijie@gmail.com>",
-    "Kata Choi <kata.choi@gmail.com>",
-    "Sora Suegami <suegamisora@gmail.com>",
-    "Yush G <aayushg@mit.edu>",
-    "Aditya Bisht <adityabisht64@gmail.com>"
-  ],
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/zkemail/zk-regex.git"
-  },
-  "scripts": {
-    "build": "cargo build && wasm-pack build --target nodejs --out-dir ./pkg/",
-    "build-debug": "npm run build --",
-    "build-release": "npm run build -- --release",
-    "install": "npm run build-release",
-    "install-debug": "npm run build-debug",
-    "test": "cargo test && wasm-pack test --node",
-    "upload-binary": "wasm-pack publish -t nodejs"
-  },
-  "license": "MIT"
-}
\ No newline at end of file
+    "name": "@zk-email/zk-regex-compiler",
+    "version": "2.2.0",
+    "description": "A compiler to generate a regex verification circuit in circom from a user-defined regex. Please check [zk-regex](https://github.com/zkemail/zk-regex/tree/main) for the detail.",
+    "contributors": [
+        "Javier Su <javier.su.weijie@gmail.com>",
+        "Kata Choi <kata.choi@gmail.com>",
+        "Sora Suegami <suegamisora@gmail.com>",
+        "Yush G <aayushg@mit.edu>",
+        "Aditya Bisht <adityabisht64@gmail.com>"
+    ],
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/zkemail/zk-regex.git"
+    },
+    "scripts": {
+        "build": "cargo build && wasm-pack build --target nodejs --out-dir ./pkg/",
+        "build-debug": "npm run build --",
+        "build-release": "npm run build -- --release",
+        "install": "npm run build-release",
+        "install-debug": "npm run build-debug",
+        "test": "cargo test && wasm-pack test --node",
+        "upload-binary": "wasm-pack publish -t nodejs"
+    },
+    "license": "MIT"
+}

From cff4dd8a9e99308b3c8b49283e01db5ee27ab4d7 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 19:12:25 +0700
Subject: [PATCH 4/7] fix: wait for wasm to initialize

---
 packages/apis/tests/extract_substr.test.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/apis/tests/extract_substr.test.js b/packages/apis/tests/extract_substr.test.js
index 6aec6ce..6e08c17 100644
--- a/packages/apis/tests/extract_substr.test.js
+++ b/packages/apis/tests/extract_substr.test.js
@@ -2,6 +2,8 @@ import { extractSubstrIdxes, extractSubstr } from '../pkg/zk_regex_apis';
 import airbnbEml from './airbnb_eml';
 
 describe('Extract substr test suite', async () => {
+    // Wait for wasm to initialize
+    await new Promise(r => setTimeout(r, 300));
     test('Should extract indicies from object input', () => {
         const parts = {
             parts: [

From 1b06f6cc91c0f8319ce091bd0a9a77298c178279 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 19:23:48 +0700
Subject: [PATCH 5/7] fix: simplify git workflow

---
 .github/workflows/test.yaml | 29 +++--------------------------
 1 file changed, 3 insertions(+), 26 deletions(-)

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index f0ec741..03fa587 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -25,33 +25,10 @@ jobs:
             - name: Install yarn
               run: npm install -g yarn
             - name: Install dependencies
-              run: yarn install --immutable
+              run: yarn install  --immutable
+            - name: Run tests
+              run: yarn test
             - name: Install bun
               uses: oven-sh/setup-bun@v1
               with:
                   bun-version: latest
-            - name: Cache build artifacts
-              uses: actions/cache@v2
-              with:
-                  path: |
-                      ./*
-                  key: ${{ runner.os }}-build-${{ github.sha }}
-
-    test:
-        needs: build
-        runs-on: ubuntu-latest
-        steps:
-            - name: Restore cached build artifacts
-              uses: actions/cache@v2
-              with:
-                  path: |
-                      ./*
-                  key: ${{ runner.os }}-build-${{ github.sha }}
-            - name: Setup Node.js
-              uses: actions/setup-node@v3
-              with:
-                  node-version: 18
-            - name: Install yarn
-              run: npm install -g yarn
-            - name: Run tests
-              run: yarn test

From bad2cc291ab4f01fdfb0ace7c5fca9a7b6b5a000 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Mon, 21 Oct 2024 19:30:56 +0700
Subject: [PATCH 6/7] fix: simplify git workflow

---
 .github/workflows/test.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 03fa587..e15a1bf 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -26,9 +26,9 @@ jobs:
               run: npm install -g yarn
             - name: Install dependencies
               run: yarn install  --immutable
-            - name: Run tests
-              run: yarn test
             - name: Install bun
               uses: oven-sh/setup-bun@v1
               with:
                   bun-version: latest
+            - name: Run tests
+              run: yarn test

From bd515aaa15d78f117e115d82d9ca51edece74364 Mon Sep 17 00:00:00 2001
From: Dimitri <dimitridumonet@gmail.com>
Date: Tue, 22 Oct 2024 10:02:27 +0700
Subject: [PATCH 7/7] fix: function signatures of extractSubstrIdxes

---
 packages/circom/tests/asterisk.test.js        | 195 +++++++-------
 packages/circom/tests/body_hash_regex.test.js | 176 ++++++------
 packages/circom/tests/caret.test.js           | 252 +++++++++---------
 packages/circom/tests/dollar.test.js          |  87 +++---
 packages/circom/tests/dot.test.js             |  68 +++--
 packages/circom/tests/plus.test.js            | 212 +++++++--------
 packages/circom/tests/question.test.js        | 171 ++++++------
 packages/circom/tests/reveal_check.test.js    | 122 ++++-----
 8 files changed, 641 insertions(+), 642 deletions(-)

diff --git a/packages/circom/tests/asterisk.test.js b/packages/circom/tests/asterisk.test.js
index 9b936ff..fe7d102 100644
--- a/packages/circom/tests/asterisk.test.js
+++ b/packages/circom/tests/asterisk.test.js
@@ -1,15 +1,15 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Asterisk Regex", () => {
+describe('Asterisk Regex', () => {
     let circuit1;
     let circuit2;
     let circuit3;
@@ -18,47 +18,47 @@ describe("Asterisk Regex", () => {
     // let circuit6;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/asterisk1_regex.circom"),
+            path.join(__dirname, './circuits/asterisk1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/asterisk1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/asterisk1.json'),
+                    'utf8'
                 ),
-                "Asterisk1Regex"
+                'Asterisk1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_asterisk1_regex.circom"),
+            path.join(__dirname, './circuits/test_asterisk1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/asterisk2_regex.circom"),
+            path.join(__dirname, './circuits/asterisk2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/asterisk2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/asterisk2.json'),
+                    'utf8'
                 ),
-                "Asterisk2Regex"
+                'Asterisk2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_asterisk2_regex.circom"),
+            path.join(__dirname, './circuits/test_asterisk2_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/asterisk3_regex.circom"),
+            path.join(__dirname, './circuits/asterisk3_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/asterisk3.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/asterisk3.json'),
+                    'utf8'
                 ),
-                "Asterisk3Regex"
+                'Asterisk3Regex'
             )
         );
         circuit3 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_asterisk3_regex.circom"),
+            path.join(__dirname, './circuits/test_asterisk3_regex.circom'),
             option
         );
 
@@ -108,11 +108,11 @@ describe("Asterisk Regex", () => {
         // );
     });
 
-    it("asterisk1 valid case 1", async () => {
+    it('asterisk1 valid case 1', async () => {
         const inputStr = `xb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -120,9 +120,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -133,11 +134,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk1 valid case 2", async () => {
+    it('asterisk1 valid case 2', async () => {
         const inputStr = `xab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -145,9 +146,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -158,11 +160,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk1 valid case 3", async () => {
+    it('asterisk1 valid case 3', async () => {
         const inputStr = `xaab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -170,9 +172,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -183,11 +186,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk1 valid case 4", async () => {
+    it('asterisk1 valid case 4', async () => {
         const inputStr = `710xab98`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -195,9 +198,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -208,12 +212,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-
-    it("asterisk1 invalid case 1", async () => {
+    it('asterisk1 invalid case 1', async () => {
         const inputStr = `xaaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -223,11 +226,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk1 invalid case 2", async () => {
+    it('asterisk1 invalid case 2', async () => {
         const inputStr = `aaabx`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -237,12 +240,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-
-    it("asterisk2 valid case 1", async () => {
+    it('asterisk2 valid case 1', async () => {
         const inputStr = `aaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -250,9 +252,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -263,11 +266,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk2 valid case 2", async () => {
+    it('asterisk2 valid case 2', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -275,9 +278,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -288,11 +292,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk2 valid case 3", async () => {
+    it('asterisk2 valid case 3', async () => {
         const inputStr = `abbba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -300,9 +304,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -313,12 +318,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-
-    it("asterisk2 valid case 4", async () => {
+    it('asterisk2 valid case 4', async () => {
         const inputStr = `717abb9`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -326,9 +330,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -339,11 +344,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk2 invalid case 1", async () => {
+    it('asterisk2 invalid case 1', async () => {
         const inputStr = `bbb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -353,11 +358,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk2 invalid case 2", async () => {
+    it('asterisk2 invalid case 2', async () => {
         const inputStr = `19bd7`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -367,11 +372,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk3 valid case 1", async () => {
+    it('asterisk3 valid case 1', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -379,9 +384,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -392,11 +398,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk3 valid case 2", async () => {
+    it('asterisk3 valid case 2', async () => {
         const inputStr = `xaxxyxby`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -404,9 +410,10 @@ describe("Asterisk Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/asterisk3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/asterisk3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -417,11 +424,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk3 invalid case 1", async () => {
+    it('asterisk3 invalid case 1', async () => {
         const inputStr = `axyxyyyx`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -431,11 +438,11 @@ describe("Asterisk Regex", () => {
         }
     });
 
-    it("asterisk3 invalid case 2", async () => {
+    it('asterisk3 invalid case 2', async () => {
         const inputStr = `xyyxxyba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -459,7 +466,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk4.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -498,7 +505,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk5.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -523,7 +530,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk5.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -562,7 +569,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk6.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -587,7 +594,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk6.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -612,7 +619,7 @@ describe("Asterisk Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/asterisk6.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -622,6 +629,4 @@ describe("Asterisk Regex", () => {
     //         }
     //     }
     // });
-
-    
 });
diff --git a/packages/circom/tests/body_hash_regex.test.js b/packages/circom/tests/body_hash_regex.test.js
index af6e24e..fd49da6 100644
--- a/packages/circom/tests/body_hash_regex.test.js
+++ b/packages/circom/tests/body_hash_regex.test.js
@@ -1,97 +1,99 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Bodyhash Regex", () => {
-  let circuit;
-  beforeAll(async () => {
-    const email_addr_json = readFileSync(
-      path.join(__dirname, "../circuits/common/body_hash.json"),
-      "utf8"
-    );
-    const circom = compiler.genFromDecomposed(
-      email_addr_json,
-      "BodyHashRegex"
-    );
-    writeFileSync(
-      path.join(__dirname, "../circuits/common/body_hash_regex.circom"),
-      circom
-    );
+describe('Bodyhash Regex', () => {
+    let circuit;
+    beforeAll(async () => {
+        const email_addr_json = readFileSync(
+            path.join(__dirname, '../circuits/common/body_hash.json'),
+            'utf8'
+        );
+        const circom = compiler.genFromDecomposed(
+            email_addr_json,
+            'BodyHashRegex'
+        );
+        writeFileSync(
+            path.join(__dirname, '../circuits/common/body_hash_regex.circom'),
+            circom
+        );
 
-    circuit = await wasm_tester(
-      path.join(__dirname, "./circuits/test_body_hash_regex.circom"),
-      option
-    );
-  });
+        circuit = await wasm_tester(
+            path.join(__dirname, './circuits/test_body_hash_regex.circom'),
+            option
+        );
+    });
 
-  it("bodyhash in the header", async () => {
-    const signatureField = `dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
-    const paddedStr = apis.padString(signatureField, 1024);
-    const circuitInputs = {
-      msg: paddedStr,
-    };
-    const witness = await circuit.calculateWitness(circuitInputs);
-    await circuit.checkConstraints(witness);
-    expect(1n).toEqual(witness[1]);
-    const prefixIdxes = apis.extractSubstrIdxes(
-      signatureField,
-      readFileSync(
-        path.join(__dirname, "../circuits/common/body_hash.json"),
-        "utf8"
-      )
-    )[0];
-    for (let idx = 0; idx < 1024; ++idx) {
-      if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
-        expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
-      } else {
-        expect(0n).toEqual(witness[2 + idx]);
-      }
-    }
-  });
+    it('bodyhash in the header', async () => {
+        const signatureField = `dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
+        const paddedStr = apis.padString(signatureField, 1024);
+        const circuitInputs = {
+            msg: paddedStr
+        };
+        const witness = await circuit.calculateWitness(circuitInputs);
+        await circuit.checkConstraints(witness);
+        expect(1n).toEqual(witness[1]);
+        const prefixIdxes = apis.extractSubstrIdxes(
+            signatureField,
+            readFileSync(
+                path.join(__dirname, '../circuits/common/body_hash.json'),
+                'utf8'
+            ),
+            false
+        )[0];
+        for (let idx = 0; idx < 1024; ++idx) {
+            if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
+                expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
+            } else {
+                expect(0n).toEqual(witness[2 + idx]);
+            }
+        }
+    });
 
-  it("bodyhash after new line", async () => {
-    const signatureField = `\r\ndkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
-    const paddedStr = apis.padString(signatureField, 1024);
-    const circuitInputs = {
-      msg: paddedStr,
-    };
-    const witness = await circuit.calculateWitness(circuitInputs);
-    await circuit.checkConstraints(witness);
-    expect(1n).toEqual(witness[1]);
-    const prefixIdxes = apis.extractSubstrIdxes(
-      signatureField,
-      readFileSync(
-        path.join(__dirname, "../circuits/common/body_hash.json"),
-        "utf8"
-      )
-    )[0];
-    for (let idx = 0; idx < 1024; ++idx) {
-      if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
-        expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
-      } else {
-        expect(0n).toEqual(witness[2 + idx]);
-      }
-    }
-  });
+    it('bodyhash after new line', async () => {
+        const signatureField = `\r\ndkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
+        const paddedStr = apis.padString(signatureField, 1024);
+        const circuitInputs = {
+            msg: paddedStr
+        };
+        const witness = await circuit.calculateWitness(circuitInputs);
+        await circuit.checkConstraints(witness);
+        expect(1n).toEqual(witness[1]);
+        const prefixIdxes = apis.extractSubstrIdxes(
+            signatureField,
+            readFileSync(
+                path.join(__dirname, '../circuits/common/body_hash.json'),
+                'utf8'
+            ),
+            false
+        )[0];
+        for (let idx = 0; idx < 1024; ++idx) {
+            if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
+                expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
+            } else {
+                expect(0n).toEqual(witness[2 + idx]);
+            }
+        }
+    });
 
-  it("invalid bodyhash", async () => {
-    const signatureField = `\r\nto: dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
-    const paddedStr = apis.padString(signatureField, 1024);
-    const circuitInputs = {
-      msg: paddedStr,
-    };
-    const witness = await circuit.calculateWitness(circuitInputs);
-    await circuit.checkConstraints(witness);
-    expect(0n).toEqual(witness[1]);
-    for (let idx = 0; idx < 1024; ++idx) {
-      expect(0n).toEqual(witness[2 + idx]);
-    }
-  });
+    it('invalid bodyhash', async () => {
+        const signatureField = `\r\nto: dkim-signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; b=`;
+        const paddedStr = apis.padString(signatureField, 1024);
+        const circuitInputs = {
+            msg: paddedStr
+        };
+        const witness = await circuit.calculateWitness(circuitInputs);
+        await circuit.checkConstraints(witness);
+        expect(0n).toEqual(witness[1]);
+        for (let idx = 0; idx < 1024; ++idx) {
+            expect(0n).toEqual(witness[2 + idx]);
+        }
+    });
 });
diff --git a/packages/circom/tests/caret.test.js b/packages/circom/tests/caret.test.js
index d4ffdfd..600b9ed 100644
--- a/packages/circom/tests/caret.test.js
+++ b/packages/circom/tests/caret.test.js
@@ -1,15 +1,15 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Caret Regex", () => {
+describe('Caret Regex', () => {
     let circuit1;
     let circuit2;
     let circuit3;
@@ -17,86 +17,86 @@ describe("Caret Regex", () => {
     let circuit5;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/caret1_regex.circom"),
+            path.join(__dirname, './circuits/caret1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/caret1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/caret1.json'),
+                    'utf8'
                 ),
-                "Caret1Regex"
+                'Caret1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_caret1_regex.circom"),
+            path.join(__dirname, './circuits/test_caret1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/caret2_regex.circom"),
+            path.join(__dirname, './circuits/caret2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/caret2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/caret2.json'),
+                    'utf8'
                 ),
-                "Caret2Regex"
+                'Caret2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_caret2_regex.circom"),
+            path.join(__dirname, './circuits/test_caret2_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/caret3_regex.circom"),
+            path.join(__dirname, './circuits/caret3_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/caret3.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/caret3.json'),
+                    'utf8'
                 ),
-                "Caret3Regex"
+                'Caret3Regex'
             )
         );
         circuit3 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_caret3_regex.circom"),
+            path.join(__dirname, './circuits/test_caret3_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/caret4_regex.circom"),
+            path.join(__dirname, './circuits/caret4_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/caret4.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/caret4.json'),
+                    'utf8'
                 ),
-                "Caret4Regex"
+                'Caret4Regex'
             )
         );
         circuit4 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_caret4_regex.circom"),
+            path.join(__dirname, './circuits/test_caret4_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/caret5_regex.circom"),
+            path.join(__dirname, './circuits/caret5_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/caret5.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/caret5.json'),
+                    'utf8'
                 ),
-                "Caret5Regex"
+                'Caret5Regex'
             )
         );
         circuit5 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_caret5_regex.circom"),
+            path.join(__dirname, './circuits/test_caret5_regex.circom'),
             option
         );
     });
 
-    it("caret1 valid case 1", async () => {
+    it('caret1 valid case 1', async () => {
         const inputStr = `a`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -104,9 +104,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -117,11 +118,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret1 valid case 2", async () => {
+    it('caret1 valid case 2', async () => {
         const inputStr = `abnjknda`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -129,9 +130,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -142,11 +144,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret1 invalid case 1", async () => {
+    it('caret1 invalid case 1', async () => {
         const inputStr = `ba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -156,11 +158,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret1 invalid case 2", async () => {
+    it('caret1 invalid case 2', async () => {
         const inputStr = `bav`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -170,12 +172,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    
-    it("caret2 valid case 1", async () => {
+    it('caret2 valid case 1', async () => {
         const inputStr = `abc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -183,9 +184,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -196,11 +198,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret2 valid case 2", async () => {
+    it('caret2 valid case 2', async () => {
         const inputStr = `bca`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -208,9 +210,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -221,11 +224,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret2 valid case 3", async () => {
+    it('caret2 valid case 3', async () => {
         const inputStr = `cab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -233,9 +236,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -246,11 +250,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret2 invalid case 1", async () => {
+    it('caret2 invalid case 1', async () => {
         const inputStr = `7abc9mna`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -260,11 +264,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret3 valid case 1", async () => {
+    it('caret3 valid case 1', async () => {
         const inputStr = `bb817267`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -272,9 +276,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -285,11 +290,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret3 valid case 2", async () => {
+    it('caret3 valid case 2', async () => {
         const inputStr = `818abbb9`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -297,9 +302,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -310,11 +316,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret3 invalid case 1", async () => {
+    it('caret3 invalid case 1', async () => {
         const inputStr = `81b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -324,11 +330,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret4 valid case 1", async () => {
+    it('caret4 valid case 1', async () => {
         const inputStr = `xabaaabb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -336,9 +342,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret4.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret4.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -349,11 +356,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret4 valid case 2", async () => {
+    it('caret4 valid case 2', async () => {
         const inputStr = `xbaab82a`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -361,9 +368,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret4.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret4.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -374,11 +382,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret4 valid case 3", async () => {
+    it('caret4 valid case 3', async () => {
         const inputStr = `7w1\nxabb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -386,9 +394,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret4.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret4.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -399,11 +408,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret4 valid case 4", async () => {
+    it('caret4 valid case 4', async () => {
         const inputStr = `7w\nxbbb9`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -411,9 +420,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret4.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret4.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -424,12 +434,11 @@ describe("Caret Regex", () => {
         }
     });
 
-
-    it("caret4 invalid case 1", async () => {
+    it('caret4 invalid case 1', async () => {
         const inputStr = `7w1nxaba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -439,11 +448,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret4 invalid case 2", async () => {
+    it('caret4 invalid case 2', async () => {
         const inputStr = `abba\nx`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -453,11 +462,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret5 valid case 1", async () => {
+    it('caret5 valid case 1', async () => {
         const inputStr = `xdefabc1`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -465,9 +474,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret5.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret5.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -478,11 +488,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret5 valid case 2", async () => {
+    it('caret5 valid case 2', async () => {
         const inputStr = `9\nx9eabc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -490,9 +500,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/caret5.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/caret5.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -503,11 +514,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret5 invalid case 1", async () => {
+    it('caret5 invalid case 1', async () => {
         const inputStr = `xabc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -517,11 +528,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret5 invalid case 2", async () => {
+    it('caret5 invalid case 2', async () => {
         const inputStr = `1\ndef`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -531,13 +542,11 @@ describe("Caret Regex", () => {
         }
     });
 
-
-
-    it("caret5 invalid case 3", async () => {
+    it('caret5 invalid case 3', async () => {
         const inputStr = `a8abc8`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -547,11 +556,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("caret5 invalid case 4", async () => {
+    it('caret5 invalid case 4', async () => {
         const inputStr = `71\na81ma`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit5.calculateWitness(circuitInputs);
         await circuit5.checkConstraints(witness);
@@ -560,5 +569,4 @@ describe("Caret Regex", () => {
             expect(0n).toEqual(witness[2 + idx]);
         }
     });
-
 });
diff --git a/packages/circom/tests/dollar.test.js b/packages/circom/tests/dollar.test.js
index 6a2cdbd..76d008b 100644
--- a/packages/circom/tests/dollar.test.js
+++ b/packages/circom/tests/dollar.test.js
@@ -1,54 +1,54 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Caret Regex", () => {
+describe('Caret Regex', () => {
     let circuit1;
     let circuit2;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/dollar1_regex.circom"),
+            path.join(__dirname, './circuits/dollar1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/dollar1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/dollar1.json'),
+                    'utf8'
                 ),
-                "Dollar1Regex"
+                'Dollar1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_dollar1_regex.circom"),
+            path.join(__dirname, './circuits/test_dollar1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/dollar2_regex.circom"),
+            path.join(__dirname, './circuits/dollar2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/dollar2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/dollar2.json'),
+                    'utf8'
                 ),
-                "Dollar2Regex"
+                'Dollar2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_dollar2_regex.circom"),
+            path.join(__dirname, './circuits/test_dollar2_regex.circom'),
             option
         );
     });
 
-    it("dollar1 valid case 1", async () => {
+    it('dollar1 valid case 1', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -56,9 +56,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/dollar1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/dollar1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -69,11 +70,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar1 invalid case 1", async () => {
+    it('dollar1 invalid case 1', async () => {
         const inputStr = `abg`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -83,11 +84,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar1 invalid case 2", async () => {
+    it('dollar1 invalid case 2', async () => {
         const inputStr = `18abcg`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -97,11 +98,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar2 valid case 1", async () => {
+    it('dollar2 valid case 1', async () => {
         const inputStr = `xab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -109,9 +110,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/dollar2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/dollar2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -122,11 +124,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar2 valid case 2", async () => {
+    it('dollar2 valid case 2', async () => {
         const inputStr = `ak\nxab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -134,9 +136,10 @@ describe("Caret Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/dollar2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/dollar2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -147,11 +150,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar2 invalid case 1", async () => {
+    it('dollar2 invalid case 1', async () => {
         const inputStr = `abg`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -161,11 +164,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar2 invalid case 2", async () => {
+    it('dollar2 invalid case 2', async () => {
         const inputStr = `\nabg`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -175,11 +178,11 @@ describe("Caret Regex", () => {
         }
     });
 
-    it("dollar2 invalid case 2", async () => {
+    it('dollar2 invalid case 2', async () => {
         const inputStr = `\nabg`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
diff --git a/packages/circom/tests/dot.test.js b/packages/circom/tests/dot.test.js
index 5bfcc8b..f5b7914 100644
--- a/packages/circom/tests/dot.test.js
+++ b/packages/circom/tests/dot.test.js
@@ -1,64 +1,62 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Dot Regex", () => {
+describe('Dot Regex', () => {
     let circuit1;
     let circuit2;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/dot1_regex.circom"),
+            path.join(__dirname, './circuits/dot1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/dot1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/dot1.json'),
+                    'utf8'
                 ),
-                "Dot1Regex"
+                'Dot1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_dot1_regex.circom"),
+            path.join(__dirname, './circuits/test_dot1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/dot2_regex.circom"),
+            path.join(__dirname, './circuits/dot2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/dot2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/dot2.json'),
+                    'utf8'
                 ),
-                "Dot2Regex"
+                'Dot2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_dot2_regex.circom"),
+            path.join(__dirname, './circuits/test_dot2_regex.circom'),
             option
         );
     });
 
-    it("dot1 valid case 1", async () => {
+    it('dot1 valid case 1', async () => {
         const inputStr = `a`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/dot1.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/dot1.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -83,7 +81,7 @@ describe("Dot Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/dot1.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -94,21 +92,19 @@ describe("Dot Regex", () => {
     //     }
     // });
 
-    it("dot2 valid case 1", async () => {
+    it('dot2 valid case 1', async () => {
         const inputStr = `a6b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/dot2.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/dot2.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -133,7 +129,7 @@ describe("Dot Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/dot2.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -144,11 +140,11 @@ describe("Dot Regex", () => {
     //     }
     // });
 
-    it("dot2 invalid case 1", async () => {
+    it('dot2 invalid case 1', async () => {
         const inputStr = `819nc8b8`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -158,11 +154,11 @@ describe("Dot Regex", () => {
         }
     });
 
-    it("dot2 invalid case 2", async () => {
+    it('dot2 invalid case 2', async () => {
         const inputStr = `78aa6cc8`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -170,5 +166,5 @@ describe("Dot Regex", () => {
         for (let idx = 0; idx < 8; ++idx) {
             expect(0n).toEqual(witness[2 + idx]);
         }
-    });    
+    });
 });
diff --git a/packages/circom/tests/plus.test.js b/packages/circom/tests/plus.test.js
index 869e11b..6a37047 100644
--- a/packages/circom/tests/plus.test.js
+++ b/packages/circom/tests/plus.test.js
@@ -1,15 +1,15 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Plus Regex", () => {
+describe('Plus Regex', () => {
     let circuit1;
     let circuit2;
     let circuit3;
@@ -18,62 +18,62 @@ describe("Plus Regex", () => {
     // let circuit6;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/plus1_regex.circom"),
+            path.join(__dirname, './circuits/plus1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/plus1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/plus1.json'),
+                    'utf8'
                 ),
-                "Plus1Regex"
+                'Plus1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_plus1_regex.circom"),
+            path.join(__dirname, './circuits/test_plus1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/plus2_regex.circom"),
+            path.join(__dirname, './circuits/plus2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/plus2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/plus2.json'),
+                    'utf8'
                 ),
-                "Plus2Regex"
+                'Plus2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_plus2_regex.circom"),
+            path.join(__dirname, './circuits/test_plus2_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/plus3_regex.circom"),
+            path.join(__dirname, './circuits/plus3_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/plus3.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/plus3.json'),
+                    'utf8'
                 ),
-                "Plus3Regex"
+                'Plus3Regex'
             )
         );
         circuit3 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_plus3_regex.circom"),
+            path.join(__dirname, './circuits/test_plus3_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/plus4_regex.circom"),
+            path.join(__dirname, './circuits/plus4_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/plus4.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/plus4.json'),
+                    'utf8'
                 ),
-                "Plus4Regex"
+                'Plus4Regex'
             )
         );
         circuit4 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_plus4_regex.circom"),
+            path.join(__dirname, './circuits/test_plus4_regex.circom'),
             option
         );
 
@@ -108,21 +108,19 @@ describe("Plus Regex", () => {
         // );
     });
 
-    it("plus1 valid case 1", async () => {
+    it('plus1 valid case 1', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus1.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus1.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -133,22 +131,19 @@ describe("Plus Regex", () => {
         }
     });
 
-
-    it("plus1 valid case 2", async () => {
+    it('plus1 valid case 2', async () => {
         const inputStr = `aaaab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus1.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus1.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -159,21 +154,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus1 valid case 3", async () => {
+    it('plus1 valid case 3', async () => {
         const inputStr = `7aab89ac`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus1.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus1.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -184,11 +177,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus1 invalid case 1", async () => {
+    it('plus1 invalid case 1', async () => {
         const inputStr = `b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -198,11 +191,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus1 invalid case 2", async () => {
+    it('plus1 invalid case 2', async () => {
         const inputStr = `aacaadae`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -212,11 +205,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus1 invalid case 3", async () => {
+    it('plus1 invalid case 3', async () => {
         const inputStr = `aaaaaaaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -226,21 +219,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus2 valid case 1", async () => {
+    it('plus2 valid case 1', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus2.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus2.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -251,21 +242,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus2 valid case 2", async () => {
+    it('plus2 valid case 2', async () => {
         const inputStr = `ac`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus2.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus2.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -276,21 +265,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus2 valid case 3", async () => {
+    it('plus2 valid case 3', async () => {
         const inputStr = `abccbbcc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus2.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus2.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -301,21 +288,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus2 valid case 4", async () => {
+    it('plus2 valid case 4', async () => {
         const inputStr = `7abbcaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus2.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus2.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -326,11 +311,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus2 invalid case 1", async () => {
+    it('plus2 invalid case 1', async () => {
         const inputStr = `adefghij`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -340,21 +325,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus3 valid case 1", async () => {
+    it('plus3 valid case 1', async () => {
         const inputStr = `abcbcbc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus3.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus3.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -365,21 +348,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus3 valid case 2", async () => {
+    it('plus3 valid case 2', async () => {
         const inputStr = `acbabcbc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus3.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus3.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -390,21 +371,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus3 valid case 3", async () => {
+    it('plus3 valid case 3', async () => {
         const inputStr = `abccbcbb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus3.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus3.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -415,11 +394,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus3 invalid case 1", async () => {
+    it('plus3 invalid case 1', async () => {
         const inputStr = `abab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -429,21 +408,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus4 valid case 1", async () => {
+    it('plus4 valid case 1', async () => {
         const inputStr = `1234512b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus4.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus4.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -454,21 +431,19 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus4 valid case 2", async () => {
+    it('plus4 valid case 2', async () => {
         const inputStr = `2134512b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
         expect(1n).toEqual(witness[1]);
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
-            readFileSync(
-                path.join(__dirname, "./circuits/plus4.json"),
-                "utf8"
-            )
+            readFileSync(path.join(__dirname, './circuits/plus4.json'), 'utf8'),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -479,11 +454,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus4 invalid case 1", async () => {
+    it('plus4 invalid case 1', async () => {
         const inputStr = `1234b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -493,11 +468,11 @@ describe("Plus Regex", () => {
         }
     });
 
-    it("plus4 invalid case 2", async () => {
+    it('plus4 invalid case 2', async () => {
         const inputStr = `34512`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit4.calculateWitness(circuitInputs);
         await circuit4.checkConstraints(witness);
@@ -521,7 +496,7 @@ describe("Plus Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/plus5.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -546,7 +521,7 @@ describe("Plus Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/plus5.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -571,7 +546,7 @@ describe("Plus Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/plus5.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -610,7 +585,6 @@ describe("Plus Regex", () => {
     //     }
     // });
 
-
     // it("plus6 valid case 1", async () => {
     //     const inputStr = `aaaabbbb`;
     //     const paddedStr = apis.padString(inputStr, 8);
@@ -625,7 +599,7 @@ describe("Plus Regex", () => {
     //         readFileSync(
     //             path.join(__dirname, "./circuits/plus6.json"),
     //             "utf8"
-    //         )
+    //         ),false
     //     )[0];
     //     for (let idx = 0; idx < 8; ++idx) {
     //         if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
diff --git a/packages/circom/tests/question.test.js b/packages/circom/tests/question.test.js
index 573358a..0a5170e 100644
--- a/packages/circom/tests/question.test.js
+++ b/packages/circom/tests/question.test.js
@@ -1,70 +1,70 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Question Regex", () => {
+describe('Question Regex', () => {
     let circuit1;
     let circuit2;
     let circuit3;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/question1_regex.circom"),
+            path.join(__dirname, './circuits/question1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/question1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/question1.json'),
+                    'utf8'
                 ),
-                "Question1Regex"
+                'Question1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_question1_regex.circom"),
+            path.join(__dirname, './circuits/test_question1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/question2_regex.circom"),
+            path.join(__dirname, './circuits/question2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/question2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/question2.json'),
+                    'utf8'
                 ),
-                "Question2Regex"
+                'Question2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_question2_regex.circom"),
+            path.join(__dirname, './circuits/test_question2_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/question3_regex.circom"),
+            path.join(__dirname, './circuits/question3_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/question3.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/question3.json'),
+                    'utf8'
                 ),
-                "Question3Regex"
+                'Question3Regex'
             )
         );
         circuit3 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_question3_regex.circom"),
+            path.join(__dirname, './circuits/test_question3_regex.circom'),
             option
         );
     });
 
-    it("question1 valid case 1", async () => {
+    it('question1 valid case 1', async () => {
         const inputStr = `b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -72,9 +72,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -85,11 +86,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question1 valid case 2", async () => {
+    it('question1 valid case 2', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -97,9 +98,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -110,11 +112,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question1 valid case 3", async () => {
+    it('question1 valid case 3', async () => {
         const inputStr = `199aabb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -122,9 +124,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question1.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -135,11 +138,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question1 invalid case 1", async () => {
+    it('question1 invalid case 1', async () => {
         const inputStr = `aaaaaaaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -149,11 +152,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question1 invalid case 2", async () => {
+    it('question1 invalid case 2', async () => {
         const inputStr = `cccccccc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -163,11 +166,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question2 valid case 1", async () => {
+    it('question2 valid case 1', async () => {
         const inputStr = `12b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -175,9 +178,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -188,11 +192,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question2 valid case 2", async () => {
+    it('question2 valid case 2', async () => {
         const inputStr = `11x2bb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -200,9 +204,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question2.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -213,11 +218,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question2 invalid case 1", async () => {
+    it('question2 invalid case 1', async () => {
         const inputStr = `1x2`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -227,11 +232,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question2 invalid case 2", async () => {
+    it('question2 invalid case 2', async () => {
         const inputStr = `1xb`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -241,11 +246,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 valid case 1", async () => {
+    it('question3 valid case 1', async () => {
         const inputStr = `12c`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -253,9 +258,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -266,11 +272,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 valid case 2", async () => {
+    it('question3 valid case 2', async () => {
         const inputStr = `12ac`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -278,9 +284,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -291,11 +298,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 valid case 2", async () => {
+    it('question3 valid case 2', async () => {
         const inputStr = `12bc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -303,9 +310,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -316,11 +324,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 valid case 4", async () => {
+    it('question3 valid case 4', async () => {
         const inputStr = `12a12bc1`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -328,9 +336,10 @@ describe("Question Regex", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/question3.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/question3.json'),
+                'utf8'
+            ),
+            false
         )[0];
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
@@ -341,11 +350,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 invalid case 1", async () => {
+    it('question3 invalid case 1', async () => {
         const inputStr = `1ac`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -355,11 +364,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 invalid case 2", async () => {
+    it('question3 invalid case 2', async () => {
         const inputStr = `12abc`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
@@ -369,11 +378,11 @@ describe("Question Regex", () => {
         }
     });
 
-    it("question3 invalid case 3", async () => {
+    it('question3 invalid case 3', async () => {
         const inputStr = `12a12b`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit3.calculateWitness(circuitInputs);
         await circuit3.checkConstraints(witness);
diff --git a/packages/circom/tests/reveal_check.test.js b/packages/circom/tests/reveal_check.test.js
index 695ebf8..3ae4603 100644
--- a/packages/circom/tests/reveal_check.test.js
+++ b/packages/circom/tests/reveal_check.test.js
@@ -1,54 +1,54 @@
-import circom_tester from "circom_tester";
-import * as path from "path";
-import { readFileSync, writeFileSync } from "fs";
-import apis from "../../apis/pkg";
-import compiler from "../../compiler/pkg";
+import circom_tester from 'circom_tester';
+import * as path from 'path';
+import { readFileSync, writeFileSync } from 'fs';
+import apis from '../../apis/pkg';
+import compiler from '../../compiler/pkg';
 const option = {
-  include: path.join(__dirname, "../../../node_modules"),
+    include: path.join(__dirname, '../../../node_modules')
 };
 const wasm_tester = circom_tester.wasm;
 
 jest.setTimeout(600000);
-describe("Revealed Chars Check", () => {
+describe('Revealed Chars Check', () => {
     let circuit1;
     let circuit2;
     beforeAll(async () => {
         writeFileSync(
-            path.join(__dirname, "./circuits/reveal_check1_regex.circom"),
+            path.join(__dirname, './circuits/reveal_check1_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/reveal_check1.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/reveal_check1.json'),
+                    'utf8'
                 ),
-                "RevealCheck1Regex"
+                'RevealCheck1Regex'
             )
         );
         circuit1 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_reveal_check1_regex.circom"),
+            path.join(__dirname, './circuits/test_reveal_check1_regex.circom'),
             option
         );
 
         writeFileSync(
-            path.join(__dirname, "./circuits/reveal_check2_regex.circom"),
+            path.join(__dirname, './circuits/reveal_check2_regex.circom'),
             compiler.genFromDecomposed(
                 readFileSync(
-                    path.join(__dirname, "./circuits/reveal_check2.json"),
-                    "utf8"
+                    path.join(__dirname, './circuits/reveal_check2.json'),
+                    'utf8'
                 ),
-                "RevealCheck2Regex"
+                'RevealCheck2Regex'
             )
         );
         circuit2 = await wasm_tester(
-            path.join(__dirname, "./circuits/test_reveal_check2_regex.circom"),
+            path.join(__dirname, './circuits/test_reveal_check2_regex.circom'),
             option
         );
     });
 
-    it("reveal check1 valid case 1", async () => {
+    it('reveal check1 valid case 1', async () => {
         const inputStr = `aba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -56,11 +56,12 @@ describe("Revealed Chars Check", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/reveal_check1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/reveal_check1.json'),
+                'utf8'
+            ),
+            false
         )[0];
-        expect(prefixIdxes).toEqual([0,3]);
+        expect(prefixIdxes).toEqual([0, 3]);
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
                 expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
@@ -70,12 +71,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-
-    it("reveal check1 valid case 2", async () => {
+    it('reveal check1 valid case 2', async () => {
         const inputStr = `7abaab9`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -83,11 +83,12 @@ describe("Revealed Chars Check", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/reveal_check1.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/reveal_check1.json'),
+                'utf8'
+            ),
+            false
         )[0];
-        expect(prefixIdxes).toEqual([1,4]);
+        expect(prefixIdxes).toEqual([1, 4]);
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
                 expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
@@ -97,11 +98,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check1 invalid case 1", async () => {
+    it('reveal check1 invalid case 1', async () => {
         const inputStr = `aca`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -111,11 +112,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check1 invalid case 2", async () => {
+    it('reveal check1 invalid case 2', async () => {
         const inputStr = `aaa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit1.calculateWitness(circuitInputs);
         await circuit1.checkConstraints(witness);
@@ -125,11 +126,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 valid case 1", async () => {
+    it('reveal check2 valid case 1', async () => {
         const inputStr = `aa`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -137,11 +138,12 @@ describe("Revealed Chars Check", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/reveal_check2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/reveal_check2.json'),
+                'utf8'
+            ),
+            false
         )[0];
-        expect(prefixIdxes).toEqual([0,2]);
+        expect(prefixIdxes).toEqual([0, 2]);
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
                 expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
@@ -151,11 +153,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 valid case 2", async () => {
+    it('reveal check2 valid case 2', async () => {
         const inputStr = `ab`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -163,11 +165,12 @@ describe("Revealed Chars Check", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/reveal_check2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/reveal_check2.json'),
+                'utf8'
+            ),
+            false
         )[0];
-        expect(prefixIdxes).toEqual([0,2]);
+        expect(prefixIdxes).toEqual([0, 2]);
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
                 expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
@@ -177,11 +180,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 valid case 3", async () => {
+    it('reveal check2 valid case 3', async () => {
         const inputStr = `aba`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -189,11 +192,12 @@ describe("Revealed Chars Check", () => {
         const prefixIdxes = apis.extractSubstrIdxes(
             inputStr,
             readFileSync(
-                path.join(__dirname, "./circuits/reveal_check2.json"),
-                "utf8"
-            )
+                path.join(__dirname, './circuits/reveal_check2.json'),
+                'utf8'
+            ),
+            false
         )[0];
-        expect(prefixIdxes).toEqual([0,2]);
+        expect(prefixIdxes).toEqual([0, 2]);
         for (let idx = 0; idx < 8; ++idx) {
             if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) {
                 expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]);
@@ -203,11 +207,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 invalid case 1", async () => {
+    it('reveal check2 invalid case 1', async () => {
         const inputStr = `ac`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -217,11 +221,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 invalid case 2", async () => {
+    it('reveal check2 invalid case 2', async () => {
         const inputStr = `bad`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -231,11 +235,11 @@ describe("Revealed Chars Check", () => {
         }
     });
 
-    it("reveal check2 invalid case 3", async () => {
+    it('reveal check2 invalid case 3', async () => {
         const inputStr = `bad`;
         const paddedStr = apis.padString(inputStr, 8);
         const circuitInputs = {
-            msg: paddedStr,
+            msg: paddedStr
         };
         const witness = await circuit2.calculateWitness(circuitInputs);
         await circuit2.checkConstraints(witness);
@@ -244,6 +248,4 @@ describe("Revealed Chars Check", () => {
             expect(0n).toEqual(witness[2 + idx]);
         }
     });
-
-    
 });