chore: update browser tests to use staging conductor URL#43
Conversation
…dregex-in-sdk-and-relayerutils Rutefig/reg 473 fix testdecomposedregex in sdk and relayerutils
…ation-for-sp1 chore: update sp1-verifier version to 5.0.0
…neration chore: updated zk-regex version
[REG-590][REG-588] fix: generate partial body hash when the body verification is enabled
Support both legacy and new circuit input formats by:
- Adding optional fields (max_match_length, max_haystack_length, regex_graph_json) with aliases for old field names
- Implementing legacy path that generates {name}RegexIdx format for old circuits
- Using NFAGraph-based generation only when regex_graph_json is present
- Adding helper methods to detect circuit version and calculate defaults
- Fixing typo: removeSoftLinesBreaks -> removeSoftLineBreaks in tests
This ensures circuits compiled before the new compiler integration continue to work while supporting the new format.
Rutefig/fix proof gen old circuits
Add rsa_key_bits parameter to allow specifying RSA key size (1024 or 2048). When not specified, key size is auto-detected from the public key length.
Change RSA key size auto-detection to explicitly match supported sizes (1024-bit and 2048-bit) and return an error for unsupported sizes. Previously, any key larger than 128 bytes would silently default to 2048-bit parameters, which would cause incorrect behavior for 4096-bit keys. Now unsupported key sizes return a clear error message.
…024-for-noir-in-our-registry feat: add support for 1024-bit RSA keys in Noir circuits
Switch from dev-conductor.zk.email to staging-conductor.zk.email as dev environment is decommissioned
📝 WalkthroughWalkthroughThis PR refactors the circuit input generation system into modular components for Circom and Noir, introduces a new Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 19
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (7)
browser_test/src/main.ts-9-15 (1)
9-15:⚠️ Potential issue | 🟡 MinorUse
classinstead ofclassNamein HTML template strings.In raw HTML assigned to
innerHTMLon line 5, browsers expect the standardclassattribute.classNameis a React/JSX convention and will not be recognized as a valid HTML attribute, preventing CSS classes from being applied to those elements.🔧 Proposed fix
- <div className="flex mt-5"> + <div class="flex mt-5"> <button class="prove">Prove with Noir</button> </div> @@ - <div className="flex mt-5"> + <div class="flex mt-5"> <button class="prove">Prove with Circom</button> </div>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/main.ts` around lines 9 - 15, The HTML template uses React/JSX attribute "className" which isn't recognized when setting innerHTML; update the template for the elements under the "noir-prover" and "circom-prover" blocks to use the standard HTML attribute "class" (e.g., change className="flex mt-5" and className="prove" to class="flex mt-5" and class="prove") so the CSS classes on the <div> and <button> elements (including the "prove" button) are applied correctly.browser_test/src/noirProver.ts-254-257 (1)
254-257:⚠️ Potential issue | 🟡 MinorType mismatch in length comparison.
partStr.lengthis the string length (number of characters), whileparseInt(publicOutputs[publicOutputIterator], 16)parses a hex string to get byte count. For ASCII content these match, but for multi-byte UTF-8 characters,partStr.length(code units) may differ from byte length.Consider whether this comparison is intentional or if you need to compare byte lengths instead:
// If comparing byte lengths: const partByteLength = new TextEncoder().encode(partStr).length; if (partByteLength !== partLength) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/noirProver.ts` around lines 254 - 257, The comparison currently uses partStr.length (code units) vs partLength parsed from publicOutputs[publicOutputIterator]; replace that check to compare the UTF‑8 byte length instead by computing the number of bytes of partStr (e.g. using a TextEncoder) and compare that byte count to partLength so multi‑byte characters are measured correctly; update the conditional around partStr, partLength, publicOutputs and publicOutputIterator accordingly.browser_test/src/prover-server.ts-59-59 (1)
59-59:⚠️ Potential issue | 🟡 MinorBoolean default using
||will ignore explicitfalsevalues.
blueprint.props.removeSoftLinebreaks || truewill always betrueeven ifremoveSoftLinebreaksis explicitly set tofalse. Use nullish coalescing (??) instead.🐛 Proposed fix
- removeSoftLineBreaks: blueprint.props.removeSoftLinebreaks || true, + removeSoftLineBreaks: blueprint.props.removeSoftLinebreaks ?? true,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/prover-server.ts` at line 59, The assignment for removeSoftLineBreaks is using the boolean-or pattern which forces true even when blueprint.props.removeSoftLinebreaks is explicitly false; update the initializer for removeSoftLineBreaks (the object key removeSoftLineBreaks) to use the nullish coalescing operator (blueprint.props.removeSoftLinebreaks ?? true) so that false is preserved and only undefined/null fall back to true.browser_test/src/localProverWorker.js-112-116 (1)
112-116:⚠️ Potential issue | 🟡 MinorVerify that
inputsis a string before parsing.
JSON.parse(inputs)will throw ifinputsis already an object (e.g., if the caller posts structured data instead of a serialized string). Consider defensive handling.🛡️ Proposed fix with type check
+ const parsedInputs = typeof inputs === 'string' ? JSON.parse(inputs) : inputs; const { proof, publicSignals } = await snarkjs.groth16.fullProve( - JSON.parse(inputs), + parsedInputs, wasmFile, circuitfile );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/localProverWorker.js` around lines 112 - 116, The call to snarkjs.groth16.fullProve uses JSON.parse(inputs) which will throw if inputs is already an object; update the code around the snarkjs.groth16.fullProve invocation to first check the type of inputs (e.g., if typeof inputs === 'string' then JSON.parse(inputs) else use inputs directly), optionally validate the resulting object shape before passing it to fullProve, and ensure any parsing/validation is wrapped so errors are handled/logged rather than letting JSON.parse throw; refer to the variables inputs and the snarkjs.groth16.fullProve call to locate the change.src/circuit/utils.rs-72-86 (1)
72-86:⚠️ Potential issue | 🟡 MinorPotential panic: slicing
original_bodywith mapped indices without bounds validation.After obtaining
original_start_indexandoriginal_end_indexfrom the position map, the code directly slicesoriginal_body[original_start_index..original_end_index]at Line 84 without verifying these indices are withinoriginal_bodybounds. If the position map contains values that exceedoriginal_body.len(), this will panic.🛡️ Proposed fix to add bounds validation
let (_, original_start_index, original_end_index) = find_selector_in_clean_content(clean_content, selector, position_map)?; + if original_end_index > original_body.len() || original_start_index > original_end_index { + return Err(anyhow!("Mapped indices out of bounds for original body")); + } + // Retrieve the substring from the original body that corresponds to the found selector let adjusted_selector = &original_body[original_start_index..original_end_index];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/utils.rs` around lines 72 - 86, The code slices original_body using original_start_index and original_end_index returned by find_selector_in_clean_content without validating bounds; update the logic in the selector-mapping block to verify that original_start_index and original_end_index are within 0..=original_body.len() and that original_start_index <= original_end_index before slicing, and if not return an Err (propagate a descriptive error) or clamp the indices safely; reference the variables original_body, original_start_index, original_end_index and the helper find_selector_in_clean_content so you add the checks immediately before creating adjusted_selector and only perform String::from_utf8 on a safe slice.src/converters.rs-436-451 (1)
436-451:⚠️ Potential issue | 🟡 MinorAdd comprehensive test coverage for edge cases in
uint_to_decimal_string.The logic is sound—
checked_subbounds safety is appropriate, and trailing-zero skipping via thefound_non_zero_decimalflag correctly handles cases like converting 0 and values with all-zero decimal places (e.g.,0.1represented as100withdecimal=3). However, this critical function has no test coverage. Add tests for:
- Converting 0
- Values with all trailing zeros in decimal portion
- Edge cases where decimal places exceed the value magnitude
- Maximum u128 values with various decimal offsets
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/converters.rs` around lines 436 - 451, Add comprehensive unit tests for the uint_to_decimal_string function to cover edge cases: include tests for converting 0, values where the decimal portion is all trailing zeros (e.g., input representing 0.1 with decimal=3), cases where decimal places exceed the integer magnitude, and maximum u128 values with several decimal offsets; ensure tests assert exact string outputs and exercise paths that use checked_sub and the found_non_zero_decimal behavior to prevent regressions.src/circuit/circom.rs-290-306 (1)
290-306:⚠️ Potential issue | 🟡 MinorFallback to index
0may mask errors.When
get_invitation_code_idxes,get_timestamp_idxes, orget_command_idxesfail, the code silently defaults to index0. Since0could be a valid index position, this makes it impossible to distinguish between "field found at position 0" and "field not found."Consider using
Option<usize>for these fields, or using a sentinel value that cannot be a valid index (e.g.,usize::MAX).💡 Alternative approach
- let mut code_idx = match parsed_email.get_invitation_code_idxes(...) { - Ok(indexes) => indexes.0, - Err(_) => 0, - }; + let mut code_idx: Option<usize> = parsed_email.get_invitation_code_idxes(...).ok().map(|i| i.0);This would require changing
EmailCircuitInput.code_idxtoOption<usize>and updating downstream consumers.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/circom.rs` around lines 290 - 306, The current code masks errors by defaulting to index 0 when parsed_email.get_invitation_code_idxes, parsed_email.get_timestamp_idxes, or parsed_email.get_command_idxes return Err, which conflates "found at 0" with "not found"; change the code to return Option<usize> (e.g., let code_idx: Option<usize> = match ... { Ok((i,_)) => Some(i), Err(_) => None }) or use a sentinel like usize::MAX, and update EmailCircuitInput.code_idx (and similar timestamp_idx/command_idx fields) and all downstream consumers to handle Option<usize> (or the sentinel) instead of assuming 0 is valid so failures are distinguishable.
🧹 Nitpick comments (13)
src/regex/padding.rs (1)
42-58: Add regression coverage for truncation semantics.The docs make silent truncation part of the contract for both helpers, but the tests only cover shorter inputs. A couple of truncation cases here would lock down the behavior callers depend on.
♻️ Suggested test additions
#[cfg(test)] mod tests { use super::*; @@ fn test_pad_bytes() { let input = vec![1, 2, 3]; let padded = pad_bytes(&input, 6); assert_eq!(padded.len(), 6); assert_eq!(&padded[0..3], &[1, 2, 3]); assert_eq!(&padded[3..6], &[0, 0, 0]); } + + #[test] + fn test_pad_string_truncates() { + let padded = pad_string("hello world", 5); + assert_eq!(padded, b"hello"); + } + + #[test] + fn test_pad_bytes_truncates() { + let padded = pad_bytes(&[1, 2, 3, 4], 2); + assert_eq!(padded, vec![1, 2]); + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/regex/padding.rs` around lines 42 - 58, Add tests covering truncation semantics for pad_string and pad_bytes: when the input length exceeds the target size, assert the returned buffer has length equal to the target and contains only the first target bytes of the input (i.e., verify pad_string("hello world", 5) yields "hello" and pad_bytes(vec![...longer...], N) yields the first N bytes). Add both a string truncation case for pad_string and a byte-vector truncation case for pad_bytes to lock down the silent-truncation behavior.browser_test/src/noirProver.ts (2)
42-42: Remove unusedparsedEmailvariable.
parsedEmailis assigned but never used.♻️ Remove unused variable
- const parsedEmail = await parseEmail(eml!);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/noirProver.ts` at line 42, The local variable parsedEmail is assigned from await parseEmail(eml!) but never used; remove the unused variable by either eliminating the assignment entirely (call await parseEmail(eml!) without binding) or delete the line, ensuring you keep the call only if side-effects are needed; target the statement that assigns parsedEmail (the parseEmail/eml usage) and update it accordingly.
24-26: Remove or use the created prover instance.The
proveris created but never used. The code manually generates inputs and proofs instead of using the prover abstraction.♻️ Remove unused prover
- const prover = blueprint.createProver({ isLocal: true }); - console.log("prover"); - console.log("typeof prover", typeof prover);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/noirProver.ts` around lines 24 - 26, The code creates a prover via blueprint.createProver({ isLocal: true }) but never uses it; either remove the unused creation and its console.logs, or switch the manual input/proof generation to the prover abstraction by calling the prover's methods (e.g., prover.generateInputs(...) to produce circuit inputs and prover.createProof(...) or prover.prove(...) to build the proof) in place of the current manual steps so the created prover instance is actually used.browser_test/src/prover-server.ts (1)
17-17: Remove unused import.
pakois imported but never used in this file.♻️ Remove unused import
-import pako from "pako";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/prover-server.ts` at line 17, Remove the unused import "pako" from the top of prover-server.ts: locate the import statement `import pako from "pako";` and delete it (or consolidate imports if later added) so there are no unused dependencies in the file; ensure no other code in prover-server.ts references `pako` after removal.browser_test/src/localProverWorker.js (2)
18-27: Consider adding backoff delay between retry attempts.The
downloadWithRetriesfunction retries immediately without any delay. If the server is temporarily overloaded or rate-limiting, immediate retries may exacerbate the issue.♻️ Proposed fix with exponential backoff
async function downloadWithRetries(link, downloadAttempts) { for (let i = 1; i <= downloadAttempts; i++) { logger.debug(`download attempt ${i} for ${link}`); - const response = await fetch(link, { method: "GET" }); - if (response.status === 200) { - return response; + try { + const response = await fetch(link, { method: "GET" }); + if (response.status === 200) { + return response; + } + } catch (e) { + logger.debug(`Fetch error on attempt ${i}: ${e.message}`); } + if (i < downloadAttempts) { + await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i - 1))); + } } throw new Error(`Error downloading ${link} after ${downloadAttempts} retries`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/localProverWorker.js` around lines 18 - 27, The downloadWithRetries function retries immediately; add an exponential backoff (with optional jitter) between attempts to avoid hammering a rate-limited/overloaded server: compute a delay like baseDelayMs * 2^(attempt-1) (add small random jitter) and await a sleep Promise before the next fetch attempt in downloadWithRetries, but do not delay after a successful fetch or after the final failed attempt; ensure the sleep is implemented using a Promise around setTimeout so the function remains async.
118-118:localforage.clear()removes all stored data, not just circuit files.If other parts of the application use
localforagefor persistence, this will wipe their data. Consider removing only the specific keys used by this worker.♻️ Proposed fix to clear only circuit-related keys
- await localforage.clear(); + // Clear only the circuit files we stored + await localforage.removeItem(`${circuitName}.zkey`); + await localforage.removeItem(`${circuitName}.wasm`); + for (const { suffix } of chunkedZkeyUrls) { + await localforage.removeItem(`${circuitName}.zkey${suffix}`); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_test/src/localProverWorker.js` at line 118, The code calls await localforage.clear() which wipes all app storage; instead change the logic in localProverWorker.js to remove only circuit-related entries: obtain the list of keys via await localforage.keys(), filter for the worker's circuit key pattern/prefix (e.g. keys that startWith or include "circuit", "prover", or whatever key names this worker uses), then call await localforage.removeItem(key) for each matching key (or remove specific known keys like "circuitFiles" if those are the exact names) rather than clearing the entire store.src/circuit/circom.rs (3)
144-163: ManualCloneimplementation could use#[derive(Clone)].All fields of
DecomposedRegeximplementClone, so the manual implementation can be replaced with#[derive(Clone)]. The current implementation is equivalent to what derive would generate.♻️ Proposed simplification
+#[derive(Clone)] #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DecomposedRegex { // ... fields ... } -impl Clone for DecomposedRegex { - fn clone(&self) -> Self { - DecomposedRegex { - parts: self - .parts - .iter() - .map(|p| match p { - RegexPart::Pattern(s) => RegexPart::Pattern(s.clone()), - RegexPart::PublicPattern((s, n)) => RegexPart::PublicPattern((s.clone(), *n)), - }) - .collect(), - name: self.name.clone(), - max_match_length: self.max_match_length, - max_haystack_length: self.max_haystack_length, - haystack_location: self.haystack_location.clone(), - regex_graph_json: self.regex_graph_json.clone(), - proving_framework: self.proving_framework, - } - } -}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/circom.rs` around lines 144 - 163, The manual impl Clone for DecomposedRegex duplicates behavior that derive would provide; remove the impl Clone block for DecomposedRegex and add #[derive(Clone)] to the DecomposedRegex struct definition so all fields (parts, name, max_match_length, max_haystack_length, haystack_location, regex_graph_json, proving_framework) are cloned automatically, ensuring you don't change any field semantics.
708-725: LGTM, but address the TODO for test coverage.The function is correct and well-documented. Consider adding unit tests as indicated by the TODO comment on line 725.
Do you want me to generate unit tests for
compute_signal_length?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/circom.rs` around lines 708 - 725, Add unit tests for compute_signal_length to satisfy the TODO: create a #[cfg(test)] mod (either in this file or in tests/) with multiple #[test] cases that call compute_signal_length and assert expected outputs — include edge cases like max_length = 0, exact multiples (31, 62), values with remainder (1, 30, 32), and a large value to ensure no overflow; use assert_eq!(compute_signal_length(x), expected) for each and remove or update the TODO comment once tests are added.
683-689: Inefficient padding creates an intermediate vector.The code creates
vec![0; ...]then maps each element to a string. This can be simplified usingstd::iter::repeat.♻️ More efficient padding
// Pad the value to the signal length if value.len() < signal_length { - value.extend( - vec![0; signal_length - value.len()] - .into_iter() - .map(|num| num.to_string()), - ); + value.extend( + std::iter::repeat("0".to_string()) + .take(signal_length - value.len()), + ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/circom.rs` around lines 683 - 689, The padding creates an intermediate Vec by building vec![0; signal_length - value.len()] then mapping to strings; replace that with an iterator using std::iter::repeat to avoid the temporary allocation: when checking if value.len() < signal_length, call value.extend(std::iter::repeat("0".to_string()).take(signal_length - value.len())) (or equivalent) so you extend the existing Vec<String> directly; update the block around value and signal_length to use repeat().take(...) instead of vec![...].into_iter().map(...).src/circuit/noir/mod.rs (4)
267-273: Clarify theprover_addressarray format.The
prover_addressis wrapped in an array containing a single string element. If the Noir circuit expects a different format (e.g., a plain string, or an array of bytes), this could cause input validation issues. Consider adding a comment documenting the expected format or verifying against the circuit specification.// prover_address is serialized as ["0x..."] - single-element array of hex string circuit_inputs["prover_address"] = serde_json::Value::Array(vec![serde_json::Value::String(prover_eth_address.clone())]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/noir/mod.rs` around lines 267 - 273, The code sets circuit_inputs["prover_address"] to a single-element JSON array of a hex string (using params.prover_eth_address) which may not match the Noir circuit's expected input shape; update or document this: either change the value to the exact format the circuit expects (e.g., a plain JSON string, an array of bytes, or a zero-padded hex string) in the block that sets circuit_inputs["prover_address"] (where params.prover_eth_address is used), or add a concise comment above that assignment explicitly stating the expected Noir format ("prover_address is serialized as [\"0x...\"]") and add a small validation/assertion against that expectation to fail fast if params.prover_eth_address does not match the required pattern.
441-467: Test lacks explicit assertions.The test only verifies that the functions don't panic (via
unwrap()), but doesn't validate the correctness of the output. Consider adding assertions to verify expected fields are present and have valid values.💡 Example assertions to add
// Test the struct-based approach let noir_circuit_input = generate_noir_circuit_input(email, params.clone()) .await .unwrap(); // Add assertions assert!(!noir_circuit_input.header.storage.is_empty(), "header should not be empty"); assert!(noir_circuit_input.header.len > 0, "header length should be positive"); assert!(!noir_circuit_input.pubkey.modulus.is_empty(), "pubkey modulus should not be empty"); assert!(!noir_circuit_input.signature.is_empty(), "signature should not be empty"); assert!(noir_circuit_input.from_header_sequence.is_some(), "from_header_sequence should be present when extract_from is true");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/noir/mod.rs` around lines 441 - 467, The test test_generate_noir_circuit_input only checks for panics; add explicit assertions to validate the returned structure from generate_noir_circuit_input and the JSON from generate_noir_circuit_input_json: after calling generate_noir_circuit_input(email, params.clone()).await.unwrap(), assert that noir_circuit_input.header.storage is not empty, noir_circuit_input.header.len > 0, noir_circuit_input.pubkey.modulus is not empty, noir_circuit_input.signature is not empty, and (since params.extract_from is Some(true)) noir_circuit_input.from_header_sequence.is_some(); similarly parse or inspect the string returned by generate_noir_circuit_input_json(email, params).await.unwrap() to assert presence of key fields (header, pubkey, signature, from_header_sequence) to ensure backward-compatible JSON output.
152-186: Duplicate condition check can be consolidated.Lines 152 and 179 both check
params.ignore_body_hash_check.is_some_and(|x| !x). The second block (lines 178-186) could be merged into the first block (lines 152-176) to reduce redundancy and improve readability.♻️ Proposed consolidation
if params.ignore_body_hash_check.is_some_and(|x| !x) { if email_circuit_inputs.body_hash_idx.is_none() { return Err(anyhow::anyhow!( "Body hash check is enabled but body hash index is missing" )); } // When sha_precompute_selector is used, body_padded is the REMAINING body after cutoff // and body_padded_len is the actual length of the remaining body let body_len = if params.sha_precompute_selector.is_some() { // Use the remaining body length from email_circuit_inputs email_circuit_inputs .body_padded_len .unwrap_or(parsed_email.canonicalized_body.len()) } else { // No selector - use the full canonicalized body length parsed_email.canonicalized_body.len() }; noir_circuit_input.body = Some(BoundedVec { storage: body_storage_zero_padded.clone(), len: body_len, }); noir_circuit_input.body_hash_index = email_circuit_inputs.body_hash_idx; - } - // Always generate partial_body_hash when body verification is enabled - if params.ignore_body_hash_check.is_some_and(|x| !x) { + // Generate partial_body_hash when body verification is enabled noir_circuit_input.partial_body_real_length = Some(parsed_email.canonicalized_body.len()); let precomputed_sha = email_circuit_inputs.precomputed_sha .ok_or_else(|| anyhow::anyhow!("Precomputed SHA is missing but body hash check is enabled"))?; let partial_hash = u8_to_u32(precomputed_sha.as_slice())?; noir_circuit_input.partial_body_hash = Some(partial_hash); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/noir/mod.rs` around lines 152 - 186, The two identical guards checking params.ignore_body_hash_check.is_some_and(|x| !x) should be consolidated into a single block: inside the existing if that sets noir_circuit_input.body and body_hash_index, also set noir_circuit_input.partial_body_real_length = Some(parsed_email.canonicalized_body.len()), retrieve precomputed_sha from email_circuit_inputs (returning the same anyhow error if missing), convert it via u8_to_u32 and assign noir_circuit_input.partial_body_hash; then remove the redundant second if entirely so all body-hash related assignments (body, body_hash_index, partial_body_real_length, partial_body_hash) live together.
24-25: Remove unusedDEFAULT_MODULUS_BITSconstant or document its intended use.The constant is defined but never used in the codebase. Key bit detection (lines 38-54) derives the value from the email's public key or the explicit
rsa_key_bitsparameter instead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/circuit/noir/mod.rs` around lines 24 - 25, The constant DEFAULT_MODULUS_BITS is declared but never used; either remove DEFAULT_MODULUS_BITS from src/circuit/noir/mod.rs to avoid dead code, or explicitly document its intended fallback role and wire it into the RSA bit-detection path (the logic that currently derives bits from the email public key or the rsa_key_bits parameter) so that when rsa_key_bits is None and no public key bits can be determined the code uses DEFAULT_MODULUS_BITS as the fallback; update the constant's doc comment if keeping it and add a reference to DEFAULT_MODULUS_BITS in the key-detection code path so its purpose is clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@browser_test/index.html`:
- Line 11: The HTML entry script src is pointing to the compiled JS file that
doesn't exist ("/src/main.js"); update the <script type="module" src="..."> tag
to reference the actual TypeScript entry ("src/main.ts") so the browser loads
the correct module, and keep type="module" intact; verify the file name used in
the tag matches the actual file in the repo (main.ts) and commit the change.
In `@browser_test/public/amazon.eml`:
- Around line 1-1000: This fixture contains real-looking PII (Delivered-To,
From: "Amazon.com" <order-update@amazon.com>, Message-ID, order number
111-3061760-5513056 and other headers/body links); replace them with anonymized
synthetic values across the file (e.g. redact Delivered-To, replace
order-update@amazon.com and any real email addresses with test@example.com,
remove or replace Message-ID and ARC/SPF metadata, and convert the order Id and
shipmentId to a clearly fake token like ORDER-TEST-0000) so the public test
asset contains no real personal identifiers while preserving the same structure
for tests.
In `@browser_test/public/github.eml`:
- Around line 1-75: The committed EML fixture (github.eml) contains real PII and
an actual GitHub OAuth event; replace it with a redacted or synthetic fixture:
remove or replace real email addresses (From/To), strip or genericize security
URLs and message-id, and replace the body with a clearly synthetic message
(e.g., placeholder sender, recipient, and fake OAuth app name/scopes) so tests
exercise parsing without exposing real data; ensure the new fixture preserves
the same MIME structure/headers your tests expect and update any tests that
assert exact strings to match the redacted placeholders.
In `@browser_test/public/residency.eml`:
- Around line 1-127: The public .eml fixture contains real PII (e.g., "From:
Leland Lee <leland@succinct.xyz>", "Cc: Uma Roy <uma@succinct.xyz>, Eli Yang
<eli@succinct.xyz>", "Bcc: adityabisht64@gmail.com", Message-ID and the real
subject "Welcome to the Succinct ZK Residency!"); replace the file contents with
a fully sanitized, synthetic email preserving the MIME structure and boundaries
but using fake names/addresses (e.g., "From: Test Sender <sender@example.com>"),
anonymized Subject and Message-ID, non-sensitive placeholder links
(example.com), and remove any real telegram/invite or personal content so the
fixture can remain in browser_test/public without exposing real data.
In `@browser_test/src/circomProver.ts`:
- Around line 59-65: The params construction in GenerateProofInputsParams (in
circomProver.ts) incorrectly uses the || true pattern for removeSoftLineBreaks
(and the duplicate block at lines ~336-342), which overrides an explicit false;
change those assignments to only default to true when the blueprint prop is
undefined (e.g., use nullish coalescing or an explicit undefined check) so that
blueprint.props.removeSoftLinebreaks === false remains respected; update both
occurrences where removeSoftLineBreaks / removeSoftLinebreaks are set and ensure
the property name matches the expected casing used by GenerateProofInputsParams.
- Around line 96-100: The mapping in dcr.parts is incorrectly converting the
snake_case regex into a boolean (`!!p.regex_def`), so change the `regex_def`
assignment in the dcr.parts mapping to preserve the actual regex string (e.g.,
pick p.regexDef if present otherwise p.regex_def) instead of coercing to
boolean; update the same pattern at the other site around the second mapping
(the block referenced at lines ~379-383) so both `regex_def` fields use the
string value from p.regexDef or p.regex_def (use nullish/coalescing or a simple
truthy fallback) while leaving `is_public` handling as-is.
- Around line 83-89: The map branch that computes maxHaystackLength (using
dcr.location and blueprint.props.emailHeaderMaxLength/emailBodyMaxLength) can
return undefined and introduce holes into decomposedRegexesCleaned; change the
logic so it never yields undefined by either substituting the corresponding
default from params (e.g., params.emailHeaderMaxLength or
params.emailBodyMaxLength) when blueprint.props value is missing, or by throwing
a clear error before building the array, and ensure the map never returns
undefined (alternatively filter out falsy results after mapping) so
decomposedRegexesCleaned contains only valid entries for the WASM serializer.
- Around line 13-19: The current init() catch only logs and leaves
relayerUtilsInit unresolved; update the promise setup so you capture both
resolve and reject (e.g., relayerUtilsResolve and relayerUtilsReject) instead of
only relayerUtilsResolver, and in the catch handler call relayerUtilsReject(err)
(or otherwise reject relayerUtilsInit with the error) so awaiting
relayerUtilsInit fails fast on WASM init errors; locate the init() call and the
relayerUtilsResolver (promise creation for relayerUtilsInit) and add the
corresponding relayerUtilsReject usage in the catch branch.
In `@browser_test/src/noirProver.ts`:
- Around line 98-101: The call to addMaxLengthToExternalInputs([],
blueprint.props.externalInputs) will throw whenever
blueprint.props.externalInputs has definitions but you pass an empty values
array; update the call site in noirProver.ts to either (a) pass the actual
external input values array (not []), e.g. the variable that holds provided
external inputs for the run, or (b) guard the call with a check on
blueprint.props.externalInputs.length and only call addMaxLengthToExternalInputs
when there are both definitions and corresponding values, otherwise
return/handle the no-external-inputs case early; reference
addMaxLengthToExternalInputs and blueprint.props.externalInputs to locate the
change.
In `@browser_test/src/prover-server.ts`:
- Around line 94-97: In the dcr.parts mapping (the arrow mapping that builds
parts objects), fix the incorrect fallback for regex_def by replacing the bogus
fallback "!!p.is_public" with the correct "p.regex_def" so that regex_def is set
from p.regexDef || p.regex_def; update the mapping where p.regexDef and
p.isPublic are used to ensure regex_def uses p.regex_def as the fallback.
In `@src/circuit/circom.rs`:
- Around line 243-250: The call to ParsedEmail::new_from_raw_email uses
params.as_ref().and_then(|p| p.ignore_body_hash_check).unwrap_or(false) which
defaults ignore_body_hash_check to false, causing inconsistency with Noir (which
defaults to true); change the unwrap_or(false) to unwrap_or(true) so
ParsedEmail::new_from_raw_email receives the same default, and ensure any unit
tests or callers that rely on ParsedEmail::new_from_raw_email or the params
struct reflect this default behavior.
- Around line 503-509: The code currently indexes decomposed_regexes[0] which
will panic if decomposed_regexes is empty; add a guard at the start of the logic
(check decomposed_regexes.is_empty()) and return a descriptive Err instead of
indexing, then only branch to call generate_circuit_inputs(...) or
generate_circuit_inputs_old(...) after confirming the vector has at least one
element; reference the decomposed_regexes variable and the
generate_circuit_inputs / generate_circuit_inputs_old call sites so you modify
the same conditional block to return an error result (with a clear message like
"no decomposed regexes provided") when empty.
In `@src/circuit/mod.rs`:
- Around line 137-138: Before calling sha256_pad, validate that the unpadded
input will not exceed the requested max once SHA-256 padding is applied: compute
the padded length (or reuse a helper like sha256_padded_length) for
params.header and compare it to params.max_header_length, and if it would
exceed, return an Err from the builder instead of calling sha256_pad (which
currently asserts/panics). Apply the same explicit check for params.body vs
params.max_body_length (the related code around lines 195–218) so oversized
inputs are rejected via Result rather than causing a panic.
In `@src/circuit/noir/utils.rs`:
- Around line 216-234: The regex currently uses .*/.*? which stops at the first
physical newline and therefore misses RFC‑822 folded header continuations;
update the pattern building in the functions (used by get_header_sequence and
get_address_header_sequence) to allow folded lines by matching the header field
name then the rest of the header value including any subsequent lines that start
with space or tab (e.g. append a repeated group like (?:\r?\n[ \t]+[^\r\n]*)* or
enable DOTALL and explicitly consume folded continuations) before ending the
match; apply the same fix to the other affected block (around the code at
260-296) and ensure the Regex::new error handling remains intact.
In `@src/circuit/utils.rs`:
- Around line 29-31: The current bounds check and mapping for selector_end_index
are wrong: allow selector_end_index == position_map.len() (use <=) and compute
the exclusive original end correctly by mapping selector_end_index to the
original byte after the match; specifically, keep original_start_index =
position_map[selector_start_index], but set original_end_index = if
selector_end_index == position_map.len() { original_body.len() } else {
position_map[selector_end_index - 1] + 1 }; update the if-condition from
selector_end_index < position_map.len() to selector_end_index <=
position_map.len() and use these computed values for slicing to avoid usize::MAX
and off-by-one errors when matches end at the cleaned content end.
In `@src/cryptos.rs`:
- Around line 523-533: The loop that strips SHA padding in the body_str
construction (working on variable trimmed_body) can underflow when
trimmed_body.len() < 2; change the logic to loop only while trimmed_body.len()
>= 2 and the last two bytes are not b"\r\n", popping bytes as you go, and after
the loop return an Err (parse error) if trimmed_body.len() < 2 or the final two
bytes are not CRLF; apply the same fix to the analogous loop around lines
589-599. Ensure you use trimmed_body.last() and trimmed_body.get(len-2) safely
by checking len >= 2 before accessing len-2 and preserve the existing Result
error type when returning the parse failure.
In `@src/regex/patterns.rs`:
- Around line 24-38: Update FROM_ADDR_CONFIG and TO_ADDR_CONFIG so they match
both display-name-with-brackets and bare-address forms; replace the surrounding
fixed Pattern parts with versions that allow optional angle-bracketed display
names (e.g. change RegexPart::Pattern(r"(?i)from:.*<") to something like
r"(?i)from:\s*(?:.*<)?", and change the trailing RegexPart::Pattern(r">") to an
optional r"(?:>)?"), and do the analogous change for the TO config; keep the
existing RegexPart::PublicPattern (the email capture) unchanged so
DecomposedRegexConfig still extracts the same group.
- Around line 42-46: The SUBJECT_CONFIG's public pattern
(RegexPart::PublicPattern currently using r".+?(?=\r?\n\S|\r?\n\r?\n)") stops at
physical newlines and thus drops RFC5322 folded continuation lines; update that
pattern to allow CRLF followed by SP/HTAB as part of the subject (for example
replace the dot-plus with a construct that matches either non-newline chars or
CRLF followed by a space/tab, e.g. a repeated group like (?:[^\r\n]|\r?\n[ \t])+
with the same lookahead and keep the existing 512 length cap) so
extract_subject_all_idxes captures folded Subject: lines fully in SUBJECT_CONFIG
/ DecomposedRegexConfig / RegexPart::PublicPattern.
---
Minor comments:
In `@browser_test/src/localProverWorker.js`:
- Around line 112-116: The call to snarkjs.groth16.fullProve uses
JSON.parse(inputs) which will throw if inputs is already an object; update the
code around the snarkjs.groth16.fullProve invocation to first check the type of
inputs (e.g., if typeof inputs === 'string' then JSON.parse(inputs) else use
inputs directly), optionally validate the resulting object shape before passing
it to fullProve, and ensure any parsing/validation is wrapped so errors are
handled/logged rather than letting JSON.parse throw; refer to the variables
inputs and the snarkjs.groth16.fullProve call to locate the change.
In `@browser_test/src/main.ts`:
- Around line 9-15: The HTML template uses React/JSX attribute "className" which
isn't recognized when setting innerHTML; update the template for the elements
under the "noir-prover" and "circom-prover" blocks to use the standard HTML
attribute "class" (e.g., change className="flex mt-5" and className="prove" to
class="flex mt-5" and class="prove") so the CSS classes on the <div> and
<button> elements (including the "prove" button) are applied correctly.
In `@browser_test/src/noirProver.ts`:
- Around line 254-257: The comparison currently uses partStr.length (code units)
vs partLength parsed from publicOutputs[publicOutputIterator]; replace that
check to compare the UTF‑8 byte length instead by computing the number of bytes
of partStr (e.g. using a TextEncoder) and compare that byte count to partLength
so multi‑byte characters are measured correctly; update the conditional around
partStr, partLength, publicOutputs and publicOutputIterator accordingly.
In `@browser_test/src/prover-server.ts`:
- Line 59: The assignment for removeSoftLineBreaks is using the boolean-or
pattern which forces true even when blueprint.props.removeSoftLinebreaks is
explicitly false; update the initializer for removeSoftLineBreaks (the object
key removeSoftLineBreaks) to use the nullish coalescing operator
(blueprint.props.removeSoftLinebreaks ?? true) so that false is preserved and
only undefined/null fall back to true.
In `@src/circuit/circom.rs`:
- Around line 290-306: The current code masks errors by defaulting to index 0
when parsed_email.get_invitation_code_idxes, parsed_email.get_timestamp_idxes,
or parsed_email.get_command_idxes return Err, which conflates "found at 0" with
"not found"; change the code to return Option<usize> (e.g., let code_idx:
Option<usize> = match ... { Ok((i,_)) => Some(i), Err(_) => None }) or use a
sentinel like usize::MAX, and update EmailCircuitInput.code_idx (and similar
timestamp_idx/command_idx fields) and all downstream consumers to handle
Option<usize> (or the sentinel) instead of assuming 0 is valid so failures are
distinguishable.
In `@src/circuit/utils.rs`:
- Around line 72-86: The code slices original_body using original_start_index
and original_end_index returned by find_selector_in_clean_content without
validating bounds; update the logic in the selector-mapping block to verify that
original_start_index and original_end_index are within 0..=original_body.len()
and that original_start_index <= original_end_index before slicing, and if not
return an Err (propagate a descriptive error) or clamp the indices safely;
reference the variables original_body, original_start_index, original_end_index
and the helper find_selector_in_clean_content so you add the checks immediately
before creating adjusted_selector and only perform String::from_utf8 on a safe
slice.
In `@src/converters.rs`:
- Around line 436-451: Add comprehensive unit tests for the
uint_to_decimal_string function to cover edge cases: include tests for
converting 0, values where the decimal portion is all trailing zeros (e.g.,
input representing 0.1 with decimal=3), cases where decimal places exceed the
integer magnitude, and maximum u128 values with several decimal offsets; ensure
tests assert exact string outputs and exercise paths that use checked_sub and
the found_non_zero_decimal behavior to prevent regressions.
---
Nitpick comments:
In `@browser_test/src/localProverWorker.js`:
- Around line 18-27: The downloadWithRetries function retries immediately; add
an exponential backoff (with optional jitter) between attempts to avoid
hammering a rate-limited/overloaded server: compute a delay like baseDelayMs *
2^(attempt-1) (add small random jitter) and await a sleep Promise before the
next fetch attempt in downloadWithRetries, but do not delay after a successful
fetch or after the final failed attempt; ensure the sleep is implemented using a
Promise around setTimeout so the function remains async.
- Line 118: The code calls await localforage.clear() which wipes all app
storage; instead change the logic in localProverWorker.js to remove only
circuit-related entries: obtain the list of keys via await localforage.keys(),
filter for the worker's circuit key pattern/prefix (e.g. keys that startWith or
include "circuit", "prover", or whatever key names this worker uses), then call
await localforage.removeItem(key) for each matching key (or remove specific
known keys like "circuitFiles" if those are the exact names) rather than
clearing the entire store.
In `@browser_test/src/noirProver.ts`:
- Line 42: The local variable parsedEmail is assigned from await
parseEmail(eml!) but never used; remove the unused variable by either
eliminating the assignment entirely (call await parseEmail(eml!) without
binding) or delete the line, ensuring you keep the call only if side-effects are
needed; target the statement that assigns parsedEmail (the parseEmail/eml usage)
and update it accordingly.
- Around line 24-26: The code creates a prover via blueprint.createProver({
isLocal: true }) but never uses it; either remove the unused creation and its
console.logs, or switch the manual input/proof generation to the prover
abstraction by calling the prover's methods (e.g., prover.generateInputs(...) to
produce circuit inputs and prover.createProof(...) or prover.prove(...) to build
the proof) in place of the current manual steps so the created prover instance
is actually used.
In `@browser_test/src/prover-server.ts`:
- Line 17: Remove the unused import "pako" from the top of prover-server.ts:
locate the import statement `import pako from "pako";` and delete it (or
consolidate imports if later added) so there are no unused dependencies in the
file; ensure no other code in prover-server.ts references `pako` after removal.
In `@src/circuit/circom.rs`:
- Around line 144-163: The manual impl Clone for DecomposedRegex duplicates
behavior that derive would provide; remove the impl Clone block for
DecomposedRegex and add #[derive(Clone)] to the DecomposedRegex struct
definition so all fields (parts, name, max_match_length, max_haystack_length,
haystack_location, regex_graph_json, proving_framework) are cloned
automatically, ensuring you don't change any field semantics.
- Around line 708-725: Add unit tests for compute_signal_length to satisfy the
TODO: create a #[cfg(test)] mod (either in this file or in tests/) with multiple
#[test] cases that call compute_signal_length and assert expected outputs —
include edge cases like max_length = 0, exact multiples (31, 62), values with
remainder (1, 30, 32), and a large value to ensure no overflow; use
assert_eq!(compute_signal_length(x), expected) for each and remove or update the
TODO comment once tests are added.
- Around line 683-689: The padding creates an intermediate Vec by building
vec![0; signal_length - value.len()] then mapping to strings; replace that with
an iterator using std::iter::repeat to avoid the temporary allocation: when
checking if value.len() < signal_length, call
value.extend(std::iter::repeat("0".to_string()).take(signal_length -
value.len())) (or equivalent) so you extend the existing Vec<String> directly;
update the block around value and signal_length to use repeat().take(...)
instead of vec![...].into_iter().map(...).
In `@src/circuit/noir/mod.rs`:
- Around line 267-273: The code sets circuit_inputs["prover_address"] to a
single-element JSON array of a hex string (using params.prover_eth_address)
which may not match the Noir circuit's expected input shape; update or document
this: either change the value to the exact format the circuit expects (e.g., a
plain JSON string, an array of bytes, or a zero-padded hex string) in the block
that sets circuit_inputs["prover_address"] (where params.prover_eth_address is
used), or add a concise comment above that assignment explicitly stating the
expected Noir format ("prover_address is serialized as [\"0x...\"]") and add a
small validation/assertion against that expectation to fail fast if
params.prover_eth_address does not match the required pattern.
- Around line 441-467: The test test_generate_noir_circuit_input only checks for
panics; add explicit assertions to validate the returned structure from
generate_noir_circuit_input and the JSON from generate_noir_circuit_input_json:
after calling generate_noir_circuit_input(email, params.clone()).await.unwrap(),
assert that noir_circuit_input.header.storage is not empty,
noir_circuit_input.header.len > 0, noir_circuit_input.pubkey.modulus is not
empty, noir_circuit_input.signature is not empty, and (since params.extract_from
is Some(true)) noir_circuit_input.from_header_sequence.is_some(); similarly
parse or inspect the string returned by generate_noir_circuit_input_json(email,
params).await.unwrap() to assert presence of key fields (header, pubkey,
signature, from_header_sequence) to ensure backward-compatible JSON output.
- Around line 152-186: The two identical guards checking
params.ignore_body_hash_check.is_some_and(|x| !x) should be consolidated into a
single block: inside the existing if that sets noir_circuit_input.body and
body_hash_index, also set noir_circuit_input.partial_body_real_length =
Some(parsed_email.canonicalized_body.len()), retrieve precomputed_sha from
email_circuit_inputs (returning the same anyhow error if missing), convert it
via u8_to_u32 and assign noir_circuit_input.partial_body_hash; then remove the
redundant second if entirely so all body-hash related assignments (body,
body_hash_index, partial_body_real_length, partial_body_hash) live together.
- Around line 24-25: The constant DEFAULT_MODULUS_BITS is declared but never
used; either remove DEFAULT_MODULUS_BITS from src/circuit/noir/mod.rs to avoid
dead code, or explicitly document its intended fallback role and wire it into
the RSA bit-detection path (the logic that currently derives bits from the email
public key or the rsa_key_bits parameter) so that when rsa_key_bits is None and
no public key bits can be determined the code uses DEFAULT_MODULUS_BITS as the
fallback; update the constant's doc comment if keeping it and add a reference to
DEFAULT_MODULUS_BITS in the key-detection code path so its purpose is clear.
In `@src/regex/padding.rs`:
- Around line 42-58: Add tests covering truncation semantics for pad_string and
pad_bytes: when the input length exceeds the target size, assert the returned
buffer has length equal to the target and contains only the first target bytes
of the input (i.e., verify pad_string("hello world", 5) yields "hello" and
pad_bytes(vec![...longer...], N) yields the first N bytes). Add both a string
truncation case for pad_string and a byte-vector truncation case for pad_bytes
to lock down the silent-truncation behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 08f641aa-14aa-4fd8-8d0e-6166c5d34231
⛔ Files ignored due to path filters (4)
Cargo.lockis excluded by!**/*.lockbrowser_test/bun.lockis excluded by!**/*.lockbrowser_test/public/vite.svgis excluded by!**/*.svgyarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (38)
.gitignoreCargo.tomlbrowser_test/.gitignorebrowser_test/index.htmlbrowser_test/package.jsonbrowser_test/public/amazon.emlbrowser_test/public/github.emlbrowser_test/public/residency.emlbrowser_test/public/x.emlbrowser_test/src/circomProver.tsbrowser_test/src/localProverWorker.jsbrowser_test/src/localProverWorkerString.tsbrowser_test/src/main.tsbrowser_test/src/noirProver.tsbrowser_test/src/prover-server.tsbrowser_test/src/style.cssbrowser_test/tsconfig.jsonbrowser_test/vite.config.jspackage.jsonsrc/circuit.rssrc/circuit/circom.rssrc/circuit/mod.rssrc/circuit/noir/mod.rssrc/circuit/noir/structs.rssrc/circuit/noir/utils.rssrc/circuit/utils.rssrc/converters.rssrc/cryptos.rssrc/lib.rssrc/parse_email.rssrc/regex/extract.rssrc/regex/mod.rssrc/regex/padding.rssrc/regex/patterns.rssrc/regex/types.rssrc/regex/wasm.rssrc/wasm.rsts_tests/circuit_input.test.ts
💤 Files with no reviewable changes (1)
- src/circuit.rs
| </head> | ||
| <body> | ||
| <div id="app"></div> | ||
| <script type="module" src="/src/main.js"></script> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Entry script reference:"
rg -n '<script[^>]+src="/src/main\.(js|ts)"' browser_test/index.html
echo "Available main entry files:"
fd -a 'main\.(js|ts)$' browser_test/srcRepository: zkemail/relayer-utils
Length of output: 218
Fix entry script path to the actual TypeScript entry file.
Line 11 references /src/main.js, but only /src/main.ts exists in this PR. This causes module loading to fail and breaks app bootstrap.
🔧 Proposed fix
- <script type="module" src="/src/main.js"></script>
+ <script type="module" src="/src/main.ts"></script>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <script type="module" src="/src/main.js"></script> | |
| <script type="module" src="/src/main.ts"></script> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_test/index.html` at line 11, The HTML entry script src is pointing to
the compiled JS file that doesn't exist ("/src/main.js"); update the <script
type="module" src="..."> tag to reference the actual TypeScript entry
("src/main.ts") so the browser loads the correct module, and keep type="module"
intact; verify the file name used in the tag matches the actual file in the repo
(main.ts) and commit the change.
| Delivered-To: aayushgupta05@gmail.com | ||
| Received: by 2002:a05:6520:4d11:b0:298:de86:b196 with SMTP id cy17csp1851324lkb; | ||
| Thu, 15 Aug 2024 18:01:48 -0700 (PDT) | ||
| X-Forwarded-Encrypted: i=3; AJvYcCWCx1Cb3kEOBBorrIS5l2e6GCzKJxzBxybTlA6eTJnE+qGUWcW3x0U2DbMEuuE94csCWxFvt47ftW92zpoSTnvWP+8Mc1JAPw== | ||
| X-Google-Smtp-Source: AGHT+IFy7itmDPuDlSHhbsl0mXcp4WaIqPBhoxgtMIUJ4rixUL/hmu7Y7lNb/3SE/waaKnYbynS7 | ||
| X-Received: by 2002:a05:6000:a8b:b0:36b:8f94:e206 with SMTP id ffacd0b85a97d-37194315781mr855253f8f.5.1723770107871; | ||
| Thu, 15 Aug 2024 18:01:47 -0700 (PDT) | ||
| ARC-Seal: i=2; a=rsa-sha256; t=1723770107; cv=pass; | ||
| d=google.com; s=arc-20240605; | ||
| b=L4ifZud+phJJXmpjp/GJ3cSjA1D4Uhl604pR5GCQDZy4O/9FpFTTyQrlajv20a3CLA | ||
| LDohZyTwGvxXuUGOp4AnE3lb/GAeb9AQ3dfKQ5NRnBbbC5j01ow9/3hi/CQUG3K3uRxG | ||
| pCJKwe65M0PZryicz8+ZB1It0JoWHN9b9rWhTUesMV60vRLKHa76jBdrS3n5ykx6u+Hg | ||
| nDR/S+g3/qmdmopzKC4T5rKleVpLdBmBBfnpURBhyrbzR4YRAYrxHh6/Xmfxm2CXnP1G | ||
| BngzD5RfJcQJVBe2Hl7hTsPXNgDIW8Ng+G1w1sU12uUFdLUNMFL3Hmp0YXx52NGCsAxM | ||
| HjSg== | ||
| ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; | ||
| h=feedback-id:bounces-to:mime-version:subject:message-id:to:from:date | ||
| :dkim-signature:dkim-signature; | ||
| bh=a+iNAUuMllM38rUYf1E0PCsZMSzHqdP5Rs6lXnKmcp4=; | ||
| fh=aslmXTwzSzJ1CMviWDZT1UuXOGBFyKTE9qzq5T44VcQ=; | ||
| b=Obl6fTQjJwbp1Z313OnnWM2NPRbOCUSY9p+6WdIDaWpqRQ0scS/tkVJPHyocDMPOFy | ||
| JxFpFA85L6u+XEVp249LYKd2p7z9z+uQaSW/sp0CrL5NPWk/jQcY37eLzlz9UDRVY0OR | ||
| Z8CxOzIiBJtsYGgMN594/rlliZQMEv7+EE7/bp4p0rEMweLeWmS73aT5JjmYvS6D0DrH | ||
| /shB9jMo5zS6qUNR8v8REiTJzcnN+yJ6iZ35c8Bg1rOu94hgJmnWNFLiiC47FEn5bzo9 | ||
| VvuVRFPJh/F8c3pEHTWLfNfjjzzZZA4PvQJS8YJ0isrIoCzeuqJMV0dOs2U8mc+H39Y5 | ||
| IGFg==; | ||
| dara=google.com | ||
| ARC-Authentication-Results: i=2; mx.google.com; | ||
| dkim=pass header.i=@amazon.com header.s=yg4mwqurec7fkhzutopddd3ytuaqrvuz header.b="sk0yWvc/"; | ||
| dkim=pass header.i=@amazonses.com header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=lUY1ph+6; | ||
| arc=pass (i=1 dkim=pass dkdomain=amazon.com dkim=pass dkdomain=amazonses.com); | ||
| spf=pass (google.com: domain of aayushg@mit.edu designates 18.9.21.22 as permitted sender) smtp.mailfrom=aayushg@mit.edu; | ||
| dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com | ||
| Return-Path: <aayushg@mit.edu> | ||
| Received: from exchange-forwarding-2.mit.edu (exchange-forwarding-2.mit.edu. [18.9.21.22]) | ||
| by mx.google.com with ESMTPS id 5b1f17b1804b1-429ded70f98si27296005e9.143.2024.08.15.18.01.47 | ||
| for <aayushgupta05@gmail.com> | ||
| (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); | ||
| Thu, 15 Aug 2024 18:01:47 -0700 (PDT) | ||
| Received-SPF: pass (google.com: domain of aayushg@mit.edu designates 18.9.21.22 as permitted sender) client-ip=18.9.21.22; | ||
| Authentication-Results: mx.google.com; | ||
| dkim=pass header.i=@amazon.com header.s=yg4mwqurec7fkhzutopddd3ytuaqrvuz header.b="sk0yWvc/"; | ||
| dkim=pass header.i=@amazonses.com header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=lUY1ph+6; | ||
| arc=pass (i=1 dkim=pass dkdomain=amazon.com dkim=pass dkdomain=amazonses.com); | ||
| spf=pass (google.com: domain of aayushg@mit.edu designates 18.9.21.22 as permitted sender) smtp.mailfrom=aayushg@mit.edu; | ||
| dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com | ||
| Received: from mailhub-dmz-4.mit.edu (MAILHUB-DMZ-4.MIT.EDU [18.7.62.38]) | ||
| by exchange-forwarding-2.mit.edu (8.14.7/8.12.4) with ESMTP id 47G11hAQ014612 | ||
| for <aayushg@EXCHANGE-FORWARDING.MIT.EDU>; Thu, 15 Aug 2024 21:01:45 -0400 | ||
| Authentication-Results: mit.edu; dmarc=pass (p=quarantine dis=none) header.from=amazon.com | ||
| Authentication-Results: mit.edu; arc=none smtp.remote-ip=18.7.62.38 | ||
| ARC-Seal: i=1; a=rsa-sha256; d=mit.edu; s=arc; t=1723770105; cv=none; b=I3uoniJRBjPCLIEB3xP3hVBkvc+i2uRrt/Qa98Z9Pew6S0B9YMYkhfyoEzqG9SAM9Me5KO0YAvZMbfMtIqtaDh99KBS+iv77kBhEsx5OqUpzb3Wl2zIM+VbewBxhPFUae85UUUYlc3FcomH+e3BYp3s0M+3tU+UeXxMu+BbkcdomHRwIHAPNE4122eo78KPjc0cWQSrX/fL+/v0Z8PY7f99hN5Rqmv15JNhgWDpyrQ7S8UZ2YwzEzN6T8pRH7VhxZDNnwP6JRhylWcaeVEOZt9/x8YaVXBxAxmzz/+mt0J19JRLghzrzbLeUJyiR2M2uqzhH2koHQFf4r5N4/zmXBA== | ||
| ARC-Message-Signature: i=1; a=rsa-sha256; d=mit.edu; s=arc; t=1723770105; | ||
| c=relaxed/relaxed; bh=a+iNAUuMllM38rUYf1E0PCsZMSzHqdP5Rs6lXnKmcp4=; | ||
| h=Date:From:Message-ID:Subject:MIME-Version:Content-Type; b=qB8UXISZyqJo1Cu2Oca57DPK/fwTk63YJ3gOT3iewE5H9ZuhwLDffJOtj+5oTIpeuPsDtEJPfxMP6K3466KjPIhHycLkjJqM1qKZM5XGjcXE2YaWVdeZvFLtPdXAbuxBc98x0GuqXpWkQUuXuDHsOMpGxeIoD0x395i4XQF6JOKCJhqf6airXGRVQ0TvLgOc1sKAsUCiy8LVFxTZIFc959rHxSCd6KN+xomr+QVCELUtwwujGEz/0d2Py7Sf6GmvpDi1Csg8B9VeLWX+vyJ08XheWzGKu7lLRZvJ9KXOTnGskQCwTXs5Melz/84G8ewhiOrHEz4sUW5fx1ksFKJmlw== | ||
| ARC-Authentication-Results: i=1; mit.edu; dkim=pass (1024-bit key; unprotected) header.d=amazon.com header.i=@amazon.com header.a=rsa-sha256 header.s=yg4mwqurec7fkhzutopddd3ytuaqrvuz header.b=sk0yWvc/; dkim=pass (1024-bit key; unprotected) header.d=amazonses.com header.i=@amazonses.com header.a=rsa-sha256 header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=lUY1ph+6 | ||
| Authentication-Results: mit.edu; | ||
| dkim=pass (1024-bit key; unprotected) header.d=amazon.com header.i=@amazon.com header.a=rsa-sha256 header.s=yg4mwqurec7fkhzutopddd3ytuaqrvuz header.b=sk0yWvc/; | ||
| dkim=pass (1024-bit key; unprotected) header.d=amazonses.com header.i=@amazonses.com header.a=rsa-sha256 header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=lUY1ph+6 | ||
| Received: from mailhub-dmz-4.mit.edu (mailhub-dmz-4.mit.edu [127.0.0.1]) | ||
| by mailhub-dmz-4.mit.edu (8.14.7/8.9.2) with ESMTP id 47G11hGU006354 | ||
| for <aayushg@exchange-forwarding.mit.edu>; Thu, 15 Aug 2024 21:01:43 -0400 | ||
| Received: (from mdefang@localhost) | ||
| by mailhub-dmz-4.mit.edu (8.14.7/8.13.8/Submit) id 47G11di4006343 | ||
| for aayushg@exchange-forwarding.mit.edu; Thu, 15 Aug 2024 21:01:39 -0400 | ||
| Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazlp17010006.outbound.protection.outlook.com [40.93.1.6]) | ||
| by MAILHUB-DMZ-4.MIT.EDU (envelope-sender <20240816010133af409d4398414b769006b814f360p0na-C1MH0WGB67NIL9@bounces.amazon.com>) (MIMEDefang) with ESMTP id 47G11bAg006339 | ||
| for <aayushg@mit.edu>; Thu, 15 Aug 2024 21:01:39 -0400 | ||
| Received: from SA9PR11CA0015.namprd11.prod.outlook.com (2603:10b6:806:6e::20) | ||
| by SA0PR01MB6188.prod.exchangelabs.com (2603:10b6:806:da::21) with Microsoft | ||
| SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id | ||
| 15.20.7875.18; Fri, 16 Aug 2024 01:01:34 +0000 | ||
| Received: from SA2PEPF00003F61.namprd04.prod.outlook.com | ||
| (2603:10b6:806:6e:cafe::b0) by SA9PR11CA0015.outlook.office365.com | ||
| (2603:10b6:806:6e::20) with Microsoft SMTP Server (version=TLS1_2, | ||
| cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7828.33 via Frontend | ||
| Transport; Fri, 16 Aug 2024 01:01:34 +0000 | ||
| Authentication-Results: spf=pass (sender IP is 54.240.13.78) | ||
| smtp.mailfrom=bounces.amazon.com; dkim=pass (signature was verified) | ||
| header.d=amazon.com;dmarc=pass action=none | ||
| header.from=amazon.com;compauth=pass reason=100 | ||
| Received-SPF: Pass (protection.outlook.com: domain of bounces.amazon.com | ||
| designates 54.240.13.78 as permitted sender) receiver=protection.outlook.com; | ||
| client-ip=54.240.13.78; helo=a13-78.smtp-out.amazonses.com; pr=C | ||
| Received: from a13-78.smtp-out.amazonses.com (54.240.13.78) by | ||
| SA2PEPF00003F61.mail.protection.outlook.com (10.167.248.36) with Microsoft | ||
| SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.7849.8 | ||
| via Frontend Transport; Fri, 16 Aug 2024 01:01:34 +0000 | ||
| DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; | ||
| s=yg4mwqurec7fkhzutopddd3ytuaqrvuz; d=amazon.com; t=1723770094; | ||
| h=Date:From:To:Message-ID:Subject:MIME-Version:Content-Type; | ||
| bh=fHIH8oc4fnqEfBc2yA88CwZjgGRwbXrwhe87j4ItCcQ=; | ||
| b=sk0yWvc/xR48M8krmQkjZbwkeIFlDIHr96+9q2KY0UxYchD4Usu4LurSXTq0YF/8 | ||
| oXyRB0j9ocgDkpl6ASsyHrQJUn/Vy1nqvmJOAFRTV9v4NJyCquwME/hanRWmyDV8AJC | ||
| SpsrDeISMzFsQMvX3/BZ09/wAO+XPKNPx3iYrwfg= | ||
| DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; | ||
| s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug; d=amazonses.com; t=1723770094; | ||
| h=Date:From:To:Message-ID:Subject:MIME-Version:Content-Type:Feedback-ID; | ||
| bh=fHIH8oc4fnqEfBc2yA88CwZjgGRwbXrwhe87j4ItCcQ=; | ||
| b=lUY1ph+6Hec4F2znvRMGzsMh87R1d8Zm/OiEqyOJdcoaC7SxQgTyiCqlG09+4OH6 | ||
| fH1GNOI1pZmXZ3eBxbRLf0r9wpTn+VpX7PkwvW6qZK4bDuEXGWcD7BOCL49qiDYgQ5E | ||
| WYWaB24Gp9ZuGr+aB8mX1q7X0tkjSQPh+SPwdWGA= | ||
| Date: Fri, 16 Aug 2024 01:01:34 +0000 | ||
| From: "Amazon.com" <order-update@amazon.com> | ||
| To: aayushg@mit.edu | ||
| Message-ID: <0100019158b441de-d0733a8e-e37c-4906-9fc0-59a546ba46cc-000000@email.amazonses.com> | ||
| Subject: Delivered: Your Amazon.com order #111-3061760-5513056 | ||
| MIME-Version: 1.0 | ||
| Content-Type: multipart/alternative; | ||
| boundary="----=_Part_533333_1464710557.1723770094034" | ||
| X-AMAZON-MAIL-RELAY-TYPE: notification | ||
| Bounces-to: 20240816010133af409d4398414b769006b814f360p0na-C1MH0WGB67NIL9@bounces.amazon.com | ||
| X-AMAZON-METADATA: CA=C1MH0WGB67NIL9-CU=A2WSYR24L0Q7DI | ||
| X-Original-MessageID: <urn.rtn.msg.20240816010133af409d4398414b769006b814f360p0na@1723770094035.> | ||
| Feedback-ID: 917195550::1.us-east-1.ZHcGJK6s+x+i9lRHKog4RW3tECwWIf1xzTYCZyUaiec=:AmazonSES | ||
| X-SES-Outgoing: 2024.08.16-54.240.13.78 | ||
| X-EOPAttributedMessage: 0 | ||
| X-EOPTenantAttributedMessage: 64afd9ba-0ecf-4acf-bc36-935f6235ba8b:0 | ||
| X-MS-PublicTrafficType: Email | ||
| X-MS-TrafficTypeDiagnostic: SA2PEPF00003F61:EE_|SA0PR01MB6188:EE_ | ||
| X-MS-Office365-Filtering-Correlation-Id: 8b39e185-a9d4-4bc2-4904-08dcbd8ef988 | ||
| X-MS-Exchange-AtpMessageProperties: SA|SL | ||
| X-MIT-ForwardedCount: 1 | ||
| X-Microsoft-Antispam: | ||
| BCL:0;ARA:13230040|1032899013|12012899012|3092899012|6062899009|5062899012|5082899009|3072899012|32142699015|2092899012|69100299015|4092899012|13102899012|13012899012; | ||
| X-Microsoft-Antispam-Message-Info: | ||
| =?utf-8?B?dDA1dE50U1hkbFJkQVd3dzF0dzZoSk53clFKYU1JTmFkY2pWQ3FvZ2poQWpM?= | ||
| =?utf-8?B?NHZNR2pkWFpDQTc4dFYzUWRQTWdwSlZNRFBLdmMwZ1NoYXd6K21sQ25VTjha?= | ||
| =?utf-8?B?Y3hvdStXM0V6WDFZc1JxaGxKYXEyZnRvOFlhREN2LzZuVzVHS09CNjBQUDA3?= | ||
| =?utf-8?B?eTgrekxSUllJWm9lMVBiV1FSME1HMHhZUkdKZkNIWG92ZzdUZ09pNDYzRGVi?= | ||
| =?utf-8?B?L001VmVhbkhJWWR4L3p5NjRLNnM3Qlc1bitEWkh5dkx2VlVGNG5NRnJGa3Yz?= | ||
| =?utf-8?B?YklZVnhVaVFkM1VjR3BBZnIvU3Q3dXQ0SndNZmMyMnNNSThtN2FnUzNyNFVh?= | ||
| =?utf-8?B?SS9VZFJ2RVdrS2RjV2pNeG1iTUYvaXFJaXdaUWJSanJ4dEJqMUcyNGo5c0wz?= | ||
| =?utf-8?B?YnVLUUM4NHNsOVpkekFqSTlHbWpqQjdWWVBBeDMxL0VLdGRiekNiL3UxZlds?= | ||
| =?utf-8?B?cGZnakJmUzJQTHdHaXp0QVkrVnpVNGFXN2ZTRW4wMEtiblR6ODUvcUxoWG5H?= | ||
| =?utf-8?B?WTVoei9kbS9yVTBJOWk1RnVzL2cvL3JadEVtNUNFVktORnlJL1FMM2dWRFVv?= | ||
| =?utf-8?B?WGdydlFDRjRaMHRBZHVpTnVrMjBpZnplcHE0MGpISHErczJRYVRrMS9Lb1BQ?= | ||
| =?utf-8?B?eWFZU1ZiVzZhbDhScFNpb0czOUU3dkNVWXdTOXQ1M3BFNmw2eDNLNjU1UnRW?= | ||
| =?utf-8?B?ZDZLZDY0b1FVWkxoeVlqTSswbmwrc09tMzdjSk1FSEZ4d3R6dWRtT1NNRnc0?= | ||
| =?utf-8?B?VUp2Y01KN3pEbHJKUXYxdTRDak5zaE1QMDh1akg4NGxOUmNodTVydVErL2J4?= | ||
| =?utf-8?B?RksvdTlROFgyUjlDbzlkZXBMYjFhUC8wcDJHR0FIYVFuZmhadmEvUjhJcC9I?= | ||
| =?utf-8?B?UERhR3VxTEFBVzBaV01weDhLWjlUZVZseVN0cytlYmtTcnNQMTFDdGsyd2sr?= | ||
| =?utf-8?B?Zk9GaXFiWmE3d2lWREc0Q3NqOXRNTlE3K29DdHJuK1NsdFB2NldVbTQ5M0Ri?= | ||
| =?utf-8?B?L1ZHTWtSTlNYZmhVbVc5WUtITVlITHJ2aWo4dmY4ZG5FTGZSNUh6a0dEdTR4?= | ||
| =?utf-8?B?TDVuS2RmT1p3bElKSFc1Z3JPSVlYM0J5YXVyOUJGKzNCbERLK3dydlk0TnV1?= | ||
| =?utf-8?B?dHJlTU1HQktidEF5ajkvd29yUEtSSmt2SDMvejY5dU9XYzZzTUhKczdGTU9j?= | ||
| =?utf-8?B?QnZQSlBVT3RtcDF5NkxEeThNaGFrRG1pdlFhWUVSSXZmYnRkTEpsenJuQy91?= | ||
| =?utf-8?B?ZnRBQ21abC9NV2pscUFZQ1JGTStOUFZSOWZNdEIzcWYvTStiQ01OUE1hazVh?= | ||
| =?utf-8?B?enN6b25qbDN5OTZmVS9sUDBXQTVXWDhoNjFxS1o1S0FjYmVxQUFneFh6QkJJ?= | ||
| =?utf-8?B?K1dVUW1nTW5PbGF2MlNiNi9rRjhvbUMxWDNXZnBvQXhDZ0FWNFRjSi93RG9I?= | ||
| =?utf-8?B?SVdIc01aSVhqMEhnRmxQdlA4MmVBYWtQdXFFcGxZTnZ4Tk5hZVdsTnRoNDlk?= | ||
| =?utf-8?B?MWthWVUxZTArYUtOSUN5MVpxWjdQbmRpSHJ6VFJUYUt1VEV0WmdsWFRtNWIv?= | ||
| =?utf-8?B?T3ZXaTVtWGM2bzJlMkN5Z0pmRGoxQ2I0MjBYUGt6WkUzSkhwZHplMjVYY1Fn?= | ||
| =?utf-8?B?RG04bTBEQXJ1NmlMVi9rN3R2NDdvSTZ0RGVrNE42dGtSNVdWZXpjaUNFaGgx?= | ||
| =?utf-8?B?V2Jja3h1WXZVaktNdm1sSjBxTVVqTGdoMTlMbTVSVjVlbk9IR3NtVlFPRzhP?= | ||
| =?utf-8?B?TWhZMkluZGllNzJqRFhKNG1sMnBpLy9nTnc0WVdzbE1DNHNzbVZFTTlvRTc2?= | ||
| =?utf-8?B?Vi8vcVdSbmRUaDJNclY0a2QxM2NTNmljR01JNHF0SjBQUklkeEllYU1wNERl?= | ||
| =?utf-8?B?ekdJVlNpa09iWkZlbEJqMXR6b1dWWHE1aWpZK3JpaXlROFJtSDRFZHZjRHp3?= | ||
| =?utf-8?B?R29COXZpN2I3ajljaGlRRjkyZDIyenA4R0dIb2xBZkFLY1FJMU1kR3J3SG1U?= | ||
| =?utf-8?B?QmNMQnYzRnNqVHdQYmtlbzdES0xtRkExZE84d3FxelRYV3gyUjBySmZjdUM3?= | ||
| =?utf-8?B?QzNWVzZUKzdaL3hVb0ZvLzZ2MFFmcEM0VHNjaVZWUjE0MDlZR3dIQnc1bkIx?= | ||
| =?utf-8?B?N2VOUlZoSnF2RGYyZzgyWWZEeXJHSHlDakNIUFJhZmU1d1VXMlBUYzZTVFcw?= | ||
| =?utf-8?B?Uk5aMit5Q3ZCNzg2eFEwNTJBT3VIZlFuYlVhRnozZGoyajNhc2dVemo0SXNN?= | ||
| =?utf-8?B?RVp2RHQ1SHcvOG5ZWC93QnpQbFMycWYzUzErM0VMeGxmUnIzcnB0OThVS1VZ?= | ||
| =?utf-8?B?bk9kNk1PNS9kSFpmU2ZxUXRhWVJkTzN5ZWFqOVN1c2lDZVhaN0VjZW56cGE4?= | ||
| =?utf-8?B?eUVlNUtWTXNMVWZxVHFydzVEVDNIUjRmc3ltWVMxU3BXUFBlSnZTeEZ5SHZJ?= | ||
| =?utf-8?B?UUVHTTA4RVR3NjFYOWlGbVp1eU1FN0NDL2F6RzROanEzMEMyQzhhd3I4enh0?= | ||
| =?utf-8?Q?y43yNOONjO+?= | ||
| X-Forefront-Antispam-Report: | ||
| CIP:54.240.13.78;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:a13-78.smtp-out.amazonses.com;PTR:a13-78.smtp-out.amazonses.com;CAT:NONE;SFS:(13230040)(1032899013)(12012899012)(3092899012)(6062899009)(5062899012)(5082899009)(3072899012)(32142699015)(2092899012)(69100299015)(4092899012)(13102899012)(13012899012);DIR:INB; | ||
| X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 | ||
| X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: | ||
| z1rzeYVa+P7w3Uut5PZY4XFxKFVPPMoRlChKSBEkqD70if+MiDWrj2kOzicowSH5/Ryv/yUxMBE5phZvD5onyE/TRH0DlXbWQHsVZq/ckPMOoPW60O70g7+Xp+ugQamDxA9jkDTgheWYPKDqTWmDgIAXrXe+gvQMpon+9pX4OvOUeIvap679lvHzOG7B3yR46+gn1J40mD9blXsZKSE+iDvWuc36A1bTZ8LPrpO4aWQP8UvqI8U+EebELungZppda6de5Si6ilLMSkckWRbqY/9LP9t+EUw6v9vh0GA2ExA/9TLvC/O9ARvbd4Yi2ZETUNj2awhkwVCrChWM05WWbbLXT1MqMzR1ErJxnDGIcs0jQ32ITjTNdC0zR4icAc72+gVhXdW8hdP5smLE1aD2h2zTGBo9nBHRterNuL1H1Cidl0rIjL3AA+5bgi01KTZNIatilr5DG9prwfrHNNkM2w/FT95g8nslWM2nEwu02YnP+XJEHHrxFXPPhJJHuGnqOI/dRGZ3YqEeO8VJMeC/dEqdsQMkVp8WR4TSd/rUgt46esSmEVXuMxpxaAMvcltPbFp9IFrfSz7JUCmxmgNAw6uGmPyiX1mFIA3PpRPODOpe2y/Bo/kJZul19eejoX2i | ||
| X-OriginatorOrg: mitprod.onmicrosoft.com | ||
| X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Aug 2024 01:01:34.7825 | ||
| (UTC) | ||
| X-MS-Exchange-CrossTenant-Network-Message-Id: 8b39e185-a9d4-4bc2-4904-08dcbd8ef988 | ||
| X-MS-Exchange-CrossTenant-Id: 64afd9ba-0ecf-4acf-bc36-935f6235ba8b | ||
| X-MS-Exchange-CrossTenant-AuthSource: | ||
| SA2PEPF00003F61.namprd04.prod.outlook.com | ||
| X-MS-Exchange-CrossTenant-AuthAs: Anonymous | ||
| X-MS-Exchange-CrossTenant-FromEntityHeader: Internet | ||
| X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR01MB6188 | ||
| X-MS-Exchange-CrossPremises-OriginalClientIPAddress: 54.240.13.78 | ||
| X-MS-Exchange-CrossPremises-TransportTrafficType: Email | ||
| X-MS-Exchange-CrossPremises-AuthSource: | ||
| SA2PEPF00003F61.namprd04.prod.outlook.com | ||
| X-MS-Exchange-CrossPremises-AuthAs: Anonymous | ||
| X-MS-Exchange-CrossPremises-Antispam-ScanContext: | ||
| DIR:Incoming;SFV:NSPM;SKIP:0; | ||
| X-MS-Exchange-CrossPremises-SCL: 1 | ||
| X-MS-Exchange-CrossPremises-Processed-By-Journaling: Journal Agent | ||
| X-OrganizationHeadersPreserved: SA0PR01MB6188.prod.exchangelabs.com | ||
|
|
||
| ------=_Part_533333_1464710557.1723770094034 | ||
| Content-Type: text/plain; charset=utf-8 | ||
| Content-Transfer-Encoding: quoted-printable | ||
|
|
||
|
|
||
| =20 | ||
|
|
||
|
|
||
| Hi Aayush, | ||
| Your package has been delivered to reception. | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| How was your delivery? | ||
| It was great https://www.amazon.com/progress-tracker/package?_encoding=3DUT= | ||
| F8&itemId=3D&orderId=3D111-3061760-5513056&packageIndex=3D0&shipmentId=3D30= | ||
| 0612189807301&ingress=3Demail&intent=3Dfeedback_happy&ref_=3Dpdc_f_h | ||
| Not so great https://www.amazon.com/progress-tracker/package?_encoding=3DUT= | ||
| F8&itemId=3D&orderId=3D111-3061760-5513056&packageIndex=3D0&shipmentId=3D30= | ||
| 0612189807301&ingress=3Demail&intent=3Dfeedback_unhappy&ref_=3Dpdc_f_s | ||
|
|
||
| Track package | ||
| https://www.amazon.com/gp/your-account/ship-track?ie=3DUTF8&itemId=3D&order= | ||
| Id=3D111-3061760-5513056&packageIndex=3D0&shipmentId=3DGhsHRNhnG&ref_=3Dpdc= | ||
| _pt_track | ||
|
|
||
| Order # 111-3061760-5513056 | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| Return or replace items in [Your Orders](https://www.amazon.com/your-orders= | ||
| /orders?ref_=3Dpdc_yo). | ||
|
|
||
|
|
||
|
|
||
| =C2=A92024 Amazon.com, Inc. or its affiliates. Amazon and all related marks= | ||
| are trademarks of Amazon.com, Inc. or its affiliates, Amazon.com, Inc. 410= | ||
| Terry Avenue N., Seattle, WA 98109. | ||
|
|
||
| Amazon.com | ||
| ------=_Part_533333_1464710557.1723770094034 | ||
| Content-Type: text/html; charset=utf-8 | ||
| Content-Transfer-Encoding: quoted-printable | ||
|
|
||
| <!doctype html><html lang=3D"en" dir=3D"auto" xmlns=3D"http://www.w3.org/19= | ||
| 99/xhtml" xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-= | ||
| microsoft-com:office:office"><head><title></title><!--[if !mso]><!--><meta = | ||
| http-equiv=3D"X-UA-Compatible" content=3D"IE=3Dedge"><!--<![endif]--><meta = | ||
| http-equiv=3D"Content-Type" content=3D"text/html; charset=3DUTF-8"><meta na= | ||
| me=3D"viewport" content=3D"width=3Ddevice-width,initial-scale=3D1"><style t= | ||
| ype=3D"text/css">#outlook a{padding:0}body{margin:0;padding:0;-webkit-text-= | ||
| size-adjust:100%;-ms-text-size-adjust:100%}table,td{border-collapse:collaps= | ||
| e;mso-table-lspace:0pt;mso-table-rspace:0pt}img{border:0;height:auto;line-h= | ||
| eight:100%;outline:0;text-decoration:none;-ms-interpolation-mode:bicubic}p{= | ||
| display:block;margin:13px 0}</style><!--[if mso]> | ||
| <noscript> | ||
| <xml> | ||
| <o:OfficeDocumentSettings> | ||
| <o:AllowPNG/> | ||
| <o:PixelsPerInch>96</o:PixelsPerInch> | ||
| </o:OfficeDocumentSettings> | ||
| </xml> | ||
| </noscript> | ||
| <![endif]--><!--[if lte mso 11]> | ||
| <style type=3D"text/css">.mj-outlook-group-fix{width:100%!important}</s= | ||
| tyle> | ||
| <![endif]--><style type=3D"text/css">@media only screen and (min-width:= | ||
| 600px){.mj-column-per-100{width:100%!important;max-width:100%}.mj-column-pe= | ||
| r-50{width:50%!important;max-width:50%}.mj-column-per-33{width:33%!importan= | ||
| t;max-width:33%}.mj-column-per-67{width:67%!important;max-width:67%}}</styl= | ||
| e><style media=3D"screen and (min-width:600px)">.moz-text-html .mj-column-p= | ||
| er-100 { width:100% !important; max-width: 100%; } | ||
| .moz-text-html .mj-column-per-50 { width:50% !important; max-width: 50%; } | ||
| .moz-text-html .mj-column-per-33 { width:33% !important; max-width: 33%; } | ||
| .moz-text-html .mj-column-per-67 { width:67% !important; max-width: 67%; }<= | ||
| /style><style type=3D"text/css">.rio-card-70 p+p{margin-top:1.2em}@media (p= | ||
| refers-color-scheme:dark){.rio-header-64,.rio-header-64 *{color:#fff!import= | ||
| ant}}@media (prefers-color-scheme:dark){.rio-header-65,.rio-header-65 *{col= | ||
| or:#fff!important}}@media (prefers-color-scheme:dark){.rio-text-121{color:#= | ||
| fff}}@media (prefers-color-scheme:dark){.rio-text-122{color:#fff}}@media (p= | ||
| refers-color-scheme:dark){.rio-text-123{color:#fff}}@media (prefers-color-s= | ||
| cheme:dark){.rio-text-124{color:#fff}}@media (prefers-color-scheme:dark){.r= | ||
| io-text-125{color:#fff}}@media (prefers-color-scheme:dark){.rio-text-126{co= | ||
| lor:#fff}}@media only screen and (min-width:600px){.rio-asin-image-1NSmq2Ns= | ||
| zkzYrLmYYAndnK .productImageTd{height:165px!important}.rio-asin-image-1NSmq= | ||
| 2NszkzYrLmYYAndnK .productImage{max-height:165px!important;max-width:165px!= | ||
| important}}@media (prefers-color-scheme:dark){.rio-text-127{color:#fff}}@me= | ||
| dia (prefers-color-scheme:dark){.rio-text-128{color:#fff}}.rio-card-72 p+p{= | ||
| margin-top:1.2em}@media (prefers-color-scheme:dark){.rio-header-66,.rio-hea= | ||
| der-66 *{color:#fff!important}}@media (prefers-color-scheme:dark){.rio-head= | ||
| er-67,.rio-header-67 *{color:#fff!important}}@media (prefers-color-scheme:d= | ||
| ark){.rio-text-129{color:#fff}}@media (prefers-color-scheme:dark){.rio-card= | ||
| ,.rio-card>table{background-color:#181a1a!important}}[data-ogsc] .rio-card,= | ||
| [data-ogsc] .rio-card>table{background-color:#181a1a!important}.rio-header = | ||
| strong{color:#067d62}@media (prefers-color-scheme:dark){.rio-header a{color= | ||
| :#6ed6e6!important}.rio-header strong{color:#13bd96!important}}[data-ogsc] = | ||
| .rio-header,[data-ogsc] .rio-header *{color:#fff!important}[data-ogsc] .rio= | ||
| -header a{color:#6ed6e6!important}[data-ogsc] .rio-header strong{color:#13b= | ||
| d96!important}@media only screen and (max-width:599px){table.mj-full-width-= | ||
| mobile{width:100%!important}td.mj-full-width-mobile{width:auto!important}}.= | ||
| rio-text strong{color:#067d62}.rio-text img{width:100%;height:auto}@media (= | ||
| prefers-color-scheme:dark){.rio-text *{color:#fff!important}.rio-text a,.ri= | ||
| o-text a>*{color:#6ed6e6!important}.rio-text strong{color:#13bd96!important= | ||
| }}[data-ogsc] .rio-text *{color:#fff!important}[data-ogsc] .rio-text a,[dat= | ||
| a-ogsc] .rio-text a>*{color:#6ed6e6!important}[data-ogsc] .rio-text strong{= | ||
| color:#13bd96!important}@media (prefers-color-scheme:dark){.rio-button-seco= | ||
| ndary *{color:#0f1111!important;background:#fefefe!important;background-col= | ||
| or:linear-gradient(#fefefe,#fefefe)!important}}[data-ogsc] .rio-button-seco= | ||
| ndary *{color:#0f1111!important;background:#fefefe!important;background-col= | ||
| or:linear-gradient(#fefefe,#fefefe)!important}.rio-asin-image .productImage= | ||
| {mix-blend-mode:multiply}u+.body .rio-asin-image .productImage{mix-blend-mo= | ||
| de:initial!important}@media (prefers-color-scheme:dark){.rio-asin-image .pr= | ||
| oductImageTd{background-image:linear-gradient(#fff,#fff)!important}.rio-asi= | ||
| n-image .productImage{mix-blend-mode:initial!important}}[data-ogsc] .rio-as= | ||
| in-image .productImageTd{background-image:linear-gradient(#fff,#fff)!import= | ||
| ant}[data-ogsc] .rio-asin-image .productImage{mix-blend-mode:initial!import= | ||
| ant}@media only screen and (min-width:600px){u+.body .rio-asin-image .produ= | ||
| ctImage{mix-blend-mode:multiply!important}}.footerCard li,.footerCard p{col= | ||
| or:inherit}.footerCard p+p{margin-top:1.2em}@media (prefers-color-scheme:da= | ||
| rk){.footerCard div{background-color:#303333!important}.footerLink div{colo= | ||
| r:#6ed6e6!important}.footerText div{color:#c8cccc!important}.lightFooterImg= | ||
| {display:none!important}.darkFooterImg{display:block!important}}[data-ogsb]= | ||
| .footerCard div{background-color:#303333!important}[data-ogsc] .footerLink= | ||
| div{color:#6ed6e6!important}[data-ogsc] .footerText div{color:#c8cccc!impo= | ||
| rtant}[data-ogsc] .lightFooterImg{display:none!important}[data-ogsc] .darkF= | ||
| ooterImg{display:block!important}</style><style type=3D"text/css">@font-fac= | ||
| e{font-family:Ember;font-weight:700;src:local("Ember"),url(https://m.media-= | ||
| amazon.com/images/G/01/outbound/AmazonEmber_Bd._CB1515450239_.WOFF) format(= | ||
| "woff");mso-generic-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-= | ||
| family:Ember;font-weight:600;src:local("Ember"),url(https://m.media-amazon.= | ||
| com/images/G/01/outbound/AmazonEmber_Bd._CB1515450239_.WOFF) format("woff")= | ||
| ;mso-generic-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-family:= | ||
| Ember;font-weight:500;src:local("Ember"),url(https://m.media-amazon.com/ima= | ||
| ges/G/01/outbound/AmazonEmber_Md._CB1515450239_.WOFF) format("woff");mso-ge= | ||
| neric-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-family:Ember;f= | ||
| ont-weight:400;font-style:normal;src:local("Ember"),url(https://m.media-ama= | ||
| zon.com/images/G/01/outbound/AmazonEmber_Rg._CB1515450239_.WOFF) format("wo= | ||
| ff");mso-generic-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-fam= | ||
| ily:Ember;font-weight:200;src:local("Ember"),url(https://m.media-amazon.com= | ||
| /images/G/01/outbound/AmazonEmber_Lt._CB1515450239_.WOFF) format("woff");ms= | ||
| o-generic-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-family:"Am= | ||
| azon Ember";font-weight:700;src:local("Amazon Ember"),url(https://m.media-a= | ||
| mazon.com/images/G/01/outbound/AmazonEmber_Bd._CB1515450239_.WOFF) format("= | ||
| woff");mso-generic-font-family:swiss;mso-font-alt:"Arial"}@font-face{font-f= | ||
| amily:"Amazon Ember";font-weight:600;src:local("Amazon Ember"),url(https://= | ||
| m.media-amazon.com/images/G/01/outbound/AmazonEmber_Bd._CB1515450239_.WOFF)= | ||
| format("woff");mso-generic-font-family:swiss;mso-font-alt:"Arial"}@font-fa= | ||
| ce{font-family:"Amazon Ember";font-weight:500;src:local("Amazon Ember"),url= | ||
| (https://m.media-amazon.com/images/G/01/outbound/AmazonEmber_Md._CB15154502= | ||
| 39_.WOFF) format("woff");mso-generic-font-family:swiss;mso-font-alt:"Arial"= | ||
| }@font-face{font-family:"Amazon Ember";font-style:normal;font-weight:400;sr= | ||
| c:local("Amazon Ember"),url(https://m.media-amazon.com/images/G/01/outbound= | ||
| /AmazonEmber_Rg._CB1515450239_.WOFF) format("woff");mso-generic-font-family= | ||
| :swiss;mso-font-alt:"Arial"}@font-face{font-family:"Amazon Ember";font-weig= | ||
| ht:200;src:local("Amazon Ember"),url(https://m.media-amazon.com/images/G/01= | ||
| /outbound/AmazonEmber_Lt._CB1515450239_.WOFF) format("woff");mso-generic-fo= | ||
| nt-family:swiss;mso-font-alt:"Arial"}*{font-family:Ember,'Amazon Ember',Ari= | ||
| al,sans-serif;border-spacing:0;margin:0;padding:0}[data-ogsc] :root{--body-= | ||
| bg:#181A1A;--body-color:#ffffff}.rootContent{background:#d5d9d9!important}.= | ||
| fonts,.sans,h1,h2,h3,h4,h5,li,p,table,td,th{color:#0f1111}a{color:#007185;t= | ||
| ext-decoration:none}@media screen and (max-width:599px){.mobile-only{displa= | ||
| y:initial!important}.desktop-only{display:none!important;mso-hide:all!impor= | ||
| tant}}@media screen and (min-width:600px){.mobile-only{display:none!importa= | ||
| nt;mso-hide:all!important}}@media (prefers-color-scheme:light){:root{--body= | ||
| -bg:#ffffff;--body-color:#000000}}@media (prefers-color-scheme:dark){:root{= | ||
| --body-bg:#181A1A;--body-color:#ffffff}body{background-color:#181a1a!import= | ||
| ant}.fonts,.sans,h1,h2,h3,h4,h5,li,p,table,td,th{color:#fff}a{color:#6ed6e6= | ||
| }.rootContent,.rootContent>table{background:#181a1a!important}}[data-ogsc] = | ||
| .fonts,[data-ogsc] .sans,[data-ogsc] h1,[data-ogsc] h2,[data-ogsc] h3,[data= | ||
| -ogsc] h4,[data-ogsc] h5,[data-ogsc] li,[data-ogsc] p{color:#fff}[data-ogsc= | ||
| ] a{color:#6ed6e6}[data-ogsc] .rootContent,[data-ogsc] .rootContent>table{b= | ||
| ackground:#181a1a!important}body{background-color:var(--body-bg)!important;= | ||
| color:var(--body-color)!important;margin:0!important;padding:0}body>img{pos= | ||
| ition:absolute}table{border-spacing:0}h3,h4,h5,p,table th{font-weight:400;m= | ||
| argin:0;padding:0}td{padding:0}img{border:0}a,span,td{word-break:break-word= | ||
| !important}ol,ul{margin-left:32px!important}.button{background-color:#ffd81= | ||
| 4;color:#0f1111!important;border-radius:24px;padding:1px 16px;display:inlin= | ||
| e-block;box-shadow:1px 2px 4px rgba(153,153,153,.2);font-size:13px;line-hei= | ||
| ght:29px;white-space:nowrap;text-decoration:none;margin-top:4px}.box-shadow= | ||
| a{box-shadow:1px 2px 4px rgba(153,153,153,.2)}a,body,table,td{-ms-text-siz= | ||
| e-adjust:100%;-webkit-text-size-adjust:100%}.appleBody a,.appleFooter a{col= | ||
| or:#007185!important;text-decoration:none}a[x-apple-data-detectors]{color:#= | ||
| 007185!important;font-family:inherit!important;font-size:inherit!important;= | ||
| font-weight:inherit!important;line-height:inherit!important}u+#body a{color= | ||
| :#007185!important;font-family:inherit!important;font-size:inherit!importan= | ||
| t;font-weight:inherit!important;line-height:inherit!important}#MessageViewB= | ||
| ody a{color:#007185!important;font-family:inherit!important;font-size:inher= | ||
| it!important;font-weight:inherit!important;line-height:inherit!important}</= | ||
| style><meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Ty= | ||
| pe"><meta content=3D"telephone=3Dno" name=3D"format-detection"><meta conten= | ||
| t=3D"width=3Ddevice-width,initial-scale=3D1;user-scalable=3Dno;" name=3D"vi= | ||
| ewport"><meta content=3D"IE=3D9; IE=3D8; IE=3D7; IE=3DEDGE" http-equiv=3D"X= | ||
| -UA-Compatible"><meta name=3D"x-apple-disable-message-reformatting"><meta c= | ||
| ontent=3D"light dark" name=3D"color-scheme"><meta content=3D"light dark" na= | ||
| me=3D"supported-color-schemes"><!-- | ||
| =20 | ||
| =20 | ||
| =20 | ||
| --><style type=3D"text/css">.productListPrice{color:#565959}.= | ||
| productDiscount{color:#cc0c39}.productPrice{color:#0f1111}@media (prefers-c= | ||
| olor-scheme:dark){.productListPrice{color:#fff!important}.productDiscount{c= | ||
| olor:#ff8c8c!important}.productPrice{color:#fff!important}}[data-ogsc] .pro= | ||
| ductListPrice{color:#fff!important}[data-ogsc] .productDiscount{color:#ff8c= | ||
| 8c!important}[data-ogsc] .productPrice{color:#fff!important}</style><style = | ||
| type=3D"text/css">.dealBadge{background-color:#cc0c39;color:#fff}.dealText{= | ||
| color:#cc0c39}@media (prefers-color-scheme:dark){.dealBadge{background-colo= | ||
| r:#ff8c8c!important;color:#000!important}.dealText{color:#ff8c8c!important}= | ||
| }[data-ogsc] .dealBadge{background-color:#ff8c8c!important;color:#000!impor= | ||
| tant}[data-ogsc] .dealText{color:#ff8c8c!important}</style><style type=3D"t= | ||
| ext/css">#amazonLogo6ifDMeVChiamBC39CTSZBx.full{max-width:100%!important;pa= | ||
| dding-left:0!important;padding-right:0!important;width:100%!important}#amaz= | ||
| onLogo6ifDMeVChiamBC39CTSZBx.zeroBorder{border:0;border-collapse:collapse;b= | ||
| order-spacing:0}#amazonLogo6ifDMeVChiamBC39CTSZBx .full{max-width:100%!impo= | ||
| rtant;padding-left:0!important;padding-right:0!important;width:100%!importa= | ||
| nt}#amazonLogo6ifDMeVChiamBC39CTSZBx .zeroBorder{border:0;border-collapse:c= | ||
| ollapse;border-spacing:0}#amazonLogo6ifDMeVChiamBC39CTSZBx .light-img{backg= | ||
| round-color:#fff;background-image:linear-gradient(#fff,#fff)}@media (prefer= | ||
| s-color-scheme:light){#amazonLogo6ifDMeVChiamBC39CTSZBx .light-img{display:= | ||
| block!important}#amazonLogo6ifDMeVChiamBC39CTSZBx .dark-img{display:none!im= | ||
| portant}}@media (prefers-color-scheme:dark){#amazonLogo6ifDMeVChiamBC39CTSZ= | ||
| Bx .content{background-color:#181a1a!important}#amazonLogo6ifDMeVChiamBC39C= | ||
| TSZBx .light-img{display:none!important}#amazonLogo6ifDMeVChiamBC39CTSZBx .= | ||
| dark-img{display:block!important}}[data-ogsc] #amazonLogo6ifDMeVChiamBC39CT= | ||
| SZBx .content{background-color:#181a1a!important}[data-ogsc] #amazonLogo6if= | ||
| DMeVChiamBC39CTSZBx .light-img{display:none!important}[data-ogsc] #amazonLo= | ||
| go6ifDMeVChiamBC39CTSZBx .dark-img{display:block!important}</style><!--[if = | ||
| gte mso 9]> | ||
| <xml> | ||
| <o:OfficeDocumentSettings> | ||
| <o:AllowPNG /> | ||
| <o:PixelsPerInch>96</o:PixelsPerInch> | ||
| </o:OfficeDocumentSettings> | ||
| </xml> | ||
| <style> | ||
| body, h1, h2, h3, h4, table, th, td, p, li, a, .sans, .fonts { | ||
| font-family: Helvetica, Arial, sans-serif !important; | ||
| } | ||
| [data-ogsc] .rootContent, [data-ogsc] .rootContent > table{ | ||
| background: #181A1A !important; | ||
| } | ||
| </style> | ||
| <![endif]--></head><body class=3D"body" style=3D"word-spacing:normal;">= | ||
| <img width=3D"1" height=3D"1" src=3D"https://www.amazon.com/gp/r.html?C=3D1= | ||
| Z6HAGN0Q74SS&K=3D1PCIPA854472X&M=3Durn:rtn:msg:20240816010133af409d4398414b= | ||
| 769006b814f360p0na&R=3DE5DJPKCG5QDU&T=3DO&U=3Dhttps%3A%2F%2Fimages-na.ssl-i= | ||
| mages-amazon.com%2Fimages%2FG%2F01%2Fnav%2Ftransp.gif&H=3DF2PRANDPDWFKMJP01= | ||
| PAQRSV6UISA&ref_=3Dpe_108877690_917195550_opens" /><div style=3D"display:no= | ||
| ne;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;max-width:0px= | ||
| ;opacity:0;overflow:hidden;">Delivered: Your Amazon.com order #111-3061760-= | ||
| 5513056͏ ‌   ­͏ ‌   ­= | ||
| ͏ ‌   ­͏ ‌   ­͏ = | ||
| ‌   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌  = | ||
| ­͏ ‌   ­͏ ‌   ­&= | ||
| #847; ‌   ­͏ ‌   ­͏ &= | ||
| zwnj;   ­͏ ‌   ­͏ ‌ &= | ||
| nbsp;   ­͏ ‌   ­͏ ‌ &= | ||
| #8199; ­͏ ‌   ­͏ ‌   = | ||
| ­͏ ‌   ­͏ ‌   ­&#= | ||
| 847; ‌   ­͏ ‌   ­͏ &z= | ||
| wnj;   ­͏ ‌   ­͏ ‌ &n= | ||
| bsp;   ­͏ ‌   ­͏ ‌ &#= | ||
| 8199; ­͏ ‌   ­͏ ‌   &= | ||
| shy;͏ ‌   ­͏ ‌   ­= | ||
| 47; ‌   ­͏ ‌   ­͏ &zw= | ||
| nj;   ­͏ ‌   ­͏ ‌ &nb= | ||
| sp;   ­͏ ‌   ­͏ ‌ = | ||
| 199; ­͏ ‌   ­͏ ‌   &s= | ||
| hy;͏ ‌   ­͏ ‌   ­T= | ||
| 7; ‌   ­͏ ‌   ­͏ &zwn= | ||
| j;   ­͏ ‌   ­͏ ‌ &nbs= | ||
| p;   ­͏ ‌   ­͏ ‌ Q= | ||
| 99; ­͏ ‌   ­͏ ‌   &sh= | ||
| y;͏ ‌   ­͏ ‌   ­͏= | ||
| ; ‌   ­͏ ‌   ­͏ &zwnj= | ||
| ;   ­͏ ‌   ­͏ ‌  = | ||
| ;   ­͏ ‌   ­͏ ‌ ̳= | ||
| 9; ­͏ ‌   ­͏ ‌   ­= | ||
| ;͏ ‌   ­͏ ‌   ­͏= | ||
| ‌   ­͏ ‌   ­͏ ‌= | ||
|   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌  = | ||
| ; ­͏ ‌   ­͏ ‌   ­= | ||
| ͏ ‌   ­͏ ‌   ­͏ = | ||
| ‌   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌  = | ||
| ­͏ ‌   ­͏ ‌   ­&= | ||
| #847; ‌   ­͏ ‌   ­͏ &= | ||
| zwnj;   ­͏ ‌   ­͏ ‌ &= | ||
| nbsp;   ­͏ ‌   ­͏ ‌ &= | ||
| #8199; ­͏ ‌   ­͏ ‌   = | ||
| ­͏ ‌   ­͏ ‌   ­&#= | ||
| 847; ‌   ­͏ ‌   ­͏ &z= | ||
| wnj;   ­͏ ‌   ­͏ ‌ &n= | ||
| bsp;   ­͏ ‌   ­͏ ‌ &#= | ||
| 8199; ­͏ ‌   ­͏ ‌   &= | ||
| shy;͏ ‌   ­͏ ‌   ­= | ||
| 47; ‌   ­͏ ‌   ­͏ &zw= | ||
| nj;   ­͏ ‌   ­͏ ‌ &nb= | ||
| sp;   ­͏ ‌   ­͏ ‌ = | ||
| 199; ­͏ ‌   ­͏ ‌   &s= | ||
| hy;͏ ‌   ­͏ ‌   ­T= | ||
| 7; ‌   ­͏ ‌   ­͏ &zwn= | ||
| j;   ­͏ ‌   ­͏ ‌ &nbs= | ||
| p;   ­͏ ‌   ­͏ ‌ Q= | ||
| 99; ­͏ ‌   ­͏ ‌   &sh= | ||
| y;͏ ‌   ­͏ ‌   ­͏= | ||
| ; ‌   ­͏ ‌   ­͏ &zwnj= | ||
| ;   ­͏ ‌   ­͏ ‌  = | ||
| ;   ­͏ ‌   ­͏ ‌ ̳= | ||
| 9; ­͏ ‌   ­͏ ‌   ­= | ||
| ;͏ ‌   ­͏ ‌   ­͏= | ||
| ‌   ­͏ ‌   ­͏ ‌= | ||
|   ­͏ ‌   ­͏ ‌ = | ||
|   ­͏ ‌   ­͏ ‌  = | ||
| ; ­</div><div class=3D"body" lang=3D"en" dir=3D"auto"><!--[if mso | IE]= | ||
| ><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" c= | ||
| lass=3D"rootContent-outlook" role=3D"presentation" style=3D"width:600px;" w= | ||
| idth=3D"600" bgcolor=3D"#D5D9D9" ><tr><td style=3D"line-height:0px;font-siz= | ||
| e:0px;mso-line-height-rule:exactly;"><![endif]--><div class=3D"rootContent"= | ||
| style=3D"background:#D5D9D9;background-color:#D5D9D9;margin:0px auto;max-w= | ||
| idth:600px;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspa= | ||
| cing=3D"0" role=3D"presentation" style=3D"background:#D5D9D9;background-col= | ||
| or:#D5D9D9;width:100%;"><tbody><tr><td style=3D"direction:ltr;font-size:0px= | ||
| ;padding:0px 0px 4px 0px;text-align:left;"><!--[if mso | IE]><table role=3D= | ||
| "presentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><![endif]--= | ||
| > <!-- PRIME LOGO --><!-- ALEXA LOGO --><!-- AMAZON BUSINESS LOGO --><!-- A= | ||
| ll European Union marketplaces need to use dma compliant logo --> <tab= | ||
| le id=3D"amazonLogo6ifDMeVChiamBC39CTSZBx" class=3D"full zeroBorder" style= | ||
| =3D"width: 100%;" role=3D"presentation"><tbody><tr><td class=3D"content" st= | ||
| yle=3D"padding:0; text-align:left; background-color: #FFFFFF"><!--[if gte m= | ||
| so 9]><table width=3D"600"><tr><td><![endif]--><a href=3D"https://www.amazo= | ||
| n.com/gp/r.html?C=3D1Z6HAGN0Q74SS&K=3D1PCIPA854472X&M=3Durn:rtn:msg:2024081= | ||
| 6010133af409d4398414b769006b814f360p0na&R=3D9WJYLFG12W1E&T=3DC&U=3Dhttps%3A= | ||
| %2F%2Fwww.amazon.com%3Fref_%3Dpe_108877690_917195550_LG0001IMG&H=3DJGWECUYR= | ||
| AY0HTEB3KEJCZQPE9H4A&ref_=3Dpe_108877690_917195550_LG0001IMG" target=3D"_bl= | ||
| ank"><img class=3D"light-img" height=3D"58" role=3D"presentation" src=3D"ht= | ||
| tps://m.media-amazon.com/images/G/01/outbound/OutboundTemplates/Amazon_logo= | ||
| _US._BG255,255,255_.png" style=3D" display:block;background-color: #ffffff;= | ||
| width:auto; height:58px; max-height:58px; max-width:100%; border:0; float:l= | ||
| eft;" alt=3D""> <!--[if !mso]><! --><img class=3D"dark-img" height=3D"58" r= | ||
| ole=3D"presentation" src=3D"https://m.media-amazon.com/images/G/01/outbound= | ||
| /OutboundTemplates/Amazon_logo_whiterev_US.png" style=3D"display:none; widt= | ||
| h:auto; height:58px; max-height:58px; max-width:100%; border:0; float:left;= | ||
| " alt=3D""><!--<![endif]--> </a><!--[if gte mso 9]></td></tr></table><![end= | ||
| if]--></td></tr></tbody></table><!--[if mso | IE]></table><![endif]--></td>= | ||
| </tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]-->= | ||
| <!--[if mso | IE]><table align=3D"center" border=3D"0" cellpadding=3D"0" ce= | ||
| llspacing=3D"0" class=3D"rootContent-outlook" role=3D"presentation" style= | ||
| =3D"width:600px;" width=3D"600" bgcolor=3D"#D5D9D9" ><tr><td style=3D"line-= | ||
| height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div cl= | ||
| ass=3D"rootContent" style=3D"background:#D5D9D9;background-color:#D5D9D9;ma= | ||
| rgin:0px auto;max-width:600px;"><table align=3D"center" border=3D"0" cellpa= | ||
| dding=3D"0" cellspacing=3D"0" role=3D"presentation" style=3D"background:#D5= | ||
| D9D9;background-color:#D5D9D9;width:100%;"><tbody><tr><td style=3D"directio= | ||
| n:ltr;font-size:0px;padding:4px 8px 4px 8px;text-align:left;"><!--[if mso |= | ||
| IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspacin= | ||
| g=3D"0"><![endif]--> <!--[if mso | IE]><tr><td align=3D"left" class= | ||
| =3D"sonar-informational-outlook sonar-informational-v1-outlook" width=3D"60= | ||
| 0px" ><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D= | ||
| "0" class=3D"rio-card-outlook rio-card-70-outlook" role=3D"presentation" st= | ||
| yle=3D"width:584px;" width=3D"584" bgcolor=3D"#ffffff" ><tr><td style=3D"li= | ||
| ne-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div= | ||
| class=3D"rio-card rio-card-70" style=3D"background:#ffffff;background-colo= | ||
| r:#ffffff;margin:0px auto;border-radius:4px;max-width:584px;"><table align= | ||
| =3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presen= | ||
| tation" style=3D"background:#ffffff;background-color:#ffffff;width:100%;bor= | ||
| der-radius:4px;"><tbody><tr><td style=3D"direction:ltr;font-size:0px;paddin= | ||
| g:12px 8px 12px 8px;text-align:left;"><!--[if mso | IE]><table role=3D"pres= | ||
| entation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td align=3D= | ||
| "left" class=3D"" width=3D"584px" ><table align=3D"center" border=3D"0" cel= | ||
| lpadding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation" style=3D"= | ||
| width:568px;" width=3D"568" ><tr><td style=3D"line-height:0px;font-size:0px= | ||
| ;mso-line-height-rule:exactly;"><![endif]--><div style=3D"margin:0px auto;m= | ||
| ax-width:568px;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cel= | ||
| lspacing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><td s= | ||
| tyle=3D"direction:ltr;font-size:0px;padding:0;text-align:left;"><!--[if mso= | ||
| | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspac= | ||
| ing=3D"0"><tr><td align=3D"left" class=3D"" style=3D"vertical-align:top;wid= | ||
| th:568px;" ><![endif]--><div class=3D"mj-column-per-100 mj-outlook-group-fi= | ||
| x" style=3D"font-size:0px;text-align:left;direction:ltr;display:inline-bloc= | ||
| k;vertical-align:top;width:100%;"><table border=3D"0" cellpadding=3D"0" cel= | ||
| lspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td style=3D= | ||
| "vertical-align:top;padding:0;"><table border=3D"0" cellpadding=3D"0" cells= | ||
| pacing=3D"0" role=3D"presentation" width=3D"100%"><tbody> <tr><td align=3D"= | ||
| left" style=3D"font-size:0px;padding:0;word-break:break-word;"><div style= | ||
| =3D"font-family:Ember,'Amazon Ember',Arial,sans-serif;font-size:15px;line-h= | ||
| eight:1;text-align:left;color:#000000;"><h2 style=3D"margin:0;padding:0;fon= | ||
| t-family:Ember,'Amazon Ember',Arial,sans-serif;font-weight:700;font-size:22= | ||
| px;line-height:28px;color:#0F1111;" class=3D"rio-header rio-header-64">Hi A= | ||
| ayush,</h2></div></td></tr></tbody></table></td></tr></tbody></table></div>= | ||
| <!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table><= | ||
| /div><!--[if mso | IE]></td></tr></table></td></tr><tr><td align=3D"left" c= | ||
| lass=3D"" width=3D"584px" ><![endif]--> <!--[if mso | IE]><table align= | ||
| =3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" class=3D"" rol= | ||
| e=3D"presentation" style=3D"width:568px;" width=3D"568" ><tr><td style=3D"l= | ||
| ine-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><di= | ||
| v style=3D"margin:0px auto;max-width:568px;"><table align=3D"center" border= | ||
| =3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" style=3D"w= | ||
| idth:100%;"><tbody><tr><td style=3D"direction:ltr;font-size:0px;padding:0;t= | ||
| ext-align:left;"><!--[if mso | IE]><table role=3D"presentation" border=3D"0= | ||
| " cellpadding=3D"0" cellspacing=3D"0"><tr><td align=3D"left" class=3D"" sty= | ||
| le=3D"vertical-align:top;width:568px;" ><![endif]--><div class=3D"mj-column= | ||
| -per-100 mj-outlook-group-fix" style=3D"font-size:0px;text-align:left;direc= | ||
| tion:ltr;display:inline-block;vertical-align:top;width:100%;"><table border= | ||
| =3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"1= | ||
| 00%"><tbody><tr><td style=3D"vertical-align:top;padding:0;"><table border= | ||
| =3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"1= | ||
| 00%"><tbody><tr><td align=3D"left" style=3D"font-size:0px;padding:0;word-br= | ||
| eak:break-word;"><div style=3D"font-family:Ember,'Amazon Ember',Arial,sans-= | ||
| serif;font-size:15px;font-weight:400;line-height:20px;text-align:left;color= | ||
| :#0F1111;"><span class=3D"rio-text rio-text-121">Your package has been deli= | ||
| vered to reception.</span></div></td></tr></tbody></table></td></tr></tbody= | ||
| ></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></= | ||
| tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--> = | ||
| <!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table>= | ||
| </div><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> <!--[if m= | ||
| so | IE]></table><![endif]--></td></tr></tbody></table></div><!--[if mso | = | ||
| IE]></td></tr></table><![endif]--><!--[if mso | IE]><table align=3D"center"= | ||
| border=3D"0" cellpadding=3D"0" cellspacing=3D"0" class=3D"rootContent-outl= | ||
| ook" role=3D"presentation" style=3D"width:600px;" width=3D"600" bgcolor=3D"= | ||
| #D5D9D9" ><tr><td style=3D"line-height:0px;font-size:0px;mso-line-height-ru= | ||
| le:exactly;"><![endif]--><div class=3D"rootContent" style=3D"background:#D5= | ||
| D9D9;background-color:#D5D9D9;margin:0px auto;max-width:600px;"><table alig= | ||
| n=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"prese= | ||
| ntation" style=3D"background:#D5D9D9;background-color:#D5D9D9;width:100%;">= | ||
| <tbody><tr><td style=3D"direction:ltr;font-size:0px;padding:4px 8px 4px 8px= | ||
| ;text-align:left;"><!--[if mso | IE]><table role=3D"presentation" border=3D= | ||
| "0" cellpadding=3D"0" cellspacing=3D"0"><![endif]--> <!--[if mso | IE]><tr>= | ||
| <td align=3D"left" class=3D"rex-order-card-outlook rex-order-card-v1-outloo= | ||
| k" width=3D"600px" ><table align=3D"center" border=3D"0" cellpadding=3D"0" = | ||
| cellspacing=3D"0" class=3D"rio-card-outlook rio-card-71-outlook" role=3D"pr= | ||
| esentation" style=3D"width:584px;" width=3D"584" bgcolor=3D"#ffffff" ><tr><= | ||
| td style=3D"line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><!= | ||
| [endif]--><div class=3D"rio-card rio-card-71" style=3D"background:#ffffff;b= | ||
| ackground-color:#ffffff;margin:0px auto;border-radius:4px;max-width:584px;"= | ||
| ><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" r= | ||
| ole=3D"presentation" style=3D"background:#ffffff;background-color:#ffffff;w= | ||
| idth:100%;border-radius:4px;"><tbody><tr><td style=3D"direction:ltr;font-si= | ||
| ze:0px;padding:12px 8px 16px 8px;text-align:left;"><!--[if mso | IE]><table= | ||
| role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><![= | ||
| endif]--> <!--[if mso | IE]><tr><td align=3D"left" class=3D"" width= | ||
| =3D"584px" ><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspac= | ||
| ing=3D"0" class=3D"" role=3D"presentation" style=3D"width:568px;" width=3D"= | ||
| 568" ><tr><td style=3D"line-height:0px;font-size:0px;mso-line-height-rule:e= | ||
| xactly;"><![endif]--><div style=3D"margin:0px auto;max-width:568px;"><table= | ||
| align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"= | ||
| presentation" style=3D"width:100%;"><tbody><tr><td style=3D"direction:ltr;f= | ||
| ont-size:0px;padding:0;text-align:left;"><!--[if mso | IE]><table role=3D"p= | ||
| resentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td align= | ||
| =3D"left" class=3D"" style=3D"vertical-align:middle;width:568px;" ><![endif= | ||
| ]--><div class=3D"mj-column-per-100 mj-outlook-group-fix" style=3D"font-siz= | ||
| e:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:mid= | ||
| dle;width:100%;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" ro= | ||
| le=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"vertical-align:m= | ||
| iddle;padding:0;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" r= | ||
| ole=3D"presentation" width=3D"100%"><tbody><tr><td align=3D"left" style=3D"= | ||
| font-size:0px;padding:0;word-break:break-word;"><div style=3D"font-family:E= | ||
| mber,'Amazon Ember',Arial,sans-serif;font-size:18px;font-weight:700;line-he= | ||
| ight:22px;text-align:left;color:#0F1111;"><span class=3D"rio-text rio-text-= | ||
| 122">How was your delivery?</span></div></td></tr><tr><td align=3D"left" cl= | ||
| ass=3D"rio-spacer" style=3D"font-size:0px;padding:0;word-break:break-word;"= | ||
| ><div style=3D"height:12px;line-height:12px;"> </div></td></tr></tbod= | ||
| y></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></tab= | ||
| le><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr>= | ||
| </table><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing= | ||
| =3D"0" class=3D"" role=3D"presentation" style=3D"width:568px;" width=3D"568= | ||
| " ><tr><td style=3D"line-height:0px;font-size:0px;mso-line-height-rule:exac= | ||
| tly;"><![endif]--><div style=3D"margin:0px auto;max-width:568px;"><table al= | ||
| ign=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"pre= | ||
| sentation" style=3D"width:100%;"><tbody><tr><td style=3D"direction:ltr;font= | ||
| -size:0px;padding:0;text-align:left;"><!--[if mso | IE]><table role=3D"pres= | ||
| entation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td align=3D= | ||
| "left" class=3D"" style=3D"width:568px;" ><![endif]--><div class=3D"mj-colu= | ||
| mn-per-100 mj-outlook-group-fix" style=3D"font-size:0;line-height:0;text-al= | ||
| ign:left;display:inline-block;width:100%;direction:ltr;"><!--[if mso | IE]>= | ||
| <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentatio= | ||
| n" ><tr><td style=3D"align:left;vertical-align:middle;width:284px;" ><![end= | ||
| if]--><div class=3D"mj-column-per-50 mj-outlook-group-fix" style=3D"font-si= | ||
| ze:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:mi= | ||
| ddle;width:50%;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" ro= | ||
| le=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"vertical-align:m= | ||
| iddle;padding:0;padding-right:4px;padding-left:0;"><table border=3D"0" cell= | ||
| padding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody= | ||
| ><tr><td align=3D"left" style=3D"font-size:0px;padding:0;word-break:break-w= | ||
| ord;"><!--[if mso | IE]><table align=3D"center" border=3D"0" cellpadding=3D= | ||
| "0" cellspacing=3D"0" class=3D"" role=3D"presentation" style=3D"width:280px= | ||
| ;" width=3D"280" ><tr><td style=3D"line-height:0px;font-size:0px;mso-line-h= | ||
| eight-rule:exactly;"><![endif]--><div style=3D"margin:0px auto;max-width:28= | ||
| 0px;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D= | ||
| "0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><td style=3D"dir= | ||
| ection:ltr;font-size:0px;padding:0;text-align:left;"><!--[if mso | IE]><tab= | ||
| le role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><= | ||
| tr><td align=3D"left" class=3D"" style=3D"vertical-align:top;width:280px;" = | ||
| ><![endif]--><div class=3D"mj-column-per-100 mj-outlook-group-fix" style=3D= | ||
| "font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-= | ||
| align:top;width:100%;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D= | ||
| "0" role=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"background= | ||
| -color:#F0F2F2;border-radius:4px;vertical-align:top;padding:0;"><table bord= | ||
| er=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D= | ||
| "100%"><tbody><tr><td align=3D"left" style=3D"font-size:0px;padding:0;word-= | ||
| break:break-word;"><div style=3D"font-family:Ember,'Amazon Ember',Arial,san= | ||
| s-serif;font-size:13px;font-weight:400;line-height:18px;text-align:center;c= | ||
| olor:#0F1111;"><span class=3D"rio-text rio-text-123"><a href=3D"https://www= | ||
| .amazon.com/gp/r.html?C=3D1Z6HAGN0Q74SS&K=3D1PCIPA854472X&M=3Durn:rtn:msg:2= | ||
| 0240816010133af409d4398414b769006b814f360p0na&R=3DSIRM1R078GGM&T=3DC&U=3Dht= | ||
| tps%3A%2F%2Fwww.amazon.com%2Fprogress-tracker%2Fpackage%3F_encoding%3DUTF8%= | ||
| 26itemId%3D%26orderId%3D111-3061760-5513056%26packageIndex%3D0%26shipmentId= | ||
| %3D300612189807301%26ingress%3Demail%26intent%3Dfeedback_happy%26ref_%3Dpe_= | ||
| 108877690_917195550_pdc_f_h&H=3DC5X8OQYHSNU4HZWASVBUOHCGVGGA&ref_=3Dpe_1088= | ||
| 77690_917195550_pdc_f_h" target=3D"_blank" style=3D"mso-margin-top-alt: 16p= | ||
| x;"><img href=3D"https://www.amazon.com/progress-tracker/package?_encoding= | ||
| =3DUTF8&itemId=3D&orderId=3D111-3061760-5513056&packageIndex=3D= | ||
| 0&shipmentId=3D300612189807301&ingress=3Demail&intent=3Dfeedbac= | ||
| k_happy&ref_=3Dpdc_f_h" src=3D"https://m.media-amazon.com/images/G/01/T= | ||
| xNotifications/Rio/thumbs_up.png" alt=3D"It was great" width=3D"24" height= | ||
| =3D"24" style=3D"margin: auto; padding: 8px; mso-padding-alt: 0; display: b= | ||
| lock; width: 24px"><p style=3D"padding-bottom: 8px; margin: 0; mso-margin-b= | ||
| ottom-alt: 8px">It was great</p></a></span></div></td></tr></tbody></table>= | ||
| </td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endi= | ||
| f]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><!= | ||
| [endif]--></td></tr></tbody></table></td></tr></tbody></table></div><!--[if= | ||
| mso | IE]></td><td style=3D"align:left;vertical-align:middle;width:284px;"= | ||
| ><![endif]--><div class=3D"mj-column-per-50 mj-outlook-group-fix" style=3D= | ||
| "font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-= | ||
| align:middle;width:50%;"><table border=3D"0" cellpadding=3D"0" cellspacing= | ||
| =3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"vertica= | ||
| l-align:middle;padding:0;padding-right:0;padding-left:4px;"><table border= | ||
| =3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"1= | ||
| 00%"><tbody><tr><td align=3D"left" style=3D"font-size:0px;padding:0;word-br= | ||
| eak:break-word;"><!--[if mso | IE]><table align=3D"center" border=3D"0" cel= | ||
| lpadding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation" style=3D"= | ||
| width:280px;" width=3D"280" ><tr><td style=3D"line-height:0px;font-size:0px= | ||
| ;mso-line-height-rule:exactly;"><![endif]--><div style=3D"margin:0px auto;m= | ||
| ax-width:280px;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cel= | ||
| lspacing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><td s= | ||
| tyle=3D"direction:ltr;font-size:0px;padding:0;text-align:left;"><!--[if mso= | ||
| | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspac= | ||
| ing=3D"0"><tr><td align=3D"left" class=3D"" style=3D"vertical-align:top;wid= | ||
| th:280px;" ><![endif]--><div class=3D"mj-column-per-100 mj-outlook-group-fi= | ||
| x" style=3D"font-size:0px;text-align:left;direction:ltr;display:inline-bloc= | ||
| k;vertical-align:top;width:100%;"><table border=3D"0" cellpadding=3D"0" cel= | ||
| lspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td style=3D= | ||
| "background-color:#F0F2F2;border-radius:4px;vertical-align:top;padding:0;">= | ||
| <table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentatio= | ||
| n" width=3D"100%"><tbody><tr><td align=3D"left" style=3D"font-size:0px;padd= | ||
| ing:0;word-break:break-word;"><div style=3D"font-family:Ember,'Amazon Ember= | ||
| ',Arial,sans-serif;font-size:13px;font-weight:400;line-height:18px;text-ali= | ||
| gn:center;color:#0F1111;"><span class=3D"rio-text rio-text-124"><a href=3D"= | ||
| https://www.amazon.com/gp/r.html?C=3D1Z6HAGN0Q74SS&K=3D1PCIPA854472X&M=3Dur= | ||
| n:rtn:msg:20240816010133af409d4398414b769006b814f360p0na&R=3DMJGP66VISZXC&T= | ||
| =3DC&U=3Dhttps%3A%2F%2Fwww.amazon.com%2Fprogress-tracker%2Fpackage%3F_encod= | ||
| ing%3DUTF8%26itemId%3D%26orderId%3D111-3061760-5513056%26packageIndex%3D0%2= | ||
| 6shipmentId%3D300612189807301%26ingress%3Demail%26intent%3Dfeedback_unhappy= | ||
| %26ref_%3Dpe_108877690_917195550_pdc_f_s&H=3DGWG8R3TO7P0CBBABRRGLVRPQV9YA&r= | ||
| ef_=3Dpe_108877690_917195550_pdc_f_s" target=3D"_blank" style=3D"mso-margin= | ||
| -top-alt: 16px;"><img href=3D"https://www.amazon.com/progress-tracker/packa= | ||
| ge?_encoding=3DUTF8&itemId=3D&orderId=3D111-3061760-5513056&pac= | ||
| kageIndex=3D0&shipmentId=3D300612189807301&ingress=3Demail&inte= | ||
| nt=3Dfeedback_unhappy&ref_=3Dpdc_f_s" src=3D"https://m.media-amazon.com= | ||
| /images/G/01/TxNotifications/Rio/thumbs_down.png" alt=3D"Not so great" widt= | ||
| h=3D"24" height=3D"24" style=3D"margin: auto; padding: 8px; mso-padding-alt= | ||
| : 0; display: block; width: 24px"><p style=3D"padding-bottom: 8px; margin: = | ||
| 0; mso-margin-bottom-alt: 8px">Not so great</p></a></span></div></td></tr><= | ||
| /tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr>= | ||
| </table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td>= | ||
| </tr></table><![endif]--></td></tr></tbody></table></td></tr></tbody></tabl= | ||
| e></div><!--[if mso | IE]></td></tr></table><![endif]--></div><!--[if mso |= | ||
| IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if = | ||
| mso | IE]></td></tr></table></td></tr><![endif]--> <!--[if mso | IE]><tr><t= | ||
| d align=3D"left" class=3D"rio-spacer-outlook" width=3D"584px" ><![endif]-->= | ||
| <div style=3D"height:20px;line-height:20px;"> </div><!--[if mso | IE]= | ||
| ></td></tr><![endif]--> <!--[if mso | IE]><tr><td align=3D"left" class=3D""= | ||
| width=3D"584px" ><table align=3D"center" border=3D"0" cellpadding=3D"0" ce= | ||
| llspacing=3D"0" class=3D"" role=3D"presentation" style=3D"width:568px;" wid= | ||
| th=3D"568" ><tr><td style=3D"line-height:0px;font-size:0px;mso-line-height-= | ||
| rule:exactly;"><![endif]--><div style=3D"margin:0px auto;max-width:568px;">= | ||
| <table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" ro= | ||
| le=3D"presentation" style=3D"width:100%;"><tbody><tr><td style=3D"direction= | ||
| :ltr;font-size:0px;padding:0;text-align:left;"><!--[if mso | IE]><table rol= | ||
| e=3D"presentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td= | ||
| align=3D"left" class=3D"" style=3D"vertical-align:top;width:568px;" ><![en= | ||
| dif]--><div class=3D"mj-column-per-100 mj-outlook-group-fix" style=3D"font-= | ||
| size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:= | ||
| top;width:100%;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" ro= | ||
| le=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"vertical-align:t= | ||
| op;padding:0;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role= | ||
| =3D"presentation" width=3D"100%"><tbody><tr><td align=3D"left" style=3D"fon= | ||
| t-size:0px;padding:0;word-break:break-word;"><div style=3D"font-family:Embe= | ||
| r,'Amazon Ember',Arial,sans-serif;font-size:15px;font-weight:400;line-heigh= | ||
| t:21px;text-align:left;color:#565959;"><span class=3D"rio-text rio-text-125= | ||
| ">Order #</span></div></td></tr><tr><td align=3D"left" style=3D"font-size:0= | ||
| px;padding:0;word-break:break-word;"><div style=3D"font-family:Ember,'Amazo= | ||
| n Ember',Arial,sans-serif;font-size:15px;font-weight:700;line-height:21px;t= | ||
| ext-align:left;color:#0F1111;"><span class=3D"rio-text rio-text-126">111-30= | ||
| 61760-5513056</span></div></td></tr></tbody></table></td></tr></tbody></tab= | ||
| le></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody>= | ||
| </table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td align= | ||
| =3D"left" class=3D"" width=3D"584px" ><table align=3D"center" border=3D"0" = | ||
| cellpadding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation" style= | ||
| =3D"width:568px;" width=3D"568" ><tr><td style=3D"line-height:0px;font-size= | ||
| :0px;mso-line-height-rule:exactly;"><![endif]--><div style=3D"margin:0px au= | ||
| to;max-width:568px;"><table align=3D"center" border=3D"0" cellpadding=3D"0"= | ||
| cellspacing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><= | ||
| td style=3D"direction:ltr;font-size:0px;padding:0;text-align:left;"><!--[if= | ||
| mso | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" cell= | ||
| spacing=3D"0"><tr><td align=3D"left" class=3D"" style=3D"width:568px;" ><![= | ||
| endif]--><div class=3D"mj-column-per-100 mj-outlook-group-fix" style=3D"fon= | ||
| t-size:0;line-height:0;text-align:left;display:inline-block;width:100%;dire= | ||
| ction:ltr;"><!--[if mso | IE]><table border=3D"0" cellpadding=3D"0" cellspa= | ||
| cing=3D"0" role=3D"presentation" ><tr><td style=3D"align:left;vertical-alig= | ||
| n:top;width:284px;" ><![endif]--><div class=3D"mj-column-per-50 mj-outlook-= | ||
| group-fix" style=3D"font-size:0px;text-align:left;direction:ltr;display:inl= | ||
| ine-block;vertical-align:top;width:50%;"><table border=3D"0" cellpadding=3D= | ||
| "0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td s= | ||
| tyle=3D"vertical-align:top;padding:0;"><table border=3D"0" cellpadding=3D"0= | ||
| " cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody> <tr><td = | ||
| align=3D"left" class=3D"rio-spacer" style=3D"font-size:0px;padding:0;word-b= | ||
| reak:break-word;"><div style=3D"height:20px;line-height:20px;"> </div= | ||
| ></td></tr><tr><td align=3D"left" style=3D"font-size:0px;padding:0;word-bre= | ||
| ak:break-word;"><!--[if gte mso 9]><style type=3D"text/css">.rio-button-cta= | ||
| -primary{background-color:#ffd814!important;border:1px solid #fcd200!import= | ||
| ant;padding:6px 16px!important;text-align:center;border-collapse:collapse!i= | ||
| mportant}.rio-button-primary{border:none!important}</style><![endif]--><tab= | ||
| le cellpadding=3D"0" cellspacing=3D"0" border=3D"0" role=3D"presentation"><= | ||
| tr><td class=3D"rio-button-cta-primary" style=3D"text-align: center"><a tar= | ||
| get=3D"_blank" aria-describedby=3D"Track package" class=3D"rio-button-prima= | ||
| ry" href=3D"https://www.amazon.com/gp/r.html?C=3D1Z6HAGN0Q74SS&K=3D1PCIPA85= | ||
| 4472X&M=3Durn:rtn:msg:20240816010133af409d4398414b769006b814f360p0na&R=3DBU= | ||
| 2DG84QM77R&T=3DC&U=3Dhttps%3A%2F%2Fwww.amazon.com%2Fgp%2Fyour-account%2Fshi= | ||
| p-track%3Fie%3DUTF8%26itemId%3D%26orderId%3D111-3061760-5513056%26packageIn= | ||
| dex%3D0%26shipmentId%3DGhsHRNhnG%26ref_%3Dpe_108877690_917195550_pdc_pt_tra= | ||
| ck&H=3DKVPMEEQKDCKNEZFWYBLC3E75A84A&ref_=3Dpe_108877690_917195550_pdc_pt_tr= | ||
| ack" style=3D"background-color: #FFD814; border: 1px solid #FCD200; color: = | ||
| #0f1111; text-decoration: none; border-radius: 24px;padding: 6px 16px;displ= | ||
| ay: inline-block;box-shadow: 1px 2px 4px rgba(153, 153, 153, 0.2);font-size= | ||
| : 13px;line-height: 18px;white-space: nowrap;"><span style=3D"text-decorati= | ||
| on: none">Track package</span></a></td></tr></table></td></tr></tbody></tab= | ||
| le></td></tr></tbody></table></div><!--[if mso | IE]></td><td style=3D"alig= | ||
| n:left;width:284px;" ><![endif]--><div class=3D"mj-column-per-50 mj-outlook= | ||
| -group-fix" style=3D"font-size:0;line-height:0;text-align:left;display:inli= | ||
| ne-block;width:100%;direction:ltr;"><!--[if mso | IE]><table border=3D"0" c= | ||
| ellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" ><tr></tr></table>= | ||
| <![endif]--></div><!--[if mso | IE]></td></tr></table><![endif]--></div><!-= | ||
| -[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></di= | ||
| v><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> <!--[if mso | = | ||
| IE]></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]><= | ||
| /td></tr></table></td></tr><![endif]--> <!--[if mso | IE]></table><![endif]= | ||
| --></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![e= | ||
| ndif]--><!--[if mso | IE]><table align=3D"center" border=3D"0" cellpadding= | ||
| =3D"0" cellspacing=3D"0" class=3D"rootContent-outlook" role=3D"presentation= | ||
| " style=3D"width:600px;" width=3D"600" bgcolor=3D"#D5D9D9" ><tr><td style= | ||
| =3D"line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-= | ||
| -><div class=3D"rootContent" style=3D"background:#D5D9D9;background-color:#= | ||
| D5D9D9;margin:0px auto;max-width:600px;"><table align=3D"center" border=3D"= | ||
| 0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" style=3D"backg= | ||
| round:#D5D9D9;background-color:#D5D9D9;width:100%;"><tbody><tr><td style=3D= | ||
| "direction:ltr;font-size:0px;padding:4px 8px 4px 8px;text-align:left;"><!--= | ||
| [if mso | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" c= | ||
| ellspacing=3D"0"><![endif]--> <!--[if mso | IE]><tr><td align=3D"left= | ||
| " class=3D"sonar-informational-outlook sonar-informational-v1-outlook" widt= | ||
| h=3D"600px" ><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspa= | ||
| cing=3D"0" class=3D"rio-card-outlook rio-card-72-outlook" role=3D"presentat= | ||
| ion" style=3D"width:584px;" width=3D"584" bgcolor=3D"#ffffff" ><tr><td styl= | ||
| e=3D"line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]= | ||
| --><div class=3D"rio-card rio-card-72" style=3D"background:#ffffff;backgrou= | ||
| nd-color:#ffffff;margin:0px auto;border-radius:4px;max-width:584px;"><table= | ||
| align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"= | ||
| presentation" style=3D"background:#ffffff;background-color:#ffffff;width:10= | ||
| 0%;border-radius:4px;"><tbody><tr><td style=3D"direction:ltr;font-size:0px;= | ||
| padding:12px 8px 12px 8px;text-align:left;"><!--[if mso | IE]><table role= | ||
| =3D"presentation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td = | ||
| align=3D"left" class=3D"" width=3D"584px" ><table align=3D"center" border= | ||
| =3D"0" cellpadding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation"= | ||
| style=3D"width:568px;" width=3D"568" ><tr><td style=3D"line-height:0px;fon= | ||
| t-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style=3D"margin:= | ||
| 0px auto;max-width:568px;"><table align=3D"center" border=3D"0" cellpadding= | ||
| =3D"0" cellspacing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody= | ||
| ><tr><td style=3D"direction:ltr;font-size:0px;padding:0;text-align:left;"><= | ||
| !--[if mso | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0= | ||
| " cellspacing=3D"0"><tr><td align=3D"left" class=3D"" style=3D"vertical-ali= | ||
| gn:top;width:568px;" ><![endif]--><div class=3D"mj-column-per-100 mj-outloo= | ||
| k-group-fix" style=3D"font-size:0px;text-align:left;direction:ltr;display:i= | ||
| nline-block;vertical-align:top;width:100%;"><table border=3D"0" cellpadding= | ||
| =3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><t= | ||
| d style=3D"vertical-align:top;padding:0;"><table border=3D"0" cellpadding= | ||
| =3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody> </tbo= | ||
| dy></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></ta= | ||
| ble><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr= | ||
| ></table></td></tr><tr><td align=3D"left" class=3D"" width=3D"584px" ><![en= | ||
| dif]--> <!--[if mso | IE]><table align=3D"center" border=3D"0" cellpad= | ||
| ding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation" style=3D"widt= | ||
| h:568px;" width=3D"568" ><tr><td style=3D"line-height:0px;font-size:0px;mso= | ||
| -line-height-rule:exactly;"><![endif]--><div style=3D"margin:0px auto;max-w= | ||
| idth:568px;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspa= | ||
| cing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><td style= | ||
| =3D"direction:ltr;font-size:0px;padding:0;text-align:left;"><!--[if mso | I= | ||
| E]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" cellspacing= | ||
| =3D"0"><tr><td align=3D"left" class=3D"" style=3D"vertical-align:top;width:= | ||
| 568px;" ><![endif]--><div class=3D"mj-column-per-100 mj-outlook-group-fix" = | ||
| style=3D"font-size:0px;text-align:left;direction:ltr;display:inline-block;v= | ||
| ertical-align:top;width:100%;"><table border=3D"0" cellpadding=3D"0" cellsp= | ||
| acing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td style=3D"ve= | ||
| rtical-align:top;padding:0;"><table border=3D"0" cellpadding=3D"0" cellspac= | ||
| ing=3D"0" role=3D"presentation" width=3D"100%"><tbody><tr><td align=3D"left= | ||
| " style=3D"font-size:0px;padding:0;word-break:break-word;"><div style=3D"fo= | ||
| nt-family:Ember,'Amazon Ember',Arial,sans-serif;font-size:15px;font-weight:= | ||
| 400;line-height:20px;text-align:left;color:#0F1111;"><span class=3D"rio-tex= | ||
| t rio-text-129">Return or replace items in=20 | ||
| <a href=3D"https://www.amazon.com/gp/r.html?C=3D1Z6HAGN0Q74SS&K=3D1PCIPA854= | ||
| 472X&M=3Durn:rtn:msg:20240816010133af409d4398414b769006b814f360p0na&R=3D2U7= | ||
| FVGB1HZ63S&T=3DC&U=3Dhttps%3A%2F%2Fwww.amazon.com%2Fyour-orders%2Forders%3F= | ||
| ref_%3Dpe_108877690_917195550_pdc_yo&H=3DMRR6NURCHGXV0VKPAM2B9LRNHGKA&ref_= | ||
| =3Dpe_108877690_917195550_pdc_yo" rel=3D"nofollow">Your Orders</a>.</span><= | ||
| /div></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso = | ||
| | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if= | ||
| mso | IE]></td></tr></table><![endif]--> <!--[if mso | IE]></td></t= | ||
| r></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></t= | ||
| d></tr></table></td></tr><![endif]--> <!--[if mso | IE]></table><![endif]-= | ||
| -></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![en= | ||
| dif]--><!--[if mso | IE]><table align=3D"center" border=3D"0" cellpadding= | ||
| =3D"0" cellspacing=3D"0" class=3D"rootContent-outlook" role=3D"presentation= | ||
| " style=3D"width:600px;" width=3D"600" bgcolor=3D"#D5D9D9" ><tr><td style= | ||
| =3D"line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-= | ||
| -><div class=3D"rootContent" style=3D"background:#D5D9D9;background-color:#= | ||
| D5D9D9;margin:0px auto;max-width:600px;"><table align=3D"center" border=3D"= | ||
| 0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" style=3D"backg= | ||
| round:#D5D9D9;background-color:#D5D9D9;width:100%;"><tbody><tr><td style=3D= | ||
| "direction:ltr;font-size:0px;padding:4px 0px 0px 0px;text-align:left;"><!--= | ||
| [if mso | IE]><table role=3D"presentation" border=3D"0" cellpadding=3D"0" c= | ||
| ellspacing=3D"0"><![endif]--> <!--[if mso | IE]><tr><td align=3D"left" clas= | ||
| s=3D"sonar-footer-outlook sonar-footer-v1-outlook" width=3D"600px" ><table = | ||
| align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" class=3D"= | ||
| footerCard-outlook" role=3D"presentation" style=3D"width:600px;" width=3D"6= | ||
| 00" bgcolor=3D"#F0F2F2" ><tr><td style=3D"line-height:0px;font-size:0px;mso= | ||
| -line-height-rule:exactly;"><![endif]--><div class=3D"footerCard" style=3D"= | ||
| background:#F0F2F2;background-color:#F0F2F2;margin:0px auto;max-width:600px= | ||
| ;"><table align=3D"center" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"= | ||
| role=3D"presentation" style=3D"background:#F0F2F2;background-color:#F0F2F2= | ||
| ;width:100%;"><tbody><tr><td style=3D"direction:ltr;font-size:0px;padding:0= | ||
| ;text-align:left;"><!--[if mso | IE]><table role=3D"presentation" border=3D= | ||
| "0" cellpadding=3D"0" cellspacing=3D"0"><tr><td align=3D"left" class=3D"foo= | ||
| terText-outlook" width=3D"600px" ><table align=3D"center" border=3D"0" cell= | ||
| padding=3D"0" cellspacing=3D"0" class=3D"footerText-outlook" role=3D"presen= | ||
| tation" style=3D"width:600px;" width=3D"600" ><tr><td style=3D"line-height:= | ||
| 0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div class=3D"= | ||
| footerText" style=3D"margin:0px auto;max-width:600px;"><table align=3D"cent= | ||
| er" border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presentation" = | ||
| style=3D"width:100%;"><tbody><tr><td style=3D"direction:ltr;font-size:0px;p= | ||
| adding:20px 16px 0;text-align:left;"><!--[if mso | IE]><table role=3D"prese= | ||
| ntation" border=3D"0" cellpadding=3D"0" cellspacing=3D"0"><tr><td align=3D"= | ||
| left" class=3D"" style=3D"vertical-align:top;width:568px;" ><![endif]--><di= | ||
| v class=3D"mj-column-per-100 mj-outlook-group-fix" style=3D"font-size:0px;t= | ||
| ext-align:left;direction:ltr;display:inline-block;vertical-align:top;width:= | ||
| 100%;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"pres= | ||
| entation" width=3D"100%"><tbody><tr><td style=3D"vertical-align:top;padding= | ||
| :0;"><table border=3D"0" cellpadding=3D"0" cellspacing=3D"0" role=3D"presen= | ||
| tation" width=3D"100%"><tbody><tr><td align=3D"left" style=3D"font-size:0px= | ||
| ;padding:0;word-break:break-word;"><div style=3D"font-family:Ember,'Amazon = | ||
| Ember',Arial,sans-serif;font-size:14px;font-weight:400;line-height:20px;tex= | ||
| t-align:left;color:#494D4D;">=C2=A92024 Amazon.com, Inc. or its affiliates.= | ||
| Amazon and all related marks are trademarks of Amazon.com, Inc. or its aff= | ||
| iliates, Amazon.com, Inc. 410 Terry Avenue N., Seattle, WA 98109.</div></td= | ||
| ></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></t= | ||
| d></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE= | ||
| ]></td></tr></table></td></tr><![endif]--> <!--[if mso | IE]><tr><td align= | ||
| =3D"left" class=3D"" width=3D"600px" ><table align=3D"center" border=3D"0" = | ||
| cellpadding=3D"0" cellspacing=3D"0" class=3D"" role=3D"presentation" style= | ||
| =3D"width:600px;" width=3D"600" ><tr><td style=3D"line-height:0px;font-size= | ||
| :0px;mso-line-height-rule:exactly;"><![endif]--><div style=3D"margin:0px au= | ||
| to;max-width:600px;"><table align=3D"center" border=3D"0" cellpadding=3D"0"= | ||
| cellspacing=3D"0" role=3D"presentation" style=3D"width:100%;"><tbody><tr><= | ||
| td style=3D"direction:ltr;font-size:0px;padding:14px 16px 4px 0;text-align:= | ||
| left;"><!--[if mso | IE]><table role=3D"presentation" border=3D"0" cellpadd= | ||
| ing=3D"0" cellspacing=3D"0"><tr><td align=3D"left" class=3D"" style=3D"vert= | ||
| ical-align:top;width:584px;" ><![endif]--><div class=3D"mj-column-per-100 m= | ||
| j-outlook-group-fix" style=3D"font-size:0px;text-align:left;direction:ltr;d= | ||
| isplay:inline-block;vertical-align:top;width:100%;"><table border=3D"0" cel= | ||
| lpadding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbod= | ||
| y><tr><td style=3D"vertical-align:top;padding:0;"><table border=3D"0" cellp= | ||
| adding=3D"0" cellspacing=3D"0" role=3D"presentation" width=3D"100%"><tbody>= | ||
| <table class=3D"lightFooterImg" style=3D"height:43px;width:86px;"><tr><td><= | ||
| img src=3D"https://m.media-amazon.com/images/G/01/outbound/OutboundTemplate= | ||
| s/Smile_Logo_Light._BG240,242,242_.png" alt=3D"Amazon.com" height=3D"43" wi= | ||
| dth=3D"86" align=3D"left"></td></tr></table><!--[if !mso]><!--><table class= | ||
| =3D"darkFooterImg" style=3D"height:43px;width:86px;display:none;"><tr><td><= | ||
| img src=3D"https://m.media-amazon.com/images/G/01/outbound/OutboundTemplate= | ||
| s/Smile_Logo_Dark.png" alt=3D"Amazon.com" height=3D"43" width=3D"86" align= | ||
| =3D"left"></td></tr></table><!--<![endif]--></tbody></table></td></tr></tbo= | ||
| dy></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr>= | ||
| </tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr></table= | ||
| ><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></= | ||
| table></td></tr><![endif]--> <!--[if mso | IE]></table><![endif]--></td></t= | ||
| r></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></d= | ||
| iv><img width=3D"1" height=3D"1" src=3D"https://www.amazon.com/gp/r.html?C= | ||
| =3D1Z6HAGN0Q74SS&K=3D1PCIPA854472X&M=3Durn:rtn:msg:20240816010133af409d4398= | ||
| 414b769006b814f360p0na&R=3D1RGIUEL0NLUB0&T=3DE&U=3Dhttps%3A%2F%2Fimages-na.= | ||
| ssl-images-amazon.com%2Fimages%2FG%2F01%2Fnav%2Ftransp.gif&H=3DHTTPRSBYHYPR= | ||
| XR0HOLWRVI18LHCA&ref_=3Dpe_108877690_917195550_open" /></body></html> | ||
| ------=_Part_533333_1464710557.1723770094034-- |
There was a problem hiding this comment.
Use sanitized fixture data; avoid committing real-looking personal email records.
Lines 1–1000 contain real-looking personal identifiers (email addresses, message metadata, order details) in a publicly served test asset. Please replace this fixture with anonymized/synthetic data.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_test/public/amazon.eml` around lines 1 - 1000, This fixture contains
real-looking PII (Delivered-To, From: "Amazon.com" <order-update@amazon.com>,
Message-ID, order number 111-3061760-5513056 and other headers/body links);
replace them with anonymized synthetic values across the file (e.g. redact
Delivered-To, replace order-update@amazon.com and any real email addresses with
test@example.com, remove or replace Message-ID and ARC/SPF metadata, and convert
the order Id and shipmentId to a clearly fake token like ORDER-TEST-0000) so the
public test asset contains no real personal identifiers while preserving the
same structure for tests.
| Delivered-To: yogeshshahi120@gmail.com | ||
| Received: by 2002:a05:7108:5e85:b0:47f:4051:d657 with SMTP id ev5csp1218074gdb; | ||
| Fri, 22 Aug 2025 23:59:07 -0700 (PDT) | ||
| X-Google-Smtp-Source: AGHT+IFLl4l7A6SKSW7/X6M4sCbyCp6E/LtBnXgQitc3mXhmvPpLD9A15zKAm4Hv1x3ACxHbyy9r | ||
| X-Received: by 2002:a05:622a:209:b0:4b2:8ac4:ef6b with SMTP id d75a77b69052e-4b2aab28ce1mr69583081cf.78.1755932346900; | ||
| Fri, 22 Aug 2025 23:59:06 -0700 (PDT) | ||
| ARC-Seal: i=1; a=rsa-sha256; t=1755932346; cv=none; | ||
| d=google.com; s=arc-20240605; | ||
| b=d0GamXf3hsBhtc6AO7TIZ5CPJMHh9iMnwtWtm4yJx72YNrw3dhgDUgdOU0EEfHvQRY | ||
| nOGpejLM54/1JgQtcrkQU/qPr5EwSWzspHh6R4OTZj5I2g9QVS+A6NVor9VtfdxevkDx | ||
| eN7j6A7NSYsqH8Ml1k9ZZ9FmeNf1jNeWaQ2JFkQoZMCsyzlG46IUMJRQ19/SDfR9++QG | ||
| kYIa8vqtE779vdBsWI/tV0mh4fJ3349bx9SWK/xsdoEwsR8ScJNFmjlmVHoYCXu5DUba | ||
| 1LHeoKsO0GszHnJjeiBzcFXn8HLmSptPkHJYxSnN5tpd9jPCeN1vDZyTeWN4xFlRkl9e | ||
| bSYQ== | ||
| ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; | ||
| h=content-transfer-encoding:mime-version:subject:message-id:to:from | ||
| :date:dkim-signature; | ||
| bh=VHgcAWi2xRXZm0DA4ihT7cYtF7t6AYCtpVyB8R4WYMY=; | ||
| fh=MrUDigLt8TyE79/Vsak8GkhPoyKFErE0pW3gJJgnYJQ=; | ||
| b=ISTi3pvc8IB6i9cnJFpLAlcdiXUS3fzaNcCMG4qCXpCvGh0sl7M9tMbfXFwvJuCzZf | ||
| KXIQHW3xkvKpYA7qPrrLYRDj89Poar6Lx9AxRnY3p4LVc6zSYmqsGujsaarceZvckFsa | ||
| 7VtsM6YzT2jd9tKSJv8DmWoc0616i8yU+XUPBOlpkVD5FElN+p9WYggbrdZLDeboiPqb | ||
| 25qyk5hyEo5RFCTSADJxHeiSKqUXMIHj0It1Lo5CrlhIfAC/BoQPGHGz6VlWmkfyozBj | ||
| c/vuFVqKkwL4x1L5LGOu5ouvql/XOt8Nu4dQmZxT58mwhQyhPMtpYSPt/58N3mrDAoOw | ||
| mDaw==; | ||
| dara=google.com | ||
| ARC-Authentication-Results: i=1; mx.google.com; | ||
| dkim=pass header.i=@github.com header.s=pf2023 header.b=Juy8nwl8; | ||
| spf=pass (google.com: domain of noreply@github.com designates 192.30.252.211 as permitted sender) smtp.mailfrom=noreply@github.com; | ||
| dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=github.com | ||
| Return-Path: <noreply@github.com> | ||
| Received: from out-28.smtp.github.com (out-28.smtp.github.com. [192.30.252.211]) | ||
| by mx.google.com with ESMTPS id d75a77b69052e-4b2b8e43c0dsi7393621cf.846.2025.08.22.23.59.06 | ||
| for <yogeshshahi120@gmail.com> | ||
| (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); | ||
| Fri, 22 Aug 2025 23:59:06 -0700 (PDT) | ||
| Received-SPF: pass (google.com: domain of noreply@github.com designates 192.30.252.211 as permitted sender) client-ip=192.30.252.211; | ||
| Authentication-Results: mx.google.com; | ||
| dkim=pass header.i=@github.com header.s=pf2023 header.b=Juy8nwl8; | ||
| spf=pass (google.com: domain of noreply@github.com designates 192.30.252.211 as permitted sender) smtp.mailfrom=noreply@github.com; | ||
| dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=github.com | ||
| Received: from github.com (hubbernetes-node-531b44e.ash1-iad.github.net [10.56.208.50]) | ||
| by smtp.github.com (Postfix) with ESMTPA id 9B1239206DD; | ||
| Fri, 22 Aug 2025 23:59:06 -0700 (PDT) | ||
| DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; | ||
| s=pf2023; t=1755932346; | ||
| bh=VHgcAWi2xRXZm0DA4ihT7cYtF7t6AYCtpVyB8R4WYMY=; | ||
| h=Date:From:To:Subject:From; | ||
| b=Juy8nwl8FUv8aQ1x1rEOCiikwzic8OqoCCOjBHaWe2hC46AFbFHQzQSFKc2lmi4H0 | ||
| 2gwbBlJQ9FU2DzNyY/l425GX+JeZMlBoJlztrmew8KoypcOHV4BqX5LhLcFAra+s5e | ||
| bDTWDfRN31+F9XhRBNpqL3jc8ybSV2rY0TWoIQEs= | ||
| Date: Fri, 22 Aug 2025 23:59:06 -0700 | ||
| From: GitHub <noreply@github.com> | ||
| To: Yogesh Shahi <yogeshshahi120@gmail.com> | ||
| Message-ID: <68a966ba9905b_fa10b81089f3@lowworker-74c7b88f6d-m2b9v.mail> | ||
| Subject: [GitHub] A third-party OAuth application has been added to your | ||
| account | ||
| Mime-Version: 1.0 | ||
| Content-Type: text/plain; | ||
| charset=UTF-8 | ||
| Content-Transfer-Encoding: 7bit | ||
| X-Auto-Response-Suppress: All | ||
|
|
||
| Hey BornPsych! | ||
|
|
||
| A third-party OAuth application (ETHGlobal) with read:user and user:email scopes was recently authorized to access your account. | ||
| Visit https://github.com/settings/connections/applications/7f0a42d8039f524b6a28 for more information. | ||
|
|
||
| To see this and other security events for your account, visit https://github.com/settings/security-log | ||
|
|
||
| If you run into problems, please contact support by visiting https://github.com/contact | ||
|
|
||
| Thanks, | ||
| The GitHub Team | ||
|
|
There was a problem hiding this comment.
Don't commit real account-security emails under public/.
This fixture exposes a real email address and a GitHub OAuth authorization event. Since it sits in browser_test/public/, the entire raw message is also directly accessible to the browser test app. Please swap this for a redacted or synthetic fixture.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_test/public/github.eml` around lines 1 - 75, The committed EML
fixture (github.eml) contains real PII and an actual GitHub OAuth event; replace
it with a redacted or synthetic fixture: remove or replace real email addresses
(From/To), strip or genericize security URLs and message-id, and replace the
body with a clearly synthetic message (e.g., placeholder sender, recipient, and
fake OAuth app name/scopes) so tests exercise parsing without exposing real
data; ensure the new fixture preserves the same MIME structure/headers your
tests expect and update any tests that assert exact strings to match the
redacted placeholders.
| Delivered-To: adityabisht64@gmail.com | ||
| Received: by 2002:a05:6504:1313:b0:279:6670:9162 with SMTP id s19csp1104512lto; | ||
| Thu, 5 Sep 2024 14:04:50 -0700 (PDT) | ||
| X-Forwarded-Encrypted: i=2; AJvYcCXmuTgC70UQT5Ts4OfBGnVnadr0JW74IPaiOJ5gDpOACNVP8eAJFJP4SA3ch7rvoG+htp/hPClBdbQKTZEu@gmail.com | ||
| X-Google-Smtp-Source: AGHT+IH76QMWC15Dg/+ThxNbcE5CDLb7cpojHoNsy/oAHrJx5dOAKtaNl1myXNjuD8Du2en5yyVL | ||
| X-Received: by 2002:a05:6870:63a9:b0:261:19a6:41ae with SMTP id 586e51a60fabf-27b82fab31bmr675802fac.30.1725570290222; | ||
| Thu, 05 Sep 2024 14:04:50 -0700 (PDT) | ||
| ARC-Seal: i=1; a=rsa-sha256; t=1725570290; cv=none; | ||
| d=google.com; s=arc-20160816; | ||
| b=LdXMuzrUNuNI+nDJ2bE4y4i/UNkay6ACfqFs51rtQOgUxDIYAuGZhqPw/monlbxkoN | ||
| NGihGo/EItYDoFyz2YenzxBQjpdSic9/g7qp6xz2O00PkGS43a1yOpd+ZVPlGaK5WZx1 | ||
| LhKdW5Fk7Jx/xJtl5rKnhBgH1SaWkv2pECv5SGasqct9PROtQeg+MMv1kwGqxFBHZ8d9 | ||
| 4ZrRPsKrp04FiG8hbMLUEV5xd1qwsdmDSqHLvmjhX82mN/ohEM4p/laq1OGzqMnM9SuC | ||
| 5vSNPUEx1wO49BEEqdQGVZ0qu8RQbAg6njk4bKUZoWSbDW1l/WU3Im+WbuCynOi8JMVw | ||
| pP6w== | ||
| ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; | ||
| h=cc:subject:message-id:date:from:mime-version:dkim-signature; | ||
| bh=ZPnp2Ot4Oq1yml0gwfVCa+vOkRh/AoPZcUFDo94M5cA=; | ||
| fh=rt5+XsSKgJXCbjLkZz2YEwXmYMAytcEAXMTatOTpOfs=; | ||
| b=qVd1nk6MrHSij4tsjZ6Lr+Ymptz0OlsUw3AMcXtBlrNhD0U+HLQPSTScNrBaX0i3uX | ||
| or7VZjCPegexDy+ovr56hI6M0878rRWyBvW8LRJVn2IsLmImIsePhDPYjU+8YGyHnJ9T | ||
| DPz0QtdM6Tzu/WeyWeYsA+B/ab+lIfZ910dtUmOjokCSa2JxGgLaTD/x75L91FpG4KSb | ||
| T+FumRRMXfEFx5I6uwMcHQmR1LE22Krkk9D/fs7WyqmNfSBL2eruURXcjOku3zjqK3Hs | ||
| mnOqjSUXqEeJLvI+DTPcZ6xqywiq5Pq8I1sCyBi4EVprdq06eDlB7yz+L4ECLB97offc | ||
| 4byg==; | ||
| dara=google.com | ||
| ARC-Authentication-Results: i=1; mx.google.com; | ||
| dkim=pass header.i=@succinct.xyz header.s=google header.b=PbaIBUZo; | ||
| spf=pass (google.com: domain of leland@succinct.xyz designates 209.85.220.41 as permitted sender) smtp.mailfrom=leland@succinct.xyz; | ||
| dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=succinct.xyz; | ||
| dara=pass header.i=@gmail.com | ||
| Return-Path: <leland@succinct.xyz> | ||
| Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) | ||
| by mx.google.com with SMTPS id 586e51a60fabf-277c34333casor4311308fac.9.2024.09.05.14.04.49 | ||
| for <adityabisht64@gmail.com> | ||
| (Google Transport Security); | ||
| Thu, 05 Sep 2024 14:04:50 -0700 (PDT) | ||
| Received-SPF: pass (google.com: domain of leland@succinct.xyz designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; | ||
| Authentication-Results: mx.google.com; | ||
| dkim=pass header.i=@succinct.xyz header.s=google header.b=PbaIBUZo; | ||
| spf=pass (google.com: domain of leland@succinct.xyz designates 209.85.220.41 as permitted sender) smtp.mailfrom=leland@succinct.xyz; | ||
| dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=succinct.xyz; | ||
| dara=pass header.i=@gmail.com | ||
| DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; | ||
| d=succinct.xyz; s=google; t=1725570289; x=1726175089; dara=google.com; | ||
| h=cc:subject:message-id:date:from:mime-version:from:to:cc:subject | ||
| :date:message-id:reply-to; | ||
| bh=ZPnp2Ot4Oq1yml0gwfVCa+vOkRh/AoPZcUFDo94M5cA=; | ||
| b=PbaIBUZod+MtWJh6mm0xQWE6KEJbub66abuVn6S+JQySDWT1c/wbaWs+Fe39s1svy3 | ||
| GTiD7JdDSgJ0XOQxdeO6vTbyFLI8lFp5UknjFxhIi9TecwN/oBgCVQpjXaQ8hdIh5fA2 | ||
| rZLURZB6/XnRnc1/I2DTrdegCDztjVty94pNZjKP1iRVCBQTfURoM4/r7ke1ez7P+qKG | ||
| uhKrt0XlPsEIbgeViKZpzlcjgfsbwEN0syimGnt+ccfmBx5r5lU9wG7HfW2i+EMOgOiu | ||
| +D4cX6uTOfYmBhCtH+HeErPenwgcQ0mTHxzcnAgPipVqTXA9VcQbgaCWB4hQtriMhYNU | ||
| B0ZA== | ||
| X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; | ||
| d=1e100.net; s=20230601; t=1725570289; x=1726175089; | ||
| h=cc:subject:message-id:date:from:mime-version:x-gm-message-state | ||
| :from:to:cc:subject:date:message-id:reply-to; | ||
| bh=ZPnp2Ot4Oq1yml0gwfVCa+vOkRh/AoPZcUFDo94M5cA=; | ||
| b=kSvDsE08OCPix+MrHQsGps+9FNVPep2YruDdHlAU9kN7KHlWYFEunPmEqxghhqMMqW | ||
| vR2nT+a+FgXLidImEorIK+DEdoIIAEPJwHnuY7C4jsTgqktXSQvYBrNqGgl0e7oEgs3X | ||
| X4OQdV/U9zQkXRF1MTBxy+OJMX1e9MQmm2Pv1FyfqWJA2x3wFo1dtmCocvjjJU7mzgl9 | ||
| 2t4ijcPtdZxsW8U9CRvwN3KzFPtdbT6c6uzUVNGhBmBSFi7HfGKbW3V2+uzRZIBAfoR9 | ||
| 4sqmGVYf5ycQAN2e5r2QwUT6oEca47vEB5IDMRadOM3caymamT2+SLR3sq5JrKm/2/j1 | ||
| C3kQ== | ||
| X-Forwarded-Encrypted: i=1; AJvYcCXxd8p4U8kra+dRtLXrArCb0RI+tf/okMTeOygvHmONJnKDrNbiVCZPinPL4j7RNT8h7+HhiwSoWhuKI1Mb@gmail.com | ||
| X-Gm-Message-State: AOJu0YxZgyTji/ChYSYLy8R8e+cfUgPmc5ZnDATk5epwZp5EqaRpnZzP | ||
| wXv1FS+cySFJJTaopk69+6+98CWXZ2JzXBqWFpLnGwLKkW6aEp7DwMSz2oXlDBdYXt+xWXULZ96 | ||
| pL4fvwj3nWBaCvEQc1dHauElTv9Bqq4rH8EwEYg== | ||
| X-Received: by 2002:a05:6870:af47:b0:278:8b:57b1 with SMTP id | ||
| 586e51a60fabf-27b82fab4a7mt675702fac.35.1725570289543; Thu, 05 Sep 2024 | ||
| 14:04:49 -0700 (PDT) | ||
| MIME-Version: 1.0 | ||
| From: Leland Lee <leland@succinct.xyz> | ||
| Date: Thu, 5 Sep 2024 14:04:38 -0700 | ||
| Message-ID: <CAPPv_w=DjyLg38_-aUvy7Lk-KP-YUaJROWForsmR6iaAgZCUVw@mail.gmail.com> | ||
| Subject: Welcome to the Succinct ZK Residency! | ||
| Cc: Uma Roy <uma@succinct.xyz>, Eli Yang <eli@succinct.xyz> | ||
| Content-Type: multipart/alternative; boundary="000000000000263095062165a40c" | ||
| Bcc: adityabisht64@gmail.com | ||
|
|
||
| --000000000000263095062165a40c | ||
| Content-Type: text/plain; charset="UTF-8" | ||
|
|
||
| Hi All, | ||
|
|
||
| We're thrilled to collaborate with you at the Succinct ZK residency in | ||
| three weeks. We can't wait to build together on a daily basis and bounce | ||
| ideas off each other. | ||
|
|
||
| To help us support your journey, please *complete the attached form | ||
| <https://docs.google.com/forms/d/e/1FAIpQLSfszQDE3DY5Tg4k3r-v9y3z8wnJy0g_mJKaB_4TRAEx-PnlpQ/viewform>* | ||
| with details about your project and a brief bio. Every resident must | ||
| complete the form. Your project information and bio will be shared with | ||
| other residents as we encourage collaboration and building in the open. | ||
|
|
||
| *Logistics* | ||
|
|
||
| - Please join residency telegram (https://t.me/+GHNdBiwW89VhOTkx) | ||
|
|
||
| We'll be sharing more information soon regarding logistics and schedules | ||
| through both email and telegram! | ||
|
|
||
| See you soon, | ||
| Succinct Team | ||
|
|
||
| --000000000000263095062165a40c | ||
| Content-Type: text/html; charset="UTF-8" | ||
| Content-Transfer-Encoding: quoted-printable | ||
|
|
||
| <div dir=3D"ltr"><div>Hi All,</div><div><br></div><div>We're thrilled t= | ||
| o collaborate with you at the Succinct ZK residency in three weeks. We can&= | ||
| #39;t wait to build together on a daily basis and bounce ideas off each oth= | ||
| er.</div><div><br></div><div>To help us support your journey, please <b><a = | ||
| href=3D"https://docs.google.com/forms/d/e/1FAIpQLSfszQDE3DY5Tg4k3r-v9y3z8wn= | ||
| Jy0g_mJKaB_4TRAEx-PnlpQ/viewform" target=3D"_blank">complete the attached f= | ||
| orm</a></b> with details about your project and a brief bio. Every resident= | ||
| must complete the form. Your project information and bio will be shared wi= | ||
| th other residents as we encourage collaboration and building in the open.<= | ||
| br></div><div><p><b>Logistics</b><br></p></div><div><ul><li>Please join res= | ||
| idency telegram (<a href=3D"https://t.me/+GHNdBiwW89VhOTkx" target=3D"_blan= | ||
| k">https://t.me/+GHNdBiwW89VhOTkx</a>)</li></ul><div>We'll be sharing m= | ||
| ore information soon regarding logistics and schedules through both email a= | ||
| nd telegram!</div><div><br></div><div>See you soon,<br></div></div><div>Suc= | ||
| cinct=C2=A0Team</div></div> | ||
|
|
||
| --000000000000263095062165a40c-- |
There was a problem hiding this comment.
Replace this public fixture with sanitized data.
This .eml contains real personal addresses, names, and live message content, and placing it under browser_test/public/ makes the raw email directly servable by the browser app. Please replace it with fully anonymized/synthetic data before merging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_test/public/residency.eml` around lines 1 - 127, The public .eml
fixture contains real PII (e.g., "From: Leland Lee <leland@succinct.xyz>", "Cc:
Uma Roy <uma@succinct.xyz>, Eli Yang <eli@succinct.xyz>", "Bcc:
adityabisht64@gmail.com", Message-ID and the real subject "Welcome to the
Succinct ZK Residency!"); replace the file contents with a fully sanitized,
synthetic email preserving the MIME structure and boundaries but using fake
names/addresses (e.g., "From: Test Sender <sender@example.com>"), anonymized
Subject and Message-ID, non-sensitive placeholder links (example.com), and
remove any real telegram/invite or personal content so the fixture can remain in
browser_test/public without exposing real data.
| init() | ||
| .then(() => { | ||
| relayerUtilsResolver(null); | ||
| }) | ||
| .catch((err) => { | ||
| console.error("Failed to initialize wasm for relayer-utils: ", err); | ||
| }); |
There was a problem hiding this comment.
Reject relayerUtilsInit when WASM initialization fails.
The catch branch only logs, so every later await relayerUtilsInit hangs forever after an init error instead of failing fast.
Proposed fix
-let relayerUtilsResolver: (value: any) => void;
-const relayerUtilsInit: Promise<void> = new Promise((resolve) => {
- relayerUtilsResolver = resolve;
+let relayerUtilsResolver!: () => void;
+let relayerUtilsRejecter!: (reason?: unknown) => void;
+const relayerUtilsInit: Promise<void> = new Promise((resolve, reject) => {
+ relayerUtilsResolver = resolve;
+ relayerUtilsRejecter = reject;
});
@@
.catch((err) => {
console.error("Failed to initialize wasm for relayer-utils: ", err);
+ relayerUtilsRejecter(err);
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_test/src/circomProver.ts` around lines 13 - 19, The current init()
catch only logs and leaves relayerUtilsInit unresolved; update the promise setup
so you capture both resolve and reject (e.g., relayerUtilsResolve and
relayerUtilsReject) instead of only relayerUtilsResolver, and in the catch
handler call relayerUtilsReject(err) (or otherwise reject relayerUtilsInit with
the error) so awaiting relayerUtilsInit fails fast on WASM init errors; locate
the init() call and the relayerUtilsResolver (promise creation for
relayerUtilsInit) and add the corresponding relayerUtilsReject usage in the
catch branch.
| pub fn trim_sha256_padding(data: &[u8]) -> &[u8] { | ||
| // SHA256 padding starts with 0x80 byte followed by zeros | ||
| // Find the last 0x80 byte (padding marker) | ||
| if let Some(padding_start) = data.iter().rposition(|&b| b == 0x80) { | ||
| // Check if everything after 0x80 is zeros or length encoding | ||
| let after_padding = &data[padding_start + 1..]; | ||
|
|
||
| // If we find 0x80 and it's followed by zeros/length, return data before padding | ||
| if after_padding.iter().rev().take(8).all(|&b| b != 0x80) { | ||
| return &data[..padding_start]; | ||
| } | ||
| } | ||
|
|
||
| // Fallback: find the last non-zero byte that isn't part of length encoding | ||
| // SHA256 padding ends with 8-byte length, so check if last 8 bytes look like length | ||
| if data.len() >= 8 { | ||
| let (content, _potential_length) = data.split_at(data.len() - 8); | ||
| // If last 8 bytes represent a reasonable length, trim from there | ||
| if let Some(last_nonzero) = content.iter().rposition(|&b| b != 0) { | ||
| if content[last_nonzero] == 0x80 { | ||
| return &content[..last_nonzero]; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Ultimate fallback: trim trailing zeros | ||
| if let Some(last_nonzero) = data.iter().rposition(|&b| b != 0) { | ||
| &data[..=last_nonzero] | ||
| } else { | ||
| data | ||
| } |
There was a problem hiding this comment.
Don't infer SHA padding from the last 0x80 byte.
A real header/body can legitimately contain 0x80, especially before UTF-8 decoding. In that case this heuristic truncates real content before src/circuit/noir/mod.rs:306-325 converts the bytes back to text. The trim point needs to be validated against the SHA-256 padding layout and length footer, not guessed from rposition(0x80).
| if selector_start_index < position_map.len() && selector_end_index < position_map.len() { | ||
| let original_start_index = position_map[selector_start_index]; | ||
| let original_end_index = position_map[selector_end_index]; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how position_map is constructed to understand the mapping semantics
rg -n "position_map" --type rust -B 3 -A 10Repository: zkemail/relayer-utils
Length of output: 7315
🏁 Script executed:
rg -n "remove_quoted_printable_soft_breaks" --type rust -A 30Repository: zkemail/relayer-utils
Length of output: 23294
Off-by-one error: selector_end_index bounds check and slicing may fail for matches at the end of cleaned content.
When the regex match ends at the last byte of the cleaned content, selector_end_index equals the actual cleaned length. Accessing position_map[selector_end_index] retrieves a padded usize::MAX value, causing the function to return an error even though the match is valid. Additionally, when in bounds, position_map[selector_end_index] provides the original index of the byte after the match, not the exclusive end needed for slicing the original body correctly.
🔧 Suggested fix for correct end index mapping
- if selector_start_index < position_map.len() && selector_end_index < position_map.len() {
+ if selector_start_index < position_map.len() && selector_end_index > 0 && selector_end_index <= position_map.len() {
let original_start_index = position_map[selector_start_index];
- let original_end_index = position_map[selector_end_index];
+ // m.end() is exclusive, so map the last matched index and add 1
+ let original_end_index = position_map[selector_end_index - 1] + 1;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if selector_start_index < position_map.len() && selector_end_index < position_map.len() { | |
| let original_start_index = position_map[selector_start_index]; | |
| let original_end_index = position_map[selector_end_index]; | |
| if selector_start_index < position_map.len() && selector_end_index > 0 && selector_end_index <= position_map.len() { | |
| let original_start_index = position_map[selector_start_index]; | |
| // m.end() is exclusive, so map the last matched index and add 1 | |
| let original_end_index = position_map[selector_end_index - 1] + 1; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/circuit/utils.rs` around lines 29 - 31, The current bounds check and
mapping for selector_end_index are wrong: allow selector_end_index ==
position_map.len() (use <=) and compute the exclusive original end correctly by
mapping selector_end_index to the original byte after the match; specifically,
keep original_start_index = position_map[selector_start_index], but set
original_end_index = if selector_end_index == position_map.len() {
original_body.len() } else { position_map[selector_end_index - 1] + 1 }; update
the if-condition from selector_end_index < position_map.len() to
selector_end_index <= position_map.len() and use these computed values for
slicing to avoid usize::MAX and off-by-one errors when matches end at the
cleaned content end.
| let body_str = { | ||
| // Undo SHA padding | ||
| let mut trimmed_body = body.clone(); | ||
| while !(trimmed_body.last() == Some(&10) | ||
| && trimmed_body.get(trimmed_body.len() - 2) == Some(&13)) | ||
| { | ||
| trimmed_body.pop(); | ||
| } | ||
|
|
||
| String::from_utf8(trimmed_body)? | ||
| }; |
There was a problem hiding this comment.
Return an error when the body never reaches \r\n.
Both loops can panic on short or malformed input: once trimmed_body.len() < 2, trimmed_body.len() - 2 underflows before you have a chance to return Err. That turns these Result-returning helpers into abort paths instead of parse failures.
Proposed fix
- while !(trimmed_body.last() == Some(&10)
- && trimmed_body.get(trimmed_body.len() - 2) == Some(&13))
- {
- trimmed_body.pop();
- }
+ while !trimmed_body.ends_with(b"\r\n") {
+ if trimmed_body.pop().is_none() {
+ return Err(Box::new(std::io::Error::new(
+ std::io::ErrorKind::InvalidData,
+ "Body does not contain a trailing CRLF before SHA padding",
+ )));
+ }
+ }Also applies to: 589-599
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/cryptos.rs` around lines 523 - 533, The loop that strips SHA padding in
the body_str construction (working on variable trimmed_body) can underflow when
trimmed_body.len() < 2; change the logic to loop only while trimmed_body.len()
>= 2 and the last two bytes are not b"\r\n", popping bytes as you go, and after
the loop return an Err (parse error) if trimmed_body.len() < 2 or the final two
bytes are not CRLF; apply the same fix to the analogous loop around lines
589-599. Ensure you use trimmed_body.last() and trimmed_body.get(len-2) safely
by checking len >= 2 before accessing len-2 and preserve the existing Result
error type when returning the parse failure.
| static ref FROM_ADDR_CONFIG: DecomposedRegexConfig = DecomposedRegexConfig { | ||
| parts: vec![ | ||
| RegexPart::Pattern(r"(?i)from:.*<".to_string()), | ||
| RegexPart::PublicPattern((r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}".to_string(), 256)), | ||
| RegexPart::Pattern(r">".to_string()), | ||
| ], | ||
| }; | ||
|
|
||
| /// Pattern for extracting To header | ||
| static ref TO_ADDR_CONFIG: DecomposedRegexConfig = DecomposedRegexConfig { | ||
| parts: vec![ | ||
| RegexPart::Pattern(r"(?i)to:.*<".to_string()), | ||
| RegexPart::PublicPattern((r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}".to_string(), 256)), | ||
| RegexPart::Pattern(r">".to_string()), | ||
| ], |
There was a problem hiding this comment.
Handle unbracketed From: / To: headers too.
These configs only match Display Name <addr> forms. Valid headers like From: alice@example.com and To: bob@example.com will return NoMatch, which then propagates into downstream parsing via src/parse_email.rs:6-9.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/regex/patterns.rs` around lines 24 - 38, Update FROM_ADDR_CONFIG and
TO_ADDR_CONFIG so they match both display-name-with-brackets and bare-address
forms; replace the surrounding fixed Pattern parts with versions that allow
optional angle-bracketed display names (e.g. change
RegexPart::Pattern(r"(?i)from:.*<") to something like r"(?i)from:\s*(?:.*<)?",
and change the trailing RegexPart::Pattern(r">") to an optional r"(?:>)?"), and
do the analogous change for the TO config; keep the existing
RegexPart::PublicPattern (the email capture) unchanged so DecomposedRegexConfig
still extracts the same group.
| static ref SUBJECT_CONFIG: DecomposedRegexConfig = DecomposedRegexConfig { | ||
| parts: vec![ | ||
| RegexPart::Pattern(r"(?i)subject:\s*".to_string()), | ||
| RegexPart::PublicPattern((r".+?(?=\r?\n\S|\r?\n\r?\n)".to_string(), 512)), | ||
| ], |
There was a problem hiding this comment.
Folded Subject: lines won't be captured completely.
.+? stops at the first physical line because . does not match \r / \n. RFC 5322 continuation lines (\r\n / \r\n\t) will be dropped even though this helper is named extract_subject_all_idxes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/regex/patterns.rs` around lines 42 - 46, The SUBJECT_CONFIG's public
pattern (RegexPart::PublicPattern currently using r".+?(?=\r?\n\S|\r?\n\r?\n)")
stops at physical newlines and thus drops RFC5322 folded continuation lines;
update that pattern to allow CRLF followed by SP/HTAB as part of the subject
(for example replace the dot-plus with a construct that matches either
non-newline chars or CRLF followed by a space/tab, e.g. a repeated group like
(?:[^\r\n]|\r?\n[ \t])+ with the same lookahead and keep the existing 512 length
cap) so extract_subject_all_idxes captures folded Subject: lines fully in
SUBJECT_CONFIG / DecomposedRegexConfig / RegexPart::PublicPattern.
Summary
prover-server.ts,circomProver.ts, andnoirProver.tsto usestaging-conductor.zk.emailinstead ofdev-conductor.zk.emailSummary by CodeRabbit
Release Notes
New Features
Improvements
Dependencies
sp1-verifierto version 5.0.0thiserror,fancy-regex, andnum-traitsdependencies